for and doFor in KissInterp2, roughly
Some checks failed
CI / test (push) Failing after 1m4s
CI / test-core (14, ubuntu-latest, 3.x, cpp) (push) Failing after 2m42s
CI / test-core (14, ubuntu-latest, 3.x, interp) (push) Failing after 2m31s
CI / test-core (14, ubuntu-latest, 3.x, nodejs) (push) Failing after 2m49s
CI / test-core (14, ubuntu-latest, 3.x, js) (push) Failing after 2m30s
CI / test-core (14, ubuntu-latest, 3.x, py) (push) Failing after 3m6s

This commit is contained in:
2025-11-12 15:58:23 -06:00
parent 3c343b4df6
commit 050a5fbf66
3 changed files with 38 additions and 6 deletions

View File

@@ -26,7 +26,7 @@
(prop :Map<String,(Array<ReaderExp>,Dynamic->Void)->Void> specialForms) (prop :Map<String,(Array<ReaderExp>,Dynamic->Void)->Void> specialForms)
(method makeExp [:ReaderExpDef def] (function makeExp [:ReaderExpDef def]
(object pos null def def)) (object pos null def def))
(method declareInScope [:Map<String,Dynamic> scope] (method declareInScope [:Map<String,Dynamic> scope]
@@ -35,8 +35,33 @@
(evalCC (second args) ->val {(dictSet scope name val) (cc val)}))) (evalCC (second args) ->val {(dictSet scope name val) (cc val)})))
(function callSymbol [:String symbolName :Array<ReaderExp> args] (function callSymbol [:String symbolName :Array<ReaderExp> args]
(ReaderExpDef.CallExp (makeExp (ReaderExpDef.CallExp
(object pos null def (ReaderExpDef.Symbol symbolName)) args)) (makeExp (ReaderExpDef.Symbol symbolName)) args)))
(function listExp [:Array<ReaderExp> args]
(makeExp (ReaderExpDef.ListExp args)))
(method forLoop [collect]
->[args cc]
(let [varName (first args) collectionExp (second args) body (args.slice 2)]
(localScopes.push (new Map))
(evalCC collectionExp ->collection
(let [:Iterable<Dynamic> collection collection
:Array<Dynamic> results []
iter (collection.iterator)]
(dictSet (last localScopes) "__iter__" iter)
(localFunction run []
(if (iter.hasNext)
(evalCC (callSymbol "let" (.concat [(listExp [varName (callSymbol "__iter__.next" [])])] body))
->v {(when collect
(results.push v))
(run)
})
{
(localScopes.pop)
(cc results)
}))
(run)))))
(method makeFunction [:Array<ReaderExp> argExps :Array<ReaderExp> bodyExps] (method makeFunction [:Array<ReaderExp> argExps :Array<ReaderExp> bodyExps]
(let [capture (localScopes.copy) (let [capture (localScopes.copy)
@@ -87,7 +112,8 @@
(if val (if val
(evalCC (second args) cc) (evalCC (second args) cc)
(evalCC (third args) cc))) (evalCC (third args) cc)))
// TODO handle early return // TODO handle early return, loop break/continue
// TODO this should make a local scope!
=>"begin" =>"begin"
->[args cc] ->[args cc]
(_evalAllCC args ->values (_evalAllCC args ->values
@@ -96,6 +122,7 @@
(declareInScope globals) (declareInScope globals)
=>"localVar" =>"localVar"
(declareInScope (nth localScopes -1)) (declareInScope (nth localScopes -1))
// TODO support list unpacking
=>"let" =>"let"
->[args cc] ->[args cc]
(let [bindings (first args) (let [bindings (first args)
@@ -155,12 +182,10 @@
func (makeFunction argExps bodyExps)] func (makeFunction argExps bodyExps)]
(dictSet globals name func) (dictSet globals name func)
(cc func)) (cc func))
/*
=>"for" =>"for"
(forLoop true) (forLoop true)
=>"doFor" =>"doFor"
(forLoop false) (forLoop false)
*/
=>"while" =>"while"
->[args cc] ->[args cc]
(let [condition (first args) body (rest args)] (let [condition (first args) body (rest args)]

View File

@@ -43,5 +43,8 @@ class KissInterp2TestCase extends Test {
function testWhile() { function testWhile() {
_testWhile(); _testWhile();
} }
function testFor() {
_testFor();
}
} }

View File

@@ -55,3 +55,7 @@
(while (< c 9) (while (< c 9)
(set c (+ c 1))) (set c (+ c 1)))
c)"))) c)")))
(function _testFor []
(let [interp (new Interp)]
(assertEval [1 2 3] "(for i (range 3) (+ i 1))")))