diff --git a/compiler/src/main/kotlin/gay/pizza/pork/compiler/CodeBuilder.kt b/compiler/src/main/kotlin/gay/pizza/pork/compiler/CodeBuilder.kt new file mode 100644 index 0000000..b84bcfa --- /dev/null +++ b/compiler/src/main/kotlin/gay/pizza/pork/compiler/CodeBuilder.kt @@ -0,0 +1,43 @@ +package gay.pizza.pork.compiler + +import gay.pizza.pork.bytecode.MutableRel +import gay.pizza.pork.bytecode.Op +import gay.pizza.pork.bytecode.Opcode + +class CodeBuilder(val symbol: CompilableSymbol) { + private val ops = mutableListOf() + + val localState: LocalState = LocalState(symbol) + + fun nextOpInst(): UInt = ops.size.toUInt() + + fun emit(op: StubOp) { + ops.add(op) + } + + fun emit(op: Op) { + ops.add(StaticOp(op)) + } + + fun emit(code: Opcode, arguments: List) { + emit(Op(code, arguments)) + } + + fun emit(code: Opcode) { + emit(code, emptyList()) + } + + fun patch(code: Opcode, arguments: List, index: Int, symbol: CompilableSymbol, rel: MutableRel) { + emit(PatchRelOp(Op(code, arguments), index, symbol, rel)) + } + + fun patch(code: Opcode, arguments: List, index: Int, symbol: CompilableSymbol, rel: UInt) { + emit(PatchRelOp(Op(code, arguments), index, symbol, MutableRel(rel))) + } + + fun patch(code: Opcode, arguments: List, patches: Map) { + ops.add(PatchSymOp(Op(code, arguments), patches)) + } + + fun build(): List = ops.toList() +} diff --git a/compiler/src/main/kotlin/gay/pizza/pork/compiler/CompilableSlab.kt b/compiler/src/main/kotlin/gay/pizza/pork/compiler/CompilableSlab.kt index 609371b..6b6db1b 100644 --- a/compiler/src/main/kotlin/gay/pizza/pork/compiler/CompilableSlab.kt +++ b/compiler/src/main/kotlin/gay/pizza/pork/compiler/CompilableSlab.kt @@ -10,7 +10,7 @@ class CompilableSlab(val compiler: Compiler, val slab: Slab) { } } - fun compilableSymbolOf(symbol: Symbol): CompilableSymbol? = compilableSymbols.firstOrNull { + fun resolve(symbol: Symbol): CompilableSymbol? = compilableSymbols.firstOrNull { it.scopeSymbol.symbol == symbol } } diff --git a/compiler/src/main/kotlin/gay/pizza/pork/compiler/CompilableSymbol.kt b/compiler/src/main/kotlin/gay/pizza/pork/compiler/CompilableSymbol.kt index fecbe67..37d3e23 100644 --- a/compiler/src/main/kotlin/gay/pizza/pork/compiler/CompilableSymbol.kt +++ b/compiler/src/main/kotlin/gay/pizza/pork/compiler/CompilableSymbol.kt @@ -24,7 +24,7 @@ class CompilableSymbol(val compilableSlab: CompilableSlab, val scopeSymbol: Scop } emitter.visit(what) emitter.exit() - return emitter.ops() + return emitter.code.build() } val id: String diff --git a/compiler/src/main/kotlin/gay/pizza/pork/compiler/Compiler.kt b/compiler/src/main/kotlin/gay/pizza/pork/compiler/Compiler.kt index a9395d1..5d94427 100644 --- a/compiler/src/main/kotlin/gay/pizza/pork/compiler/Compiler.kt +++ b/compiler/src/main/kotlin/gay/pizza/pork/compiler/Compiler.kt @@ -13,7 +13,7 @@ class Compiler { fun resolveOrNull(scopeSymbol: ScopeSymbol): CompilableSymbol? { val compiledSlab = compilableSlabs.of(scopeSymbol.slabScope.slab) - return compiledSlab.compilableSymbolOf(scopeSymbol.symbol) + return compiledSlab.resolve(scopeSymbol.symbol) } fun resolve(scopeSymbol: ScopeSymbol): CompilableSymbol = resolveOrNull(scopeSymbol) ?: diff --git a/compiler/src/main/kotlin/gay/pizza/pork/compiler/Loadable.kt b/compiler/src/main/kotlin/gay/pizza/pork/compiler/Loadable.kt new file mode 100644 index 0000000..9f4cc26 --- /dev/null +++ b/compiler/src/main/kotlin/gay/pizza/pork/compiler/Loadable.kt @@ -0,0 +1,6 @@ +package gay.pizza.pork.compiler + +class Loadable( + val call: CompilableSymbol? = null, + val stubVar: StubVar? = null +) diff --git a/compiler/src/main/kotlin/gay/pizza/pork/compiler/LocalState.kt b/compiler/src/main/kotlin/gay/pizza/pork/compiler/LocalState.kt new file mode 100644 index 0000000..56014db --- /dev/null +++ b/compiler/src/main/kotlin/gay/pizza/pork/compiler/LocalState.kt @@ -0,0 +1,55 @@ +package gay.pizza.pork.compiler + +import gay.pizza.pork.ast.gen.Symbol +import gay.pizza.pork.bytecode.MutableRel + +class LocalState(val symbol: CompilableSymbol) { + private var internalLoopState: LoopState? = null + val loopState: LoopState? + get() = internalLoopState + + private var localVarIndex: UInt = 0u + private val variables = mutableListOf>() + + fun startLoop(startOfLoop: UInt, exitJumpTarget: MutableRel) { + internalLoopState = LoopState( + startOfLoop = startOfLoop, + exitJumpTarget = exitJumpTarget, + scopeDepth = (internalLoopState?.scopeDepth ?: 0u) + 1u, + enclosing = internalLoopState + ) + } + + fun endLoop() { + internalLoopState = internalLoopState?.enclosing + } + + fun createLocal(symbol: Symbol): StubVar { + val scope = variables.last() + val variable = StubVar(localVarIndex++, symbol) + scope.add(variable) + return variable + } + + fun pushScope() { + variables.add(mutableListOf()) + } + + fun popScope() { + variables.removeLast() + } + + fun resolve(symbol: Symbol): Loadable { + for (scope in variables.reversed()) { + val found = scope.firstOrNull { it.symbol == symbol } + if (found != null) { + return Loadable(stubVar = found) + } + } + val found = this.symbol.compilableSlab.resolve(symbol) + if (found != null) { + return Loadable(call = found) + } + throw RuntimeException("Unable to resolve symbol: ${symbol.id}") + } +} diff --git a/compiler/src/main/kotlin/gay/pizza/pork/compiler/LoopState.kt b/compiler/src/main/kotlin/gay/pizza/pork/compiler/LoopState.kt index 09f0747..6ffecf9 100644 --- a/compiler/src/main/kotlin/gay/pizza/pork/compiler/LoopState.kt +++ b/compiler/src/main/kotlin/gay/pizza/pork/compiler/LoopState.kt @@ -5,7 +5,6 @@ import gay.pizza.pork.bytecode.MutableRel class LoopState( val startOfLoop: UInt, val exitJumpTarget: MutableRel, - val body: MutableRel, - val scopeDepth: Int, + val scopeDepth: UInt, val enclosing: LoopState? = null ) diff --git a/compiler/src/main/kotlin/gay/pizza/pork/compiler/StubOpEmitter.kt b/compiler/src/main/kotlin/gay/pizza/pork/compiler/StubOpEmitter.kt index e006f22..2a09b8b 100644 --- a/compiler/src/main/kotlin/gay/pizza/pork/compiler/StubOpEmitter.kt +++ b/compiler/src/main/kotlin/gay/pizza/pork/compiler/StubOpEmitter.kt @@ -3,99 +3,55 @@ package gay.pizza.pork.compiler import gay.pizza.pork.ast.FunctionLevelVisitor import gay.pizza.pork.ast.gen.* import gay.pizza.pork.bytecode.MutableRel -import gay.pizza.pork.bytecode.Op import gay.pizza.pork.bytecode.Opcode class StubOpEmitter(val compiler: Compiler, val symbol: CompilableSymbol) : FunctionLevelVisitor() { - private val ops = mutableListOf() - - private var loopState: LoopState? = null - private val localVariables = mutableListOf>() - private var localVarIndex = 0u - - private val requiredLoopState: LoopState - get() { - if (loopState != null) { - return loopState!! - } - throw RuntimeException("loopState expected but was not found.") - } - - private fun allocateLocalVariable(symbol: Symbol): StubVar { - val scope = localVariables.last() - val variable = StubVar(localVarIndex++, symbol) - scope.add(variable) - return variable - } - - private fun resolveSymbol(symbol: Symbol): CallOrStubVar { - for (scope in localVariables.reversed()) { - val found = scope.firstOrNull { it.symbol == symbol } - if (found != null) { - return CallOrStubVar(stubVar = found) - } - } - val found = this.symbol.compilableSlab.compilableSymbolOf(symbol) - if (found != null) { - return CallOrStubVar(call = found) - } - throw RuntimeException("Unable to resolve symbol: ${symbol.id}") - } - - private fun pushScope() { - emit(Opcode.ScopeIn) - localVariables.add(mutableListOf()) - } - - private fun popScope() { - emit(Opcode.ScopeOut) - localVariables.removeLast() - } - - fun enter() { - pushScope() - } + val code = CodeBuilder(symbol) fun allocateOuterScope(definition: FunctionDefinition) { val allNormalArguments = definition.arguments.takeWhile { !it.multiple } val varArgument = definition.arguments.firstOrNull { it.multiple } for (arg in allNormalArguments.reversed()) { - val functionLocal = allocateLocalVariable(arg.symbol) - emit(Opcode.StoreLocal, listOf(functionLocal.index)) + val functionLocal = code.localState.createLocal(arg.symbol) + code.emit(Opcode.StoreLocal, listOf(functionLocal.index)) } if (varArgument != null) { - val functionLocal = allocateLocalVariable(varArgument.symbol) - emit(Opcode.StoreLocal, listOf(functionLocal.index)) + val functionLocal = code.localState.createLocal(varArgument.symbol) + code.emit(Opcode.StoreLocal, listOf(functionLocal.index)) } } + fun enter() { + code.localState.pushScope() + } + fun exit() { - popScope() - emit(Opcode.Return) + code.localState.popScope() + code.emit(Opcode.Return) } override fun visitBlock(node: Block) { - pushScope() + code.localState.pushScope() node.visitChildren(this) - popScope() + code.localState.popScope() } override fun visitBooleanLiteral(node: BooleanLiteral) { - emit(if (node.value) Opcode.True else Opcode.False) + code.emit(if (node.value) Opcode.True else Opcode.False) } override fun visitBreak(node: Break) { - patch(Opcode.Jump, listOf(0u), 0, symbol, requiredLoopState.exitJumpTarget) + code.patch(Opcode.Jump, listOf(0u), 0, symbol, code.localState.loopState!!.exitJumpTarget) } override fun visitContinue(node: Continue) { - patch(Opcode.Jump, listOf(0u), 0, symbol, requiredLoopState.startOfLoop) + code.patch(Opcode.Jump, listOf(0u), 0, symbol, code.localState.loopState!!.startOfLoop) } override fun visitDoubleLiteral(node: DoubleLiteral) { - emit(Opcode.Integer, listOf(node.value.toUInt())) + code.emit(Opcode.Integer, listOf(node.value.toUInt())) } override fun visitForIn(node: ForIn) { @@ -108,7 +64,7 @@ class StubOpEmitter(val compiler: Compiler, val symbol: CompilableSymbol) : Func val targetSymbol = compiler.resolve(targetScopeSymbol) val functionDefinition = targetSymbol.scopeSymbol.definition as FunctionDefinition val retRel = MutableRel(0u) - patch(Opcode.Integer, listOf(0u), 0, symbol, retRel) + code.patch(Opcode.Integer, listOf(0u), 0, symbol, retRel) val normalArguments = mutableListOf() var variableArguments: List? = null @@ -127,70 +83,70 @@ class StubOpEmitter(val compiler: Compiler, val symbol: CompilableSymbol) : Func for (item in variableArguments.reversed()) { item.visit(this) } - emit(Opcode.List, listOf(variableArguments.size.toUInt())) + code.emit(Opcode.List, listOf(variableArguments.size.toUInt())) } for (item in normalArguments.reversed()) { visit(item) } - retRel.rel = (ops.size + 1).toUInt() - patch(Opcode.Call, listOf(0u), mapOf(0 to targetSymbol)) + retRel.rel = code.nextOpInst() + 1u + code.patch(Opcode.Call, listOf(0u), mapOf(0 to targetSymbol)) } override fun visitIf(node: If) { val thenRel = MutableRel(0u) val endRel = MutableRel(0u) node.condition.visit(this) - patch(Opcode.JumpIf, listOf(0u), 0, symbol, thenRel) + code.patch(Opcode.JumpIf, listOf(0u), 0, symbol, thenRel) node.elseBlock?.visit(this) - patch(Opcode.Jump, listOf(0u), 0, symbol, endRel) - thenRel.rel = ops.size.toUInt() + code.patch(Opcode.Jump, listOf(0u), 0, symbol, endRel) + thenRel.rel = code.nextOpInst() node.thenBlock.visit(this) - endRel.rel = ops.size.toUInt() + endRel.rel = code.nextOpInst() } override fun visitIndexedBy(node: IndexedBy) { node.expression.visit(this) node.index.visit(this) - emit(Opcode.Index) + code.emit(Opcode.Index) } override fun visitInfixOperation(node: InfixOperation) { node.left.visit(this) node.right.visit(this) when (node.op) { - InfixOperator.Plus -> emit(Opcode.Add) - InfixOperator.Minus -> emit(Opcode.Subtract) - InfixOperator.Multiply -> emit(Opcode.Multiply) - InfixOperator.Divide -> emit(Opcode.Divide) - InfixOperator.Equals -> emit(Opcode.CompareEqual) + InfixOperator.Plus -> code.emit(Opcode.Add) + InfixOperator.Minus -> code.emit(Opcode.Subtract) + InfixOperator.Multiply -> code.emit(Opcode.Multiply) + InfixOperator.Divide -> code.emit(Opcode.Divide) + InfixOperator.Equals -> code.emit(Opcode.CompareEqual) InfixOperator.NotEquals -> { - emit(Opcode.CompareEqual) - emit(Opcode.Not) + code.emit(Opcode.CompareEqual) + code.emit(Opcode.Not) } - InfixOperator.EuclideanModulo -> emit(Opcode.EuclideanModulo) - InfixOperator.Remainder -> emit(Opcode.Remainder) - InfixOperator.Lesser -> emit(Opcode.CompareLesser) - InfixOperator.Greater -> emit(Opcode.CompareGreater) - InfixOperator.GreaterEqual -> emit(Opcode.CompareGreaterEqual) - InfixOperator.LesserEqual -> emit(Opcode.CompareLesserEqual) - InfixOperator.BooleanAnd -> emit(Opcode.And) - InfixOperator.BooleanOr -> emit(Opcode.Or) - InfixOperator.BinaryAnd -> emit(Opcode.BinaryAnd) - InfixOperator.BinaryOr -> emit(Opcode.BinaryOr) - InfixOperator.BinaryExclusiveOr -> emit(Opcode.BinaryXor) + InfixOperator.EuclideanModulo -> code.emit(Opcode.EuclideanModulo) + InfixOperator.Remainder -> code.emit(Opcode.Remainder) + InfixOperator.Lesser -> code.emit(Opcode.CompareLesser) + InfixOperator.Greater -> code.emit(Opcode.CompareGreater) + InfixOperator.GreaterEqual -> code.emit(Opcode.CompareGreaterEqual) + InfixOperator.LesserEqual -> code.emit(Opcode.CompareLesserEqual) + InfixOperator.BooleanAnd -> code.emit(Opcode.And) + InfixOperator.BooleanOr -> code.emit(Opcode.Or) + InfixOperator.BinaryAnd -> code.emit(Opcode.BinaryAnd) + InfixOperator.BinaryOr -> code.emit(Opcode.BinaryOr) + InfixOperator.BinaryExclusiveOr -> code.emit(Opcode.BinaryXor) } } override fun visitIntegerLiteral(node: IntegerLiteral) { - emit(Opcode.Integer, listOf(node.value.toUInt())) + code.emit(Opcode.Integer, listOf(node.value.toUInt())) } override fun visitLetAssignment(node: LetAssignment) { - val variable = allocateLocalVariable(node.symbol) + val variable = code.localState.createLocal(node.symbol) node.value.visit(this) - emit(Opcode.StoreLocal, listOf(variable.index)) + code.emit(Opcode.StoreLocal, listOf(variable.index)) } override fun visitListLiteral(node: ListLiteral) { @@ -198,15 +154,15 @@ class StubOpEmitter(val compiler: Compiler, val symbol: CompilableSymbol) : Func for (item in node.items) { item.visit(this) } - emit(Opcode.List, listOf(count.toUInt())) + code.emit(Opcode.List, listOf(count.toUInt())) } override fun visitLongLiteral(node: LongLiteral) { - emit(Opcode.Integer, listOf(node.value.toUInt())) + code.emit(Opcode.Integer, listOf(node.value.toUInt())) } override fun visitNoneLiteral(node: NoneLiteral) { - emit(Opcode.None) + code.emit(Opcode.None) } override fun visitParentheses(node: Parentheses) { @@ -216,121 +172,90 @@ class StubOpEmitter(val compiler: Compiler, val symbol: CompilableSymbol) : Func override fun visitPrefixOperation(node: PrefixOperation) { node.expression.visit(this) when (node.op) { - PrefixOperator.BooleanNot -> emit(Opcode.Not) - PrefixOperator.UnaryPlus -> emit(Opcode.UnaryPlus) - PrefixOperator.UnaryMinus -> emit(Opcode.UnaryMinus) - PrefixOperator.BinaryNot -> emit(Opcode.BinaryNot) + PrefixOperator.BooleanNot -> code.emit(Opcode.Not) + PrefixOperator.UnaryPlus -> code.emit(Opcode.UnaryPlus) + PrefixOperator.UnaryMinus -> code.emit(Opcode.UnaryMinus) + PrefixOperator.BinaryNot -> code.emit(Opcode.BinaryNot) } } override fun visitSetAssignment(node: SetAssignment) { - val stubVarOrCall = resolveSymbol(node.symbol) + val stubVarOrCall = code.localState.resolve(node.symbol) if (stubVarOrCall.stubVar == null) { throw RuntimeException("Invalid set assignment.") } node.value.visit(this) - emit(Opcode.StoreLocal, listOf(stubVarOrCall.stubVar.index)) + code.emit(Opcode.StoreLocal, listOf(stubVarOrCall.stubVar.index)) } override fun visitStringLiteral(node: StringLiteral) { val bytes = node.text.toByteArray() val constant = compiler.constantPool.assign(bytes) - emit(Opcode.Constant, listOf(constant)) + code.emit(Opcode.Constant, listOf(constant)) } override fun visitSuffixOperation(node: SuffixOperation) { - val stubVarOrCall = resolveSymbol(node.reference.symbol) + val stubVarOrCall = code.localState.resolve(node.reference.symbol) if (stubVarOrCall.stubVar == null) { throw RuntimeException("Invalid suffix operation.") } load(stubVarOrCall) when (node.op) { SuffixOperator.Increment -> { - emit(Opcode.Integer, listOf(1u)) - emit(Opcode.Add, emptyList()) - emit(Opcode.StoreLocal, listOf(stubVarOrCall.stubVar.index)) + code.emit(Opcode.Integer, listOf(1u)) + code.emit(Opcode.Add, emptyList()) + code.emit(Opcode.StoreLocal, listOf(stubVarOrCall.stubVar.index)) } SuffixOperator.Decrement -> { - emit(Opcode.Integer, listOf(1u)) - emit(Opcode.Subtract, emptyList()) - emit(Opcode.StoreLocal, listOf(stubVarOrCall.stubVar.index)) + code.emit(Opcode.Integer, listOf(1u)) + code.emit(Opcode.Subtract, emptyList()) + code.emit(Opcode.StoreLocal, listOf(stubVarOrCall.stubVar.index)) } } } override fun visitSymbolReference(node: SymbolReference) { - val variable = resolveSymbol(node.symbol) + val variable = code.localState.resolve(node.symbol) load(variable) } override fun visitVarAssignment(node: VarAssignment) { - val variable = allocateLocalVariable(node.symbol) + val variable = code.localState.createLocal(node.symbol) node.value.visit(this) - emit(Opcode.StoreLocal, listOf(variable.index)) + code.emit(Opcode.StoreLocal, listOf(variable.index)) } override fun visitWhile(node: While) { val startOfBody = MutableRel(0u) + val startOfLoop = MutableRel(0u) val endOfLoop = MutableRel(0u) - val currentLoopState = LoopState( - startOfLoop = ops.size.toUInt(), - exitJumpTarget = endOfLoop, - body = startOfBody, - scopeDepth = (loopState?.scopeDepth ?: 0) + 1, - enclosing = loopState - ) - loopState = currentLoopState + code.localState.startLoop(code.nextOpInst(), endOfLoop) + startOfLoop.rel = code.nextOpInst() node.condition.visit(this) - patch(Opcode.JumpIf, listOf(0u), 0, symbol, startOfBody) - patch(Opcode.Jump, listOf(0u), 0, symbol, endOfLoop) - startOfBody.rel = ops.size.toUInt() + code.patch(Opcode.JumpIf, listOf(0u), 0, symbol, startOfBody) + code.patch(Opcode.Jump, listOf(0u), 0, symbol, endOfLoop) + startOfBody.rel = code.nextOpInst() node.block.visit(this) - patch(Opcode.Jump, listOf(0u), 0, symbol, currentLoopState.startOfLoop) - endOfLoop.rel = ops.size.toUInt() + code.patch(Opcode.Jump, listOf(0u), 0, symbol, startOfLoop) + endOfLoop.rel = code.nextOpInst() + code.localState.endLoop() } override fun visitNativeFunctionDescriptor(node: NativeFunctionDescriptor) { for (def in node.definitions) { val defConstant = compiler.constantPool.assign(def.text.toByteArray()) - emit(Opcode.Constant, listOf(defConstant)) + code.emit(Opcode.Constant, listOf(defConstant)) } val formConstant = compiler.constantPool.assign(node.form.id.toByteArray()) - emit(Opcode.Native, listOf(formConstant, node.definitions.size.toUInt())) + code.emit(Opcode.Native, listOf(formConstant, node.definitions.size.toUInt())) } - private fun emit(code: Opcode) { - emit(code, emptyList()) - } - - private fun emit(code: Opcode, arguments: List) { - ops.add(StaticOp(Op(code, arguments))) - } - - private fun patch(code: Opcode, arguments: List, index: Int, symbol: CompilableSymbol, rel: MutableRel) { - ops.add(PatchRelOp(Op(code, arguments), index, symbol, rel)) - } - - private fun patch(code: Opcode, arguments: List, index: Int, symbol: CompilableSymbol, rel: UInt) { - ops.add(PatchRelOp(Op(code, arguments), index, symbol, MutableRel(rel))) - } - - private fun patch(code: Opcode, arguments: List, patches: Map) { - ops.add(PatchSymOp(Op(code, arguments), patches)) - } - - fun ops(): List = ops - - private fun load(callOrStubVar: CallOrStubVar) { + private fun load(callOrStubVar: Loadable) { if (callOrStubVar.stubVar != null) { - emit(Opcode.LoadLocal, listOf(callOrStubVar.stubVar.index)) + code.emit(Opcode.LoadLocal, listOf(callOrStubVar.stubVar.index)) } else { - emit(Opcode.Integer, listOf(ops.size.toUInt() + 2u)) - patch(Opcode.Call, listOf(0u), mapOf(0 to callOrStubVar.call!!)) + code.emit(Opcode.Integer, listOf(code.nextOpInst() + 2u)) + code.patch(Opcode.Call, listOf(0u), mapOf(0 to callOrStubVar.call!!)) } } - - private class CallOrStubVar( - val call: CompilableSymbol? = null, - val stubVar: StubVar? = null - ) } diff --git a/tool/src/main/kotlin/gay/pizza/pork/tool/CompileCommand.kt b/tool/src/main/kotlin/gay/pizza/pork/tool/CompileCommand.kt index bf53e06..150cb92 100644 --- a/tool/src/main/kotlin/gay/pizza/pork/tool/CompileCommand.kt +++ b/tool/src/main/kotlin/gay/pizza/pork/tool/CompileCommand.kt @@ -17,7 +17,7 @@ class CompileCommand : CliktCommand(help = "Compile Pork to Bytecode", name = "c val compiler = Compiler() val slab = world.load(tool.rootImportLocator) val compiledSlab = compiler.compilableSlabs.of(slab) - val compiledMain = compiledSlab.compilableSymbolOf(Symbol("main")) + val compiledMain = compiledSlab.resolve(Symbol("main")) ?: throw RuntimeException("'main' function not found.") val compiledWorld = compiler.compile(compiledMain) for (symbol in compiledWorld.symbolTable.symbols) { diff --git a/vm/src/main/kotlin/gay/pizza/pork/vm/VirtualMachineProvider.kt b/vm/src/main/kotlin/gay/pizza/pork/vm/VirtualMachineProvider.kt index 83896df..768ea0a 100644 --- a/vm/src/main/kotlin/gay/pizza/pork/vm/VirtualMachineProvider.kt +++ b/vm/src/main/kotlin/gay/pizza/pork/vm/VirtualMachineProvider.kt @@ -12,7 +12,7 @@ class VirtualMachineProvider(val world: World) : ExecutionContextProvider { val compiler = Compiler() val slab = world.load(importLocator) val compilableSlab = compiler.compilableSlabs.of(slab) - val compilableSymbol = compilableSlab.compilableSymbolOf(entryPointSymbol) ?: + val compilableSymbol = compilableSlab.resolve(entryPointSymbol) ?: throw RuntimeException("Unable to find compilable symbol for entry point '${entryPointSymbol.id}'") val compiledWorld = compiler.compile(compilableSymbol) return VirtualMachine(compiledWorld)