summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornea <nea@nea.moe>2023-08-10 01:37:33 +0200
committernea <nea@nea.moe>2023-08-10 01:37:33 +0200
commit74371302593ee2ee365e697911c364246f460b63 (patch)
treef4c8e5c4e7f31fbab219425795d967ed8b77e4d0
parent7ce91434a452dc68f39aa34b646e691635c55e07 (diff)
downloadnealisp-74371302593ee2ee365e697911c364246f460b63.tar.gz
nealisp-74371302593ee2ee365e697911c364246f460b63.tar.bz2
nealisp-74371302593ee2ee365e697911c364246f460b63.zip
Add builtins
-rw-r--r--res/builtins.lisp16
-rw-r--r--src/Builtins.kt18
-rw-r--r--src/LispExecutionContext.kt7
-rw-r--r--src/LispScriptEngine.kt6
-rw-r--r--test/res/test.lisp9
-rw-r--r--test/src/TestLisp.kt3
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)
}