aboutsummaryrefslogtreecommitdiffstats
path: root/alv-lib/array.moon
diff options
context:
space:
mode:
authors-ol <s+removethis@s-ol.nu>2021-05-01 17:57:02 +0000
committers-ol <s+removethis@s-ol.nu>2025-03-02 14:24:49 +0000
commit90cc5071e97d357f0c357afc3bcf720e2825d9cc (patch)
tree6725e61caeb08cb73f7eef062b15cc6db75b2cf7 /alv-lib/array.moon
parentdocs/reference: fix link to guide (diff)
downloadalive-90cc5071e97d357f0c357afc3bcf720e2825d9cc.tar.gz
alive-90cc5071e97d357f0c357afc3bcf720e2825d9cc.zip
add array/map
Diffstat (limited to 'alv-lib/array.moon')
-rw-r--r--alv-lib/array.moon50
1 files changed, 49 insertions, 1 deletions
diff --git a/alv-lib/array.moon b/alv-lib/array.moon
index 6005b14..aeb6820 100644
--- a/alv-lib/array.moon
+++ b/alv-lib/array.moon
@@ -1,5 +1,9 @@
-import Array, Op, PureOp, Constant, Error, const, sig, evt from require 'alv.base'
+import Array, Op, PureOp, Builtin, Constant, Error, const, sig, evt, T from require 'alv.base'
+import Cell from require 'alv.cell'
+import Tag from require 'alv.tag'
+builtins = require 'alv.builtins'
+unpack or= table.unpack
any = sig! / evt!
get = Constant.meta
@@ -236,6 +240,49 @@ concat = Constant.meta
@out\set out
+array_constr = builtins!\get('array').result
+map = Constant.meta
+ meta:
+ name: 'map'
+ summary: "Apply an function to each value in an array."
+ examples: { '(map array fn)' }
+ description: "
+Invokes `fn` once for each element in `array` and returns an array of the results.
+`fn` must take one argument and return the same type consistently."
+
+ value: class extends Builtin
+ eval: (scope, tail) =>
+ L\trace "evaling #{@}"
+ assert #tail == 2, "'map' takes exactly two arguments"
+ tail = [L\push t\eval, scope for t in *tail]
+ { array, fn } = tail
+
+ fndef = fn.result
+ assert fn\type! == T.fndef, "fn has to be a fndef"
+ array_type = array\type!
+ assert array_type.__class == Array, Error 'argument', "expected an Array"
+
+ invocations = for i=1, array_type.size
+ tag_o = @tag\clone Tag.parse tostring i
+ tag_i = @tag\clone tag_o
+ Cell tag_o, {
+ with Constant.literal T.fndef, fndef!, 'fn'
+ .meta = fndef.meta
+ Cell tag_i, {
+ Constant.literal T.opdef, get!, 'get'
+ Constant.literal array_type, array.result!, 'array'
+ Constant.num i-1
+ }
+ }
+
+ tag = @tag\clone Tag.parse '-1'
+ inner = Cell tag, {
+ Constant.literal T.opdef, array_constr, 'array'
+ unpack invocations
+ }
+ super inner\eval scope
+
+
Constant.meta
meta:
name: 'array'
@@ -245,5 +292,6 @@ Constant.meta
:get, :set
:head, :tail, :prepend
:insert, :remove
+ :map
:size, :concat