diff options
| author | s-ol <s-ol@users.noreply.github.com> | 2020-05-14 15:18:40 +0000 |
|---|---|---|
| committer | s-ol <s+removethis@s-ol.nu> | 2025-03-02 14:24:49 +0000 |
| commit | 6255ff9d6fcc36c752f9a0229db4eaecb5a9e466 (patch) | |
| tree | 1cebf8b34b98970910b18fc164f32e208ec68f0a | |
| parent | fix osc/sync (diff) | |
| download | alive-6255ff9d6fcc36c752f9a0229db4eaecb5a9e466.tar.gz alive-6255ff9d6fcc36c752f9a0229db4eaecb5a9e466.zip | |
pureops with arbitrary pattern
| -rw-r--r-- | alv/base/op.moon | 21 | ||||
| -rw-r--r-- | alv/base/pureop.moon | 32 | ||||
| -rw-r--r-- | alv/util.moon | 28 |
3 files changed, 53 insertions, 28 deletions
diff --git a/alv/base/op.moon b/alv/base/op.moon index da90288..a88bbe5 100644 --- a/alv/base/op.moon +++ b/alv/base/op.moon @@ -2,31 +2,16 @@ -- Persistent expression Operator. -- -- @classmod Op - -deepcopy = (val) -> - switch type val - when 'number', 'string', 'boolean', 'nil' - val - when 'table' - assert (not getmetatable {}), "state should only contain simple tables!" - {(deepcopy k), (deepcopy v) for k,v in pairs val} - else - error "state cannot contain values of type '#{type val}'" +import deep_copy, deep_iter from require 'alv.util' class Op --- members -- @section members - do_yield = (table) -> - for k, v in pairs table - if v.__class - coroutine.yield v - else - do_yield v --- yield all `Input`s from the (potentially nested) `inputs` table -- -- @treturn iterator iterator over `inputs` - all_inputs: => coroutine.wrap -> do_yield @inputs + all_inputs: => coroutine.wrap -> deep_iter @inputs --- create a mutable copy of this Op. -- @@ -36,7 +21,7 @@ class Op -- @treturn Op fork: => out = if @out then @out\fork! - state = if @state then deepcopy @state + state = if @state then deep_copy @state @@ out, state --- internal state of this Op. diff --git a/alv/base/pureop.moon b/alv/base/pureop.moon index ea3b810..6a058f6 100644 --- a/alv/base/pureop.moon +++ b/alv/base/pureop.moon @@ -10,8 +10,9 @@ -- @classmod PureOp import Op from require 'alv.base.op' import Input from require 'alv.base.input' -import SigStream, EvtStream from require 'alv.result' +import Type from require 'alv.type' import Error from require 'alv.error' +import ancestor, deep_iter, deep_map from require 'alv.util' unpack or= table.unpack @@ -24,32 +25,43 @@ class PureOp extends Op -- Must resolve to a simple sequence-table (depth 1). -- -- @tfield match.Pattern pattern - @pattern: nil - --- the result type. - -- @tfield type.Type type - @type: nil + --- the result type or a method that returns it. + -- + -- Can be either a method or just a fixed type. + -- + -- @tparam table args as parsed by `pattern` + -- @treturn type.Type --- set up inputs for a range of things. setup: (inputs) => args = @@pattern\match inputs local trigger - for arg in *args + for arg in coroutine.wrap -> deep_iter args if arg.result.metatype == '!' assert not trigger, Error 'argument', "pure op can take at most one !-stream." trigger = arg + typ = if (type @type) == 'table' then @type else @type args + assert (ancestor typ.__class) == Type, "not a type: #{typ}" + if trigger - super for a in *args + super deep_map args, (a) -> if a == trigger Input.hot trigger else Input.cold a - @out = EvtStream @@type + -- super for a in *args + -- if a == trigger + -- Input.hot trigger + -- else + -- Input.cold a + @out = typ\mk_evt! else - super [Input.hot a for a in *args] - @out or= SigStream @@type + -- super [Input.hot a for a in *args] + super deep_map args, (a) -> Input.hot a + @out or= typ\mk_sig! { :PureOp diff --git a/alv/util.moon b/alv/util.moon index 316233b..e175600 100644 --- a/alv/util.moon +++ b/alv/util.moon @@ -31,7 +31,35 @@ ancestor = (klass) -> klass = klass.__parent klass +--- check whether a table is a 'plain' table +is_plain_table = (val) -> (type val) == 'table' and not val.__class + +--- recursively copy a value +deep_copy = (val) -> + if is_plain_table val + {(deep_copy k), (deep_copy v) for k,v in pairs val} + else + val + +--- map leaf values in a table +deep_map = (val, fn) -> + if is_plain_table val + {k, (deep_map v, fn) for k,v in pairs val} + else + fn val + +--- yield all leaf values in a table +deep_iter = (table) -> + for k, v in pairs table + if is_plain_table v + deep_iter v + else + coroutine.yield v + { :opairs :ancestor + :deep_copy + :deep_map + :deep_iter } |
