summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.gradle.kts10
-rw-r--r--res/META-INF/services/javax.script.ScriptEngineFactory1
-rw-r--r--settings.gradle.kts1
-rw-r--r--src/LispExecutionContext.kt6
-rw-r--r--src/LispScriptEngine.kt39
-rw-r--r--src/LispScriptEngineFactory.kt47
6 files changed, 102 insertions, 2 deletions
diff --git a/build.gradle.kts b/build.gradle.kts
index 0a2df9e..48834ea 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,5 +1,15 @@
plugins { kotlin("jvm").version("1.7.20"); java; `maven-publish` }
+group = "moe.nea"
+version = "1.0.0"
repositories { mavenCentral() }
java.toolchain { languageVersion.set(JavaLanguageVersion.of(8)) }
sourceSets.main { java.setSrcDirs(listOf("src/")); resources.setSrcDirs(listOf("res")) }
sourceSets.test { java.setSrcDirs(listOf("test/src")); resources.setSrcDirs(listOf("test/res")) }
+
+publishing {
+ publications {
+ create<MavenPublication>("maven") {
+ from(components["java"])
+ }
+ }
+}
diff --git a/res/META-INF/services/javax.script.ScriptEngineFactory b/res/META-INF/services/javax.script.ScriptEngineFactory
new file mode 100644
index 0000000..e410783
--- /dev/null
+++ b/res/META-INF/services/javax.script.ScriptEngineFactory
@@ -0,0 +1 @@
+moe.nea.lisp.LispScriptEngineFactory \ No newline at end of file
diff --git a/settings.gradle.kts b/settings.gradle.kts
new file mode 100644
index 0000000..c0a30d0
--- /dev/null
+++ b/settings.gradle.kts
@@ -0,0 +1 @@
+rootProject.name = "nealisp"
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