honeylisp/stream.fnl
Jeremy Penner 1a93fc7e84 A bunch of stuff
- refactor assembler to be more modular / extensible
- fix a bunch of bugs
- better error reporting
- stop using imgui in favour of lite commands
- in-editor hotswap & eval hotkeys
- machine:write in batches so bytes aren't dropped
- first cut at stack VM primitives
2020-09-20 13:55:06 -04:00

164 lines
3.7 KiB
Fennel

(var make-stream nil)
(fn stream [table]
(make-stream
{:table (or table [])
:i 0
:n (length (or table []))
:step 1
:next
(fn [self]
(when (~= self.i self.n)
(set self.i (+ self.i self.step))
true))
:curr (fn [self] (. self.table self.i))
:reverse
(fn [self]
(local prev-i self.i)
(set self.i (+ self.n self.step))
(set self.n (+ prev-i self.step))
(set self.step (* self.step -1))
self)}))
(fn kvstream [table]
(make-stream
{:table (or table {})
:curr-key nil
:curr-val :start
:curr (fn [self] (values self.curr-key self.curr-val))
:keys (fn [self] (self:map (fn [k v] k)))
:values (fn [self] (self:map (fn [k v] v)))
:next
(fn [self]
(when self.curr-val
(set (self.curr-key self.curr-val) (next self.table self.curr-key)))
(~= self.curr-key nil))}))
(fn one [...]
(make-stream
{:vals [...]
:advanced false
:curr (fn [self] (unpack self.vals))
:next
(fn [self]
(if self.advanced
false
(do
(set self.advanced true)
true)))}))
(fn iter [self]
(values
(fn [self _]
(when (self:next)
(self:curr)))
self
nil))
(fn first [self]
(if (self:next) (self:curr) nil))
(fn map [stream f]
(make-stream
{: stream : f
:curr (fn [self] (self.f (self.stream:curr)))
:next (fn [self] (self.stream:next))
:reverse
(fn [self]
(set self.stream (self.stream:reverse))
self)}))
(fn filter [stream f]
(make-stream
{: stream : f :curr-val nil
:curr (fn [self] self.curr-val)
:next
(fn [self]
(set self.curr-val nil)
(var has-more (self.stream:next))
(while has-more
(let [curr (self.stream:curr)
include? (self.f curr)]
(when include?
(set self.curr-val curr))
(set has-more (if include? false (self.stream:next)))))
self.curr-val)}))
(fn reduce [stream f init]
(var val init)
(each [v (stream:iter)]
(set val (f val v)))
val)
(fn flatten [stream]
(make-stream
{: stream
:curr-stream nil
:curr (fn [self] (self.curr-stream:curr))
:next
(fn [self]
(var reached-next
(if self.curr-stream (self.curr-stream:next) false))
(while (not reached-next)
(set self.curr-stream
(if (self.stream:next) (self.stream:curr) nil))
(set reached-next
(if self.curr-stream (self.curr-stream:next) true)))
(~= self.curr-stream nil))}))
(fn concat [s ...]
(: (stream [s ...]) :flatten))
(fn skip [stream n]
(make-stream
{: stream
: n
:curr (fn [self] (self.stream:curr))
:next
(fn [self]
(for [_ 1 self.n]
(self.stream:next))
(set self.n 0)
(self.stream:next))}))
(fn take [stream n]
(make-stream
{: stream
: next
:curr (fn [self] (self.stream:curr))
:next
(fn [self]
(if (> self.n 0)
(do
(set self.n (- self.n 1))
(self.stream:next))
false))}))
(fn tolist [stream]
(let [l []]
(each [v (stream:iter)]
(table.insert l v))
l))
(fn tomap [stream]
(let [m {}]
(each [k v (stream:iter)]
(tset m k v))
m))
(set make-stream
(fn [stream]
(set stream.iter iter)
(set stream.map map)
(set stream.filter filter)
(set stream.first first)
(set stream.reduce reduce)
(set stream.flatten flatten)
(set stream.concat concat)
(set stream.skip skip)
(set stream.take take)
(set stream.tolist tolist)
(set stream.tomap tomap)
stream))
{: stream : kvstream : one}