mirror of
https://github.com/janet-lang/janet
synced 2025-03-28 19:16:56 +00:00
Add array and tuple versions of map and for.
This commit is contained in:
parent
45f8db0360
commit
f5b4bc4fdf
@ -26,7 +26,7 @@
|
|||||||
(def start (fstart 0))
|
(def start (fstart 0))
|
||||||
(def fnbody (tuple.prepend (tuple.prepend (tuple.slice more start) name) 'fn))
|
(def fnbody (tuple.prepend (tuple.prepend (tuple.slice more start) name) 'fn))
|
||||||
(def formargs (array.concat @['def name] (array.slice more 0 start) @[fnbody]))
|
(def formargs (array.concat @['def name] (array.slice more 0 start) @[fnbody]))
|
||||||
(apply1 tuple formargs)))
|
(tuple.slice formargs 0)))
|
||||||
|
|
||||||
(def defmacro :macro
|
(def defmacro :macro
|
||||||
"Define a macro."
|
"Define a macro."
|
||||||
@ -36,17 +36,17 @@
|
|||||||
(defmacro defmacro-
|
(defmacro defmacro-
|
||||||
"Define a private macro that will not be exported."
|
"Define a private macro that will not be exported."
|
||||||
[name & more]
|
[name & more]
|
||||||
(apply1 tuple (array.concat @['defmacro name :private] more)))
|
(tuple.slice (array.concat @['defmacro name :private] more) 0))
|
||||||
|
|
||||||
(defmacro defn-
|
(defmacro defn-
|
||||||
"Define a private function that will not be exported."
|
"Define a private function that will not be exported."
|
||||||
[name & more]
|
[name & more]
|
||||||
(apply1 tuple (array.concat @['defn name :private] more)))
|
(tuple.slice (array.concat @['defn name :private] more) 0))
|
||||||
|
|
||||||
(defmacro def-
|
(defmacro def-
|
||||||
"Define a private value that will not be exported."
|
"Define a private value that will not be exported."
|
||||||
[name & more]
|
[name & more]
|
||||||
(apply1 tuple (array.concat @['def name :private] more)))
|
(tuple.slice (array.concat @['def name :private] more) 0))
|
||||||
|
|
||||||
(defmacro defasm
|
(defmacro defasm
|
||||||
"Define a function using assembly"
|
"Define a function using assembly"
|
||||||
@ -230,7 +230,7 @@
|
|||||||
(array.push accum (tuple 'def k v))
|
(array.push accum (tuple 'def k v))
|
||||||
(+= i 2))
|
(+= i 2))
|
||||||
(array.concat accum body)
|
(array.concat accum body)
|
||||||
(apply1 tuple accum))
|
(tuple.slice accum 0))
|
||||||
|
|
||||||
(defmacro and
|
(defmacro and
|
||||||
"Evaluates to the last argument if all preceding elements are true, otherwise
|
"Evaluates to the last argument if all preceding elements are true, otherwise
|
||||||
@ -294,7 +294,7 @@
|
|||||||
(def subloop (doone (+ i 3) preds))
|
(def subloop (doone (+ i 3) preds))
|
||||||
(tuple 'do
|
(tuple 'do
|
||||||
(tuple 'var $iter nil)
|
(tuple 'var $iter nil)
|
||||||
(tuple 'while (apply1 tuple preds)
|
(tuple 'while (tuple.slice preds 0)
|
||||||
(tuple 'def bindings $iter)
|
(tuple 'def bindings $iter)
|
||||||
subloop)))
|
subloop)))
|
||||||
:range (do
|
:range (do
|
||||||
@ -307,7 +307,7 @@
|
|||||||
(tuple 'do
|
(tuple 'do
|
||||||
(tuple 'var $iter start)
|
(tuple 'var $iter start)
|
||||||
(tuple 'def endsym end)
|
(tuple 'def endsym end)
|
||||||
(tuple 'while (apply1 tuple preds)
|
(tuple 'while (tuple.slice preds 0)
|
||||||
(tuple 'def bindings $iter)
|
(tuple 'def bindings $iter)
|
||||||
subloop
|
subloop
|
||||||
(tuple ':= $iter (tuple + $iter inc)))))
|
(tuple ':= $iter (tuple + $iter inc)))))
|
||||||
@ -319,7 +319,7 @@
|
|||||||
(tuple 'do
|
(tuple 'do
|
||||||
(tuple 'def $dict object)
|
(tuple 'def $dict object)
|
||||||
(tuple 'var $iter (tuple next $dict nil))
|
(tuple 'var $iter (tuple next $dict nil))
|
||||||
(tuple 'while (apply1 tuple preds)
|
(tuple 'while (tuple.slice preds 0)
|
||||||
(tuple 'def bindings $iter)
|
(tuple 'def bindings $iter)
|
||||||
subloop
|
subloop
|
||||||
(tuple ':= $iter (tuple next $dict $iter)))))
|
(tuple ':= $iter (tuple next $dict $iter)))))
|
||||||
@ -333,14 +333,14 @@
|
|||||||
(tuple 'def $indexed object)
|
(tuple 'def $indexed object)
|
||||||
(tuple 'def $len (tuple length $indexed))
|
(tuple 'def $len (tuple length $indexed))
|
||||||
(tuple 'var $i 0)
|
(tuple 'var $i 0)
|
||||||
(tuple 'while (apply1 tuple preds)
|
(tuple 'while (tuple.slice preds 0)
|
||||||
(tuple 'def bindings (tuple get $indexed $i))
|
(tuple 'def bindings (tuple get $indexed $i))
|
||||||
subloop
|
subloop
|
||||||
(tuple ':= $i (tuple + 1 $i)))))
|
(tuple ':= $i (tuple + 1 $i)))))
|
||||||
(error (string "unexpected loop verb: " verb)))))))
|
(error (string "unexpected loop verb: " verb)))))))
|
||||||
(doone 0 nil))
|
(doone 0 nil))
|
||||||
|
|
||||||
(defmacro for
|
(defmacro fora
|
||||||
"Similar to loop, but accumulates the loop body into an array and returns that."
|
"Similar to loop, but accumulates the loop body into an array and returns that."
|
||||||
[head & body]
|
[head & body]
|
||||||
(def $accum (gensym))
|
(def $accum (gensym))
|
||||||
@ -351,6 +351,17 @@
|
|||||||
(tuple.prepend body 'do)))
|
(tuple.prepend body 'do)))
|
||||||
$accum))
|
$accum))
|
||||||
|
|
||||||
|
(defmacro for
|
||||||
|
"Similar to loop, but accumulates the loop body into a tuple and returns that."
|
||||||
|
[head & body]
|
||||||
|
(def $accum (gensym))
|
||||||
|
(tuple 'do
|
||||||
|
(tuple 'def $accum @[])
|
||||||
|
(tuple 'loop head
|
||||||
|
(tuple array.push $accum
|
||||||
|
(tuple.prepend body 'do)))
|
||||||
|
(tuple tuple.slice $accum 0)))
|
||||||
|
|
||||||
(defn sum [xs]
|
(defn sum [xs]
|
||||||
(var accum 0)
|
(var accum 0)
|
||||||
(loop [x :in xs] (+= accum x))
|
(loop [x :in xs] (+= accum x))
|
||||||
@ -482,10 +493,10 @@
|
|||||||
|
|
||||||
(defn sorted
|
(defn sorted
|
||||||
"Returns the sorted version of an indexed data structure."
|
"Returns the sorted version of an indexed data structure."
|
||||||
@[ind by]
|
@[ind by t]
|
||||||
(def sa (sort (apply1 array ind) by))
|
(def sa (sort (array.slice ind 0) by))
|
||||||
(if (= :tuple (type ind))
|
(if (= :tuple (or t (type ind)))
|
||||||
(apply1 tuple sa)
|
(tuple.slice sa 0)
|
||||||
sa))
|
sa))
|
||||||
|
|
||||||
(defn reduce
|
(defn reduce
|
||||||
@ -497,9 +508,9 @@
|
|||||||
(:= res (f res x)))
|
(:= res (f res x)))
|
||||||
res)
|
res)
|
||||||
|
|
||||||
(defn map
|
(defn mapa
|
||||||
"Map a function over every element in an array or tuple and return
|
"Map a function over every element in an indexed data structure and
|
||||||
the same type as the input sequence."
|
return an array of the results."
|
||||||
[f & inds]
|
[f & inds]
|
||||||
(def ninds (length inds))
|
(def ninds (length inds))
|
||||||
(if (= 0 ninds) (error "expected at least 1 indexed collection"))
|
(if (= 0 ninds) (error "expected at least 1 indexed collection"))
|
||||||
@ -520,6 +531,12 @@
|
|||||||
(put res i (apply1 f args))))
|
(put res i (apply1 f args))))
|
||||||
res)
|
res)
|
||||||
|
|
||||||
|
(defn map
|
||||||
|
"Map a function over every element in an indexed data structure and
|
||||||
|
return a tuple of the results."
|
||||||
|
[f & inds]
|
||||||
|
(tuple.slice (apply mapa f inds) 0))
|
||||||
|
|
||||||
(defn each
|
(defn each
|
||||||
"Map a function over every element in an array or tuple but do not
|
"Map a function over every element in an array or tuple but do not
|
||||||
return a new indexed type."
|
return a new indexed type."
|
||||||
@ -543,26 +560,27 @@
|
|||||||
|
|
||||||
(defn mapcat
|
(defn mapcat
|
||||||
"Map a function over every element in an array or tuple and
|
"Map a function over every element in an array or tuple and
|
||||||
use array to concatenate the results. Returns the same
|
use array to concatenate the results. Returns the type given
|
||||||
type as the input sequence."
|
as the third argument, or same type as the input indexed structure."
|
||||||
@[f ind t]
|
@[f ind t]
|
||||||
(def res @[])
|
(def res @[])
|
||||||
(loop [x :in ind]
|
(loop [x :in ind]
|
||||||
(array.concat res (f x)))
|
(array.concat res (f x)))
|
||||||
(if (= :tuple (type (or t ind)))
|
(if (= :tuple (or t (type ind)))
|
||||||
(apply1 tuple res)
|
(tuple.slice res 0)
|
||||||
res))
|
res))
|
||||||
|
|
||||||
(defn filter
|
(defn filter
|
||||||
"Given a predicate, take only elements from an array or tuple for
|
"Given a predicate, take only elements from an array or tuple for
|
||||||
which (pred element) is truthy. Returns the same type as the input sequence."
|
which (pred element) is truthy. Returns the type given as the
|
||||||
|
third argument, or the same type as the input indexed structure."
|
||||||
@[pred ind t]
|
@[pred ind t]
|
||||||
(def res @[])
|
(def res @[])
|
||||||
(loop [item :in ind]
|
(loop [item :in ind]
|
||||||
(if (pred item)
|
(if (pred item)
|
||||||
(array.push res item)))
|
(array.push res item)))
|
||||||
(if (= :tuple (type (or t ind)))
|
(if (= :tuple (or t (type ind)))
|
||||||
(apply1 tuple res)
|
(tuple.slice res 0)
|
||||||
res))
|
res))
|
||||||
|
|
||||||
(defn range
|
(defn range
|
||||||
@ -618,7 +636,7 @@
|
|||||||
the predicate, and abort on first failure. Returns a new tuple."
|
the predicate, and abort on first failure. Returns a new tuple."
|
||||||
[pred ind]
|
[pred ind]
|
||||||
(def i (find-index pred ind))
|
(def i (find-index pred ind))
|
||||||
(tuple.slice ind i -1))
|
(tuple.slice ind i))
|
||||||
|
|
||||||
(defn drop-while
|
(defn drop-while
|
||||||
"Same as (drop-until (complement pred) ind)."
|
"Same as (drop-until (complement pred) ind)."
|
||||||
@ -631,7 +649,7 @@
|
|||||||
(def ret @[])
|
(def ret @[])
|
||||||
(loop [f :in funs]
|
(loop [f :in funs]
|
||||||
(array.push ret (apply1 f args)))
|
(array.push ret (apply1 f args)))
|
||||||
(apply1 tuple ret)))
|
(tuple.slice ret 0)))
|
||||||
|
|
||||||
(defmacro juxt
|
(defmacro juxt
|
||||||
[& funs]
|
[& funs]
|
||||||
@ -639,7 +657,7 @@
|
|||||||
(def $args (gensym))
|
(def $args (gensym))
|
||||||
(loop [f :in funs]
|
(loop [f :in funs]
|
||||||
(array.push parts (tuple apply1 f $args)))
|
(array.push parts (tuple apply1 f $args)))
|
||||||
(tuple 'fn (tuple '& $args) (apply1 tuple parts)))
|
(tuple 'fn (tuple '& $args) (tuple.slice parts 0)))
|
||||||
|
|
||||||
(defmacro ->
|
(defmacro ->
|
||||||
"Threading macro. Inserts x as the second value in the first form
|
"Threading macro. Inserts x as the second value in the first form
|
||||||
@ -651,7 +669,7 @@
|
|||||||
[tuple (get n 0) (array.slice n 1)]
|
[tuple (get n 0) (array.slice n 1)]
|
||||||
[tuple n @[]]))
|
[tuple n @[]]))
|
||||||
(def parts (array.concat @[h last] t))
|
(def parts (array.concat @[h last] t))
|
||||||
(apply1 tuple parts))
|
(tuple.slice parts 0))
|
||||||
(reduce fop x forms))
|
(reduce fop x forms))
|
||||||
|
|
||||||
(defmacro ->>
|
(defmacro ->>
|
||||||
@ -664,7 +682,7 @@
|
|||||||
[tuple (get n 0) (array.slice n 1)]
|
[tuple (get n 0) (array.slice n 1)]
|
||||||
[tuple n @[]]))
|
[tuple n @[]]))
|
||||||
(def parts (array.concat @[h] t @[last]))
|
(def parts (array.concat @[h] t @[last]))
|
||||||
(apply1 tuple parts))
|
(tuple.slice parts 0))
|
||||||
(reduce fop x forms))
|
(reduce fop x forms))
|
||||||
|
|
||||||
(defn partial
|
(defn partial
|
||||||
@ -697,7 +715,7 @@
|
|||||||
(defn tuple.reverse
|
(defn tuple.reverse
|
||||||
"Reverses the order of the elements given an array or tuple and returns a tuple"
|
"Reverses the order of the elements given an array or tuple and returns a tuple"
|
||||||
[t]
|
[t]
|
||||||
(apply1 tuple (array.reverse t)))
|
(tuple.slice (array.reverse t) 0))
|
||||||
|
|
||||||
(defn reverse
|
(defn reverse
|
||||||
"Reverses order of elements in a given array or tuple"
|
"Reverses order of elements in a given array or tuple"
|
||||||
@ -889,7 +907,7 @@
|
|||||||
(defn expand-bindings [x]
|
(defn expand-bindings [x]
|
||||||
(case (type x)
|
(case (type x)
|
||||||
:array (map expand-bindings x)
|
:array (map expand-bindings x)
|
||||||
:tuple (apply1 tuple (map expand-bindings x))
|
:tuple (tuple.slice (map expand-bindings x) 0)
|
||||||
:table (dotable x expand-bindings)
|
:table (dotable x expand-bindings)
|
||||||
:struct (table.to-struct (dotable x expand-bindings))
|
:struct (table.to-struct (dotable x expand-bindings))
|
||||||
(macroexpand-1 x)))
|
(macroexpand-1 x)))
|
||||||
@ -898,8 +916,8 @@
|
|||||||
(def len (length t))
|
(def len (length t))
|
||||||
(def last (get t (- len 1)))
|
(def last (get t (- len 1)))
|
||||||
(def last2 (get t (- len 2)))
|
(def last2 (get t (- len 2)))
|
||||||
(apply1 tuple (array.concat (array.slice t 0 -3)
|
(tuple.slice (array.concat (array.slice t 0 -3)
|
||||||
@[(expand-bindings last2) (macroexpand-1 last)])))
|
@[(expand-bindings last2) (macroexpand-1 last)]) 0))
|
||||||
|
|
||||||
(defn expandall [t]
|
(defn expandall [t]
|
||||||
(def args (map macroexpand-1 (tuple.slice t 1)))
|
(def args (map macroexpand-1 (tuple.slice t 1)))
|
||||||
@ -928,7 +946,7 @@
|
|||||||
(cond
|
(cond
|
||||||
s (s t)
|
s (s t)
|
||||||
m? (apply1 m (tuple.slice t 1))
|
m? (apply1 m (tuple.slice t 1))
|
||||||
(apply1 tuple (map macroexpand-1 t))))
|
(tuple.slice (map macroexpand-1 t) 0)))
|
||||||
|
|
||||||
(def ret
|
(def ret
|
||||||
(case (type x)
|
(case (type x)
|
||||||
@ -1166,7 +1184,7 @@
|
|||||||
(def last (get parts (- (length parts) 1)))
|
(def last (get parts (- (length parts) 1)))
|
||||||
(def normname (string.replace-all "." "/" path))
|
(def normname (string.replace-all "." "/" path))
|
||||||
(array.push
|
(array.push
|
||||||
(map (fn [x]
|
(mapa (fn [x]
|
||||||
(def y (string.replace "??" last x))
|
(def y (string.replace "??" last x))
|
||||||
(string.replace "?" normname y))
|
(string.replace "?" normname y))
|
||||||
paths)
|
paths)
|
||||||
|
@ -164,11 +164,11 @@
|
|||||||
(testmarsh (fn name [x] x) "marshal function 1")
|
(testmarsh (fn name [x] x) "marshal function 1")
|
||||||
(testmarsh (fn [x] (+ 10 x 2)) "marshal function 2")
|
(testmarsh (fn [x] (+ 10 x 2)) "marshal function 2")
|
||||||
(testmarsh (fn thing [x] (+ 11 x x 30)) "marshal function 3")
|
(testmarsh (fn thing [x] (+ 11 x x 30)) "marshal function 3")
|
||||||
(testmarsh map "marshal function 4")
|
(testmarsh mapa "marshal function 4")
|
||||||
(testmarsh reduce "marshal function 4")
|
(testmarsh reduce "marshal function 5")
|
||||||
|
|
||||||
# Large functions
|
# Large functions
|
||||||
(def manydefs (for [i :range [0 300]] (tuple 'def (gensym) (string "value_" i))))
|
(def manydefs (fora [i :range [0 300]] (tuple 'def (gensym) (string "value_" i))))
|
||||||
(array.push manydefs (tuple * 10000 3 5 7 9))
|
(array.push manydefs (tuple * 10000 3 5 7 9))
|
||||||
(def f (compile (tuple.prepend manydefs 'do) *env*))
|
(def f (compile (tuple.prepend manydefs 'do) *env*))
|
||||||
(assert (= (f) (* 10000 3 5 7 9)) "long function compilation")
|
(assert (= (f) (* 10000 3 5 7 9)) "long function compilation")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user