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")
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 {

View File

@ -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
}

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

View File

@ -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")

View File

@ -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
}

View File

@ -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")
}
}