fix some initial value datatypes and type casting in assignments

This commit is contained in:
Irmen de Jong 2019-06-24 01:31:25 +02:00
parent e53c860f1a
commit a079e44b02
6 changed files with 56 additions and 53 deletions

View File

@ -111,7 +111,7 @@ private fun compileMain(args: Array<String>) {
} }
//println(" time2: $time2") //println(" time2: $time2")
val time3 = measureTimeMillis { 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") //println(" time3: $time3")
val time4 = measureTimeMillis { val time4 = measureTimeMillis {

View File

@ -525,7 +525,12 @@ private class AstChecker(private val program: Program,
when { when {
decl.datatype in NumericDatatypes -> { decl.datatype in NumericDatatypes -> {
// initialize numeric var with value zero by default. // 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 litVal.parent = decl
decl.value = litVal decl.value = litVal
} }

View File

@ -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. // - 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. // - 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") 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) 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<IStatement>): Pair<List<Assignment>, IStatement?> { private fun sortConstantAssignmentSequence(first: Assignment, stmtIter: MutableIterator<IStatement>): Pair<List<Assignment>, IStatement?> {
val sequence= mutableListOf(first) val sequence= mutableListOf(first)
var trailing: IStatement? = null var trailing: IStatement? = null

View File

@ -198,7 +198,25 @@ class AstVm(val program: Program) {
} else TODO("$stmt") } else TODO("$stmt")
} }
is PostIncrDecr -> { 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 -> { is Jump -> {
TODO("$stmt") TODO("$stmt")

View File

@ -37,11 +37,12 @@
; found next one, mark the multiples and return it. ; found next one, mark the multiples and return it.
sieve[candidate_prime] = true 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
uword multiple = candidate_prime as uword ; TODO should not be required
while multiple < len(sieve) { while multiple < len(sieve) {
sieve[lsb(multiple)] = true sieve[lsb(multiple)] = true
multiple += candidate_prime as uword ; TODO cast should not be required multiple += candidate_prime
c64scr.print_uw(multiple) ; TODO c64scr.print_uw(multiple) ; TODO
c64.CHROUT('\n') ; TODO c64.CHROUT('\n') ; TODO
} }

View File

@ -4,58 +4,17 @@
sub start() { sub start() {
greeting() uword multiple
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 {
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")
}
} }