interp special forms map, if
Some checks failed
CI / test-core (14, ubuntu-latest, 3.x, py) (push) Failing after 1m56s
CI / test-core (14, ubuntu-latest, 3.x, interp) (push) Successful in 2m28s
CI / test-core (14, ubuntu-latest, 3.x, nodejs) (push) Successful in 2m34s
CI / test-core (14, ubuntu-latest, 3.x, cpp) (push) Successful in 3m28s
CI / test-core (14, ubuntu-latest, 3.x, js) (push) Successful in 3m39s

This commit is contained in:
2025-09-12 19:52:13 -05:00
parent 722e475925
commit 4670a8bd4e
4 changed files with 41 additions and 3 deletions

View File

@@ -23,7 +23,7 @@ class KissInterp2 {
kind: FFun({ kind: FFun({
args: [], args: [],
expr: macro { expr: macro {
specialForms = _specialForms();
} }
}) })
}); });

View File

@@ -2,6 +2,7 @@
(import kiss.Reader) (import kiss.Reader)
(import kiss.Reader.ReadFunction) (import kiss.Reader.ReadFunction)
(import kiss.Reader.ReadTable) (import kiss.Reader.ReadTable)
(import kiss.ReaderExp)
(import kiss.ReaderExp.ReaderExpDef) (import kiss.ReaderExp.ReaderExpDef)
(import kiss.Stream) (import kiss.Stream)
@@ -11,9 +12,26 @@
(prop &mut :ReadTable endOfFileReadTable (new Map)) (prop &mut :ReadTable endOfFileReadTable (new Map))
(prop &mut :Map<String,ReaderExpDef> identAliases (new Map)) (prop &mut :Map<String,ReaderExpDef> identAliases (new Map))
(prop :Map<String,Dynamic> globals (new Map)) (prop :Map<String,Dynamic> globals [=>"false" false =>"true" true =>"null" null])
(prop :Array<Map<String,Dynamic>> localScopes [])
(prop :Map<String,(Array<ReaderExp>,Dynamic->Void)->Void> specialForms)
(method :Map<String,(Array<ReaderExp>,Dynamic->Void)->Void> _specialForms [] [
=>"if"
->[args cc]
(evalCC (first ~args)
->val
(if val
(evalCC (second args) cc)
(evalCC (third args) cc)))
])
(method :Void evalCC [:Dynamic input :Dynamic->Void cc] (method :Void evalCC [:Dynamic input :Dynamic->Void cc]
// Std.isOfType can't handle typedefs
(when (and (Reflect.hasField input "pos") (Reflect.hasField input "def"))
(evalCC input.def cc)
(return))
(typeCase [input] (typeCase [input]
([:String str] ([:String str]
(let [stream (Stream.fromString str)] (let [stream (Stream.fromString str)]
@@ -24,7 +42,19 @@
(throw "Couldn't read valid expression from $s"))) (throw "Couldn't read valid expression from $s")))
([:ReaderExpDef def] ([:ReaderExpDef def]
(case def (case def
((when (specialForms.exists form) (CallExp (object def (Symbol form)) args))
((dictGet specialForms form) args cc))
((Symbol ident) ((Symbol ident)
// Check for numbers
(let [f (Std.parseFloat ident)]
(unless (Math.isNaN f)
(cc f)
(return)))
(doFor i (range localScopes.length)
(let [scope (nth localScopes (- localScopes.length i 1))]
(when (scope.exists ident)
(cc (dictGet scope ident))
(return))))
(cc (dictGet globals ident))) (cc (dictGet globals ident)))
(never otherwise))) (never otherwise)))
(otherwise (throw "Can't interpret ${input}")))) (otherwise (throw "Can't interpret ${input}"))))

View File

@@ -16,4 +16,7 @@ class KissInterp2TestCase extends Test {
function testEvalGlobal() { function testEvalGlobal() {
_testEvalGlobal(); _testEvalGlobal();
} }
function testIf() {
_testIf();
}
} }

View File

@@ -2,3 +2,8 @@
(let [interp (new Interp)] (let [interp (new Interp)]
(dictSet interp.globals "a" 5) (dictSet interp.globals "a" 5)
(interp.evalCC "a" ->v (Assert.equals 5 v)))) (interp.evalCC "a" ->v (Assert.equals 5 v))))
(function _testIf []
(let [interp (new Interp)]
(interp.evalCC "(if true 5 3)" ->v (Assert.equals 5 v))
(interp.evalCC "(if false 5 3)" ->v (Assert.equals 3 v))))