From 86d2785d5e2fc8edf56c556c85c678c07c11a888 Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Wed, 28 Nov 2018 16:30:53 -0500 Subject: [PATCH] Add example of new iteration macro that may replace or complement the loop macro. The loop macro is still useful though and not nearly as complicated as the common lisp loop macro. --- examples/newiter.janet | 73 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 examples/newiter.janet diff --git a/examples/newiter.janet b/examples/newiter.janet new file mode 100644 index 00000000..88fc85c4 --- /dev/null +++ b/examples/newiter.janet @@ -0,0 +1,73 @@ +# Simpler iteration primitives example. + +(defn- iter-for + [prelude binding start end body] + (def $end (gensym)) + (tuple 'do + prelude + (tuple 'var binding start) + (tuple 'def $end end) + (tuple 'while (tuple < binding $end) + body + (tuple '++ binding)))) + +(defn- iter-keys + [prelude binding tab body] + (tuple 'do + prelude + (tuple 'var binding (tuple next tab nil)) + (tuple 'while (tuple not= nil binding) + body + (tuple := binding (tuple next tab binding))))) + +(defmacro do-range + "Iterate over a half open integer range." + [binding start end & body] + (def $iter (gensym)) + (iter-for nil $iter start end + (apply tuple 'do (tuple 'def binding $iter) body))) + +(defmacro each + "Iterate over an indexed data structure." + [binding ind & body] + (def $iter (gensym)) + (def $ind (gensym)) + (iter-for (tuple 'def $ind ind) + $iter 0 (tuple length $ind) + (apply tuple 'do (tuple 'def binding (tuple get $ind $iter)) body))) + + +(defmacro each-key + "Iterate over keys of a table or structure." + [binding tab & body] + (def $tab (gensym)) + (def $key (gensym)) + (iter-keys + (tuple 'def $tab tab) + $key + $tab + (apply tuple 'do (tuple 'def binding $key) body))) + +(defmacro each-value + "Iterate over values of a table or structure." + [binding tab & body] + (def $tab (gensym)) + (def $key (gensym)) + (iter-keys + (tuple 'def $tab tab) + $key + $tab + (apply tuple 'do (tuple 'def binding (tuple 'get $tab $key)) body))) + +(defmacro each-pair + "Iterate over keys and values of a table or structure." + [k v tab & body] + (def $tab (gensym)) + (def $key (gensym)) + (iter-keys + (tuple 'def $tab tab) + $key + $tab + (apply tuple 'do + (tuple 'def k $key) + (tuple 'def v (tuple 'get $tab $key)) body)))