KissInterp2 lambda/localFunction/function
Some checks failed
CI / test (push) Failing after 56s
CI / test-core (14, ubuntu-latest, 3.x, js) (push) Failing after 1m52s
CI / test-core (14, ubuntu-latest, 3.x, interp) (push) Failing after 1m39s
CI / test-core (14, ubuntu-latest, 3.x, py) (push) Failing after 2m19s
CI / test-core (14, ubuntu-latest, 3.x, nodejs) (push) Failing after 1m46s
CI / test-core (14, ubuntu-latest, 3.x, cpp) (push) Failing after 2m5s
Some checks failed
CI / test (push) Failing after 56s
CI / test-core (14, ubuntu-latest, 3.x, js) (push) Failing after 1m52s
CI / test-core (14, ubuntu-latest, 3.x, interp) (push) Failing after 1m39s
CI / test-core (14, ubuntu-latest, 3.x, py) (push) Failing after 2m19s
CI / test-core (14, ubuntu-latest, 3.x, nodejs) (push) Failing after 1m46s
CI / test-core (14, ubuntu-latest, 3.x, cpp) (push) Failing after 2m5s
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
(prop &mut :Map<String,ReaderExpDef> callAliases (new Map))
|
||||
|
||||
(prop :Map<String,Dynamic> globals [=>"false" false =>"true" true =>"null" null])
|
||||
(prop :kiss.List<Map<String,Dynamic>> localScopes [])
|
||||
(prop &mut :kiss.List<Map<String,Dynamic>> localScopes [])
|
||||
|
||||
(prop :Map<String,(Array<ReaderExp>,Dynamic->Void)->Void> specialForms)
|
||||
|
||||
@@ -28,6 +28,47 @@
|
||||
(let [name (symbolNameValue (first args))]
|
||||
(evalCC (second args) ->val {(dictSet scope name val) (cc val)})))
|
||||
|
||||
(method makeFunction [:Array<ReaderExp> argExps :Array<ReaderExp> bodyExps]
|
||||
(let [capture (localScopes.copy)
|
||||
argNames []
|
||||
&mut hasOpt false
|
||||
&mut minArgs 0]
|
||||
(doFor arg argExps
|
||||
(case arg.def
|
||||
((MetaExp "rest" arg)
|
||||
(throw "KissInterp2 does not support &rest args"))
|
||||
((MetaExp "opt" arg)
|
||||
(set hasOpt true)
|
||||
(argNames.push (symbolNameValue arg)))
|
||||
((Symbol argName)
|
||||
(argNames.push argName)
|
||||
(unless hasOpt
|
||||
++minArgs))
|
||||
(never otherwise)))
|
||||
(let [f_ (lambda [:Array<Dynamic> args]
|
||||
(let [currentLocals (localScopes.copy)
|
||||
innerCapture (capture.copy)
|
||||
// Oof -- everything needs to be synchronous
|
||||
&mut :Dynamic returnValue null]
|
||||
(set localScopes innerCapture)
|
||||
(localScopes.push (new Map))
|
||||
(doFor [idx argName] (enumerate argNames)
|
||||
(dictSet (last localScopes) argName
|
||||
(if (< idx argNames.length)
|
||||
(nth args idx)
|
||||
(if hasOpt
|
||||
null
|
||||
(throw "not enough arguments! need $argName")))))
|
||||
(evalCC (ReaderExpDef.CallExp (object pos null def (ReaderExpDef.Symbol "begin")) bodyExps)
|
||||
->v
|
||||
{
|
||||
(set localScopes currentLocals)
|
||||
(set returnValue v)
|
||||
})
|
||||
returnValue))
|
||||
f (Reflect.makeVarArgs f_)]
|
||||
f)))
|
||||
|
||||
(method :Map<String,(Array<ReaderExp>,Dynamic->Void)->Void> _specialForms [] [
|
||||
=>"if"
|
||||
->[args cc]
|
||||
@@ -36,6 +77,7 @@
|
||||
(if val
|
||||
(evalCC (second args) cc)
|
||||
(evalCC (third args) cc)))
|
||||
// TODO handle early return
|
||||
=>"begin"
|
||||
->[args cc]
|
||||
(_evalAllCC args ->values
|
||||
@@ -87,6 +129,22 @@
|
||||
(evalCC (second args)
|
||||
->key
|
||||
(cc (container.get key))))
|
||||
=>"lambda"
|
||||
->[args cc]
|
||||
(let [argExps (Prelude.argList (first args) "lambda") bodyExps (rest args)]
|
||||
(cc (makeFunction argExps bodyExps)))
|
||||
=>"localFunction"
|
||||
->[args cc]
|
||||
(let [name (symbolNameValue (first args)) argExps (Prelude.argList (second args) "lambda") bodyExps (args.slice 2)
|
||||
func (makeFunction argExps bodyExps)]
|
||||
(dictSet (last localScopes) name func)
|
||||
(cc func))
|
||||
=>"function"
|
||||
->[args cc]
|
||||
(let [name (symbolNameValue (first args)) argExps (Prelude.argList (second args) "lambda") bodyExps (args.slice 2)
|
||||
func (makeFunction argExps bodyExps)]
|
||||
(dictSet globals name func)
|
||||
(cc func))
|
||||
])
|
||||
|
||||
(method :ReaderExp read [:Dynamic input]
|
||||
|
||||
@@ -37,4 +37,8 @@ class KissInterp2TestCase extends Test {
|
||||
function testNth() {
|
||||
_testNth();
|
||||
}
|
||||
function testLambda() {
|
||||
_testLambda();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -44,3 +44,7 @@
|
||||
(let [interp (new Interp)]
|
||||
(assertEval 2 "(nth [1 2 3] 1)")
|
||||
(assertEval 9 #"(dictGet [=>"a" 2 =>"b" 9 =>"c" 3] "b")"#)))
|
||||
|
||||
(function _testLambda []
|
||||
(let [interp (new Interp)]
|
||||
(assertEval 6 "(let [add ->[a b] (+ a b)] (add 2 4))")))
|
||||
|
||||
Reference in New Issue
Block a user