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({
args: [],
expr: macro {
specialForms = _specialForms();
}
})
});

View File

@@ -2,6 +2,7 @@
(import kiss.Reader)
(import kiss.Reader.ReadFunction)
(import kiss.Reader.ReadTable)
(import kiss.ReaderExp)
(import kiss.ReaderExp.ReaderExpDef)
(import kiss.Stream)
@@ -11,9 +12,26 @@
(prop &mut :ReadTable endOfFileReadTable (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]
// Std.isOfType can't handle typedefs
(when (and (Reflect.hasField input "pos") (Reflect.hasField input "def"))
(evalCC input.def cc)
(return))
(typeCase [input]
([:String str]
(let [stream (Stream.fromString str)]
@@ -24,7 +42,19 @@
(throw "Couldn't read valid expression from $s")))
([:ReaderExpDef def]
(case def
((when (specialForms.exists form) (CallExp (object def (Symbol form)) args))
((dictGet specialForms form) args cc))
((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)))
(never otherwise)))
(otherwise (throw "Can't interpret ${input}"))))

View File

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

View File

@@ -1,4 +1,9 @@
(function _testEvalGlobal []
(let [interp (new Interp)]
(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))))