prepare parser to be more flexible with array indexed expressions

This commit is contained in:
Irmen de Jong 2023-08-15 12:54:30 +02:00
parent 75514fc7af
commit 66857ca477
3 changed files with 25 additions and 21 deletions

View File

@ -8,6 +8,7 @@ import prog8.ast.expressions.*
import prog8.ast.statements.* import prog8.ast.statements.*
import prog8.code.core.* import prog8.code.core.*
import prog8.parser.Prog8ANTLRParser import prog8.parser.Prog8ANTLRParser
import prog8.parser.Prog8ANTLRParser.*
import kotlin.io.path.Path import kotlin.io.path.Path
import kotlin.io.path.isRegularFile import kotlin.io.path.isRegularFile
@ -310,12 +311,18 @@ private fun Prog8ANTLRParser.Sub_paramsContext.toAst(): List<SubroutineParameter
} }
private fun Prog8ANTLRParser.Assign_targetContext.toAst() : AssignTarget { private fun Prog8ANTLRParser.Assign_targetContext.toAst() : AssignTarget {
val identifier = scoped_identifier() return when(this) {
return when { is IdentifierTargetContext ->
identifier!=null -> AssignTarget(identifier.toAst(), null, null, toPosition()) AssignTarget(scoped_identifier().toAst(), null, null, scoped_identifier().toPosition())
arrayindexed()!=null -> AssignTarget(null, arrayindexed().toAst(), null, toPosition()) is MemoryTargetContext ->
directmemory()!=null -> AssignTarget(null, null, DirectMemoryWrite(directmemory().expression().toAst(), toPosition()), toPosition()) AssignTarget(null, null, DirectMemoryWrite(directmemory().expression().toAst(), directmemory().toPosition()), toPosition())
else -> AssignTarget(scoped_identifier()?.toAst(), null, null, toPosition()) is ArrayindexedTargetContext -> {
val arrayvar = scoped_identifier().toAst()
val index = arrayindex().toAst()
val arrayindexed = ArrayIndexedExpression(arrayvar, index, scoped_identifier().toPosition())
AssignTarget(null, arrayindexed, null, toPosition())
}
else -> throw FatalAstException("weird assign target node $this")
} }
} }
@ -427,6 +434,12 @@ private fun Prog8ANTLRParser.ExpressionContext.toAst() : Expression {
} }
} }
if(arrayindex()!=null) {
val identifier = scoped_identifier().toAst()
val index = arrayindex().toAst()
return ArrayIndexedExpression(identifier, index, scoped_identifier().toPosition())
}
if(scoped_identifier()!=null) if(scoped_identifier()!=null)
return scoped_identifier().toAst() return scoped_identifier().toAst()
@ -448,9 +461,6 @@ private fun Prog8ANTLRParser.ExpressionContext.toAst() : Expression {
if(childCount==3 && children[0].text=="(" && children[2].text==")") if(childCount==3 && children[0].text=="(" && children[2].text==")")
return expression(0).toAst() // expression within ( ) return expression(0).toAst() // expression within ( )
if(arrayindexed()!=null)
return arrayindexed().toAst()
if(typecast()!=null) if(typecast()!=null)
return TypecastExpression(expression(0).toAst(), typecast().datatype().toAst(), false, toPosition()) return TypecastExpression(expression(0).toAst(), typecast().datatype().toAst(), false, toPosition())
@ -497,12 +507,6 @@ private fun Prog8ANTLRParser.StringliteralContext.toAst(): StringLiteral {
} }
} }
private fun Prog8ANTLRParser.ArrayindexedContext.toAst(): ArrayIndexedExpression {
return ArrayIndexedExpression(scoped_identifier().toAst(),
arrayindex().toAst(),
toPosition())
}
private fun Prog8ANTLRParser.Expression_listContext.toAst() = expression().map{ it.toAst() } private fun Prog8ANTLRParser.Expression_listContext.toAst() = expression().map{ it.toAst() }
private fun Prog8ANTLRParser.Scoped_identifierContext.toAst() : IdentifierReference = private fun Prog8ANTLRParser.Scoped_identifierContext.toAst() : IdentifierReference =

View File

@ -1,6 +1,8 @@
TODO TODO
==== ====
- allow 'chained' array indexing for expressions: value = ptrarray[0][0]
- allow 'chained' array indexing for assign targets: ptrarray[0][0] = 42 this is just evaluating the lhs as a uword pointer expression
- [on branch:] investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 .... - [on branch:] investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 ....
- IR: reduce the number of branch instructions such as BEQ, BEQR, etc (gradually), replace with CMP(I) + status branch instruction - IR: reduce the number of branch instructions such as BEQ, BEQR, etc (gradually), replace with CMP(I) + status branch instruction
- IR: reduce amount of CMP/CMPI after instructions that set the status bits correctly (LOADs? INC? etc), but only after setting the status bits is verified! - IR: reduce amount of CMP/CMPI after instructions that set the status bits correctly (LOADs? INC? etc), but only after setting the status bits is verified!

View File

@ -152,9 +152,9 @@ augassignment :
; ;
assign_target: assign_target:
scoped_identifier scoped_identifier #IdentifierTarget
| arrayindexed | scoped_identifier arrayindex #ArrayindexedTarget // TODO expression instead of just scoped_identifier
| directmemory | directmemory #MemoryTarget
; ;
postincrdecr : assign_target operator = ('++' | '--') ; postincrdecr : assign_target operator = ('++' | '--') ;
@ -180,7 +180,7 @@ expression :
| left = expression EOL? bop = 'xor' EOL? right = expression | left = expression EOL? bop = 'xor' EOL? right = expression
| literalvalue | literalvalue
| scoped_identifier | scoped_identifier
| arrayindexed | scoped_identifier arrayindex // TODO expression instead of just scoped_identifier
| directmemory | directmemory
| addressof | addressof
| expression typecast | expression typecast
@ -188,8 +188,6 @@ expression :
typecast : 'as' datatype; typecast : 'as' datatype;
arrayindexed : scoped_identifier arrayindex ;
directmemory : '@' '(' expression ')'; directmemory : '@' '(' expression ')';
addressof : <assoc=right> ADDRESS_OF scoped_identifier ; addressof : <assoc=right> ADDRESS_OF scoped_identifier ;