diff options
-rw-r--r-- | res/builtins.lisp | 16 | ||||
-rw-r--r-- | src/Builtins.kt | 18 | ||||
-rw-r--r-- | src/LispExecutionContext.kt | 7 | ||||
-rw-r--r-- | src/LispScriptEngine.kt | 6 | ||||
-rw-r--r-- | test/res/test.lisp | 9 | ||||
-rw-r--r-- | test/src/TestLisp.kt | 3 |
6 files changed, 51 insertions, 8 deletions
diff --git a/res/builtins.lisp b/res/builtins.lisp new file mode 100644 index 0000000..7bab9b4 --- /dev/null +++ b/res/builtins.lisp @@ -0,0 +1,16 @@ +(defun comment (...) ((pure nil))) +(comment "comment is a noop function for documentation") + + +(comment "if! a strict version of a regular if, meaning it evaluates both the falsy and the truthy case, instead of only one.") +(defun if! (cond ifTrue ifFalse) (if cond ifTrue ifFalse)) +(export if!) + +(comment "return immediately returns a value where an invocation is expected") +(defun return (value) ((pure value))) +(export return) + +(comment "noop is a do nothing function") +(defun noop () (return nil)) +(export noop) + diff --git a/src/Builtins.kt b/src/Builtins.kt new file mode 100644 index 0000000..484ea3a --- /dev/null +++ b/src/Builtins.kt @@ -0,0 +1,18 @@ +package moe.nea.lisp + +object Builtins { + val builtinSource = Builtins::class.java.getResourceAsStream("/builtins.lisp")!!.bufferedReader().readText() + val builtinProgram = LispParser.parse("builtins.lisp", builtinSource) + fun loadBuiltins( + lispExecutionContext: LispExecutionContext, + consumer: (String, LispData) -> Unit, + ) { + val stackFrame = lispExecutionContext.genBindings() + stackFrame.setValueLocal("export", LispData.externalRawCall { context, callsite, stackFrame, args -> + val (name) = args + consumer((name as LispAst.Reference).label, context.resolveValue(stackFrame, name)) + return@externalRawCall LispData.LispNil + }) + lispExecutionContext.executeProgram(stackFrame, builtinProgram) + } +}
\ No newline at end of file diff --git a/src/LispExecutionContext.kt b/src/LispExecutionContext.kt index ba7df41..f85cc4b 100644 --- a/src/LispExecutionContext.kt +++ b/src/LispExecutionContext.kt @@ -3,7 +3,7 @@ package moe.nea.lisp class LispExecutionContext() { private val errorReporter = LispErrorReporter() - private val rootStackFrame = StackFrame(null) + val rootStackFrame = StackFrame(null) fun reportError(name: String, position: HasLispPosition): LispData.LispNil { @@ -16,6 +16,11 @@ class LispExecutionContext() { return StackFrame(rootStackFrame) } + fun setupStandardBindings() { + CoreBindings.offerAllTo(rootStackFrame) + Builtins.loadBuiltins(this, rootStackFrame::setValueLocal) + } + fun executeProgram(stackFrame: StackFrame, program: LispAst.Program): LispData? { var lastValue: LispData? = null for (node in program.nodes) { diff --git a/src/LispScriptEngine.kt b/src/LispScriptEngine.kt index 3d2db8f..94dd4c6 100644 --- a/src/LispScriptEngine.kt +++ b/src/LispScriptEngine.kt @@ -8,11 +8,15 @@ import javax.script.SimpleBindings class LispScriptEngine(private val factory: LispScriptEngineFactory) : AbstractScriptEngine() { val executionContext = LispExecutionContext() + + init { + executionContext.setupStandardBindings() + } + override fun eval(script: String, context: ScriptContext): LispData? { val fileName = context.getAttribute("scriptName") as? String ?: "script.lisp" val program = LispParser.parse(fileName, script) val root = executionContext.genBindings() - CoreBindings.offerAllTo(root) for ((name, value) in context.getBindings(ScriptContext.ENGINE_SCOPE)) { when (value) { is String -> root.setValueLocal(name, LispData.LispString(value)) diff --git a/test/res/test.lisp b/test/res/test.lisp index edadffd..5f32bee 100644 --- a/test/res/test.lisp +++ b/test/res/test.lisp @@ -2,10 +2,6 @@ (defun myfun (var) (debuglog var)) (myfun :myfunworks) ((lambda (a) (debuglog a)) :atom) -(debuglog a) -(defun testsomething (c) (debuglog (if c "truthy value" "falsey value"))) -(testsomething true) -(testsomething false) (defun testlog (a ...) (seq (debuglog "a" a) (debuglog "..." ...))) @@ -16,3 +12,8 @@ (debuglog "-" (- 1 3)) (debuglog "*" (* 10 10)) (debuglog "/" (/ 1 3 2)) +(debuglog "============") +(defun testsomething (c) (debuglog (if! c (seq (debuglog "left evaluated") (return "truthy value")) "falsey value"))) +(testsomething true) +(testsomething false) +(noop) diff --git a/test/src/TestLisp.kt b/test/src/TestLisp.kt index f986f1c..7a520fb 100644 --- a/test/src/TestLisp.kt +++ b/test/src/TestLisp.kt @@ -1,4 +1,3 @@ -import moe.nea.lisp.CoreBindings import moe.nea.lisp.LispExecutionContext import moe.nea.lisp.LispParser import java.io.File @@ -8,7 +7,7 @@ object T fun main() { val otherP = LispParser.parse(File(T::class.java.getResource("/test.lisp")!!.file)) val executionContext = LispExecutionContext() + executionContext.setupStandardBindings() val bindings = executionContext.genBindings() - CoreBindings.offerAllTo(bindings) executionContext.executeProgram(bindings, otherP) } |