diff options
| author | s-ol <s+removethis@s-ol.nu> | 2021-05-01 20:46:09 +0000 |
|---|---|---|
| committer | s-ol <s+removethis@s-ol.nu> | 2025-03-02 14:24:49 +0000 |
| commit | 495b2ac5abfdb1a75ad97277742fa44880834a12 (patch) | |
| tree | aeec647385e96a8b3832e0a910bfa35f85845bc1 | |
| parent | rename array/struct modules to avoid name conflict (diff) | |
| download | alive-495b2ac5abfdb1a75ad97277742fa44880834a12.tar.gz alive-495b2ac5abfdb1a75ad97277742fa44880834a12.zip | |
add thread-first/thread-last macro + spec
| -rw-r--r-- | alv/builtins.moon | 47 | ||||
| -rw-r--r-- | spec/lang/thread_spec.moon | 25 |
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 |
