From cbc3e37a89cc15dbda364c441498cf17221bb3df Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Mon, 22 Mar 2021 01:57:52 +0100 Subject: [PATCH] stuff --- compiler/src/prog8/compiler/Compiler.kt | 2 +- compiler/src/prog8/compiler/astprocessing/AstChecker.kt | 7 ++----- .../prog8/compiler/astprocessing/StatementReorderer.kt | 4 ++-- .../src/prog8/compiler/target/cpu6502/codegen/AsmGen.kt | 7 ++++++- compilerAst/src/prog8/ast/base/Base.kt | 8 +++++++- 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/compiler/src/prog8/compiler/Compiler.kt b/compiler/src/prog8/compiler/Compiler.kt index 948c04109..1199b8769 100644 --- a/compiler/src/prog8/compiler/Compiler.kt +++ b/compiler/src/prog8/compiler/Compiler.kt @@ -297,7 +297,7 @@ private fun writeAssembly(programAst: Program, errors: IErrorReporter, outputDir: Path, compilerOptions: CompilationOptions): String { - // asm generation directly from the Ast, + // asm generation directly from the Ast programAst.processAstBeforeAsmGeneration(errors, compilerOptions.compTarget) errors.report() diff --git a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt index 9b8906a5c..2a9ae76f8 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt @@ -953,21 +953,17 @@ internal class AstChecker(private val program: Program, } } - // check if a function that doesn't return a value, is used in an expression or assignment + // functions that don't return a value, can't be used in an expression or assignment if(targetStatement is Subroutine) { if(targetStatement.returntypes.isEmpty()) { if(functionCall.parent is Expression || functionCall.parent is Assignment) errors.err("subroutine doesn't return a value", functionCall.position) - else - TODO("check $functionCall ${functionCall.parent}") } } else if(targetStatement is BuiltinFunctionStatementPlaceholder) { if(builtinFunctionReturnType(targetStatement.name, functionCall.args, program).isUnknown) { if(functionCall.parent is Expression || functionCall.parent is Assignment) errors.err("function doesn't return a value", functionCall.position) - else - TODO("check builtinfunc $functionCall ${functionCall.parent}") } } @@ -1136,6 +1132,7 @@ internal class AstChecker(private val program: Program, if(dtxVar!=null && dtxVar != DataType.UBYTE && dtxVar != DataType.BYTE) errors.err("array indexing is limited to byte size 0..255", arrayIndexedExpression.position) + // TODO remove this once this rewriter is moved to BeforeAsmGen if(arrayIndexedExpression.indexer.origExpression!=null) throw FatalAstException("array indexer should have been replaced with a temp var @ ${arrayIndexedExpression.indexer.position}") diff --git a/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt b/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt index 88749c99e..c89419fd8 100644 --- a/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt +++ b/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt @@ -114,7 +114,7 @@ internal class StatementReorderer(val program: Program, val errors: IErrorReport return noModifications } is Expression -> { - // replace complex indexing with a temp variable + // replace complex indexing with a temp variable TODO move this to BeforeAsmGeneration transformer, get rid of indexNum/indexVar/origExpression differentiation? (just use 'is Identifier' etc)? return getAutoIndexerVarFor(arrayIndexedExpression) } else -> return noModifications @@ -209,7 +209,7 @@ internal class StatementReorderer(val program: Program, val errors: IErrorReport val indexerVarPrefix = "prog8_autovar_index_" val repo = subroutine.asmGenInfo.usedAutoArrayIndexerForStatements - // TODO make this a bit smarter so it can reuse indexer variables. BUT BEWARE of scoping+initialization problems then + // TODO [codegen] make this a bit smarter so it can reuse indexer variables. BUT BEWARE of scoping+initialization problems then // add another loop index var to be used for this expression val indexerVarName = "$indexerVarPrefix${expr.indexer.hashCode()}" val indexerVar = AsmGenInfo.ArrayIndexerInfo(indexerVarName, expr.indexer) diff --git a/compiler/src/prog8/compiler/target/cpu6502/codegen/AsmGen.kt b/compiler/src/prog8/compiler/target/cpu6502/codegen/AsmGen.kt index a8e28e79f..1d187a938 100644 --- a/compiler/src/prog8/compiler/target/cpu6502/codegen/AsmGen.kt +++ b/compiler/src/prog8/compiler/target/cpu6502/codegen/AsmGen.kt @@ -720,7 +720,12 @@ internal class AsmGen(private val program: Program, return } - val indexName = asmVariableName(expr.indexer.indexVar!!) + val indexVar = expr.indexer.indexVar + ?: throw AssemblyError("array indexer should have been replaced with a temp var @ ${expr.indexer.position}") + + // must be indexed via variable (arbitrary expression is already replaced out) + + val indexName = asmVariableName(indexVar) if(addOneExtra) { // add 1 to the result when(elementDt) { diff --git a/compilerAst/src/prog8/ast/base/Base.kt b/compilerAst/src/prog8/ast/base/Base.kt index 0f8b3b2a1..42a570070 100644 --- a/compilerAst/src/prog8/ast/base/Base.kt +++ b/compilerAst/src/prog8/ast/base/Base.kt @@ -60,7 +60,13 @@ enum class DataType { enum class CpuRegister { A, X, - Y + Y; + + fun asRegisterOrPair(): RegisterOrPair = when(this) { + A -> RegisterOrPair.A + X -> RegisterOrPair.X + Y -> RegisterOrPair.Y + } } enum class RegisterOrPair {