summaryrefslogtreecommitdiff
path: root/src/LispExecutionContext.kt
diff options
context:
space:
mode:
Diffstat (limited to 'src/LispExecutionContext.kt')
-rw-r--r--src/LispExecutionContext.kt61
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)
+ }
+ }
+}
+