diff options
Diffstat (limited to 'dot_config/nvim/fnl/toast')
| -rw-r--r-- | dot_config/nvim/fnl/toast/core.fnl | 36 | ||||
| -rw-r--r-- | dot_config/nvim/fnl/toast/macros.fnl | 24 | ||||
| -rw-r--r-- | dot_config/nvim/fnl/toast/table.fnl | 12 |
3 files changed, 62 insertions, 10 deletions
diff --git a/dot_config/nvim/fnl/toast/core.fnl b/dot_config/nvim/fnl/toast/core.fnl index 82b0c40..11a294b 100644 --- a/dot_config/nvim/fnl/toast/core.fnl +++ b/dot_config/nvim/fnl/toast/core.fnl @@ -18,6 +18,12 @@ (fn number? [n] "Returns true if the argument is a number." (= :number (type n))) +(fn even? [n] + "Returns true if the argument is an even number." + (and (number? n) (= 0 (% n 2)))) +(fn odd? [n] + "Returns true if the argument is an odd number." + (and (number? n) (not= 0 (% n 2)))) (fn every? [pred xs] "Returns true if (pred x) is logical true for every x in xs, else false." @@ -72,6 +78,15 @@ 0 t 1 (error "assoc expects even number of arguments after table, found odd number") _ (assoc t (unpack xs))))) +; TODO: split into filter and kfilter? +(fn filter [f xs] + "Returns a sequential table consisting only of elements in xs that return a truth value when passed to f. + Note that the call will be (f k v), not (f v)." + (accumulate [out [] + k v (ipairs xs)] + (if (f k v) + (insert out v) + out))) (fn map [f xs] "Returns a sequential table consisting of the result of apply f to every item in xs." (accumulate [out [] @@ -80,6 +95,20 @@ (insert out (if (= 0 (select :# mapped)) nil mapped))))) +; TODO: rework +(fn mapcat [f xs] + (accumulate [out [] + _ v (ipairs xs)] + (do (each [_ v (ipairs (f v))] + (table.insert out v)) + out))) + +; sequences cont +(fn flat [xs] + "Flattens a sequential table xs such that there are no sub-tables." + (case (type xs) + :table (mapcat flat xs) + _ [xs])) {;math : dec @@ -88,12 +117,17 @@ : empty? : nil? : number? + : even? + : odd? : every? ; sequences : drop : first : last : group + : flat ; HOF : assoc - : map} + : filter + : map + : mapcat} diff --git a/dot_config/nvim/fnl/toast/macros.fnl b/dot_config/nvim/fnl/toast/macros.fnl index e9d5038..8d7f219 100644 --- a/dot_config/nvim/fnl/toast/macros.fnl +++ b/dot_config/nvim/fnl/toast/macros.fnl @@ -2,8 +2,12 @@ (local {: inc : drop - : assoc} (require :toast.core)) -(local {: insert} (require :toast.table)) + : assoc + : filter + : even? + : odd? + : last} (require :toast.core)) +(local {: insert : unpack : concat} (require :toast.table)) (fn mixed-table [...] "Generate a mixed table. @@ -11,12 +15,16 @@ This macro simply expands to the correct data during compile-time. It is recommended to import this as a single character macro locally." (let [args [...] - pre (accumulate [out [] - _ v (ipairs args) - &until (= v '&)] - (insert out v)) - post (drop (inc (length pre)) args)] - (assoc pre (unpack post)))) + ; groups, separated by &s + grps (accumulate [out [[]] + _ v (ipairs args)] + (if (= v '&) + (insert out []) + (do (table.insert (last out) v) + out))) + kvs (concat (unpack (filter even? grps))) + arr (concat (unpack (filter odd? grps)))] + (assoc arr (unpack kvs)))) (fn recc [reqspec key ...] "A common lua pattern is `require 'something'.call(arg1, arg2)`. diff --git a/dot_config/nvim/fnl/toast/table.fnl b/dot_config/nvim/fnl/toast/table.fnl index fe118e8..17934b2 100644 --- a/dot_config/nvim/fnl/toast/table.fnl +++ b/dot_config/nvim/fnl/toast/table.fnl @@ -11,8 +11,18 @@ (table.insert t ...) t) +(fn concat [...] + "Join an arbitrary amount of tables. + Equivalent to a single 'layer' of flat." + (let [out []] + (each [_ xs (ipairs [...])] + (each [_ v (ipairs xs)] + (insert out v))) + out)) + (local unpack (or table.unpack unpack)) {: from-pairs : insert - : unpack} + : unpack + : concat} |
