summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authornea <nea@nea.moe>2023-08-09 23:27:09 +0200
committernea <nea@nea.moe>2023-08-09 23:27:09 +0200
commit4878767a97c9ca78ec279e5a33cd7ae5b7b65493 (patch)
tree6f2c3ca568e5d2ea5090c92dcfffb3031f8e1680 /src
parent0b518030fcdffb68e6b62ffddfe4b784db9f272c (diff)
downloadnealisp-4878767a97c9ca78ec279e5a33cd7ae5b7b65493.tar.gz
nealisp-4878767a97c9ca78ec279e5a33cd7ae5b7b65493.tar.bz2
nealisp-4878767a97c9ca78ec279e5a33cd7ae5b7b65493.zip
JSR and publishing
Diffstat (limited to 'src')
-rw-r--r--src/LispExecutionContext.kt6
-rw-r--r--src/LispScriptEngine.kt39
-rw-r--r--src/LispScriptEngineFactory.kt47
3 files changed, 90 insertions, 2 deletions
diff --git a/src/LispExecutionContext.kt b/src/LispExecutionContext.kt
index 20d581e..ba7df41 100644
--- a/src/LispExecutionContext.kt
+++ b/src/LispExecutionContext.kt
@@ -16,10 +16,12 @@ class LispExecutionContext() {
return StackFrame(rootStackFrame)
}
- fun executeProgram(stackFrame: StackFrame, program: LispAst.Program) {
+ fun executeProgram(stackFrame: StackFrame, program: LispAst.Program): LispData? {
+ var lastValue: LispData? = null
for (node in program.nodes) {
- executeLisp(stackFrame, node)
+ lastValue = executeLisp(stackFrame, node)
}
+ return lastValue
}
diff --git a/src/LispScriptEngine.kt b/src/LispScriptEngine.kt
new file mode 100644
index 0000000..3d2db8f
--- /dev/null
+++ b/src/LispScriptEngine.kt
@@ -0,0 +1,39 @@
+package moe.nea.lisp
+
+import java.io.Reader
+import javax.script.AbstractScriptEngine
+import javax.script.Bindings
+import javax.script.ScriptContext
+import javax.script.SimpleBindings
+
+class LispScriptEngine(private val factory: LispScriptEngineFactory) : AbstractScriptEngine() {
+ val executionContext = LispExecutionContext()
+ 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))
+ is Number -> root.setValueLocal(name, LispData.LispNumber(value.toDouble()))
+ is Boolean -> root.setValueLocal(name, LispData.LispNumber(if (value) 1.0 else 0.0))
+ null -> root.setValueLocal(name, LispData.LispNil)
+ else -> error("Could not convert $value to lisp value")
+ }
+ }
+ return executionContext.executeProgram(root, program)
+ }
+
+ override fun eval(reader: Reader, context: ScriptContext): LispData? {
+ return eval(reader.readText(), context)
+ }
+
+ override fun createBindings(): Bindings {
+ return SimpleBindings()
+ }
+
+ override fun getFactory(): LispScriptEngineFactory {
+ return factory
+ }
+} \ No newline at end of file
diff --git a/src/LispScriptEngineFactory.kt b/src/LispScriptEngineFactory.kt
new file mode 100644
index 0000000..cceb0df
--- /dev/null
+++ b/src/LispScriptEngineFactory.kt
@@ -0,0 +1,47 @@
+package moe.nea.lisp
+
+import javax.script.ScriptEngine
+import javax.script.ScriptEngineFactory
+
+class LispScriptEngineFactory : ScriptEngineFactory {
+ override fun getEngineName(): String = "nealisp"
+
+ override fun getEngineVersion(): String = "1.0.0"
+
+ override fun getExtensions(): List<String> = listOf("lsp", "lisp", "nealisp")
+
+ override fun getMimeTypes(): List<String> = listOf("application/x-lisp", "application/x-nealisp")
+
+ override fun getNames(): List<String> = listOf("NeaLisp", "Lisp")
+
+ override fun getLanguageName(): String = "Lisp"
+
+ override fun getLanguageVersion(): String = "1.0.0"
+
+ override fun getParameter(key: String?): String? {
+ return when (key) {
+ ScriptEngine.NAME -> languageName
+ ScriptEngine.ENGINE_VERSION -> engineVersion
+ ScriptEngine.ENGINE -> engineName
+ ScriptEngine.LANGUAGE -> languageName
+ ScriptEngine.LANGUAGE_VERSION -> languageVersion
+ else -> null
+ }
+ }
+
+ override fun getMethodCallSyntax(obj: String?, m: String?, vararg args: String?): String {
+ return "($m $obj ${args.joinToString(" ")})"
+ }
+
+ override fun getOutputStatement(toDisplay: String?): String {
+ return "(print $toDisplay)"
+ }
+
+ override fun getProgram(vararg statements: String?): String {
+ return statements.joinToString("\n")
+ }
+
+ override fun getScriptEngine(): LispScriptEngine {
+ return LispScriptEngine(this)
+ }
+} \ No newline at end of file