From 158fe7596bad1684bbc9416140d99217bc29b734 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Tue, 9 Jul 2019 00:17:34 +0200 Subject: [PATCH] astvm eval of 'when' --- compiler/src/prog8/CompilerMain.kt | 3 +- compiler/src/prog8/compiler/Main.kt | 41 +++++++++++++++------------- compiler/src/prog8/vm/astvm/AstVm.kt | 17 ++++++++++++ examples/test.p8 | 2 +- 4 files changed, 42 insertions(+), 21 deletions(-) diff --git a/compiler/src/prog8/CompilerMain.kt b/compiler/src/prog8/CompilerMain.kt index e5b272f8b..514be2d02 100644 --- a/compiler/src/prog8/CompilerMain.kt +++ b/compiler/src/prog8/CompilerMain.kt @@ -63,7 +63,8 @@ private fun compileMain(args: Array) { 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) { println("\nLaunching AST-based vm...") diff --git a/compiler/src/prog8/compiler/Main.kt b/compiler/src/prog8/compiler/Main.kt index 193a537a6..2371dab64 100644 --- a/compiler/src/prog8/compiler/Main.kt +++ b/compiler/src/prog8/compiler/Main.kt @@ -24,7 +24,8 @@ import kotlin.system.measureTimeMillis fun compileProgram(filepath: Path, optimize: Boolean, optimizeInlining: Boolean, - writeVmCode: Boolean, writeAssembly: Boolean): Pair { + generateVmCode: Boolean, writeVmCode: Boolean, + writeAssembly: Boolean): Pair { lateinit var programAst: Program var programName: String? = null @@ -89,26 +90,28 @@ fun compileProgram(filepath: Path, // printAst(programAst) // namespace.debugPrint() - // compile the syntax tree into stackvmProg form, and optimize that - val compiler = Compiler(programAst) - val intermediate = compiler.compile(compilerOptions) - if (optimize) - intermediate.optimize() + if(generateVmCode) { + // compile the syntax tree into stackvmProg form, and optimize that + val compiler = Compiler(programAst) + val intermediate = compiler.compile(compilerOptions) + if (optimize) + intermediate.optimize() - if (writeVmCode) { - val stackVmFilename = intermediate.name + ".vm.txt" - val stackvmFile = PrintStream(File(stackVmFilename), "utf-8") - intermediate.writeCode(stackvmFile) - stackvmFile.close() - println("StackVM program code written to '$stackVmFilename'") - } + if (writeVmCode) { + val stackVmFilename = intermediate.name + ".vm.txt" + val stackvmFile = PrintStream(File(stackVmFilename), "utf-8") + intermediate.writeCode(stackvmFile) + stackvmFile.close() + println("StackVM program code written to '$stackVmFilename'") + } - if (writeAssembly) { - val zeropage = C64Zeropage(compilerOptions) - intermediate.allocateZeropage(zeropage) - val assembly = AsmGen(compilerOptions, intermediate, programAst.heap, zeropage).compileToAssembly(optimize) - assembly.assemble(compilerOptions) - programName = assembly.name + if (writeAssembly) { + val zeropage = C64Zeropage(compilerOptions) + intermediate.allocateZeropage(zeropage) + val assembly = AsmGen(compilerOptions, intermediate, programAst.heap, zeropage).compileToAssembly(optimize) + assembly.assemble(compilerOptions) + programName = assembly.name + } } } println("\nTotal compilation+assemble time: ${totalTime / 1000.0} sec.") diff --git a/compiler/src/prog8/vm/astvm/AstVm.kt b/compiler/src/prog8/vm/astvm/AstVm.kt index 872040741..ecc030dde 100644 --- a/compiler/src/prog8/vm/astvm/AstVm.kt +++ b/compiler/src/prog8/vm/astvm/AstVm.kt @@ -442,6 +442,23 @@ class AstVm(val program: Program) { } } 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 -> { TODO("implement $stmt") } diff --git a/examples/test.p8 b/examples/test.p8 index b6f51767f..8a2d6c09e 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -16,8 +16,8 @@ 4 -> { Y=7 } - 5 -> Y=5 else -> A=99 + 5 -> Y=5 ; @todo error; else already seen } }