1
0
mirror of https://github.com/janet-lang/janet synced 2024-11-24 17:27:18 +00:00

Update lazyseqs.dst and boot.dst

This commit is contained in:
Calvin Rose 2018-03-25 20:39:38 -04:00
parent a3ed7327c9
commit 44d2049c94
2 changed files with 44 additions and 47 deletions

View File

@ -106,46 +106,38 @@ body once, and then memoizes the result."
(def thehead (get HEAD x)) (def thehead (get HEAD x))
(if thehead (tuple thehead (take-while pred (get TAIL x))))))) (if thehead (tuple thehead (take-while pred (get TAIL x)))))))
#Iterators is a conscept that looks a lot like lazy seq # Iterators are a concept that looks a lot like lazy seq
#The following functions turn iterators to lazy seq and vice versa # The following functions turn iterators to lazy seq and vice versa
(defn- iter-self (defn- iter-self
[next] [next more]
(delay (tuple (next) (iter-self next)))) (delay
(if (more) (tuple (next) (iter-self next more)))))
(defn iter2lazy (defn iter2lazy
"Create a lazy sequence froma an iterator" "Create a lazy sequence from an iterator"
[iter] [iter]
(def {:more more :next next} iter) (def {:more more :next next} iter)
(iter-self next)) (iter-self next more))
(defn lazy2iter (defn lazy2iter
"turn a lazy-seq to an iterator" "turn a lazy-seq to an iterator"
[lazy-seq] [lazy-seq]
(var result (head lazy-seq) ) (var node lazy-seq)
(var rest (tail lazy-seq)) {:more (fn [] (node))
{:more (fn [] result) :next (fn []
:next (fn [] (def next result) (when-let [n (node)]
(when result (:= node (get n 1))
(:= result (head rest)) (get n 0)))})
(:= rest (tail rest)))
next)})
# Now we can use the non-functional filter from boot.dst
#Now we can use the nonfuctional filter from boot.dst # to write a filter version that returns a lazy sequence
#to write a filter version that returns a lazy sequence # Be careful when creating lazy sequences from mutable
#Be carefull when creating lazy sequences from mutable # data structures as their values are references to this
#data structures as their values are references to this # data structures. Same is true for iterators
#data structures. Same is true for iterators
(defn filter2 [pred coll] (defn filter2 [pred coll]
(tail (iter2lazy (filter pred coll)))) (tail (iter2lazy (filter pred coll))))
(def arr [0 -1 -2 33 -3 0 302 -3 2 8 54 3 -2 0]) # be careful with the filter function. First element in (filter pos? arr) is nil
# last element is false
(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

View File

@ -578,6 +578,11 @@ third argument is given"
(:= current (macroexpand1 current))) (:= current (macroexpand1 current)))
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] (defn make-env [parent]
(def parent (if parent parent _env)) (def parent (if parent parent _env))
(def newenv (setproto @{} parent)) (def newenv (setproto @{} parent))
@ -613,19 +618,19 @@ onvalue."
(var temp nil) (var temp nil)
(var tempval nil) (var tempval nil)
# Stream of values # Stream of values
(def f (fiber (fn [] (def f (coro
(def p (parser 1)) (def p (parser 1))
(while going (while going
(select (parser-status p) (select (parser-status p)
:full (yield (parser-produce p)) :full (yield (parser-produce p))
:error (onerr "parse" (parser-error p)) :error (onerr "parse" (parser-error p))
(select (fiber-status chars) (select (fiber-status chars)
:new (parser-byte p (resume chars)) :new (parser-byte p (resume chars))
:pending (parser-byte p (resume chars)) :pending (parser-byte p (resume chars))
(:= going false)))) (:= going false))))
(when (not= :root (parser-status p)) (when (not= :root (parser-status p))
(onerr "parse" "unexpected end of source")) (onerr "parse" "unexpected end of source"))
nil))) nil))
(defn more [] (if temp true (defn more [] (if temp true
(do (do
(:= temp true) (:= temp true)
@ -638,19 +643,22 @@ onvalue."
(fn [env chunks onvalue onerr] (fn [env chunks onvalue onerr]
(defn doone [source] (defn doone [source]
(var good true) (var good true)
(def f (fiber (fn [] (def f (coro
(def res (compile source env)) (def res (compile source env))
(if (= (type res) :function) (if (= (type res) :function)
(res) (res)
(do (do
(:= good false) (:= good false)
(onerr "compile" (get res :error))))))) (onerr "compile" (get res :error))))))
(def res (resume f)) (def res (resume f))
(if good (if good
(if (= (fiber-status f) :error) (if (= (fiber-status f) :error)
(onerr "runtime" res f) (onerr "runtime" res f)
(onvalue res)))) (onvalue res))))
(def oldenv *env*)
(:= *env* env)
(foreach (val-stream chunks onerr) doone) (foreach (val-stream chunks onerr) doone)
(:= *env* oldenv)
env))) env)))
(defn default-error-handler (defn default-error-handler
@ -689,11 +697,8 @@ onvalue."
(put loading path true) (put loading path true)
(def f (file-open path)) (def f (file-open path))
(defn chunks [buf] (file-read f 1024 buf)) (defn chunks [buf] (file-read f 1024 buf))
(def oldenv *env*)
(:= *env* newenv)
(run-context newenv chunks identity default-error-handler) (run-context newenv chunks identity default-error-handler)
(file-close f) (file-close f)
(:= *env* oldenv)
(put loading path nil) (put loading path nil)
newenv))))) newenv)))))