From 6b41734d6a31cd229a6b27e8e89e51da53f8fd8b Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sun, 21 Aug 2022 15:37:05 +0200 Subject: [PATCH] check memory() calls before entering codegen --- .../prog8/codegen/virtual/ExpressionGen.kt | 1 - .../astprocessing/VerifyFunctionArgTypes.kt | 31 +++++++++++++++++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/codeGenVirtual/src/prog8/codegen/virtual/ExpressionGen.kt b/codeGenVirtual/src/prog8/codegen/virtual/ExpressionGen.kt index 6dd6263df..2cfdb44a0 100644 --- a/codeGenVirtual/src/prog8/codegen/virtual/ExpressionGen.kt +++ b/codeGenVirtual/src/prog8/codegen/virtual/ExpressionGen.kt @@ -3,7 +3,6 @@ package prog8.codegen.virtual import prog8.code.StRomSub import prog8.code.StStaticVariable import prog8.code.StSub -import prog8.code.StSubroutineParameter import prog8.code.ast.* import prog8.code.core.* import prog8.vm.Opcode diff --git a/compiler/src/prog8/compiler/astprocessing/VerifyFunctionArgTypes.kt b/compiler/src/prog8/compiler/astprocessing/VerifyFunctionArgTypes.kt index d4483304f..f72627916 100644 --- a/compiler/src/prog8/compiler/astprocessing/VerifyFunctionArgTypes.kt +++ b/compiler/src/prog8/compiler/astprocessing/VerifyFunctionArgTypes.kt @@ -2,9 +2,7 @@ package prog8.compiler.astprocessing import prog8.ast.IFunctionCall import prog8.ast.Program -import prog8.ast.expressions.Expression -import prog8.ast.expressions.FunctionCallExpression -import prog8.ast.expressions.TypecastExpression +import prog8.ast.expressions.* import prog8.ast.statements.* import prog8.ast.walk.IAstVisitor import prog8.code.core.DataType @@ -14,16 +12,43 @@ import prog8.compiler.BuiltinFunctions internal class VerifyFunctionArgTypes(val program: Program, val errors: IErrorReporter) : IAstVisitor { + override fun visit(program: Program) { + super.visit(program) + + // detect invalid (double) memory slabs + for(slab in memorySlabs) { + val other = memorySlabs.first { it.name==slab.name } + if(other!==slab && (other.size!=slab.size || other.align!=slab.align)) { + errors.err("memory block '${slab.name}' already exists with a different size and/or alignment at ${other.position}", slab.position) + } + } + } + + private class Slab(val name: String, val size: Int, val align: Int, val position: Position) + private val memorySlabs = mutableListOf() + override fun visit(functionCallExpr: FunctionCallExpression) { val error = checkTypes(functionCallExpr as IFunctionCall, program) if(error!=null) errors.err(error.first, error.second) + else { + if(functionCallExpr.target.nameInSource==listOf("memory")) { + val name = (functionCallExpr.args[0] as StringLiteral).value + val size = (functionCallExpr.args[1] as NumericLiteral).number.toInt() + val align = (functionCallExpr.args[2] as NumericLiteral).number.toInt() + memorySlabs.add(Slab(name, size, align, functionCallExpr.position)) + } + } + + super.visit(functionCallExpr) } override fun visit(functionCallStatement: FunctionCallStatement) { val error = checkTypes(functionCallStatement as IFunctionCall, program) if(error!=null) errors.err(error.first, error.second) + + super.visit(functionCallStatement) } companion object {