aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s+removethis@s-ol.nu>2021-05-01 20:46:09 +0000
committers-ol <s+removethis@s-ol.nu>2025-03-02 14:24:49 +0000
commit495b2ac5abfdb1a75ad97277742fa44880834a12 (patch)
treeaeec647385e96a8b3832e0a910bfa35f85845bc1
parentrename array/struct modules to avoid name conflict (diff)
downloadalive-495b2ac5abfdb1a75ad97277742fa44880834a12.tar.gz
alive-495b2ac5abfdb1a75ad97277742fa44880834a12.zip
add thread-first/thread-last macro + spec
-rw-r--r--alv/builtins.moon47
-rw-r--r--spec/lang/thread_spec.moon25
2 files changed, 72 insertions, 0 deletions
diff --git a/alv/builtins.moon b/alv/builtins.moon
index 47dbab8..6d69735 100644
--- a/alv/builtins.moon
+++ b/alv/builtins.moon
@@ -620,6 +620,50 @@ bound to `nv2`…
table.insert children, node
super RTNode :children, result: node.result
+mk_thread = (name, thread_first) ->
+ class extends Builtin
+ eval: (scope, tail) =>
+ L\trace "evaling #{@}"
+ assert #tail > 1, "'#{name}' requires at least 2 arguments"
+
+ last_result = tail[1]
+
+ for cell in *tail[2,]
+ assert cell.__class == Cell, "'#{name}'s arguments have to be expressions"
+
+ children = [c for c in *cell.children]
+ if thread_first
+ table.insert children, 2, last_result
+ else
+ table.insert children, last_result
+
+ last_result = Cell cell.tag, children
+
+ super last_result\eval scope, tail
+
+thread_first = Constant.meta
+ meta:
+ name: '->'
+ summary: "Thread first macro."
+ examples: { '(-> initial [expr1 expr2…])' }
+ description: "
+Evaluate expressions `expr1`, `expr2`, … while passing the result of the
+previous expression to the following one, starting with `initial`. The value
+is always inserted as the first argument."
+
+ value: mk_thread '->', true
+
+thread_last = Constant.meta
+ meta:
+ name: '->>'
+ summary: "Thread last macro."
+ examples: { '(->> initial [expr1 expr2…])' }
+ description: "
+Evaluate expressions `expr1`, `expr2`, … while passing the result of the
+previous expression to the following one, starting with `initial`. The value
+is always inserted as the last argument."
+
+ value: mk_thread '->>', false
Constant.meta
meta:
@@ -646,6 +690,9 @@ Constant.meta
'~': to_sig
'!': to_evt
+ '->': thread_first
+ '->>': thread_last
+
:array, :struct
:loop, :recur
diff --git a/spec/lang/thread_spec.moon b/spec/lang/thread_spec.moon
new file mode 100644
index 0000000..aa30a1b
--- /dev/null
+++ b/spec/lang/thread_spec.moon
@@ -0,0 +1,25 @@
+import TestPilot from require 'spec.test_setup'
+import T, Struct, Array, Constant from require 'alv'
+
+describe "thread macros", ->
+ COPILOT = TestPilot ''
+
+ it "thread forward (->)", ->
+ rt = COPILOT\eval_once '
+ (import* math)
+ #((/ (+ 10 2) 2) = 6)
+ (-> 10
+ (+ 2)
+ (/ 2))'
+ assert.is.true rt\is_const!
+ assert.is.equal (Constant.num 6), rt.result
+
+ it "thread last forward (->>)", ->
+ rt = COPILOT\eval_once '
+ (import* math)
+ #((/ 10 (+ 2 3)) = 2)
+ (->> 3
+ (+ 2)
+ (/ 10))'
+ assert.is.true rt\is_const!
+ assert.is.equal (Constant.num 2), rt.result