1 Commits

Author SHA1 Message Date
8792a36dfe implement field access
Some checks failed
CI / test-core (14, ubuntu-latest, 3.x, js) (push) Successful in 1m40s
CI / test-core (14, ubuntu-latest, 3.x, py) (push) Failing after 1m46s
CI / test-core (14, ubuntu-latest, 3.x, nodejs) (push) Successful in 2m16s
CI / test-core (14, ubuntu-latest, 3.x, interp) (push) Failing after 3m10s
CI / test-core (14, ubuntu-latest, 3.x, cpp) (push) Successful in 2m58s
2025-09-12 20:27:32 -05:00
3 changed files with 38 additions and 3 deletions

View File

@@ -4,6 +4,8 @@
(import kiss.Reader.ReadTable) (import kiss.Reader.ReadTable)
(import kiss.ReaderExp) (import kiss.ReaderExp)
(import kiss.ReaderExp.ReaderExpDef) (import kiss.ReaderExp.ReaderExpDef)
(import kiss.ReaderExp.ReaderExpDef.Symbol)
(import kiss.ReaderExp.ReaderExpDef.FieldExp)
(import kiss.Stream) (import kiss.Stream)
(prop &mut :ReadTable readTable (Reader.builtins)) (prop &mut :ReadTable readTable (Reader.builtins))
@@ -42,14 +44,35 @@
(throw "Couldn't read valid expression from $s"))) (throw "Couldn't read valid expression from $s")))
([:ReaderExpDef def] ([:ReaderExpDef def]
(case def (case def
// Special form call
((when (specialForms.exists form) (CallExp (object def (Symbol form)) args)) ((when (specialForms.exists form) (CallExp (object def (Symbol form)) args))
((dictGet specialForms form) args cc)) ((dictGet specialForms form) args cc))
// Field access
((FieldExp field obj safe)
(evalCC obj ->v
(if ~v
(cc ~(Reflect.getProperty v field))
(if safe
(cc null)
(throw "field access on null! $(Reader.toString obj.def)")))))
// Symbol
((Symbol ident) ((Symbol ident)
// Check for numbers // Check for numbers
(let [f (Std.parseFloat ident)] (let [f (Std.parseFloat ident)]
(unless (Math.isNaN f) (unless (Math.isNaN f)
(cc f) (cc f)
(return))) (return)))
// Check for field access
(let [idx (ident.indexOf ".")]
(unless (= -1 idx)
(let [parts (ident.split ".")
&mut exp (object pos null def (Symbol (first parts)))]
(doFor part (parts.slice 1)
(let [safe (StringTools.startsWith part "?")]
(when safe (set part (part.substr 1)))
(set exp (object pos null def (FieldExp part exp safe)))))
(evalCC exp cc)
(return))))
(doFor i (range localScopes.length) (doFor i (range localScopes.length)
(let [scope (nth localScopes (- localScopes.length i 1))] (let [scope (nth localScopes (- localScopes.length i 1))]
(when (scope.exists ident) (when (scope.exists ident)

View File

@@ -19,4 +19,7 @@ class KissInterp2TestCase extends Test {
function testIf() { function testIf() {
_testIf(); _testIf();
} }
function testField() {
_testField();
}
} }

View File

@@ -1,9 +1,18 @@
(defMacro assertEval [expected exp]
`(interp.evalCC ,exp ->v (Assert.equals ,expected v)))
(function _testEvalGlobal [] (function _testEvalGlobal []
(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)))) (assertEval 5 "a")))
(function _testIf [] (function _testIf []
(let [interp (new Interp)] (let [interp (new Interp)]
(interp.evalCC "(if true 5 3)" ->v (Assert.equals 5 v)) (assertEval 5 "(if true 5 3)")
(interp.evalCC "(if false 5 3)" ->v (Assert.equals 3 v)))) (assertEval 3 "(if false 5 3)")))
(function _testField []
(let [interp (new Interp)]
(dictSet interp.globals "obj" (object a 5 b (object c 3)))
(assertEval 5 "obj.a")
(assertEval 3 "obj.b.c")))