astvm eval of 'when'

This commit is contained in:
Irmen de Jong 2019-07-09 00:17:34 +02:00
parent f4f113da7b
commit 158fe7596b
4 changed files with 42 additions and 21 deletions

View File

@ -63,7 +63,8 @@ private fun compileMain(args: Array<String>) {
val filepath = Paths.get(moduleFile).normalize() val filepath = Paths.get(moduleFile).normalize()
val (programAst, programName) = compileProgram(filepath, optimize, optimizeInlining, writeVmCode, writeAssembly) val (programAst, programName) = compileProgram(filepath, optimize, optimizeInlining,
!launchAstVm, writeVmCode, writeAssembly)
if(launchAstVm) { if(launchAstVm) {
println("\nLaunching AST-based vm...") println("\nLaunching AST-based vm...")

View File

@ -24,7 +24,8 @@ import kotlin.system.measureTimeMillis
fun compileProgram(filepath: Path, fun compileProgram(filepath: Path,
optimize: Boolean, optimizeInlining: Boolean, optimize: Boolean, optimizeInlining: Boolean,
writeVmCode: Boolean, writeAssembly: Boolean): Pair<Program, String?> { generateVmCode: Boolean, writeVmCode: Boolean,
writeAssembly: Boolean): Pair<Program, String?> {
lateinit var programAst: Program lateinit var programAst: Program
var programName: String? = null var programName: String? = null
@ -89,26 +90,28 @@ fun compileProgram(filepath: Path,
// printAst(programAst) // printAst(programAst)
// namespace.debugPrint() // namespace.debugPrint()
// compile the syntax tree into stackvmProg form, and optimize that if(generateVmCode) {
val compiler = Compiler(programAst) // compile the syntax tree into stackvmProg form, and optimize that
val intermediate = compiler.compile(compilerOptions) val compiler = Compiler(programAst)
if (optimize) val intermediate = compiler.compile(compilerOptions)
intermediate.optimize() if (optimize)
intermediate.optimize()
if (writeVmCode) { if (writeVmCode) {
val stackVmFilename = intermediate.name + ".vm.txt" val stackVmFilename = intermediate.name + ".vm.txt"
val stackvmFile = PrintStream(File(stackVmFilename), "utf-8") val stackvmFile = PrintStream(File(stackVmFilename), "utf-8")
intermediate.writeCode(stackvmFile) intermediate.writeCode(stackvmFile)
stackvmFile.close() stackvmFile.close()
println("StackVM program code written to '$stackVmFilename'") println("StackVM program code written to '$stackVmFilename'")
} }
if (writeAssembly) { if (writeAssembly) {
val zeropage = C64Zeropage(compilerOptions) val zeropage = C64Zeropage(compilerOptions)
intermediate.allocateZeropage(zeropage) intermediate.allocateZeropage(zeropage)
val assembly = AsmGen(compilerOptions, intermediate, programAst.heap, zeropage).compileToAssembly(optimize) val assembly = AsmGen(compilerOptions, intermediate, programAst.heap, zeropage).compileToAssembly(optimize)
assembly.assemble(compilerOptions) assembly.assemble(compilerOptions)
programName = assembly.name programName = assembly.name
}
} }
} }
println("\nTotal compilation+assemble time: ${totalTime / 1000.0} sec.") println("\nTotal compilation+assemble time: ${totalTime / 1000.0} sec.")

View File

@ -442,6 +442,23 @@ class AstVm(val program: Program) {
} }
} while (!condition.asBoolean) } while (!condition.asBoolean)
} }
is WhenStatement -> {
val condition=evaluate(stmt.condition, evalCtx)
for(choice in stmt.choices) {
if(choice.value==null) {
// the 'else' choice
executeAnonymousScope(choice.statements)
break
} else {
val value = choice.value.constValue(evalCtx.program) ?: throw VmExecutionException("can only use const values in when choices ${choice.position}")
val rtval = RuntimeValue.from(value, evalCtx.program.heap)
if(condition==rtval) {
executeAnonymousScope(choice.statements)
break
}
}
}
}
else -> { else -> {
TODO("implement $stmt") TODO("implement $stmt")
} }

View File

@ -16,8 +16,8 @@
4 -> { 4 -> {
Y=7 Y=7
} }
5 -> Y=5
else -> A=99 else -> A=99
5 -> Y=5 ; @todo error; else already seen
} }
} }