Lazy Sequences
Lazy sequences through closures. Based on extempore_lang.xtm.
;; this leaks memory :(
(bind-type seq <i64,seq*>)
(bind-func cons:[seq*,i64,seq*]*
(lambda (a:i64 s:seq*)
(let ((new_s:seq* (halloc))) ; should this be halloc?
(tset! new_s 0 a)
(tset! new_s 1 s)
new_s)))
(bind-func print-seq:[i64,seq*]*
(lambda (a:seq*)
(if (= null (cast a i8*))
(begin
(printf "x\ndone\n")
1)
(begin
(printf "%d > " (tref a 0))
(print-seq (tref a 1))))))
(bind-func test-seq
(lambda ()
(print-seq (cons 1 (cons 6 (cast null seq*))))))
($ (test-seq))
(bind-type lazy-seq <i64,[lazy-seq*]*>)
(bind-func car:[i64,lazy-seq*]*
(lambda (s:lazy-seq*)
(tref s 0)))
(bind-func cdr:[lazy-seq*,lazy-seq*]*
(lambda (s:lazy-seq*)
((tref s 1)))) ; note the double parens for call
(bind-func repeat:[lazy-seq*,i64]*
(lambda (e:i64)
(let ((s:lazy-seq* (alloc)))
(tset! s 0 e)
(tset! s 1 (lambda () (repeat e)))
s)))
(bind-func take:[seq*,i64,lazy-seq*]*
(lambda (n:i64 ls:lazy-seq*)
(let ((first:i64 (car ls))
(rest:lazy-seq* (cdr ls)))
(if (or (= null (cast rest i8*))
(= n 1))
(cons first (cast null seq*))
(cons first (take (- n 1) rest))))))
($ (print-seq (take 10 (repeat 5))))