From 30e2bdad79a9e611a066f47067fd6fc76edab7b9 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Mon, 26 Nov 2018 01:18:06 +0100 Subject: [PATCH] fix some problems with subroutine parameters --- compiler/examples/test.p8 | 46 ++++++++++++------------- compiler/src/prog8/ast/AstChecker.kt | 8 +++-- compiler/src/prog8/compiler/Compiler.kt | 18 +++++----- 3 files changed, 37 insertions(+), 35 deletions(-) diff --git a/compiler/examples/test.p8 b/compiler/examples/test.p8 index 4a0dc1d81..f8cd7cbbf 100644 --- a/compiler/examples/test.p8 +++ b/compiler/examples/test.p8 @@ -18,30 +18,30 @@ sub start() { word[10] wordarray c64.CHROUT(X) - c64.CHROUT(b1) ; @todo fix compiler crash expression identifierref should be a vardef, not null - c64.CHROUT(ub1) ; @todo fix compiler crash expression identifierref should be a vardef, not null - c64.CHROUT(mb1) ; @todo fix compiler crash " - c64.CHROUT(mub1) ; @todo fix compiler crash " - c64.CHROUT(bytearray[1]) ; @todo fix compiler crash null cannot be cast to non-null type prog8.ast.VarDecl - c64.CHROUT(ubytearray[1]) ; @todo fix compiler crash null cannot be cast to non-null type prog8.ast.VarDecl - c64.CHROUT(membytearray[1]) ; @todo fix compiler crash null cannot be cast to non-null type prog8.ast.VarDecl - c64.CHROUT(memubytearray[1]) ; @todo fix compiler crash null cannot be cast to non-null type prog8.ast.VarDecl - c64.CHROUT(ubytearray[X]) ; @todo fix compiler crash " - c64.CHROUT(memubytearray[X]) ; @todo fix compiler crash " - c64.CHROUT(wordarray[1]) ; @todo fix compiler crash " + c64.CHROUT(ub1) + c64.CHROUT(mub1) + c64.CHROUT(ubytearray[1]) + c64.CHROUT(memubytearray[1]) + c64.CHROUT(ubytearray[X]) + c64.CHROUT(memubytearray[X]) + c64.CHROUT(b1) ; @todo fix compiler crash incompatible data types + c64.CHROUT(mb1) ; @todo fix compiler crash incompatible data types + c64.CHROUT(bytearray[1]) ; @todo fix compiler crash incompatible data types + c64.CHROUT(membytearray[1]) ; @todo fix compiler crash incompatible data types + c64.CHROUT(wordarray[1]) ; @todo fix compiler crash incompatible data types - testsub(X) ; @todo fix compiler crash - testsub(b1) ; @todo fix compiler crash - testsub(ub1) ; @todo fix compiler crash - testsub(mb1) ; @todo fix compiler crash - testsub(mub1) ; @todo fix compiler crash - testsub(bytearray[1]) ; @todo fix compiler crash - testsub(ubytearray[1]) ; @todo fix compiler crash - testsub(membytearray[1]) ; @todo fix compiler crash - testsub(memubytearray[1]) ; @todo fix compiler crash - testsub(ubytearray[X]) ; @todo fix compiler crash - testsub(memubytearray[X]) ; @todo fix compiler crash - testsub(wordarray[1]) ; @todo fix compiler crash + testsub(X) + testsub(ub1) + testsub(mub1) + testsub(ubytearray[1]) + testsub(memubytearray[1]) + testsub(ubytearray[X]) + testsub(memubytearray[X]) + testsub(b1) ; @todo should give datatype error + testsub(mb1) ; @todo should give datatype error + testsub(bytearray[1]) ; @todo should give datatype error + testsub(membytearray[1]) ; @todo should give datatype error + testsub(wordarray[1]) ; @todo should give datatype error return } diff --git a/compiler/src/prog8/ast/AstChecker.kt b/compiler/src/prog8/ast/AstChecker.kt index 7ce816d26..75aa6616d 100644 --- a/compiler/src/prog8/ast/AstChecker.kt +++ b/compiler/src/prog8/ast/AstChecker.kt @@ -707,9 +707,11 @@ class AstChecker(private val namespace: INameScope, if(argDt!=null && !argDt.assignableTo(arg.second.type)) checkResult.add(ExpressionError("subroutine argument ${arg.first.index+1} has invalid type, expected ${arg.second.type}", position)) - if(target.asmParameterRegisters[arg.first.index].registerOrPair in setOf(RegisterOrPair.AX, RegisterOrPair.XY, RegisterOrPair.X)) { - if(arg.first.value !is LiteralValue && arg.first.value !is IdentifierReference) - printWarning("calling a subroutine that expects X as a parameter is problematic, more so when providing complex arguments. If you see a compiler error/crash about this later, try to simplify this call", position) + if(target.isAsmSubroutine) { + if (target.asmParameterRegisters[arg.first.index].registerOrPair in setOf(RegisterOrPair.AX, RegisterOrPair.XY, RegisterOrPair.X)) { + if (arg.first.value !is LiteralValue && arg.first.value !is IdentifierReference) + printWarning("calling a subroutine that expects X as a parameter is problematic, more so when providing complex arguments. If you see a compiler error/crash about this later, try to simplify this call", position) + } } } } diff --git a/compiler/src/prog8/compiler/Compiler.kt b/compiler/src/prog8/compiler/Compiler.kt index 1e1f8324a..0500ad215 100644 --- a/compiler/src/prog8/compiler/Compiler.kt +++ b/compiler/src/prog8/compiler/Compiler.kt @@ -780,18 +780,18 @@ private class StatementTranslator(private val prog: IntermediateProgram, when (arg.second.registerOrPair!!) { A -> { val assign = Assignment(listOf(AssignTarget(Register.A, null, null, callPosition)), null, arg.first, callPosition) - assign.linkParents(subroutine.parent) + assign.linkParents(arguments[0].parent) translate(assign) } X -> { // TODO: save X on stack & restore after call val assign = Assignment(listOf(AssignTarget(Register.X, null, null, callPosition)), null, arg.first, callPosition) - assign.linkParents(subroutine.parent) + assign.linkParents(arguments[0].parent) translate(assign) } Y -> { val assign = Assignment(listOf(AssignTarget(Register.Y, null, null, callPosition)), null, arg.first, callPosition) - assign.linkParents(subroutine.parent) + assign.linkParents(arguments[0].parent) translate(assign) } AX -> { @@ -804,8 +804,8 @@ private class StatementTranslator(private val prog: IntermediateProgram, valueX=LiteralValue.optimalInteger(0, callPosition) val assignA = Assignment(listOf(AssignTarget(Register.A, null, null, callPosition)), null, valueA, callPosition) val assignX = Assignment(listOf(AssignTarget(Register.X, null, null, callPosition)), null, valueX, callPosition) - assignA.linkParents(subroutine.parent) - assignX.linkParents(subroutine.parent) + assignA.linkParents(arguments[0].parent) + assignX.linkParents(arguments[0].parent) translate(assignA) translate(assignX) } else if(paramDt==DataType.UWORD) { @@ -823,8 +823,8 @@ private class StatementTranslator(private val prog: IntermediateProgram, valueY=LiteralValue.optimalInteger(0, callPosition) val assignA = Assignment(listOf(AssignTarget(Register.A, null, null, callPosition)), null, valueA, callPosition) val assignY = Assignment(listOf(AssignTarget(Register.Y, null, null, callPosition)), null, valueY, callPosition) - assignA.linkParents(subroutine.parent) - assignY.linkParents(subroutine.parent) + assignA.linkParents(arguments[0].parent) + assignY.linkParents(arguments[0].parent) translate(assignA) translate(assignY) } else if(paramDt==DataType.UWORD) { @@ -843,8 +843,8 @@ private class StatementTranslator(private val prog: IntermediateProgram, valueY=LiteralValue.optimalInteger(0, callPosition) val assignX = Assignment(listOf(AssignTarget(Register.X, null, null, callPosition)), null, valueX, callPosition) val assignY = Assignment(listOf(AssignTarget(Register.Y, null, null, callPosition)), null, valueY, callPosition) - assignX.linkParents(subroutine.parent) - assignY.linkParents(subroutine.parent) + assignX.linkParents(arguments[0].parent) + assignY.linkParents(arguments[0].parent) translate(assignX) translate(assignY) } else if(paramDt==DataType.UWORD) {