aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s-ol@users.noreply.github.com>2020-07-11 17:10:44 +0000
committers-ol <s+removethis@s-ol.nu>2025-03-02 14:24:49 +0000
commit3066cdcbfce5876e2b2660ad41ffe6b0cc1490c5 (patch)
tree523ad5a078df01df87adae9660e5ba267873757e
parentsmall cleanup (diff)
downloadalive-3066cdcbfce5876e2b2660ad41ffe6b0cc1490c5.tar.gz
alive-3066cdcbfce5876e2b2660ad41ffe6b0cc1490c5.zip
move util/switch to builtins
-rw-r--r--alv-lib/util.moon44
-rw-r--r--alv/builtins.moon63
2 files changed, 58 insertions, 49 deletions
diff --git a/alv-lib/util.moon b/alv-lib/util.moon
index c8f354e..69ef389 100644
--- a/alv-lib/util.moon
+++ b/alv-lib/util.moon
@@ -1,48 +1,5 @@
import Constant, Op, Input, T, sig, evt from require 'alv.base'
-all_same = (list) ->
- for v in *list[2,]
- if v != list[1]
- return false
-
- list[1]
-
-switch_ = Constant.meta
- meta:
- name: 'switch'
- summary: "Switch between multiple inputs."
- examples: { '(switch i v1 v2…)' }
- description: "
-- when `i` is `true`, the first value is reproduced.
-- when `i` is `false`, the second value is reproduced.
-- when `i` is a `num`, it is [math/floor][]ed and the matching argument
- (indexed starting from 0) is reproduced."
-
- value: class extends Op
- val_or_evt = (sig! / evt!)!
- pattern = (sig.num / sig.bool) + val_or_evt*0
- setup: (inputs) =>
- { i, values } = pattern\match inputs
-
- @out = if values[1].result.metatype ~= '!'
- values[1]\type!\mk_sig!
- else
- values[1]\type!\mk_evt!
-
- super
- i: Input.hot i
- values: [Input.hot v for v in *values]
-
- tick: =>
- { :i, :values } = @inputs
- ii = switch i!
- when true then 1
- when false then 2
- else 1 + (math.floor i!) % #values
-
- @state = ii - 1
- @out\set values[ii] and values[ii]!
-
edge = Constant.meta
meta:
name: 'edge'
@@ -62,6 +19,5 @@ edge = Constant.meta
@state = now
{
- 'switch': switch_
:edge
}
diff --git a/alv/builtins.moon b/alv/builtins.moon
index 9966f3b..9fffabc 100644
--- a/alv/builtins.moon
+++ b/alv/builtins.moon
@@ -272,7 +272,10 @@ to `then-expr`, otherwise it is equivalent to `else-xpr` if given, or nil otherw
{ xif, xthen, xelse } = tail
xif = L\push xif\eval, scope
- xif = xif\const!\unwrap!
+ if not xif\is_const!
+ msg = "'if'-expression needs to be constant, did you mean 'switch'?"
+ error Error 'argument', msg
+ xif = xif\result!\unwrap!
super if xif
xthen\eval scope
@@ -281,6 +284,55 @@ to `then-expr`, otherwise it is equivalent to `else-xpr` if given, or nil otherw
else
RTNode!
+switch_ = Constant.meta
+ meta:
+ name: 'switch'
+ summary: "Switch between multiple inputs."
+ examples: { '(switch i v1 v2…)' }
+ description: "
+- When fed a bang! trigger, steps forward to the next step on each trigger.
+- When fed a num~ or num! stream, reproduces the matching argument (indexed
+ starting from 0).
+- When fed a bool~ or bool! stream, outputs the first or second argument for
+ `true` and `false` respectively. This version takes at most two argumetns."
+
+ value: class extends Op
+ val_or_evt = (sig! / evt!)!
+ pattern = (sig.num / sig.bool / evt.num / evt.bool / evt.bang) + val_or_evt*0
+ setup: (inputs) =>
+ { i, values } = pattern\match inputs
+
+ @out = if values[1].result.metatype ~= '!'
+ values[1]\type!\mk_sig!
+ else
+ values[1]\type!\mk_evt!
+
+ if i\type! == T.bang
+ @state or= 1
+ else
+ @state = nil
+
+ super
+ i: Input.hot i
+ values: [Input.hot v for v in *values]
+
+ tick: =>
+ { :i, :values } = @inputs
+
+ ii = if i\type! == T.bang
+ if i\dirty!
+ @state += 1
+ while @state >= #values
+ @state -= #values
+ @state
+ else
+ switch i!
+ when true then 0
+ when false then 1
+ else (math.floor i!) % #values
+
+ @out\set if v = values[ii + 1] then v!
+
trace_ = Constant.meta
meta:
name: 'trace='
@@ -561,6 +613,11 @@ Scope.from_table {
export: export_
'export*': export_star
+ :fn, :defn
+ 'do': do_expr
+ 'if': if_
+ 'switch': switch_
+
'=': to_const
'~': to_sig
'!': to_evt
@@ -586,8 +643,4 @@ Scope.from_table {
name: 'bang'
summary: "A `bang` value-constant."
value: Constant T.bang, true
-
- :fn, :defn
- 'do': do_expr
- if: if_
}