From f2e2720b1534ef27f080c6fe0fc1b7e2f0d70a1b Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sun, 4 Oct 2020 18:47:47 +0200 Subject: [PATCH] compiler crash fixed when dealing with functioncall returning a str --- .../compiler/BeforeAsmGenerationAstChanger.kt | 12 ++++--- .../target/c64/codegen/ExpressionsAsmGen.kt | 20 ++++++----- .../target/c64/codegen/FunctionCallAsmGen.kt | 8 +++-- examples/test.p8 | 10 ++++-- examples/textelite.p8 | 36 +++++++++---------- 5 files changed, 49 insertions(+), 37 deletions(-) diff --git a/compiler/src/prog8/compiler/BeforeAsmGenerationAstChanger.kt b/compiler/src/prog8/compiler/BeforeAsmGenerationAstChanger.kt index f554b1bcf..d82ea95c3 100644 --- a/compiler/src/prog8/compiler/BeforeAsmGenerationAstChanger.kt +++ b/compiler/src/prog8/compiler/BeforeAsmGenerationAstChanger.kt @@ -161,11 +161,13 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, val errors: E if(sourceDt in PassByReferenceDatatypes) { if(typecast.type==DataType.UWORD) { - return listOf(IAstModification.ReplaceNode( - typecast, - AddressOf(typecast.expression as IdentifierReference, typecast.position), - parent - )) + if(typecast.expression is IdentifierReference) { + return listOf(IAstModification.ReplaceNode( + typecast, + AddressOf(typecast.expression as IdentifierReference, typecast.position), + parent + )) + } } else { errors.err("cannot cast pass-by-reference value to type ${typecast.type} (only to UWORD)", typecast.position) } diff --git a/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt index 6c1e95b3d..31b147a42 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt @@ -992,11 +992,11 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } - private fun translateExpression(expr: TypecastExpression) { - translateExpression(expr.expression) - when(expr.expression.inferType(program).typeOrElse(DataType.STRUCT)) { + private fun translateExpression(typecast: TypecastExpression) { + translateExpression(typecast.expression) + when(typecast.expression.inferType(program).typeOrElse(DataType.STRUCT)) { DataType.UBYTE -> { - when(expr.type) { + when(typecast.type) { DataType.UBYTE, DataType.BYTE -> {} DataType.UWORD, DataType.WORD -> { if(CompilationTarget.instance.machine.cpu==CpuType.CPU65c02) @@ -1010,7 +1010,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } DataType.BYTE -> { - when(expr.type) { + when(typecast.type) { DataType.UBYTE, DataType.BYTE -> {} DataType.UWORD, DataType.WORD -> { // sign extend @@ -1027,7 +1027,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } DataType.UWORD -> { - when(expr.type) { + when(typecast.type) { DataType.BYTE, DataType.UBYTE -> {} DataType.WORD, DataType.UWORD -> {} DataType.FLOAT -> asmgen.out(" jsr floats.stack_uw2float") @@ -1036,7 +1036,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } DataType.WORD -> { - when(expr.type) { + when(typecast.type) { DataType.BYTE, DataType.UBYTE -> {} DataType.WORD, DataType.UWORD -> {} DataType.FLOAT -> asmgen.out(" jsr floats.stack_w2float") @@ -1045,7 +1045,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge } } DataType.FLOAT -> { - when(expr.type) { + when(typecast.type) { DataType.UBYTE -> asmgen.out(" jsr floats.stack_float2uw") DataType.BYTE -> asmgen.out(" jsr floats.stack_float2w") DataType.UWORD -> asmgen.out(" jsr floats.stack_float2uw") @@ -1055,6 +1055,10 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge else -> throw AssemblyError("weird type") } } + DataType.STR -> { + if (typecast.type != DataType.UWORD && typecast.type == DataType.STR) + throw AssemblyError("cannot typecast a string into another incompatitble type") + } in PassByReferenceDatatypes -> throw AssemblyError("cannot cast pass-by-reference value into another type") else -> throw AssemblyError("weird type") } diff --git a/compiler/src/prog8/compiler/target/c64/codegen/FunctionCallAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/FunctionCallAsmGen.kt index 05ecf251a..836edf320 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/FunctionCallAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/FunctionCallAsmGen.kt @@ -218,8 +218,12 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg // via register or register pair val target = AsmAssignTarget.fromRegisters(register!!, program, asmgen) val src = if(valueDt in PassByReferenceDatatypes) { - val addr = AddressOf(value as IdentifierReference, Position.DUMMY) - AsmAssignSource.fromAstSource(addr, program).adjustDataTypeToTarget(target) + if(value is IdentifierReference) { + val addr = AddressOf(value, Position.DUMMY) + AsmAssignSource.fromAstSource(addr, program).adjustDataTypeToTarget(target) + } else { + AsmAssignSource.fromAstSource(value, program).adjustDataTypeToTarget(target) + } } else { AsmAssignSource.fromAstSource(value, program).adjustDataTypeToTarget(target) } diff --git a/examples/test.p8 b/examples/test.p8 index 204857a34..dde5ae683 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -8,13 +8,19 @@ main { str planet_name = "12345678" sub start() { -; txt.print(planet_name) -; txt.chrout('\n') + ; TODO : make str name=... work (although it's doing something else namely a strcpy) + + txt.print(planet_name) + txt.chrout('\n') planet_name = "saturn" ; TODO make strcpy() actually work it now sets the address in the first two bytes... txt.print(planet_name) txt.chrout('\n') + txt.print_ub(len(planet_name)) + txt.chrout('\n') + txt.print_ub(strlen(planet_name)) + txt.chrout('\n') } asmsub testX() { diff --git a/examples/textelite.p8 b/examples/textelite.p8 index 11dcf26ed..d5108b2a0 100644 --- a/examples/textelite.p8 +++ b/examples/textelite.p8 @@ -11,13 +11,12 @@ main { goatsoup.set_seed($2211, $f19e) - goatsoup.planet_name = "saturn" ; TODO make strcpy() actually work it now sets the address in the first two bytes... + goatsoup.planet_name = "saturn" goatsoup.print_soup() txt.chrout('\n') repeat 20 { - uword name = goatsoup.random_name() ; TODO : make str name=... work - txt.print(name) ; TODO: make print(random_name()) work + txt.print(goatsoup.random_name()) txt.chrout(' ') } } @@ -142,9 +141,7 @@ goatsoup { } sub print_soup() { - ; str source = "\x8F is \x97." - str source = "derp \xb0 \xb1 \xb2 \xb2 xxxx \x8F is \x97." - + str source = "\x8F is \x97." reset_rnd() ubyte c for c in source { @@ -159,25 +156,24 @@ goatsoup { ; soup(self.desc_list[ord(c) - 0x81][(rnr >= 0x33) + (rnr >= 0x66) + (rnr >= 0x99) + (rnr >= 0xCC)]) } else { if c == $b0 { - txt.print("!!PLANETNAME!!:") - txt.print(planet_name) ; TODO uppercase first char? + txt.chrout(planet_name[0] | 32) + txt.print(&planet_name + 1) } else if c == $b1 { - ; planet name + ian TODO capitalize first name letter? - txt.print(planet_name) + ; planet name + ian + txt.chrout(planet_name[0] | 32) + ubyte ni + for ni in 1 to len(planet_name) { + ubyte cc = planet_name[ni] + if cc=='e' or cc=='o' or cc==0 + break + else + txt.chrout(cc) + } txt.print("ian") -; name = self.name.title() -; result += name[0] -; for nn in name[1:]: -; if nn in ('e', 'i', '\0'): -; break -; result += nn -; result += "ian" } else if c == $b2 { - ; txt.print(random_name()) TODO make this work - uword name = goatsoup.random_name() - txt.print(name) + txt.print(random_name()) } ; else BAD CHAR DATA }