diff --git a/examples/lazyseqs.dst b/examples/lazyseqs.dst index f7d49284..c3d8695f 100644 --- a/examples/lazyseqs.dst +++ b/examples/lazyseqs.dst @@ -106,46 +106,38 @@ body once, and then memoizes the result." (def thehead (get HEAD x)) (if thehead (tuple thehead (take-while pred (get TAIL x))))))) -#Iterators is a conscept that looks a lot like lazy seq -#The following functions turn iterators to lazy seq and vice versa +# Iterators are a concept that looks a lot like lazy seq +# The following functions turn iterators to lazy seq and vice versa (defn- iter-self - [next] - (delay (tuple (next) (iter-self next)))) + [next more] + (delay + (if (more) (tuple (next) (iter-self next more))))) (defn iter2lazy -"Create a lazy sequence froma an iterator" +"Create a lazy sequence from an iterator" [iter] - (def {:more more :next next} iter) - (iter-self next)) + (def {:more more :next next} iter) + (iter-self next more)) (defn lazy2iter "turn a lazy-seq to an iterator" [lazy-seq] - (var result (head lazy-seq) ) - (var rest (tail lazy-seq)) - {:more (fn [] result) - :next (fn [] (def next result) - (when result - (:= result (head rest)) - (:= rest (tail rest))) - next)}) + (var node lazy-seq) + {:more (fn [] (node)) + :next (fn [] + (when-let [n (node)] + (:= node (get n 1)) + (get n 0)))}) - -#Now we can use the nonfuctional filter from boot.dst -#to write a filter version that returns a lazy sequence -#Be carefull when creating lazy sequences from mutable -#data structures as their values are references to this -#data structures. Same is true for iterators +# Now we can use the non-functional filter from boot.dst +# to write a filter version that returns a lazy sequence +# Be careful when creating lazy sequences from mutable +# data structures as their values are references to this +# data structures. Same is true for iterators (defn filter2 [pred coll] (tail (iter2lazy (filter pred coll)))) -(def arr [0 -1 -2 33 -3 0 302 -3 2 8 54 3 -2 0]) - -(def filtered (filter2 pos? arr)) - -(defn run-me [] (realize filtered)) - -#be carfull with the filter function. First element in (filter pos? arr) is nil -#last element is false +# be careful with the filter function. First element in (filter pos? arr) is nil +# last element is false diff --git a/src/compiler/boot.dst b/src/compiler/boot.dst index 310f4158..2727b7b0 100644 --- a/src/compiler/boot.dst +++ b/src/compiler/boot.dst @@ -578,6 +578,11 @@ third argument is given" (:= current (macroexpand1 current))) current) +(defmacro coro + "A wrapper for making fibers. Same as (fiber (fn [] ...body))." + [& body] + (tuple fiber (apply tuple 'fn [] body))) + (defn make-env [parent] (def parent (if parent parent _env)) (def newenv (setproto @{} parent)) @@ -613,19 +618,19 @@ onvalue." (var temp nil) (var tempval nil) # Stream of values - (def f (fiber (fn [] - (def p (parser 1)) - (while going - (select (parser-status p) - :full (yield (parser-produce p)) - :error (onerr "parse" (parser-error p)) - (select (fiber-status chars) - :new (parser-byte p (resume chars)) - :pending (parser-byte p (resume chars)) - (:= going false)))) - (when (not= :root (parser-status p)) - (onerr "parse" "unexpected end of source")) - nil))) + (def f (coro + (def p (parser 1)) + (while going + (select (parser-status p) + :full (yield (parser-produce p)) + :error (onerr "parse" (parser-error p)) + (select (fiber-status chars) + :new (parser-byte p (resume chars)) + :pending (parser-byte p (resume chars)) + (:= going false)))) + (when (not= :root (parser-status p)) + (onerr "parse" "unexpected end of source")) + nil)) (defn more [] (if temp true (do (:= temp true) @@ -638,19 +643,22 @@ onvalue." (fn [env chunks onvalue onerr] (defn doone [source] (var good true) - (def f (fiber (fn [] + (def f (coro (def res (compile source env)) (if (= (type res) :function) (res) (do (:= good false) - (onerr "compile" (get res :error))))))) + (onerr "compile" (get res :error)))))) (def res (resume f)) (if good (if (= (fiber-status f) :error) (onerr "runtime" res f) (onvalue res)))) + (def oldenv *env*) + (:= *env* env) (foreach (val-stream chunks onerr) doone) + (:= *env* oldenv) env))) (defn default-error-handler @@ -689,11 +697,8 @@ onvalue." (put loading path true) (def f (file-open path)) (defn chunks [buf] (file-read f 1024 buf)) - (def oldenv *env*) - (:= *env* newenv) (run-context newenv chunks identity default-error-handler) (file-close f) - (:= *env* oldenv) (put loading path nil) newenv)))))