mirror of
https://github.com/janet-lang/janet
synced 2025-01-22 13:16:52 +00:00
More work on closures in loops. Fix loop macro to
not store bindings as vars.
This commit is contained in:
parent
79f84e52fc
commit
abe7d592aa
@ -289,34 +289,40 @@
|
||||
(error ("unexpected loop predicate: " verb)))
|
||||
(case verb
|
||||
:iterate (do
|
||||
(def preds @['and (tuple ':= bindings object)])
|
||||
(def $iter (gensym))
|
||||
(def preds @['and (tuple ':= $iter object)])
|
||||
(def subloop (doone (+ i 3) preds))
|
||||
(tuple 'do
|
||||
(tuple 'var bindings nil)
|
||||
(tuple 'var $iter nil)
|
||||
(tuple 'while (apply1 tuple preds)
|
||||
(tuple 'def bindings $iter)
|
||||
subloop)))
|
||||
:range (do
|
||||
(def [start end _inc] object)
|
||||
(def inc (if _inc _inc 1))
|
||||
(def endsym (gensym))
|
||||
(def preds @['and (tuple < bindings endsym)])
|
||||
(def $iter (gensym))
|
||||
(def preds @['and (tuple < $iter endsym)])
|
||||
(def subloop (doone (+ i 3) preds))
|
||||
(tuple 'do
|
||||
(tuple 'var bindings start)
|
||||
(tuple 'var $iter start)
|
||||
(tuple 'def endsym end)
|
||||
(tuple 'while (apply1 tuple preds)
|
||||
(tuple 'def bindings $iter)
|
||||
subloop
|
||||
(tuple ':= bindings (tuple + bindings inc)))))
|
||||
(tuple ':= $iter (tuple + $iter inc)))))
|
||||
:keys (do
|
||||
(def $dict (gensym))
|
||||
(def preds @['and (tuple not= nil bindings)])
|
||||
(def $iter (gensym))
|
||||
(def preds @['and (tuple not= nil $iter)])
|
||||
(def subloop (doone (+ i 3) preds))
|
||||
(tuple 'do
|
||||
(tuple 'def $dict object)
|
||||
(tuple 'var bindings (tuple next $dict nil))
|
||||
(tuple 'var $iter (tuple next $dict nil))
|
||||
(tuple 'while (apply1 tuple preds)
|
||||
(tuple 'def bindings $iter)
|
||||
subloop
|
||||
(tuple ':= bindings (tuple next $dict bindings)))))
|
||||
(tuple ':= $iter (tuple next $dict $iter)))))
|
||||
:in (do
|
||||
(def $len (gensym))
|
||||
(def $i (gensym))
|
||||
|
@ -441,13 +441,14 @@ static DstSlot dstc_while(DstFopts opts, int32_t argn, const Dst *argv) {
|
||||
dstc_emit(c, DOP_TAILCALL | (tempself << 8));
|
||||
/* Compile function */
|
||||
DstFuncDef *def = dstc_pop_funcdef(c);
|
||||
def->name = dst_cstring("_while-iife");
|
||||
def->name = dst_cstring("_while");
|
||||
int32_t defindex = dstc_addfuncdef(c, def);
|
||||
/* And then load the closure and call it. */
|
||||
int32_t cloreg = dstc_regalloc_temp(&c->scope->ra, DSTC_REGTEMP_0);
|
||||
dstc_emit(c, DOP_CLOSURE | (cloreg << 8) | (defindex << 16));
|
||||
dstc_emit(c, DOP_CALL | (cloreg << 8) | (cloreg << 16));
|
||||
dstc_regalloc_free(&c->scope->ra, cloreg);
|
||||
c->scope->flags |= DST_SCOPE_CLOSURE;
|
||||
return dstc_cslot(dst_wrap_nil());
|
||||
}
|
||||
|
||||
@ -480,6 +481,7 @@ static DstSlot dstc_fn(DstFopts opts, int32_t argn, const Dst *argv) {
|
||||
int selfref = 0;
|
||||
|
||||
/* Begin function */
|
||||
c->scope->flags |= DST_SCOPE_CLOSURE;
|
||||
dstc_scope(&fnscope, c, DST_SCOPE_FUNCTION, "function");
|
||||
|
||||
if (argn < 2) {
|
||||
|
@ -202,4 +202,14 @@
|
||||
(assert (not= 1 1 0) "not= 1")
|
||||
(assert (not= 0 1 1) "not= 2")
|
||||
|
||||
# Closure in while loop
|
||||
(def closures @[])
|
||||
(loop [i :range [0 5]]
|
||||
(array.push closures (fn [] i)))
|
||||
(assert (= 0 ((get closures 0))) "closure in loop 0")
|
||||
(assert (= 1 ((get closures 1))) "closure in loop 1")
|
||||
(assert (= 2 ((get closures 2))) "closure in loop 2")
|
||||
(assert (= 3 ((get closures 3))) "closure in loop 3")
|
||||
(assert (= 4 ((get closures 4))) "closure in loop 4")
|
||||
|
||||
(end-suite)
|
||||
|
Loading…
Reference in New Issue
Block a user