diff options
| author | s-ol <s-ol@users.noreply.github.com> | 2020-05-09 14:49:08 +0000 |
|---|---|---|
| committer | s-ol <s+removethis@s-ol.nu> | 2025-03-02 14:23:21 +0000 |
| commit | 61eb86951287667ca0ee305baa5c3cd6ad29ba36 (patch) | |
| tree | 7551d6b9c8af01c049adab0ee027dbad68f28808 | |
| parent | more internal doc fixes (diff) | |
| download | alive-61eb86951287667ca0ee305baa5c3cd6ad29ba36.tar.gz alive-61eb86951287667ca0ee305baa5c3cd6ad29ba36.zip | |
add types.T, fix spec + docs
37 files changed, 486 insertions, 428 deletions
diff --git a/alv-lib/logic.moon b/alv-lib/logic.moon index 3c893df..c3cc66f 100644 --- a/alv-lib/logic.moon +++ b/alv-lib/logic.moon @@ -1,4 +1,4 @@ -import Op, ValueStream, Input, Error, val from require 'alv.base' +import Op, SigStream, Constant, Input, Error, T, val from require 'alv.base' all_same = (first, list) -> for v in *list @@ -17,7 +17,7 @@ tobool = (val) -> class ReduceOp extends Op pattern = val! + val! * 0 setup: (inputs) => - @out or= ValueStream 'bool' + @out or= SigStream T.bool { first, rest } = pattern\match inputs super first: Input.hot first @@ -31,7 +31,7 @@ class ReduceOp extends Op @out\set accum -eq = ValueStream.meta +eq = Constant.meta meta: name: 'eq' summary: "Check for equality." @@ -41,7 +41,7 @@ eq = ValueStream.meta value: class extends Op pattern = val! + val! * 0 setup: (inputs) => - @out or= ValueStream 'bool', false + @out or= SigStream T.bool, false { first, rest } = pattern\match inputs same = all_same first\type!, [i\type! for i in *rest] @@ -68,7 +68,7 @@ eq = ValueStream.meta @out\set equal -not_eq = ValueStream.meta +not_eq = Constant.meta meta: name: 'not-eq' summary: "Check for inequality." @@ -77,7 +77,7 @@ not_eq = ValueStream.meta value: class extends Op setup: (inputs) => - @out or= ValueStream 'bool', false + @out or= SigStream T.bool, false assert #inputs > 1, Error 'argument', "need at least two values" super [Input.hot v for v in *inputs] @@ -97,7 +97,7 @@ not_eq = ValueStream.meta @out\set diff -and_ = ValueStream.meta +and_ = Constant.meta meta: name: 'and' summary: "Logical AND." @@ -105,7 +105,7 @@ and_ = ValueStream.meta value: class extends ReduceOp fn: (a, b) -> a and b -or_ = ValueStream.meta +or_ = Constant.meta meta: name: 'or' summary: "Logical OR." @@ -113,7 +113,7 @@ or_ = ValueStream.meta value: class extends ReduceOp fn: (a, b) -> a or b -not_ = ValueStream.meta +not_ = Constant.meta meta: name: 'not' summary: "Logical NOT." @@ -121,14 +121,14 @@ not_ = ValueStream.meta value: class extends Op setup: (inputs) => - @out or= ValueStream 'bool', false + @out or= SigStream T.bool, false value = val!\match inputs super value: Input.hot value tick: => @out\set not tobool @inputs.value! -bool = ValueStream.meta +bool = Constant.meta meta: name: 'bool' summary: "Cast value to bool." @@ -137,7 +137,7 @@ bool = ValueStream.meta value: class extends Op setup: (inputs) => - @out or= ValueStream 'bool' + @out or= SigStream T.bool value = val!\match inputs super value: Input.hot value diff --git a/alv-lib/math.moon b/alv-lib/math.moon index 2cf8e5d..8037e8a 100644 --- a/alv-lib/math.moon +++ b/alv-lib/math.moon @@ -1,10 +1,10 @@ -import Op, ValueStream, Error, Input, val from require 'alv.base' +import Op, Constant, SigStream, Error, Input, T, val from require 'alv.base' unpack or= table.unpack class ReduceOp extends Op pattern = val.num + val.num*0 setup: (inputs) => - @out or= ValueStream 'num' + @out or= SigStream T.num { first, rest } = pattern\match inputs super first: Input.hot first @@ -21,14 +21,16 @@ func_op = (func, pattern) -> class extends Op setup: (inputs) => - @out or= ValueStream 'num' + @out or= SigStream T.num + params = pattern\match inputs super [Input.hot p for p in *params] + tick: => @out\set func unpack @unwrap_all! func_def = (name, args, func, summary, pattern) -> - ValueStream.meta + Constant.meta meta: :name :summary @@ -39,17 +41,17 @@ evenodd_op = (remainder) -> class extends Op pattern = val.num + -val.num setup: (inputs) => - @out or= ValueStream 'bool' + @out or= SigStream T.bool { val, div } = pattern\match inputs super val: Input.hot val - div: Input.hot div or ValueStream.num 2 + div: Input.hot div or SigStream.num 2 tick: => { :val, :div } = @unwrap_all! @out\set (val % div) == remainder -add = ValueStream.meta +add = Constant.meta meta: name: 'add' summary: "Add values." @@ -58,7 +60,7 @@ add = ValueStream.meta value: class extends ReduceOp fn: (a, b) -> a + b -sub = ValueStream.meta +sub = Constant.meta meta: name: 'sub' summary: "Subtract values." @@ -67,7 +69,7 @@ sub = ValueStream.meta value: class extends ReduceOp fn: (a, b) -> a - b -mul = ValueStream.meta +mul = Constant.meta meta: name: 'mul' summary: "Multiply values." @@ -75,7 +77,7 @@ mul = ValueStream.meta value: class extends ReduceOp fn: (a, b) -> a * b -div = ValueStream.meta +div = Constant.meta meta: name: 'div' summary: "Divide values." @@ -84,7 +86,7 @@ div = ValueStream.meta value: class extends ReduceOp fn: (a, b) -> a / b -pow = ValueStream.meta +pow = Constant.meta meta: name: 'pow' summary: "Raise to a power." @@ -93,7 +95,7 @@ pow = ValueStream.meta value: class extends ReduceOp fn: (a, b) -> a ^ b -mod = ValueStream.meta +mod = Constant.meta meta: name: 'mod' summary: 'Modulo operator.' @@ -101,7 +103,7 @@ mod = ValueStream.meta description: "Calculate remainder of division by `div`." value: func_op ((a, b) -> a % b), val.num + val.num -even = ValueStream.meta +even = Constant.meta meta: name: 'even' summary: 'Check whether val is even.' @@ -110,7 +112,7 @@ even = ValueStream.meta `div` defaults to 2." value: evenodd_op 0 -odd = ValueStream.meta +odd = Constant.meta meta: name: 'odd' summary: 'Check whether val is odd.' @@ -119,7 +121,7 @@ odd = ValueStream.meta `div` defaults to 2." value: evenodd_op 1 -mix = ValueStream.meta +mix = Constant.meta meta: name: 'mix' summary: 'Linearly interpolate.' @@ -127,7 +129,7 @@ mix = ValueStream.meta description: "Interpolate between `a` and `b` using `i` in range 0-1." value: func_op ((a, b, i) -> i*b + (1-i)*a), val.num + val.num + val.num -min = ValueStream.meta +min = Constant.meta meta: name: 'min' summary: "Find the minimum." @@ -135,7 +137,7 @@ min = ValueStream.meta description: "Return the lowest of arguments." value: func_op math.min, val.num*0 -max = ValueStream.meta +max = Constant.meta meta: name: 'max' summary: "Find the maximum." @@ -176,12 +178,17 @@ sqrt = func_def 'sqrt', 'val', math.sqrt, "Square root function." :mix :min, :max - pi: with ValueStream.wrap math.pi - .meta = summary: 'The pi constant.' - tau: with ValueStream.wrap math.pi*2 - .meta = summary: 'The tau constant.' - huge: with ValueStream.wrap math.huge - .meta = summary: 'Positive infinity constant.' + pi: Constant.meta + value: math.pi + meta: summary: 'The pi constant.' + + tau: Constant.meta + value: math.pi*2 + meta: summary: 'The tau constant.' + + huge: Constant.meta + value: math.huge + meta: summary: 'Positive infinity constant.' :sin, :cos, :tan :asin, :acos, :atan, :atan2 diff --git a/alv-lib/midi.moon b/alv-lib/midi.moon index 88d9547..e3bbe01 100644 --- a/alv-lib/midi.moon +++ b/alv-lib/midi.moon @@ -1,7 +1,7 @@ -import ValueStream, EventStream, Op, Input, val, evt from require 'alv.base' +import Constant, Op, Input, T, val, evt from require 'alv.base' import input, output, inout, apply_range from require 'alv-lib.midi.core' -gate = ValueStream.meta +gate = Constant.meta meta: name: 'gate' summary: "gate from note-on and note-off messages." @@ -10,12 +10,12 @@ gate = ValueStream.meta value: class extends Op pattern = -evt['midi/port'] + val.num -val.num setup: (inputs, scope) => - @out or= ValueStream 'bool' + @out or= T.bool\mk_sig! { port, note, chan } = pattern\match inputs super port: Input.hot port or scope\get '*midi*' note: Input.hot note - chan: Input.hot chan or ValueStream.num -1 + chan: Input.hot chan or Constant.num -1 tick: => { :port, :note, :chan } = @inputs @@ -31,7 +31,7 @@ gate = ValueStream.meta elseif msg.status == 'note-off' @out\set false -trig = ValueStream.meta +trig = Constant.meta meta: name: 'trig' summary: "`bang`s from note-on messages." @@ -40,12 +40,12 @@ trig = ValueStream.meta value: class extends Op pattern = -evt['midi/port'] + val.num -val.num setup: (inputs, scope) => - @out or= EventStream 'bang' + @out or= T.bang\mk_evt! { port, note, chan } = pattern\match inputs super port: Input.hot port or scope\get '*midi*' note: Input.cold note - chan: Input.cold chan or ValueStream.num -1 + chan: Input.cold chan or Constant.num -1 tick: => { :port, :note, :chan } = @inputs @@ -55,7 +55,7 @@ trig = ValueStream.meta if msg.status == 'note-on' @out\add true -cc = ValueStream.meta +cc = Constant.meta meta: name: 'cc' summary: "`num` from cc-change messages." @@ -76,10 +76,10 @@ cc = ValueStream.meta super port: Input.hot port or scope\get '*midi*' cc: Input.cold cc - chan: Input.cold chan or ValueStream.num -1 - range: Input.cold range or ValueStream.str 'uni' + chan: Input.cold chan or Constant.num -1 + range: Input.cold range or Constant.str 'uni' - @out or= ValueStream 'num', apply_range @inputs.range, 0 + @out or= T.num\mk_sig apply_range @inputs.range, 0 tick: => { :port, :cc, :chan, :range } = @inputs diff --git a/alv-lib/midi/core.moon b/alv-lib/midi/core.moon index 3adc401..71d1e9f 100644 --- a/alv-lib/midi/core.moon +++ b/alv-lib/midi/core.moon @@ -1,4 +1,4 @@ -import ValueStream, IOStream, Op, Input, Error, val from require 'alv.base' +import Constant, IOStream, Op, Input, T, Error, val from require 'alv.base' import RtMidiIn, RtMidiOut, RtMidi from require 'luartmidi' bit = do @@ -31,7 +31,7 @@ find_port = (Klass, name) -> \openport id class MidiPort extends IOStream - new: => super 'midi/port' + new: => super T['midi/port'] setup: (inp, out) => @inp = inp and find_port RtMidiIn, inp @@ -63,7 +63,7 @@ class PortOp extends Op { :inp, :out } = @unwrap_all! @out\setup inp, out -input = ValueStream.meta +input = Constant.meta meta: name: 'input' summary: "Create a MIDI input port." @@ -74,7 +74,7 @@ input = ValueStream.meta name = val.str\match inputs super inp: Input.hot name -output = ValueStream.meta +output = Constant.meta meta: name: 'output' summary: "Create a MIDI output port." @@ -85,7 +85,7 @@ output = ValueStream.meta name = val.str\match inputs super out: Input.hot name -inout = ValueStream.meta +inout = Constant.meta meta: name: 'inout' summary: "Create a bidirectional MIDI port." @@ -99,7 +99,7 @@ inout = ValueStream.meta out: Input.hot out apply_range = (range, val) -> - if range\type! == 'str' + if range\type! == T.str switch range! when 'raw' then val when 'uni' then val / 128 @@ -108,7 +108,7 @@ apply_range = (range, val) -> when 'deg' then val / 128 * 360 else error Error 'argument', "unknown range '#{range!}'" - elseif range.type == 'num' + elseif range.type == T.num val / 128 * range! else error Error 'argument', "range has to be a string or number" diff --git a/alv-lib/midi/launchctl.moon b/alv-lib/midi/launchctl.moon index 90e8956..3f47a5d 100644 --- a/alv-lib/midi/launchctl.moon +++ b/alv-lib/midi/launchctl.moon @@ -1,10 +1,10 @@ -import ValueStream, EventStream, Op, Input, val, evt from require 'alv.base' +import Constant, Op, Input, T, val, evt from require 'alv.base' import apply_range, bit from require 'alv-lib.midi.core' import bor, lshift from bit color = (r, g) -> bit.bor 12, r, (bit.lshift g, 4) -cc_seq = ValueStream.meta +cc_seq = Constant.meta meta: name: 'cc-seq' summary: "MIDI CC-Sequencer." @@ -32,11 +32,11 @@ range can be one of: i: Input.hot i start: Input.hot start chan: Input.hot chan - steps: Input.hot steps or ValueStream.num 8 - range: Input.hot range or ValueStream.str 'uni' + steps: Input.hot steps or Constant.num 8 + range: Input.hot range or Constant.str 'uni' @state or= {} - @out or= ValueStream 'num', apply_range @inputs.range, 0 + @out or= T.num\mk_sig apply_range @inputs.range, 0 tick: => { :port, :i, :start, :chan, :steps, :range } = @inputs @@ -60,7 +60,7 @@ range can be one of: else @out\set apply_range range, @state[curr_i+1] -gate_seq = ValueStream.meta +gate_seq = Constant.meta meta: name: 'gate-seq' summary: "MIDI Gate-Sequencer." @@ -72,7 +72,7 @@ Send `true` or `false` for the `i`-th note-button (MIDI-notes starting from value: class extends Op pattern = -evt['midi/port'] + val.num + val.num + val.num + -val.num setup: (inputs, scope) => - @out or= ValueStream 'bool' + @out or= T.bool\mk_sig! @state or= {} { port, i, start, chan, steps } = pattern\match inputs @@ -81,7 +81,7 @@ Send `true` or `false` for the `i`-th note-button (MIDI-notes starting from i: Input.hot i start: Input.hot start chan: Input.hot chan - steps: Input.hot steps or ValueStream.num 8 + steps: Input.hot steps or Constant.num 8 light = (set, active) -> set = if set then 'S' else ' ' @@ -123,7 +123,7 @@ Send `true` or `false` for the `i`-th note-button (MIDI-notes starting from @out\set @state[curr_i+1] -trig_seq = ValueStream.meta +trig_seq = Constant.meta meta: name: 'trig-seq' summary: "MIDI Trigger-Sequencer." @@ -135,7 +135,7 @@ Send bangs for the `i`-th note-button (MIDI-notes starting from `start`). value: class extends Op pattern = -evt['midi/port'] + val.num + val.num + val.num + -val.num setup: (inputs, scope) => - @out or= EventStream 'bang' + @out or= T.bang\mk_evt! @state or= {} { port, i, start, chan, steps } = pattern\match inputs @@ -144,7 +144,7 @@ Send bangs for the `i`-th note-button (MIDI-notes starting from `start`). i: Input.hot i start: Input.hot start chan: Input.hot chan - steps: Input.hot steps or ValueStream.num 8 + steps: Input.hot steps or Constant.num 8 light = (set, active) -> set = if set then 'S' else ' ' diff --git a/alv-lib/osc.moon b/alv-lib/osc.moon index b7e25e7..bbf07a1 100644 --- a/alv-lib/osc.moon +++ b/alv-lib/osc.moon @@ -1,10 +1,10 @@ -import Op, ValueStream, Input, val, evt from require 'alv.base' +import Op, Constant, SigStream, Input, T, val, evt from require 'alv.base' import pack from require 'osc' import dns, udp from require 'socket' unpack or= table.unpack -connect = ValueStream.meta +connect = Constant.meta meta: name: 'connect' summary: "Create a UDP remote." @@ -13,7 +13,7 @@ connect = ValueStream.meta value: class extends Op pattern = val.str + val.num setup: (inputs) => - @out or= ValueStream 'udp/socket' + @out or= SigStream T['udp/socket'] { host, port } = pattern\match inputs super host: Input.hot host @@ -26,7 +26,7 @@ connect = ValueStream.meta @out\set with sock = udp! \setpeername ip, port -send = ValueStream.meta +send = Constant.meta meta: name: 'send' summary: "Send events via OSC." @@ -52,7 +52,7 @@ send = ValueStream.meta msg = pack path, if 'table' == type val then unpack val else val socket\send msg -sync = ValueStream.meta +sync = Constant.meta meta: name: 'sync' summary: "Synchronize a value via OSC." diff --git a/alv-lib/pilot.moon b/alv-lib/pilot.moon index 0d6eefb..e2103c6 100644 --- a/alv-lib/pilot.moon +++ b/alv-lib/pilot.moon @@ -1,4 +1,4 @@ -import Op, ValueStream, Input, val, evt from require 'alv.base' +import Op, Constant, Input, val, evt from require 'alv.base' import udp from require 'socket' local conn @@ -22,7 +22,7 @@ send = (...) -> arg = val.num / val.str -play = ValueStream.meta +play = Constant.meta meta: name: 'play' summary: "Play a note when a bang arrives." @@ -41,7 +41,7 @@ play = ValueStream.meta for _ in *trig! send [a! for a in *@inputs.args] -play_ = ValueStream.meta +play_ = Constant.meta meta: name: 'play!' summary: "Play a note when a note arrives." @@ -63,7 +63,7 @@ play_ = ValueStream.meta for note in *note! send { chan!, octv!, note }, args -effect = ValueStream.meta +effect = Constant.meta meta: name: 'effect' summary: "Set effect parameters." diff --git a/alv-lib/random.moon b/alv-lib/random.moon index 8c4d096..a2e4c60 100644 --- a/alv-lib/random.moon +++ b/alv-lib/random.moon @@ -1,7 +1,7 @@ -import ValueStream, Error, Op, Input, val, evt from require 'alv.base' +import Constant, Error, Op, Input, T, Array, val, evt from require 'alv.base' apply_range = (range, val) -> - if range\type! == 'str' + if range\type! == T.str switch range! when 'uni' then val when 'bip' then val*2 - 1 @@ -9,7 +9,7 @@ apply_range = (range, val) -> when 'deg' then val * 360 else error Error 'argument', "unknown range '#{range!}'" - elseif range\type! == 'num' + elseif range\type! == T.num val * range! else error Error 'argument', "range has to be a string or number" @@ -24,7 +24,7 @@ range can be one of: pattern = -evt.bang + -(val.num / val.str) -num = ValueStream.meta +num = Constant.meta meta: name: 'num' summary: 'Generate a random number.' @@ -35,7 +35,7 @@ num = ValueStream.meta value: class extends Op new: (...) => super ... - @out or= ValueStream 'num' + @out or= T.num\mk_sig! @state or @gen! gen: => @state = math.random! @@ -44,25 +44,26 @@ num = ValueStream.meta { trig, range } = pattern\match inputs super trig: trig and Input.hot trig - range: Input.hot range or ValueStream.str 'uni' + range: Input.hot range or Constant.str 'uni' tick: => @gen! if @inputs.trig and @inputs.trig\dirty! @out\set apply_range @inputs.range, @state vec = (n) -> - ValueStream.meta + typ = Array n, T.num + Constant.meta meta: name: "vec#{n}" summary: 'Generate a random vector.' examples: { '(random/vec#{n} [trigger] [range]))' } - description: "Generate a random vec#{n} in `range` when created and on `trig`. + description: "Generate a random #{typ} in `range` when created and on `trig`. #{range_doc}" value: class extends Op new: (...) => super ... - @out or= ValueStream "vec#{n}" + @out or= typ\mk_sig! @state or @gen! gen: => @state = for i=1,n do math.random! @@ -71,9 +72,9 @@ vec = (n) -> { trig, range } = pattern\match inputs super trig: trig and Input.hot trig - range: Input.hot range or ValueStream.str 'uni' + range: Input.hot range or Constant.str 'uni' - tick: => + tick: (setup) => @gen! if @inputs.trig and @inputs.trig\dirty! @out\set [apply_range @inputs.range, v for v in *@state] diff --git a/alv-lib/sc.moon b/alv-lib/sc.moon index 2857392..7e4c711 100644 --- a/alv-lib/sc.moon +++ b/alv-lib/sc.moon @@ -1,10 +1,10 @@ -import Op, ValueStream, Input, val, evt from require 'alv.base' +import Op, Constant, Input, val, evt from require 'alv.base' import pack from require 'osc' import dns, udp from require 'socket' unpack or= table.unpack -play = ValueStream.meta +play = Constant.meta meta: name: 'play' summary: 'Play a SuperCollider SynthDef on bangs.' @@ -39,7 +39,7 @@ Plays the synth `synth` on the `udp/socket` `socket` whenever `trig` is live. msg = pack '/s_new', synth, -1, 0, 1, unpack ctrls socket\send msg -play_ = ValueStream.meta +play_ = Constant.meta meta: name: 'play!' summary: 'Play a SuperCollider SynthDef on events.' diff --git a/alv-lib/string.moon b/alv-lib/string.moon index 5f54b07..9f09f10 100644 --- a/alv-lib/string.moon +++ b/alv-lib/string.moon @@ -1,13 +1,13 @@ -import Op, ValueStream, Input from require 'alv.base' +import Op, Constant, SigStream, Input, T from require 'alv.base' -str = ValueStream.meta +str = Constant.meta meta: name: 'str' summary: "Concatenate/stringify values." examples: { '(.. v1 [v2…])', '(str v1 [v2…])' } value: class extends Op setup: (inputs) => - @out or= ValueStream 'str' + @out or= SigStream T.str super [Input.hot v for v in *inputs] tick: => diff --git a/alv-lib/time.moon b/alv-lib/time.moon index ba7aa4a..86d7e4c 100644 --- a/alv-lib/time.moon +++ b/alv-lib/time.moon @@ -1,12 +1,10 @@ -import - ValueStream, EventStream, IOStream, - Error, Op, Input, val, evt -from require 'alv.base' +import Constant, EvtStream, IOStream, Error, Op, Input, T, val, evt + from require 'alv.base' import monotime from require 'system' class Clock extends IOStream new: (@frametime) => - super 'clock' + super T.clock return unless monotime @last = monotime! @@ -19,11 +17,11 @@ class Clock extends IOStream @add { dt: @dt, :time } @last = time -class ScaledClock extends EventStream +class ScaledClock extends EvtStream set: (val) => @value unwrap: => @value -clock = ValueStream.meta +clock = Constant.meta meta: name: 'clock' summary: "Create a clock source." @@ -41,13 +39,13 @@ frame rate. setup: (inputs) => fps = (-val.num)\match inputs - super fps: Input.hot fps or ValueStream.num 60 + super fps: Input.hot fps or Constant.num 60 @out.frametime = 1 / @inputs.fps! tick: => @out.frametime = 1 / @inputs.fps! -scale_time = ValueStream.meta +scale_time = Constant.meta meta: name: 'scale-time' summary: "Scale clock time." @@ -60,7 +58,7 @@ scale_time = ValueStream.meta value: class extends Op new: (...) => super ... - @out or= EventStream 'clock' + @out or= EvtStream T.clock pattern = -evt.clock + val.num + -val.str setup: (inputs, scope) => @@ -74,7 +72,7 @@ scale_time = ValueStream.meta for evt in *@inputs.clock! @out\add {k, v*scale for k,v in pairs evt} -lfo = ValueStream.meta +lfo = Constant.meta meta: name: 'lfo' summary: "Low-frequency oscillator." @@ -92,9 +90,9 @@ lfo = ValueStream.meta new: (...) => super ... @state or= 0 - @out or= ValueStream 'num' + @out or= T.num\mk_sig! - default_wave = ValueStream.str 'sin' + default_wave = Constant.str 'sin' pattern = -evt.clock + val.num + -val.str setup: (inputs, scope) => { clock, freq, wave } = pattern\match inputs @@ -114,7 +112,7 @@ lfo = ValueStream.meta when 'tri' then math.abs (2*@state % 2) - 1 else error Error 'argument', "unknown wave type '#{wave}'" -ramp = ValueStream.meta +ramp = Constant.meta meta: name: 'ramp' summary: "Sawtooth LFO." @@ -129,7 +127,7 @@ ramp = ValueStream.meta new: (...) => super ... @state or= 0 - @out or= ValueStream 'num' + @out or= T.num\mk_sig! pattern = -evt.clock + val.num + -val.num setup: (inputs, scope) => @@ -150,7 +148,7 @@ ramp = ValueStream.meta @out\set @phase * max -tick = ValueStream.meta +tick = Constant.meta meta: name: 'tick' summary: "Count ticks." @@ -165,7 +163,7 @@ tick = ValueStream.meta new: (...) => super ... @state or= { phase: 0, count: 0 } - @out or= ValueStream 'num', @state.count + @out or= T.num\mk_sig! @state.count pattern = -evt.clock + val.num setup: (inputs, scope) => @@ -183,7 +181,7 @@ tick = ValueStream.meta @state.count += 1 @out\set @state.count -every = ValueStream.meta +every = Constant.meta meta: name: 'every' summary: "Emit events regularly." @@ -206,8 +204,8 @@ every = ValueStream.meta super clock: Input.hot clock or scope\get '*clock*' period: Input.cold period - evt: Input.cold evt or ValueStream 'bang', true - @out = EventStream @inputs.evt\type! + evt: Input.cold evt or Constant.bang, true + @out = @inputs.evt\type!\mk_evt! tick: => for tick in *@inputs.clock! @@ -217,7 +215,7 @@ every = ValueStream.meta @state -= 1 @out\add @inputs.evt! -sequence = ValueStream.meta +sequence = Constant.meta meta: name: 'sequence' summary: "Emit a sequence of values as events over time." @@ -246,7 +244,7 @@ Emits `evt1`, `evt2`, … as events with delays `delay0`, `delay1`, … in betwe setup: (inputs, scope) => { clock, first, steps } = pattern\match inputs - @out = EventStream steps[1].value\type! + @out = EvtStream steps[1].value\type! table.insert steps, 1, { delay: first } super clock: Input.hot clock or scope\get '*clock*' diff --git a/alv-lib/util.moon b/alv-lib/util.moon index abb49c0..512d74d 100644 --- a/alv-lib/util.moon +++ b/alv-lib/util.moon @@ -1,4 +1,4 @@ -import Op, ValueStream, EventStream, Input, val, evt from require 'alv.base' +import Constant, Op, Input, T, val, evt from require 'alv.base' all_same = (list) -> for v in *list[2,] @@ -7,7 +7,7 @@ all_same = (list) -> list[1] -switch_ = ValueStream.meta +switch_ = Constant.meta meta: name: 'switch' summary: "Switch between multiple inputs." @@ -24,12 +24,12 @@ switch_ = ValueStream.meta setup: (inputs) => { i, values } = pattern\match inputs - @state = values[1].value.__class == ValueStream + @state = values[1].value.metatype == '~' @out = if @state - ValueStream values[1]\type! + values[1]\type!\mk_sig! else - EventStream values[1]\type! + values[1]\type!\mk_evt! super i: Input.hot i @@ -52,7 +52,7 @@ switch_ = ValueStream.meta for event in *active! @out\add event -edge = ValueStream.meta +edge = Constant.meta meta: name: 'edge' summary: "Convert rising edges to bangs." @@ -60,7 +60,7 @@ edge = ValueStream.meta value: class extends Op setup: (inputs) => - @out or= EventStream 'bang' + @out or= T.bang\mk_evt! value = val.bool\match inputs super value: Input.hot value @@ -70,7 +70,7 @@ edge = ValueStream.meta @out\add true @state = now -change = ValueStream.meta +change = Constant.meta meta: name: 'change' summary: "Convert value changes to events." @@ -79,7 +79,7 @@ change = ValueStream.meta value: class extends Op setup: (inputs) => value = val!\match inputs - @out or= EventStream value\type! + @out or= value\type!\mk_evt! super value: Input.hot value tick: => @@ -88,7 +88,7 @@ change = ValueStream.meta @out\add @inputs.value! @state = now -hold = ValueStream.meta +hold = Constant.meta meta: name: 'hold' summary: "Convert events to value changes." @@ -97,7 +97,7 @@ hold = ValueStream.meta value: class extends Op setup: (inputs) => event = evt!\match inputs - @out or= ValueStream event\type! + @out or= event\type!\mk_sig! super event: Input.hot event tick: => diff --git a/alv/base/init.moon b/alv/base/init.moon index 62de2ab..90f1dfc 100644 --- a/alv/base/init.moon +++ b/alv/base/init.moon @@ -15,6 +15,10 @@ -- @see SigStream -- @see EvtStream -- @see IOStream +-- @see type.T +-- @see type.Primitive +-- @see type.Array +-- @see type.Struct -- @see RTNode -- @see Error @@ -24,7 +28,7 @@ import FnDef from require 'alv.base.fndef' import Input from require 'alv.base.input' import val, evt from require 'alv.base.match' import Constant, SigStream, EvtStream, IOStream from require 'alv.result' -import Primitive, Array, Struct from require 'alv.type' +import T, Primitive, Array, Struct from require 'alv.type' import RTNode from require 'alv.rtnode' import Error from require 'alv.error' @@ -41,7 +45,7 @@ import Error from require 'alv.error' :Constant, :SigStream, :EvtStream, :IOStream -- Types - :Primitive, :Array, :Struct + :T, :Primitive, :Array, :Struct :RTNode :Error diff --git a/alv/base/input.moon b/alv/base/input.moon index a9f0e32..b73a476 100644 --- a/alv/base/input.moon +++ b/alv/base/input.moon @@ -35,9 +35,9 @@ class Input --- create a new Input. -- -- @classmethod - -- @tparam Result stream - new: (@stream) => - assert @stream, "nil passed to Input: #{value}" + -- @tparam Result result + new: (@result) => + assert @result, "nil passed to Input: #{value}" --- copy state from old instance (optional). -- @@ -53,10 +53,10 @@ class Input -- -- must return a boolean indicating whether `Op`s that refer to this instance -- should be notified (via `Op:tick`). If not overwritten, delegates to - -- `stream`:@{SigStream:dirty|dirty}. + -- `result`:@{SigStream:dirty|dirty}. -- -- @treturn bool whether processing is necessary - dirty: => @stream\dirty! + dirty: => @result\dirty! --- leave setup state (optional). -- @@ -67,25 +67,25 @@ class Input --- unwrap to Lua value (optional). -- -- @treturn any the raw Lua value - unwrap: => @stream\unwrap! + unwrap: => @result\unwrap! --- return the type name of this `Input` (optional). - type: => @stream.type + type: => @result.type --- return the metatype name of this `Input` (optional). - metatype: => @stream.metatype + metatype: => @result.metatype --- the current value -- - -- @tfield SigStream stream + -- @tfield SigStream result --- members -- @section members --- alias for `unwrap`. - __call: => @stream\unwrap! + __call: => @result\unwrap! - __tostring: => "#{@@__name}:#{@stream}" + __tostring: => "#{@@__name}:#{@result}" __inherited: (cls) => cls.__base.__call = @__call cls.__base.__tostring = @__tostring @@ -95,7 +95,7 @@ class Input --- Create a `cold` `Input`. -- - -- Never marked dirty. Use this for input streams that are only read when + -- Never marked dirty. Use this for input results that are only read when -- another `Input` is dirty. -- -- @tparam Result|RTNode value @@ -128,17 +128,17 @@ class ColdInput extends Input dirty: => false class ValueInput extends Input - setup: (old) => @dirty_setup = not old or @stream != old.stream + setup: (old) => @dirty_setup = not old or @result != old.result finish_setup: => @dirty_setup = nil dirty: => return @dirty_setup if @dirty_setup != nil - @stream\dirty! + @result\dirty! class IOInput extends Input io: true mapping = { - [Constant]: ColdInput + [Constant]: ValueInput [SigStream]: ValueInput [EvtStream]: Input [IOStream]: IOInput diff --git a/alv/builtin.moon b/alv/builtin.moon index 29602e2..45ee626 100644 --- a/alv/builtin.moon +++ b/alv/builtin.moon @@ -5,7 +5,7 @@ -- documentation. -- -- @module builtin -import Builtin, Op, Primitive, FnDef, Input, val, evt from require 'alv.base' +import Builtin, Op, T, FnDef, Input, val, evt from require 'alv.base' import Constant from require 'alv.result' import Error from require 'alv.error' import RTNode from require 'alv.rtnode' @@ -58,7 +58,7 @@ Define the symbols `sym1`, `sym2`, … to resolve to the values of `val-expr1`, children = L\push -> return for i=1,#tail,2 name, val_expr = tail[i], tail[i+1] - name = name\unwrap 'sym' + name = name\unwrap T.sym with val_expr\eval scope scope\set name, \make_ref! @@ -117,7 +117,7 @@ current scope." assert #tail > 0, "'import' requires at least one arguments" children = for i, child in ipairs tail - name = child\unwrap 'sym' + name = child\unwrap T.sym with COPILOT\require name scope\set name, \make_ref! RTNode :children @@ -136,8 +136,8 @@ Requires modules `sym1`, `sym2`, … and merges them into the current scope." assert #tail > 0, "'import' requires at least one arguments" children = for i, child in ipairs tail - with COPILOT\require child\unwrap 'sym' - scope\use .value\unwrap 'scope' + with COPILOT\require child\unwrap T.sym + scope\use .result\unwrap T.scope RTNode :children export_ = Constant.meta @@ -175,7 +175,7 @@ Copies the containing scope if no symbols are given." node else for child in *tail - name = child\unwrap 'sym' + name = child\unwrap T.sym with node = scope\get name new_scope\set name, node @@ -198,7 +198,7 @@ function is invoked." assert params.__class == Cell, "'fn's first argument has to be an expression" param_symbols = for param in *params.children - assert param.type == 'sym', "function parameter declaration has to be a symbol" + assert param.type == T.sym, "function parameter declaration has to be a symbol" param RTNode result: with Constant.wrap FnDef param_symbols, body, scope @@ -223,10 +223,10 @@ function is invoked." assert #tail == 3, "'defn' takes exactly three arguments" { name, params, body } = tail - name = name\unwrap 'sym' + name = name\unwrap T.sym assert params.__class == Cell, "'defn's second argument has to be an expression" param_symbols = for param in *params.children - assert param.type == 'sym', "function parameter declaration has to be a symbol" + assert param.type == T.sym, "function parameter declaration has to be a symbol" param result = with Constant.wrap FnDef param_symbols, body, scope @@ -305,7 +305,7 @@ trace = Constant.meta value: Input.hot inputs[2] tick: => - L\print "trace #{@inputs.prefix!}: #{@inputs.value.stream}" + L\print "trace #{@inputs.prefix!}: #{@inputs.value\type!\pp @inputs.value!}" eval: (scope, tail) => L\trace "evaling #{@}" @@ -313,7 +313,7 @@ trace = Constant.meta tag = @tag\clone Tag.parse '-1' inner = Cell tag, { - Constant.literal Primitive.op, traceOp, 'trace' + Constant.literal T.opdef, traceOp, 'trace' Constant.str tostring tail[1] tail[1] } @@ -364,7 +364,7 @@ Scope.from_table { meta: name: 'bang' summary: "A `bang` value-constant." - value: Constant 'bang', true + value: Constant T.bang, true :fn, :defn 'do': do_expr diff --git a/alv/cell.moon b/alv/cell.moon index 759e7aa..36d5f43 100644 --- a/alv/cell.moon +++ b/alv/cell.moon @@ -5,7 +5,7 @@ -- nodes), a `Tag`, and optionally the internal whitespace as parsed. -- -- @classmod Cell -import Primitive from require 'alv.type' +import T from require 'alv.type' import Constant from require 'alv.result' import Error from require 'alv.error' import op_invoke, fn_invoke from require 'alv.invoke' @@ -74,11 +74,11 @@ class Cell head = assert @head!, Error 'syntax', "cannot evaluate empty expr" head = (head\eval scope)\const! Builtin = switch head.type - when Primitive.op + when T.opdef op_invoke - when Primitive.fn + when T.fndef fn_invoke - when Primitive.builtin + when T.builtin head\unwrap! else error Error 'type', "#{head} is not an opdef, fndef or builtin" diff --git a/alv/copilot.moon b/alv/copilot.moon index 55e00c8..e6eb293 100644 --- a/alv/copilot.moon +++ b/alv/copilot.moon @@ -53,7 +53,7 @@ class Copilot mod.root\make_ref! else last = @active_module - prefix = @active_module.file\match('(.*)/[^/]*$') .. '/' or '' + prefix = if b = last.file\match'(.*)/[^/]*$' then b .. '/' else '' mod = @last_modules[name] or Module "#{prefix}#{name}.alv" L\trace "entering module #{mod}" @modules[name] = mod diff --git a/alv/error.moon b/alv/error.moon index e72cc5f..c049f8f 100644 --- a/alv/error.moon +++ b/alv/error.moon @@ -48,7 +48,9 @@ class Error if err.__class == Error err else - Error 'implementation', err, debug.traceback "Lua error below:", 2 + trace = debug.traceback "Lua error below:", 2 + Error 'implementation', err, trace + --- Wrap function errors in a traceback frame. -- -- Execute `fn(...)`, and turn any error thrown as a result into an @@ -65,8 +67,8 @@ class Error if ok unpack results else - error with results[1] - \add_frame frame + results[1]\add_frame frame if frame + error results[1] --- Capture and wrap function errors in traceback frame. -- @@ -76,7 +78,7 @@ class Error -- When `Error` instances are caught, `frame` is added to the traceback. -- All other error values are turned into `'implementation'` Errors. -- - -- @tparam string frame + -- @tparam ?string frame -- @tparam function fn -- @treturn boolean `ok` true if exeuction suceeded without errors -- @treturn Error|any `error_or_results` the `Error` instance or results @@ -86,9 +88,8 @@ class Error if ok ok, unpack results else - ok, with results[1] - \add_frame frame - + results[1]\add_frame frame if frame + ok, unpack results { :Error } diff --git a/alv/init.moon b/alv/init.moon index ec90a10..fc85f8b 100644 --- a/alv/init.moon +++ b/alv/init.moon @@ -14,7 +14,7 @@ cycle = require 'alv.cycle' version = require 'alv.version' import Logger from require 'alv.logger' -import Primitive, Struct, Array from require 'alv.type' +import T, Primitive, Struct, Array from require 'alv.type' import Constant, SigStream, EvtStream, IOStream from require 'alv.result' import RTNode from require 'alv.rtnode' import Scope from require 'alv.scope' @@ -40,6 +40,10 @@ import Copilot from require 'alv.copilot' -- @tfield SigStream SigStream -- @tfield EvtStream EvtStream -- @tfield IOStream IOStream +-- @tfield type.T T +-- @tfield type.Primitive Primitive +-- @tfield type.Array Array +-- @tfield type.Struct Struct -- @tfield RTNode RTNode -- @tfield Cell Cell -- @tfield RootCell RootCell @@ -58,7 +62,7 @@ import Copilot from require 'alv.copilot' :Cell, :RootCell :RTNode, :Scope, :Error - :Primitive, :Struct, :Array + :T, :Primitive, :Struct, :Array :Registry, :SimpleRegistry, :Tag diff --git a/alv/invoke.moon b/alv/invoke.moon index 390e19f..9acb77c 100644 --- a/alv/invoke.moon +++ b/alv/invoke.moon @@ -5,7 +5,7 @@ import RTNode from require 'alv.rtnode' import Builtin from require 'alv.base' import Scope from require 'alv.scope' -import Primitive from require 'alv.type' +import T from require 'alv.type' import Error from require 'alv.error' get_name = (value, raw) -> @@ -35,14 +35,14 @@ class op_invoke extends Builtin @op = prev.op\fork! prev.forked = COPILOT.T else - def = @head\unwrap Primitive.opdef, "cant op-invoke #{@head}" + def = @head\unwrap T.opdef, "cant op-invoke #{@head}" @op = def! --- `Builtin:destroy` implementation. -- -- calls `op`:@{Op:destroy|destroy}. destroy: => - if @forked ~= COPILOT.T + if @op and @forked ~= COPILOT.T @op\destroy! --- perform an `Op` invocation. @@ -60,19 +60,20 @@ class op_invoke extends Builtin children = [L\push expr\eval, scope for expr in *tail] frame = "invoking op #{get_name @head, @cell\head!} at [#{@tag}]" - Error.wrap frame, @op\setup, [node for node in *children], scope + Error.wrap frame, -> + @op\setup [node for node in *children], scope - any_dirty = false - for input in @op\all_inputs! - if input\dirty! - any_dirty = true - break + any_dirty = false + for input in @op\all_inputs! + if input\dirty! + any_dirty = true + break - if any_dirty - @op\tick true + if any_dirty + @op\tick true - for input in @op\all_inputs! - input\finish_setup! + for input in @op\all_inputs! + input\finish_setup! RTNode :children, result: @op.out, op: @op @@ -104,7 +105,7 @@ class fn_invoke extends Builtin name = get_name @head, @cell\head! frame = "invoking function #{name} at [#{@tag}]" - fndef = @head\unwrap Primitive.fndef, "cant fn-invoke #{@head}" + fndef = @head\unwrap T.fndef, "cant fn-invoke #{@head}" { :params, :body } = fndef if #params != #tail err = Error 'argument', "expected #{#params} arguments, found #{#tail}" @@ -114,7 +115,7 @@ class fn_invoke extends Builtin fn_scope = Scope fndef.scope, caller_scope children = for i=1,#params - name = params[i]\unwrap Primitive.sym + name = params[i]\unwrap T.sym with L\push tail[i]\eval, caller_scope fn_scope\set name, \make_ref! diff --git a/alv/module.moon b/alv/module.moon index 7179ab6..0e95593 100644 --- a/alv/module.moon +++ b/alv/module.moon @@ -34,7 +34,7 @@ class Module -- @treturn bool whether the file was changed since the last call poll: => { :mode, :modification } = (lfs.attributes @file) or {} - assert mode == 'file', Error 'io', "not a file: '#{file}'" + assert mode == 'file', Error 'io', "not a file: '#{@file}'" modification --- start an evaluation cycle. diff --git a/alv/result/base.moon b/alv/result/base.moon index 6accb1e..7775349 100644 --- a/alv/result/base.moon +++ b/alv/result/base.moon @@ -24,7 +24,11 @@ class Result -- @function fork -- @treturn Result - __tostring: => "<#{@type}#{@metatype} #{@type\pp @value}>" + __tostring: => + if @value then + "<#{@type}#{@metatype} #{@type\pp @value}>" + else + "<#{@type}#{@metatype}>" __inherited: (cls) => cls.__base.__tostring or= @__tostring --- the type of this Result's value. @@ -56,12 +60,14 @@ class Result --- static functions -- @section static + _type = type --- construct a new Result. -- -- @classmethod -- @tparam type.Type type the type -- @tparam ?table meta the `meta` table new: (@type, @meta={}) => + assert @type and (_type @type) == 'table', "not a type: #{@type}" { :Result diff --git a/alv/result/const.moon b/alv/result/const.moon index b88de2c..077a2d8 100644 --- a/alv/result/const.moon +++ b/alv/result/const.moon @@ -5,16 +5,11 @@ -- -- @classmod Constant import Result from require 'alv.result.base' -import Primitive from require 'alv.type' +import T from require 'alv.type' import RTNode from require 'alv.rtnode' import Error from require 'alv.error' import scope, base from require 'alv.cycle' -num = Primitive 'num' -str = Primitive 'str' -sym = Primitive 'sym' -bool = Primitive 'bool' - ancestor = (klass) -> assert klass, "cant find the ancestor of nil" while klass.__parent @@ -78,9 +73,9 @@ class Constant extends Result return RTNode result: @ if @literal switch @type - when num, str + when T.num, T.str RTNode result: @ - when sym + when T.sym Error.wrap "resolving symbol '#{@value}'", scope\get, @value else error "cannot evaluate #{@}" @@ -106,7 +101,9 @@ class Constant extends Result -- @tparam string type the type name -- @tparam any value the Lua value to be accessed through `unwrap` -- @tparam string raw the raw string that resulted in this value. Used by `parsing`. - new: (type, @value, @raw) => super type + new: (type, @value, @raw) => + super type + assert @value ~= nil, "Constant without value" unescape = (str) -> str\gsub '\\([\'"\\])', '%1' --- create a capture-function (for parsing with Lpeg). @@ -115,9 +112,9 @@ class Constant extends Result -- @tparam string sep the seperator char (only for `str`) @parse: (type, sep) => switch type - when 'num' then (match) -> @ num, (tonumber match), match - when 'sym' then (match) -> @ sym, match, match - when 'str' then (match) -> @ str, (unescape match), sep .. match .. sep + when 'num' then (match) -> @ T.num, (tonumber match), match + when 'sym' then (match) -> @ T.sym, match, match + when 'str' then (match) -> @ T.str, (unescape match), sep .. match .. sep --- wrap a Lua value. -- @@ -128,28 +125,28 @@ class Constant extends Result -- @treturn Constant @wrap: (val, name='(unknown)') -> typ = switch type val - when 'number' then Primitive.num - when 'string' then Primitive.str + when 'number' then T.num + when 'string' then T.str when 'table' if rawget val, '__base' -- a class switch ancestor val - when base.Op then Primitive.op - when base.Builtin then Primitive.builtin + when base.Op then T.opdef + when base.Builtin then T.builtin else error "#{name}: cannot wrap class '#{val.__name}'" elseif val.__class -- an instance switch ancestor val.__class - when scope.Scope then Primitive.scope - when base.FnDef then Primitive.fn + when scope.Scope then T.scope + when base.FnDef then T.fndef when Result then return val else error "#{name}: cannot wrap '#{val.__class.__name}' instance" else -- plain table val = scope.Scope.from_table val - Primitive.scope + T.scope else error "#{name}: cannot wrap Lua type '#{type val}'" @@ -158,22 +155,22 @@ class Constant extends Result --- create a constant number. -- @tparam number num the number -- @treturn Constant - @num: (num) -> Constant Primitive.num, num, tostring num + @num: (num) -> Constant T.num, num, tostring num --- create a constant string. -- @tparam string str the string -- @treturn Constant - @str: (str) -> Constant Primitive.str, str, "'#{str}'" + @str: (str) -> Constant T.str, str, "'#{str}'" --- create a constant symbol. -- @tparam string sym the symbol -- @treturn Constant - @sym: (sym) -> Constant Primitive.sym, sym, sym + @sym: (sym) -> Constant T.sym, sym, sym --- create a constant boolean. -- @tparam boolean bool the boolean -- @treturn Constant - @bool: (bool) -> Constant Primitive.bool, bool, tostring bool + @bool: (bool) -> Constant T.bool, bool, tostring bool --- create a forced-literal Constant. -- diff --git a/alv/result/evt.moon b/alv/result/evt.moon index bab502c..7e6a249 100644 --- a/alv/result/evt.moon +++ b/alv/result/evt.moon @@ -35,7 +35,10 @@ class EvtStream extends Result --- alias for `unwrap`. __call: (...) => @unwrap ... - __tostring: => "<#{@type}#{@metatype} #{@type\pp @value}>" + + __tostring: => + events = table.concat [@type\pp e for e in *@events], ' ' + "<#{@type}#{@metatype} #{events}>" --- the type of this Result's value. -- @tfield type.Type type @@ -79,7 +82,9 @@ class EvtStream extends Result -- -- @classmethod -- @tparam type.Type type the type - new: (type) => super type + new: (type) => + super type + @events = {} { :EvtStream diff --git a/alv/result/sig.moon b/alv/result/sig.moon index 73f06d1..b23afbe 100644 --- a/alv/result/sig.moon +++ b/alv/result/sig.moon @@ -3,7 +3,6 @@ -- -- @classmod SigStream import Result from require 'alv.result.base' -import Primitive from require 'alv.type' class SigStream extends Result --- Result interface @@ -79,33 +78,13 @@ class SigStream extends Result --- static functions -- @section static - --- construct a new SigStream. + --- construct a new Constant. -- -- @classmethod - -- @tparam type.Type type the type - -- @tparam any value the Lua value to be accessed through `unwrap` + -- @tparam string type the type name + -- @tparam ?any value the Lua value to be accessed through `unwrap` new: (type, @value) => super type - --- create a number stream. - -- @tparam number val the number - -- @treturn SigStream - @num: (val) -> SigStream Primitive'num', val - - --- create a string stream. - -- @tparam string val the string - -- @treturn SigStream - @str: (val) -> SigStream Primitive'str', val - - --- create a symbol stream. - -- @tparam string val the symbol - -- @treturn symbol - @sym: (val) -> SigStream Primitive'sym', val - - --- create a boolean stream. - -- @tparam boolean val the boolean - -- @treturn SigStream - @bool: (val) -> SigStream Primitive'bool', val - { :SigStream } diff --git a/alv/rtnode.moon b/alv/rtnode.moon index a8ebec3..61222ef 100644 --- a/alv/rtnode.moon +++ b/alv/rtnode.moon @@ -5,6 +5,9 @@ -- between `Op`s. -- -- @classmod RTNode + +import Error from require 'alv.error' + class RTNode --- members -- @section members @@ -41,15 +44,15 @@ class RTNode --- poll all IOStream instances that are effecting this (sub)tree. -- should be called once per frame on the root, right before tick. poll_io: => - for stream, input in pairs @side_inputs - stream\poll! if input.io + for result, input in pairs @side_inputs + result\poll! if input.io --- in depth-first order, tick all Ops which have dirty Inputs. -- -- short-circuits if there are no dirty Inputs in the entire subtree tick: => any_dirty = false - for stream, input in pairs @side_inputs + for result, input in pairs @side_inputs if input\dirty! any_dirty = true break @@ -70,7 +73,7 @@ class RTNode return unless self_dirty - @op\tick! + Error.wrap "ticking #{op}", @op\tick __tostring: => buf = "<RT=#{@result}" @@ -111,15 +114,15 @@ class RTNode @side_inputs, is_child = {}, {} for child in *@children - for stream, input in pairs child.side_inputs - @side_inputs[stream] = input + for result, input in pairs child.side_inputs + @side_inputs[result] = input if child.result is_child[child.result] = true if @op for input in @op\all_inputs! - if input.io or not is_child[input.stream] - @side_inputs[input.stream] = input + if input.io or not is_child[input.result] + @side_inputs[input.result] = input if @result and @result.metatype == '=' assert not (next @side_inputs), "Const result has side_inputs" diff --git a/alv/scope.moon b/alv/scope.moon index b150280..4adf07d 100644 --- a/alv/scope.moon +++ b/alv/scope.moon @@ -5,7 +5,7 @@ import Constant from require 'alv.result' import RTNode from require 'alv.rtnode' import Error from require 'alv.error' -import Primitive from require 'alv.type' +import T from require 'alv.type' class Scope --- members @@ -57,7 +57,7 @@ class Scope child = @get start if not child error Error 'reference', "undefined symbol '#{start}'" - if child\type! != Primitive.scope + if child\type! != T.scope error Error 'reference', "'#{start}' is not a scope" child.result!\get rest, while_msg diff --git a/alv/type.moon b/alv/type.moon index 8a3708b..5c76b86 100644 --- a/alv/type.moon +++ b/alv/type.moon @@ -3,6 +3,7 @@ -- -- @module type import opairs from require 'alv.util' +import result from require 'alv.cycle' shared_shape = (a, b) -> for key in pairs a @@ -20,74 +21,54 @@ same = (a, b) -> true ---- Interface for types. +--- Base class for types. -- @type Type class Type - new: => - --- pretty-print a value of this type. -- @function pp -- @tparam any value -- @treturn string + --- create a `SigStream` of this type. + -- @tparam ?any init initial value + -- @treturn SigStream + mk_sig: (init) => + result.SigStream @, init + + --- create a `EvtStream` of this type. + -- @treturn EvtStream + mk_evt: => + result.EvtStream @ + + --- create a `Constant` of this type. + -- @tparam any val value + -- @treturn Constant + mk_const: (val) => + result.Constant @, val + --- Primitive type. -- --- Implements the `Type` interface. +-- Extends `Type`. -- -- @type Primitive -class Primitive +class Primitive extends Type pp: (value) => tostring value - __eq: (other) => @type == other.type - __tostring: => @type - - --- shorthand for number type. - -- @tfield Primitive num - @num: @ 'num' - - --- shorthand for string type. - -- @tfield Primitive str - @str: @ 'str' - - --- shorthand for symbol type. - -- @tfield Primitive sym - @sym: @ 'sym' - - --- shorthand for boolean type. - -- @tfield Primitive bool - @bool: @ 'bool' - - --- shorthand for bang type. - -- @tfield Primitive bang - @bang: @ 'bang' - - --- shorthand for `Scope` type. - -- @tfield Primitive scope - @scope: @ 'scope' - - --- shorthand for `Op` type. - -- @tfield Primitive op - @op: @ 'opdef' - - --- shorthand for `FnDef` type. - -- @tfield Primitive fn - @fn: @ 'fndef' - - --- shorthand for `Builtin` type. - -- @tfield Primitive builtin - @builtin: @ 'builtin' + __eq: (other) => @name == other.name + __tostring: => @name --- instantiate a Primitive type. -- @classmethod - -- @tparam string type the typename - new: (@type) => + -- @tparam string name the typename + new: (@name) => + assert (type @name) == 'string', "Typename has to be a string: '#{@name}'" --- Struct/Hashmap type. -- --- Implements the `Type` interface. +-- Extends `Type`. -- -- @type Struct -class Struct +class Struct extends Type pp: (value) => inner = table.concat ["#{k}: #{@types[k]\pp v}" for k, v in opairs value], ', ' "{#{inner}}" @@ -111,10 +92,10 @@ class Struct --- Array type. -- --- Implements the `Type` interface. +-- Extends `Type`. -- -- @type Array -class Array +class Array extends Type pp: (value) => inner = table.concat [@type\pp v for v in *value], ' ' "[#{inner}]" @@ -128,7 +109,17 @@ class Array -- @tparam Type type new: (@size, @type) => +--- Magic table containing all `Primitive` types. +-- +-- When indexed with a string returns a (cached) instance of that type. +-- +-- @table T +T = setmetatable {}, __index: (key) => + with type = Primitive key + rawset @, key, type + { + :T :Primitive :Array :Struct diff --git a/docs/gen/index b/docs/gen/index index a2fe486..55dd1df 100755 --- a/docs/gen/index +++ b/docs/gen/index @@ -1,4 +1,5 @@ #!/usr/bin/env moon +require 'alv' import render, layout, autoref from require 'docs.gen.layout' import section, h1, h2, p, ul, li, a, code from require 'docs.gen.dom' import opairs from require 'alv.util' @@ -43,6 +44,6 @@ spit OUT, layout p "These definitions are automatically loaded into the global Scope of every alive session." ul for key, val in opairs (require 'alv.builtin').values - li render key, val.value + li render key, val.result } } diff --git a/docs/gen/layout.moon b/docs/gen/layout.moon index 60ee80d..f695963 100644 --- a/docs/gen/layout.moon +++ b/docs/gen/layout.moon @@ -21,13 +21,13 @@ render = (name, result, prefix=nil, index=false) -> import div, label, code, ul, li, i, a, pre from dom id = if prefix then "#{prefix}/#{name}" else name - type = i tostring result.type + typestr = i tostring result.type assert result.meta, "#{id} doesn't have any metadata!" summary = assert result.meta.summary, "#{id} doesn't have a summary!" if index div { - label (a (code name), href: "##{id}"), ' (', type, '):  – ' + label (a (code name), href: "##{id}"), ' (', typestr, '):  – ' summary } else @@ -41,7 +41,7 @@ render = (name, result, prefix=nil, index=false) -> content.class = 'nest' div { :id, class: 'def' - label (a (code name), href: "##{id}"), ' (', type, '):  – ' + label (a (code name), href: "##{id}"), ' (', typestr, '):  – ' summary div content } diff --git a/spec/input_spec.moon b/spec/input_spec.moon index 8a8defe..8dbd726 100644 --- a/spec/input_spec.moon +++ b/spec/input_spec.moon @@ -1,130 +1,160 @@ import do_setup, do_teardown from require 'spec.test_setup' -import Input, Primitive, Result, SigStream, EvtStream, IOStream - from require 'alv.base' +import Input, T, Result, IOStream from require 'alv.base' setup do_setup teardown do_teardown -my_io = Primitive 'my-io' - class MyIO extends IOStream - new: => super my_io + new: => super T.my_io dirty: => @is_dirty -basic_tests = (stream, input) -> +basic_tests = (result, input) -> it 'gives access to the Result', -> - assert.is.equal stream, input.stream + assert.is.equal result, input.result it 'forwards :unwrap', -> - assert.is.same stream\unwrap!, input\unwrap! - assert.is.same stream\unwrap!, input! + assert.is.same result\unwrap!, input\unwrap! + assert.is.same result\unwrap!, input! it 'gives access to the type string', -> - assert.is.equal stream.type, input\type! + assert.is.equal result.type, input\type! it 'gives access to the metatype string', -> - assert.is.equal stream.metatype, input\metatype! + assert.is.equal result.metatype, input\metatype! describe 'Input.cold', -> - stream = SigStream.num 1 - input = Input.cold stream + result = T.num\mk_sig 1 + input = Input.cold result - basic_tests stream, input + basic_tests result, input it 'is never dirty', -> assert.is.false input\dirty! - stream\set 2 + result\set 2 assert.is.false input\dirty! input\setup nil assert.is.false input\dirty! input\finish_setup! - new_input = Input.cold SigStream.num 3 + new_input = Input.cold T.num\mk_sig 3 new_input\setup input assert.is.false new_input\dirty! - new_input.stream\set 4 + new_input.result\set 4 assert.is.false new_input\dirty! input\finish_setup! describe 'Input.hot', -> + describe 'with Constant', -> + result = T.num\mk_const 1 + input = Input.hot result + + basic_tests result, input + + describe 'at evaltime', -> + it 'is dirty when new', -> + assert.is.false result\dirty! + + newinput = Input.hot result + newinput\setup nil + assert.is.true newinput\dirty! + newinput\finish_setup! + + it 'is dirty when different', -> + newval = T.num\mk_const 2 + + assert.is.false newval\dirty! + newinput = Input.hot newval + newinput\setup input + assert.is.true newinput\dirty! + newinput\finish_setup! + + it 'is not dirty when equal', -> + newval = T.num\mk_const 1 + + assert.is.false newval\dirty! + newinput = Input.hot newval + newinput\setup input + assert.is.false newinput\dirty! + newinput\finish_setup! + describe 'with EvtStream', -> - stream = EvtStream Primitive 'num' - input = Input.hot stream + result = T.num\mk_evt! + input = Input.hot result - basic_tests stream, input + basic_tests result, input it 'is marked for lifting', -> assert.is.nil input.io it 'is dirty when the EvtStream is dirty', -> assert.is.false input\dirty! - assert.is.false stream\dirty! + assert.is.false result\dirty! input\setup nil assert.is.false input\dirty! input\finish_setup! COPILOT\next_tick! - stream\add 1 + result\add 1 assert.is.true input\dirty! - assert.is.true stream\dirty! + assert.is.true result\dirty! input\setup nil assert.is.true input\dirty! input\finish_setup! assert.is.true input\dirty! - assert.is.true stream\dirty! + assert.is.true result\dirty! describe 'with IOStream', -> - stream = MyIO! - input = Input.hot stream + result = MyIO! + input = Input.hot result - basic_tests stream, input + basic_tests result, input it 'is marked for lifting', -> assert.is.true input.io it 'is dirty when the IOStream is dirty', -> - stream.is_dirty = false + result.is_dirty = false assert.is.false input\dirty! - assert.is.false stream\dirty! + assert.is.false result\dirty! input\setup nil assert.is.false input\dirty! input\finish_setup! COPILOT\next_tick! - stream.is_dirty = true + result.is_dirty = true assert.is.true input\dirty! - assert.is.true stream\dirty! + assert.is.true result\dirty! input\setup nil assert.is.true input\dirty! input\finish_setup! assert.is.true input\dirty! - assert.is.true stream\dirty! + assert.is.true result\dirty! describe 'with SigStream', -> - stream = SigStream.num 1 + result = T.num\mk_sig 1 local input describe 'at evaltime', -> it 'is dirty when new', -> - assert.is.false stream\dirty! + assert.is.false result\dirty! - input = Input.hot stream + input = Input.hot result input\setup nil assert.is.true input\dirty! input\finish_setup! it 'is dirty when different', -> - newval = SigStream.num 2 + newval = T.num\mk_sig 2 assert.is.false newval\dirty! newinput = Input.hot newval @@ -133,7 +163,7 @@ describe 'Input.hot', -> newinput\finish_setup! it 'is not dirty when equal', -> - newval = SigStream.num! + newval = T.num\mk_sig! newval\set 1 assert.is.true newval\dirty! @@ -143,11 +173,11 @@ describe 'Input.hot', -> newinput\finish_setup! describe 'at runtime', -> - it 'is dirty when the stream is dirty', -> - stream\set 3 - assert.is.true stream\dirty! + it 'is dirty when the result is dirty', -> + result\set 3 + assert.is.true result\dirty! assert.is.true input\dirty! COPILOT\next_tick! - assert.is.false stream\dirty! + assert.is.false result\dirty! assert.is.false input\dirty! diff --git a/spec/match_spec.moon b/spec/match_spec.moon index 1e2ce61..afaef56 100644 --- a/spec/match_spec.moon +++ b/spec/match_spec.moon @@ -1,13 +1,13 @@ import val, evt from require 'alv.base.match' -import RTNode, Primitive, SigStream, EvtStream, Error from require 'alv' +import RTNode, T, Error from require 'alv' mk_val = (type, const) -> - result = SigStream Primitive type + result = T[type]\mk_sig! with RTNode :result .side_inputs = { 'fake' } unless const mk_evt = (type, const) -> - result = EvtStream Primitive type + result = T[type]\mk_evt! with RTNode :result .side_inputs = { 'fake' } unless const diff --git a/spec/result/const_spec.moon b/spec/result/const_spec.moon index dfcdafa..a6ab43e 100644 --- a/spec/result/const_spec.moon +++ b/spec/result/const_spec.moon @@ -1,5 +1,5 @@ import do_setup from require 'spec.test_setup' -import Constant, RTNode, Scope, SimpleRegistry, Primitive from require 'alv' +import Constant, RTNode, Scope, SimpleRegistry, T from require 'alv' import Op, Builtin from require 'alv.base' class TestOp extends Op @@ -11,15 +11,20 @@ class TestBuiltin extends Builtin setup do_setup describe 'Constant', -> + it 'requires a value', -> + assert.has.error -> Constant.num! + assert.has.error -> Constant T.num + assert.has.no.error -> Constant T.bool, false + describe '.wrap', -> it 'wraps numbers', -> got = Constant.wrap 3 - assert.is.equal Primitive.num, got.type + assert.is.equal T.num, got.type assert.is.equal 3, got.value it 'wraps strings', -> got = Constant.wrap "im a happy string" - assert.is.equal Primitive.str, got.type + assert.is.equal T.str, got.type assert.is.equal "im a happy string", got.value it 'wraps Constants', -> @@ -31,27 +36,27 @@ describe 'Constant', -> it 'wraps Opdefs', -> got = Constant.wrap TestOp - assert.is.equal Primitive.op, got.type + assert.is.equal T.opdef, got.type assert.is.equal TestOp, got.value it 'wraps Bultins', -> got = Constant.wrap TestBuiltin - assert.is.equal Primitive.builtin, got.type + assert.is.equal T.builtin, got.type assert.is.equal TestBuiltin, got.value it 'wraps Scopes', -> sub = Scope! got = Constant.wrap sub - assert.is.equal Primitive.scope, got.type + assert.is.equal T.scope, got.type assert.is.equal sub, got.value it 'wraps tables', -> pi = Constant.num 3.14 got = Constant.wrap { :pi } - assert.is.equal Primitive.scope, got.type + assert.is.equal T.scope, got.type assert.is.equal pi, (got.value\get 'pi')\const! describe ':unwrap', -> @@ -61,23 +66,23 @@ describe 'Constant', -> assert.is.equal 'hi', (Constant.sym 'hi')\unwrap! test 'can assert the type', -> - assert.is.equal 3.14, (Constant.num 3.14)\unwrap Primitive.num - assert.is.equal 'hi', (Constant.str 'hi')\unwrap Primitive.str - assert.is.equal 'hi', (Constant.sym 'hi')\unwrap Primitive.sym - assert.has_error -> (Constant.num 3.14)\unwrap Primitive.sym - assert.has_error -> (Constant.str 'hi')\unwrap Primitive.num - assert.has_error -> (Constant.sym 'hi')\unwrap Primitive.str + assert.is.equal 3.14, (Constant.num 3.14)\unwrap T.num + assert.is.equal 'hi', (Constant.str 'hi')\unwrap T.str + assert.is.equal 'hi', (Constant.sym 'hi')\unwrap T.sym + assert.has_error -> (Constant.num 3.14)\unwrap T.sym + assert.has_error -> (Constant.str 'hi')\unwrap T.num + assert.has_error -> (Constant.sym 'hi')\unwrap T.str test 'has __call shorthand', -> assert.is.equal 3.14, (Constant.num 3.14)! assert.is.equal 'hi', (Constant.str 'hi')! assert.is.equal 'hi', (Constant.sym 'hi')! - assert.is.equal 3.14, (Constant.num 3.14) Primitive.num - assert.is.equal 'hi', (Constant.str 'hi') Primitive.str - assert.is.equal 'hi', (Constant.sym 'hi') Primitive.sym - assert.has_error -> (Constant.num 3.14) Primitive.sym - assert.has_error -> (Constant.str 'hi') Primitive.num - assert.has_error -> (Constant.sym 'hi') Primitive.str + assert.is.equal 3.14, (Constant.num 3.14) T.num + assert.is.equal 'hi', (Constant.str 'hi') T.str + assert.is.equal 'hi', (Constant.sym 'hi') T.sym + assert.has_error -> (Constant.num 3.14) T.sym + assert.has_error -> (Constant.str 'hi') T.num + assert.has_error -> (Constant.sym 'hi') T.str describe 'overrides __eq', -> it 'compares the type', -> @@ -134,7 +139,7 @@ describe 'Constant', -> it 'is equal to the original', -> a = Constant.num 2 b = Constant.str 'asdf' - c = Constant (Primitive 'weird'), {}, '(raw)' + c = Constant T.weird, {}, '(raw)' aa, bb, cc = a\fork!, b\fork!, c\fork! assert.is.equal a, aa diff --git a/spec/result/sig_spec.moon b/spec/result/sig_spec.moon index 93a9eb4..4d04b9c 100644 --- a/spec/result/sig_spec.moon +++ b/spec/result/sig_spec.moon @@ -1,5 +1,5 @@ import do_setup from require 'spec.test_setup' -import SigStream, RTNode, Scope, SimpleRegistry, Primitive from require 'alv' +import SigStream, RTNode, Scope, SimpleRegistry, T from require 'alv' import Op, Builtin from require 'alv.base' class TestOp extends Op @@ -13,55 +13,55 @@ setup do_setup describe 'SigStream', -> describe ':unwrap', -> it 'returns the raw value!', -> - assert.is.equal 3.14, (SigStream.num 3.14)\unwrap! - assert.is.equal 'hi', (SigStream.str 'hi')\unwrap! - assert.is.equal 'hi', (SigStream.sym 'hi')\unwrap! + assert.is.equal 3.14, (SigStream T.num, 3.14)\unwrap! + assert.is.equal 'hi', (SigStream T.str, 'hi')\unwrap! + assert.is.equal 'hi', (SigStream T.sym, 'hi')\unwrap! test 'can assert the type', -> - assert.is.equal 3.14, (SigStream.num 3.14)\unwrap Primitive 'num' - assert.is.equal 'hi', (SigStream.str 'hi')\unwrap Primitive 'str' - assert.is.equal 'hi', (SigStream.sym 'hi')\unwrap Primitive 'sym' - assert.has_error -> (SigStream.num 3.14)\unwrap Primitive 'sym' - assert.has_error -> (SigStream.str 'hi')\unwrap Primitive 'num' - assert.has_error -> (SigStream.sym 'hi')\unwrap Primitive 'str' + assert.is.equal 3.14, (SigStream T.num, 3.14)\unwrap T.num + assert.is.equal 'hi', (SigStream T.str, 'hi')\unwrap T.str + assert.is.equal 'hi', (SigStream T.sym, 'hi')\unwrap T.sym + assert.has_error -> (SigStream T.num, 3.14)\unwrap T.sym + assert.has_error -> (SigStream T.str, 'hi')\unwrap T.num + assert.has_error -> (SigStream T.sym, 'hi')\unwrap T.str test 'has __call shorthand', -> - assert.is.equal 3.14, (SigStream.num 3.14)! - assert.is.equal 'hi', (SigStream.str 'hi')! - assert.is.equal 'hi', (SigStream.sym 'hi')! - assert.is.equal 3.14, (SigStream.num 3.14) Primitive 'num' - assert.is.equal 'hi', (SigStream.str 'hi') Primitive 'str' - assert.is.equal 'hi', (SigStream.sym 'hi') Primitive 'sym' - assert.has_error -> (SigStream.num 3.14) Primitive 'sym' - assert.has_error -> (SigStream.str 'hi') Primitive 'num' - assert.has_error -> (SigStream.sym 'hi') Primitive 'str' + assert.is.equal 3.14, (SigStream T.num, 3.14)! + assert.is.equal 'hi', (SigStream T.str, 'hi')! + assert.is.equal 'hi', (SigStream T.sym, 'hi')! + assert.is.equal 3.14, (SigStream T.num, 3.14) T.num + assert.is.equal 'hi', (SigStream T.str, 'hi') T.str + assert.is.equal 'hi', (SigStream T.sym, 'hi') T.sym + assert.has_error -> (SigStream T.num, 3.14) T.sym + assert.has_error -> (SigStream T.str, 'hi') T.num + assert.has_error -> (SigStream T.sym, 'hi') T.str describe 'overrides __eq', -> it 'compares the type', -> - val = SigStream.num 3 - assert.is.equal (SigStream.num 3), val - assert.not.equal (SigStream.str '3'), val + val = SigStream T.num, 3 + assert.is.equal (SigStream T.num, 3), val + assert.not.equal (SigStream T.str, '3'), val - val = SigStream.str 'hello' - assert.is.equal (SigStream.str 'hello'), val - assert.not.equal (SigStream.sym 'hello'), val + val = SigStream T.str, 'hello' + assert.is.equal (SigStream T.str, 'hello'), val + assert.not.equal (SigStream T.sym, 'hello'), val it 'compares the value', -> - val = SigStream.num 3 - assert.is.equal (SigStream.num 3), val - assert.not.equal (SigStream.num 4), val + val = SigStream T.num, 3 + assert.is.equal (SigStream T.num, 3), val + assert.not.equal (SigStream T.num, 4), val describe ':set', -> it 'sets the value', -> - val = SigStream.num 3 - assert.is.equal (SigStream.num 3), val + val = SigStream T.num, 3 + assert.is.equal (SigStream T.num, 3), val val\set 4 - assert.is.equal (SigStream.num 4), val - assert.not.equal (SigStream.num 3), val + assert.is.equal (SigStream T.num, 4), val + assert.not.equal (SigStream T.num, 3), val it 'marks the value dirty', -> - val = SigStream.num 3 + val = SigStream T.num, 3 assert.is.false val\dirty! val\set 4 @@ -69,9 +69,9 @@ describe 'SigStream', -> describe ':fork', -> it 'is equal to the original', -> - a = SigStream.num 2 - b = SigStream.str 'asdf' - c = with SigStream 'weird', {}, '(raw)' + a = SigStream T.num, 2 + b = SigStream T.str, 'asdf' + c = with SigStream T.weird, {}, '(raw)' \set {} aa, bb, cc = a\fork!, b\fork!, c\fork! @@ -86,8 +86,8 @@ describe 'SigStream', -> assert.is.equal c.raw, cc.raw it 'isolates the original from the fork', -> - a = SigStream.num 3 - b = with SigStream 'weird', {}, '(raw)' + a = SigStream T.num, 3 + b = with SigStream T.weird, {}, '(raw)' \set {} aa, bb = a\fork!, b\fork! diff --git a/spec/rtnode_spec.moon b/spec/rtnode_spec.moon index a6cd63d..5dfebf7 100644 --- a/spec/rtnode_spec.moon +++ b/spec/rtnode_spec.moon @@ -1,11 +1,8 @@ import do_setup from require 'spec.test_setup' import RTNode, Scope, SimpleRegistry from require 'alv' -import Primitive, Input, Op, Constant, SigStream, EvtStream, IOStream - from require 'alv.base' +import T, Input, Op, Constant, IOStream from require 'alv.base' setup do_setup -num = Primitive 'num' -bang = Primitive 'bang' op_with_inputs = (inputs) -> with Op! @@ -16,7 +13,7 @@ node_with_sideinput = (result, input) -> .side_inputs = { [result]: input } class DirtyIO extends IOStream - new: => super Primitive 'dirty-io' + new: => super T.dirty_io dirty: => true describe 'RTNode', -> @@ -34,7 +31,7 @@ describe 'RTNode', -> it ':type gets type and assets value', -> node = RTNode result: Constant.num 2 - assert.is.equal num, node\type! + assert.is.equal T.num, node\type! node = RTNode! assert.has.error -> node\type! @@ -52,7 +49,7 @@ describe 'RTNode', -> assert.has.error (-> impure\const 'test'), 'test' it ':make_ref', -> - result = SigStream.num 2 + result = T.num\mk_sig 2 input = Input.hot result op = op_with_inputs { input } thick = RTNode :result, :op, children: { RTNode!, RTNode! } @@ -65,10 +62,10 @@ describe 'RTNode', -> assert.is.nil ref.op it 'lifts up inputs from op', -> - event = EvtStream bang + event = T.bang\mk_evt! event_input = Input.hot event - value = SigStream num, 4 + value = T.num\mk_sig 4 value_input = Input.hot value op = op_with_inputs { event_input, value_input } @@ -79,10 +76,10 @@ describe 'RTNode', -> node.side_inputs it 'does not lift up op inputs that are also child values', -> - event = EvtStream bang + event = T.bang\mk_evt! event_input = Input.hot event - result = SigStream num, 4 + result = T.num\mk_sig 4 value_input = Input.hot result op = op_with_inputs { event_input, value_input } @@ -91,12 +88,12 @@ describe 'RTNode', -> assert.is.same { [event]: event_input }, node.side_inputs it 'lifts up side_inputs from children', -> - event_value = EvtStream bang + event_value = T.bang\mk_evt! event_input = Input.hot event_value event = RTNode op: op_with_inputs { event_input } assert.is.same { [event_value]: event_input }, event.side_inputs - value_value = SigStream num, 4 + value_value = T.num\mk_sig 4 value_input = Input.hot value_value value = RTNode op: op_with_inputs { value_input } assert.is.same { [value_value]: value_input }, value.side_inputs @@ -109,11 +106,11 @@ describe 'RTNode', -> local a_value, a_child, a_input local b_value, b_child, b_input before_each -> - a_value = EvtStream num + a_value = T.num\mk_evt! a_input = Input.hot a_value a_child = node_with_sideinput a_value, a_input - b_value = EvtStream num + b_value = T.num\mk_evt! b_input = Input.hot b_value b_child = node_with_sideinput b_value, b_input diff --git a/spec/scope_spec.moon b/spec/scope_spec.moon index 7278b9e..637b5f5 100644 --- a/spec/scope_spec.moon +++ b/spec/scope_spec.moon @@ -1,4 +1,4 @@ -import Scope, Primitive, Constant, RTNode from require 'alv' +import Scope, T, Constant, RTNode from require 'alv' import Op from require 'alv.base' import Logger from require 'alv.logger' Logger\init 'silent' @@ -8,11 +8,6 @@ class TestOp extends Op wrap_res = (result) -> RTNode :result -num = Primitive 'num' -str = Primitive 'str' -opdef = Primitive 'opdef' -scope_t = Primitive 'scope' - describe 'Scope', -> describe 'constifies', -> scope = Scope! @@ -38,21 +33,21 @@ describe 'Scope', -> scope\set_raw 'test', TestOp got = (scope\get 'test')\const! - assert.is.equal TestOp, got opdef + assert.is.equal TestOp, got T.opdef test 'Scopes', -> sub = Scope! scope\set_raw 'sub', sub got = (scope\get 'sub')\const! - assert.is.equal sub, got scope_t + assert.is.equal sub, got T.scope test 'tables', -> pi = Constant.num 3.14 scope\set_raw 'math', { :pi } got = (scope\get 'math')\const! - assert.is.equal scope_t, got.type + assert.is.equal T.scope, got.type assert.is.equal Scope, got.value.__class assert.is.equal pi, (got.value\get 'pi')\const! assert.is.equal pi, (scope\get 'math/pi')\const! @@ -68,18 +63,18 @@ describe 'Scope', -> } got = (scope\get 'num')\const! - assert.is.equal 3, got num + assert.is.equal 3, got T.num got = (scope\get 'str')\const! - assert.is.equal "im a happy string", got str + assert.is.equal "im a happy string", got T.str assert.is.equal pi, (scope\get 'pi')\const! got = (scope\get 'test')\const! - assert.is.equal TestOp, got opdef + assert.is.equal TestOp, got T.opdef got = (scope\get 'math')\const! - assert.is.equal scope_t, got.type + assert.is.equal T.scope, got.type assert.is.equal pi, (scope\get 'math/pi')\const! it 'gets from nested scopes', -> @@ -116,13 +111,13 @@ describe 'Scope', -> it 'allows access', -> got = (scope\get 'inherited')\const! - assert.is.equal "inherited string", got str + assert.is.equal "inherited string", got T.str it 'can be shadowed', -> scope\set_raw 'hidden', "overwritten" got = (scope\get 'hidden')\const! - assert.is.equal "overwritten", got str + assert.is.equal "overwritten", got T.str describe 'dynamic inheritance', -> root = Scope! diff --git a/spec/type_spec.moon b/spec/type_spec.moon index 14d7894..d33fcb4 100644 --- a/spec/type_spec.moon +++ b/spec/type_spec.moon @@ -1,5 +1,5 @@ require 'spec.test_setup' -import Primitive, Array, Struct from require 'alv' +import T, Primitive, Array, Struct from require 'alv' bool = Primitive 'bool' num = Primitive 'num' @@ -43,3 +43,36 @@ describe 'Struct', -> assert.not.equal play, Struct { note: str } assert.not.equal play, Struct { note: str, dur: str } assert.not.equal play, Struct { note: str, dur: num, extra: num } + +describe 'T', -> + it 'provides shorthand for Primitives', -> + assert.is.equal num, T.num + assert.is.equal str, T.str + assert.is.equal (Primitive 'midi/evt'), T['midi/evt'] + +for type in *{num, str, (Array 3, num)} + describe "#{type}", -> + describe ':mk_sig', -> + it 'can create value-less Streams', -> + stream = type\mk_sig! + assert.is.equal 'SigStream', stream.__class.__name + assert.is.equal type, stream.type + assert.is.nil stream! + + it 'can take an initial value', -> + stream = type\mk_sig 4 + assert.is.equal 'SigStream', stream.__class.__name + assert.is.equal type, stream.type + assert.is.equal 4, stream! + + describe ':mk_const', -> + it 'takes a value', -> + stream = type\mk_const 4 + assert.is.equal 'Constant', stream.__class.__name + assert.is.equal type, stream.type + assert.is.equal 4, stream! + + describe ':mk_evt', -> + stream = type\mk_evt! + assert.is.equal 'EvtStream', stream.__class.__name + assert.is.equal type, stream.type |
