diff --git a/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt b/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt index c8abc0994..35df9a197 100644 --- a/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt +++ b/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt @@ -8,6 +8,7 @@ import prog8.ast.expressions.* import prog8.ast.statements.* import prog8.code.core.* import prog8.parser.Prog8ANTLRParser +import prog8.parser.Prog8ANTLRParser.* import kotlin.io.path.Path import kotlin.io.path.isRegularFile @@ -310,12 +311,18 @@ private fun Prog8ANTLRParser.Sub_paramsContext.toAst(): List AssignTarget(identifier.toAst(), null, null, toPosition()) - arrayindexed()!=null -> AssignTarget(null, arrayindexed().toAst(), null, toPosition()) - directmemory()!=null -> AssignTarget(null, null, DirectMemoryWrite(directmemory().expression().toAst(), toPosition()), toPosition()) - else -> AssignTarget(scoped_identifier()?.toAst(), null, null, toPosition()) + return when(this) { + is IdentifierTargetContext -> + AssignTarget(scoped_identifier().toAst(), null, null, scoped_identifier().toPosition()) + is MemoryTargetContext -> + AssignTarget(null, null, DirectMemoryWrite(directmemory().expression().toAst(), directmemory().toPosition()), 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) return scoped_identifier().toAst() @@ -448,9 +461,6 @@ private fun Prog8ANTLRParser.ExpressionContext.toAst() : Expression { if(childCount==3 && children[0].text=="(" && children[2].text==")") return expression(0).toAst() // expression within ( ) - if(arrayindexed()!=null) - return arrayindexed().toAst() - if(typecast()!=null) 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.Scoped_identifierContext.toAst() : IdentifierReference = diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 024b27b62..8d60e4534 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -1,6 +1,8 @@ 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 .... - 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! diff --git a/parser/antlr/Prog8ANTLR.g4 b/parser/antlr/Prog8ANTLR.g4 index 37d9011dd..742fd95cc 100644 --- a/parser/antlr/Prog8ANTLR.g4 +++ b/parser/antlr/Prog8ANTLR.g4 @@ -152,9 +152,9 @@ augassignment : ; assign_target: - scoped_identifier - | arrayindexed - | directmemory + scoped_identifier #IdentifierTarget + | scoped_identifier arrayindex #ArrayindexedTarget // TODO expression instead of just scoped_identifier + | directmemory #MemoryTarget ; postincrdecr : assign_target operator = ('++' | '--') ; @@ -180,7 +180,7 @@ expression : | left = expression EOL? bop = 'xor' EOL? right = expression | literalvalue | scoped_identifier - | arrayindexed + | scoped_identifier arrayindex // TODO expression instead of just scoped_identifier | directmemory | addressof | expression typecast @@ -188,8 +188,6 @@ expression : typecast : 'as' datatype; -arrayindexed : scoped_identifier arrayindex ; - directmemory : '@' '(' expression ')'; addressof : ADDRESS_OF scoped_identifier ;