This commit is contained in:
Irmen de Jong
2021-03-22 01:57:52 +01:00
parent 3626828ceb
commit cbc3e37a89
5 changed files with 18 additions and 10 deletions

View File

@@ -297,7 +297,7 @@ private fun writeAssembly(programAst: Program,
errors: IErrorReporter, errors: IErrorReporter,
outputDir: Path, outputDir: Path,
compilerOptions: CompilationOptions): String { compilerOptions: CompilationOptions): String {
// asm generation directly from the Ast, // asm generation directly from the Ast
programAst.processAstBeforeAsmGeneration(errors, compilerOptions.compTarget) programAst.processAstBeforeAsmGeneration(errors, compilerOptions.compTarget)
errors.report() errors.report()

View File

@@ -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 is Subroutine) {
if(targetStatement.returntypes.isEmpty()) { if(targetStatement.returntypes.isEmpty()) {
if(functionCall.parent is Expression || functionCall.parent is Assignment) if(functionCall.parent is Expression || functionCall.parent is Assignment)
errors.err("subroutine doesn't return a value", functionCall.position) errors.err("subroutine doesn't return a value", functionCall.position)
else
TODO("check $functionCall ${functionCall.parent}")
} }
} }
else if(targetStatement is BuiltinFunctionStatementPlaceholder) { else if(targetStatement is BuiltinFunctionStatementPlaceholder) {
if(builtinFunctionReturnType(targetStatement.name, functionCall.args, program).isUnknown) { if(builtinFunctionReturnType(targetStatement.name, functionCall.args, program).isUnknown) {
if(functionCall.parent is Expression || functionCall.parent is Assignment) if(functionCall.parent is Expression || functionCall.parent is Assignment)
errors.err("function doesn't return a value", functionCall.position) 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) if(dtxVar!=null && dtxVar != DataType.UBYTE && dtxVar != DataType.BYTE)
errors.err("array indexing is limited to byte size 0..255", arrayIndexedExpression.position) 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) if(arrayIndexedExpression.indexer.origExpression!=null)
throw FatalAstException("array indexer should have been replaced with a temp var @ ${arrayIndexedExpression.indexer.position}") throw FatalAstException("array indexer should have been replaced with a temp var @ ${arrayIndexedExpression.indexer.position}")

View File

@@ -114,7 +114,7 @@ internal class StatementReorderer(val program: Program, val errors: IErrorReport
return noModifications return noModifications
} }
is Expression -> { 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) return getAutoIndexerVarFor(arrayIndexedExpression)
} }
else -> return noModifications else -> return noModifications
@@ -209,7 +209,7 @@ internal class StatementReorderer(val program: Program, val errors: IErrorReport
val indexerVarPrefix = "prog8_autovar_index_" val indexerVarPrefix = "prog8_autovar_index_"
val repo = subroutine.asmGenInfo.usedAutoArrayIndexerForStatements 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 // add another loop index var to be used for this expression
val indexerVarName = "$indexerVarPrefix${expr.indexer.hashCode()}" val indexerVarName = "$indexerVarPrefix${expr.indexer.hashCode()}"
val indexerVar = AsmGenInfo.ArrayIndexerInfo(indexerVarName, expr.indexer) val indexerVar = AsmGenInfo.ArrayIndexerInfo(indexerVarName, expr.indexer)

View File

@@ -720,7 +720,12 @@ internal class AsmGen(private val program: Program,
return 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) { if(addOneExtra) {
// add 1 to the result // add 1 to the result
when(elementDt) { when(elementDt) {

View File

@@ -60,7 +60,13 @@ enum class DataType {
enum class CpuRegister { enum class CpuRegister {
A, A,
X, X,
Y Y;
fun asRegisterOrPair(): RegisterOrPair = when(this) {
A -> RegisterOrPair.A
X -> RegisterOrPair.X
Y -> RegisterOrPair.Y
}
} }
enum class RegisterOrPair { enum class RegisterOrPair {