From a079e44b021cbd29c6c40c386b80677a4d81ee75 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Mon, 24 Jun 2019 01:31:25 +0200 Subject: [PATCH] fix some initial value datatypes and type casting in assignments --- compiler/src/prog8/CompilerMain.kt | 2 +- compiler/src/prog8/ast/AstChecker.kt | 7 +++- compiler/src/prog8/ast/StmtReorderer.kt | 20 ++++++++++ compiler/src/prog8/astvm/AstVm.kt | 20 +++++++++- examples/primes.p8 | 7 ++-- examples/test.p8 | 53 +++---------------------- 6 files changed, 56 insertions(+), 53 deletions(-) diff --git a/compiler/src/prog8/CompilerMain.kt b/compiler/src/prog8/CompilerMain.kt index 8d2286424..e9bd3a32c 100644 --- a/compiler/src/prog8/CompilerMain.kt +++ b/compiler/src/prog8/CompilerMain.kt @@ -111,7 +111,7 @@ private fun compileMain(args: Array) { } //println(" time2: $time2") val time3 = measureTimeMillis { - programAst.reorderStatements() // reorder statements to please the compiler later + programAst.reorderStatements() // reorder statements and add type casts, to please the compiler later } //println(" time3: $time3") val time4 = measureTimeMillis { diff --git a/compiler/src/prog8/ast/AstChecker.kt b/compiler/src/prog8/ast/AstChecker.kt index 049f87c67..c976e95a4 100644 --- a/compiler/src/prog8/ast/AstChecker.kt +++ b/compiler/src/prog8/ast/AstChecker.kt @@ -525,7 +525,12 @@ private class AstChecker(private val program: Program, when { decl.datatype in NumericDatatypes -> { // initialize numeric var with value zero by default. - val litVal = LiteralValue(DataType.UBYTE, 0, position = decl.position) + val litVal = + when { + decl.datatype in ByteDatatypes -> LiteralValue(decl.datatype, bytevalue=0, position = decl.position) + decl.datatype in WordDatatypes -> LiteralValue(decl.datatype, wordvalue=0, position = decl.position) + else -> LiteralValue(decl.datatype, floatvalue=0.0, position = decl.position) + } litVal.parent = decl decl.value = litVal } diff --git a/compiler/src/prog8/ast/StmtReorderer.kt b/compiler/src/prog8/ast/StmtReorderer.kt index 5732e4531..d1bb37761 100644 --- a/compiler/src/prog8/ast/StmtReorderer.kt +++ b/compiler/src/prog8/ast/StmtReorderer.kt @@ -22,6 +22,8 @@ private class StatementReorderer(private val program: Program): IAstProcessor { // // - the 'start' subroutine in the 'main' block will be moved to the top immediately following the directives. // - all other subroutines will be moved to the end of their block. + // + // Also, makes sure any value assignments get the proper type casts if needed to cast them into the target variable's type. private val directivesToMove = setOf("%output", "%launcher", "%zeropage", "%zpreserved", "%address", "%option") @@ -189,6 +191,24 @@ private class StatementReorderer(private val program: Program): IAstProcessor { statements.addAll(result) } + + override fun process(assignment: Assignment): IStatement { + val target=assignment.singleTarget + if(target!=null) { + // see if a typecast is needed to convert the value's type into the proper target type + val valuetype = assignment.value.resultingDatatype(program) + val targettype = target.determineDatatype(program, assignment) + if(targettype!=null && valuetype!=null && valuetype!=targettype) { + if(valuetype isAssignableTo targettype) { + assignment.value = TypecastExpression(assignment.value, targettype, assignment.value.position) + } + // if they're not assignable, we'll get a proper error later from the AstChecker + } + } else TODO("multi-target assign") + + return super.process(assignment) + } + private fun sortConstantAssignmentSequence(first: Assignment, stmtIter: MutableIterator): Pair, IStatement?> { val sequence= mutableListOf(first) var trailing: IStatement? = null diff --git a/compiler/src/prog8/astvm/AstVm.kt b/compiler/src/prog8/astvm/AstVm.kt index ef4a63942..f50e25d8d 100644 --- a/compiler/src/prog8/astvm/AstVm.kt +++ b/compiler/src/prog8/astvm/AstVm.kt @@ -198,7 +198,25 @@ class AstVm(val program: Program) { } else TODO("$stmt") } is PostIncrDecr -> { - TODO("$stmt") + when { + stmt.target.identifier!=null -> { + val ident = stmt.definingScope().lookup(stmt.target.identifier!!.nameInSource, stmt) as VarDecl + val identScope = ident.definingScope() + var value = runtimeVariables.get(identScope, ident.name) + value = when { + stmt.operator=="++" -> value.add(RuntimeValue(value.type, 1)) + stmt.operator=="--" -> value.sub(RuntimeValue(value.type, 1)) + else -> throw VmExecutionException("strange postincdec operator $stmt") + } + runtimeVariables.set(identScope, ident.name, value) + } + stmt.target.memoryAddress!=null -> { + TODO("$stmt") + } + stmt.target.arrayindexed!=null -> { + TODO("$stmt") + } + } } is Jump -> { TODO("$stmt") diff --git a/examples/primes.p8 b/examples/primes.p8 index 62a106495..e894ebc6e 100644 --- a/examples/primes.p8 +++ b/examples/primes.p8 @@ -37,11 +37,12 @@ ; found next one, mark the multiples and return it. sieve[candidate_prime] = true - ; uword multiple = candidate_prime ; TODO the parser should have added a type cast from UBYTE to UWORD here - uword multiple = candidate_prime as uword ; TODO should not be required + uword multiple = candidate_prime + + while multiple < len(sieve) { sieve[lsb(multiple)] = true - multiple += candidate_prime as uword ; TODO cast should not be required + multiple += candidate_prime c64scr.print_uw(multiple) ; TODO c64.CHROUT('\n') ; TODO } diff --git a/examples/test.p8 b/examples/test.p8 index 29c3e241f..506e12781 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -4,58 +4,17 @@ sub start() { - greeting() - - ubyte square = stuff.function(12) - - c64scr.print_ub(square) - c64.CHROUT('\n') - - stuff.name() - stuff.name() - stuff.bye() - - abs(4) - abs(4) - abs(4) - abs(4) - abs(4) - foobar() - foobar() - foobar() - foobar() - - - if(false) { - } else { + uword multiple + while multiple < 5 { + multiple += 2 + c64scr.print_uw(multiple) ; TODO + c64.CHROUT('\n') ; TODO } + c64scr.print("done!\n") } - sub foobar() { - } - - sub greeting() { - c64scr.print("hello\n") - } -} - - -~ stuff { - - sub function(ubyte v) -> ubyte { - return v*v - } - - sub name() { - c64scr.print("name\n") - } - - sub bye() { - c64scr.print("bye\n") - } - }