diff options
Diffstat (limited to 'src/LispExecutionContext.kt')
-rw-r--r-- | src/LispExecutionContext.kt | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/src/LispExecutionContext.kt b/src/LispExecutionContext.kt new file mode 100644 index 0000000..f169ba9 --- /dev/null +++ b/src/LispExecutionContext.kt @@ -0,0 +1,61 @@ +package moe.nea.lisp + +class LispExecutionContext() { + + private val errorReporter = LispErrorReporter() + private val rootStackFrame = StackFrame(null) + + + fun reportError(name: String, position: HasLispPosition): LispData.LispNil { + println("Error: $name ${position.position}") + return LispData.LispNil + } + + + fun genBindings(): StackFrame { + return StackFrame(rootStackFrame) + } + + fun executeProgram(stackFrame: StackFrame, program: LispAst.Program) { + for (node in program.nodes) { + executeLisp(stackFrame, node) + } + } + + + fun executeLisp(stackFrame: StackFrame, node: LispAst.LispNode): LispData { + when (node) { + is LispAst.Parenthesis -> { + val first = node.items.firstOrNull() + ?: return reportError("Cannot execute empty parenthesis ()", node) + + val rest = node.items.drop(1) + return when (val resolvedValue = resolveValue(stackFrame, first)) { + is LispData.Atom -> reportError("Cannot execute atom", node) + LispData.LispNil -> reportError("Cannot execute nil", node) + is LispData.LispNumber -> reportError("Cannot execute number", node) + is LispData.LispNode -> reportError("Cannot execute node", node) + is LispData.LispObject<*> -> reportError("Cannot execute object-value", node) + is LispData.LispExecutable -> { + resolvedValue.execute(this, node, stackFrame, rest) + } + } + + } + + else -> return reportError("Expected invocation", node) + } + } + + fun resolveValue(stackFrame: StackFrame, node: LispAst.LispNode): LispData { + return when (node) { + is LispAst.Atom -> LispData.Atom(node.label) + is LispAst.Parenthesis -> executeLisp(stackFrame, node) + is LispAst.Reference -> stackFrame.resolveReference(node.label) + ?: reportError("Could not resolve variable ${node.label}", node) + + is LispAst.StringLiteral -> LispData.string(node.parsedString) + } + } +} + |