prog8/compiler/src/prog8/astvm/VariablesCreator.kt
2019-07-08 13:33:31 +02:00

78 lines
3.6 KiB
Kotlin

package prog8.astvm
import prog8.ast.*
import prog8.ast.base.*
import prog8.ast.expressions.LiteralValue
import prog8.ast.processing.IAstProcessor
import prog8.ast.statements.VarDecl
import prog8.compiler.HeapValues
import prog8.compiler.RuntimeValue
class VariablesCreator(private val runtimeVariables: RuntimeVariables, private val heap: HeapValues) : IAstProcessor {
override fun process(program: Program) {
// define the three registers as global variables
runtimeVariables.define(program.namespace, Register.A.name, RuntimeValue(DataType.UBYTE, 0))
runtimeVariables.define(program.namespace, Register.X.name, RuntimeValue(DataType.UBYTE, 255))
runtimeVariables.define(program.namespace, Register.Y.name, RuntimeValue(DataType.UBYTE, 0))
val globalpos = Position("<<global>>", 0, 0, 0)
val vdA = VarDecl(VarDeclType.VAR, DataType.UBYTE, false, null, Register.A.name, LiteralValue.optimalInteger(0, globalpos), isArray = false, autoGenerated = true, position = globalpos)
val vdX = VarDecl(VarDeclType.VAR, DataType.UBYTE, false, null, Register.X.name, LiteralValue.optimalInteger(255, globalpos), isArray = false, autoGenerated = true, position = globalpos)
val vdY = VarDecl(VarDeclType.VAR, DataType.UBYTE, false, null, Register.Y.name, LiteralValue.optimalInteger(0, globalpos), isArray = false, autoGenerated = true, position = globalpos)
vdA.linkParents(program.namespace)
vdX.linkParents(program.namespace)
vdY.linkParents(program.namespace)
program.namespace.statements.add(vdA)
program.namespace.statements.add(vdX)
program.namespace.statements.add(vdY)
super.process(program)
}
override fun process(decl: VarDecl): IStatement {
when(decl.type) {
VarDeclType.VAR -> {
val value = when (decl.datatype) {
in NumericDatatypes -> {
if(decl.value !is LiteralValue) {
TODO("evaluate vardecl expression $decl")
//RuntimeValue(decl.datatype, num = evaluate(decl.value!!, program, runtimeVariables, executeSubroutine).numericValue())
} else {
RuntimeValue.from(decl.value as LiteralValue, heap)
}
}
in StringDatatypes -> {
RuntimeValue.from(decl.value as LiteralValue, heap)
}
in ArrayDatatypes -> {
RuntimeValue.from(decl.value as LiteralValue, heap)
}
else -> throw VmExecutionException("weird type ${decl.datatype}")
}
runtimeVariables.define(decl.definingScope(), decl.name, value)
}
VarDeclType.MEMORY -> {
if(decl.value !is LiteralValue) {
TODO("evaluate vardecl expression $decl")
//RuntimeValue(decl.datatype, num = evaluate(decl.value!!, program, runtimeVariables, executeSubroutine).numericValue())
} else {
runtimeVariables.defineMemory(decl.definingScope(), decl.name, (decl.value as LiteralValue).asIntegerValue!!)
}
}
VarDeclType.CONST -> {
// consts should have been const-folded away
}
}
return super.process(decl)
}
// override fun process(assignment: Assignment): IStatement {
// if(assignment is VariableInitializationAssignment) {
// println("INIT VAR $assignment")
// }
// return super.process(assignment)
// }
}