From 7c5ec1853df3449f2be6acffffbe60380eea2a2b Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sun, 28 Nov 2021 01:36:44 +0100 Subject: [PATCH] nice error message if pop() argument is wrong --- .../src/prog8/compiler/target/C64Target.kt | 2 +- .../src/prog8/compiler/target/Cx16Target.kt | 2 +- .../compiler/astprocessing/AstChecker.kt | 34 +++++++++++++------ docs/source/todo.rst | 3 +- examples/test.p8 | 2 +- 5 files changed, 28 insertions(+), 15 deletions(-) diff --git a/codeGeneration/src/prog8/compiler/target/C64Target.kt b/codeGeneration/src/prog8/compiler/target/C64Target.kt index f16fe858f..9d30c52da 100644 --- a/codeGeneration/src/prog8/compiler/target/C64Target.kt +++ b/codeGeneration/src/prog8/compiler/target/C64Target.kt @@ -27,7 +27,7 @@ object C64Target: ICompilationTarget { if (altEncoding) Petscii.decodeScreencode(bytes, true) else Petscii.decodePetscii(bytes, true) override fun asmsubArgsEvalOrder(sub: Subroutine): List = asmsub6502ArgsEvalOrder(sub) - override fun asmsubArgsHaveRegisterClobberRisk(args: List): Boolean = asmsub6502ArgsHaveRegisterClobberRisk(args) + override fun asmsubArgsHaveRegisterClobberRisk(args: List) = asmsub6502ArgsHaveRegisterClobberRisk(args) override fun memorySize(dt: DataType): Int { return when(dt) { diff --git a/codeGeneration/src/prog8/compiler/target/Cx16Target.kt b/codeGeneration/src/prog8/compiler/target/Cx16Target.kt index e75204cdb..7a634d60c 100644 --- a/codeGeneration/src/prog8/compiler/target/Cx16Target.kt +++ b/codeGeneration/src/prog8/compiler/target/Cx16Target.kt @@ -28,7 +28,7 @@ object Cx16Target: ICompilationTarget { if (altEncoding) Petscii.decodeScreencode(bytes, true) else Petscii.decodePetscii(bytes, true) override fun asmsubArgsEvalOrder(sub: Subroutine): List = asmsub6502ArgsEvalOrder(sub) - override fun asmsubArgsHaveRegisterClobberRisk(args: List): Boolean = asmsub6502ArgsHaveRegisterClobberRisk(args) + override fun asmsubArgsHaveRegisterClobberRisk(args: List) = asmsub6502ArgsHaveRegisterClobberRisk(args) override fun memorySize(dt: DataType): Int { return when(dt) { diff --git a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt index d227c7c36..bd47edd82 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt @@ -981,19 +981,31 @@ internal class AstChecker(private val program: Program, checkUnusedReturnValues(functionCallStatement, targetStatement, program, errors) } - if(functionCallStatement.target.nameInSource.last() == "sort") { - // sort is not supported on float arrays - val idref = functionCallStatement.args.singleOrNull() as? IdentifierReference - if(idref!=null && idref.inferType(program) istype DataType.ARRAY_F) { - errors.err("sorting a floating point array is not supported", functionCallStatement.args.first().position) - } - } + val funcName = functionCallStatement.target.nameInSource - if(functionCallStatement.target.nameInSource.last() in arrayOf("rol", "ror", "rol2", "ror2", "swap", "sort", "reverse")) { - // in-place modification, can't be done on literals - if(functionCallStatement.args.any { it !is IdentifierReference && it !is ArrayIndexedExpression && it !is DirectMemoryRead }) { - errors.err("invalid argument to a in-place modifying function", functionCallStatement.args.first().position) + if(funcName.size==1) { + // check some builtin function calls + if(funcName[0] == "sort") { + // sort is not supported on float arrays + val idref = functionCallStatement.args.singleOrNull() as? IdentifierReference + if(idref!=null && idref.inferType(program) istype DataType.ARRAY_F) { + errors.err("sorting a floating point array is not supported", functionCallStatement.args.first().position) + } } + else if(funcName[0] in arrayOf("pop", "popw")) { + // can only pop into a variable, that has to have the correct type + val idref = functionCallStatement.args.singleOrNull() as? IdentifierReference + if(idref==null) + errors.err("invalid argument to pop, must be a variable with the correct type: ${functionCallStatement.args.first()}", functionCallStatement.args.first().position) + } + + if(funcName[0] in arrayOf("rol", "ror", "rol2", "ror2", "swap", "sort", "reverse")) { + // in-place modification, can't be done on literals + if(functionCallStatement.args.any { it !is IdentifierReference && it !is ArrayIndexedExpression && it !is DirectMemoryRead }) { + errors.err("invalid argument to a in-place modifying function", functionCallStatement.args.first().position) + } + } + } val error = diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 6a4d59dd8..e5b476417 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -6,7 +6,8 @@ For next compiler release (7.4) Use GoSub to call subroutines (statements): - [DONE] allow separate assigns to subroutine's parameter variables / registers - [DONE] turn a regular subroutine call into assignments to the parameters + GoSub (take code from gosub branch) - - also do this for asmsubs taking >0 parameters + - [DONE] also do this for asmsubs taking >0 parameters + - make that push(x+1) doesn't use stack evaluation, via a temp var? Optimize Function calls in expressions: - move args to assignments to params diff --git a/examples/test.p8 b/examples/test.p8 index 16804ad7f..672e6d5a7 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -8,9 +8,9 @@ main { uword @shared uw ubyte @shared ub + word @shared ww push(127) - popw(ub) ; TODO give type error pop(ub) txt.print_ub(ub) txt.nl()