aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s-ol@users.noreply.github.com>2020-05-09 14:49:08 +0000
committers-ol <s+removethis@s-ol.nu>2025-03-02 14:23:21 +0000
commit61eb86951287667ca0ee305baa5c3cd6ad29ba36 (patch)
tree7551d6b9c8af01c049adab0ee027dbad68f28808
parentmore internal doc fixes (diff)
downloadalive-61eb86951287667ca0ee305baa5c3cd6ad29ba36.tar.gz
alive-61eb86951287667ca0ee305baa5c3cd6ad29ba36.zip
add types.T, fix spec + docs
-rw-r--r--alv-lib/logic.moon24
-rw-r--r--alv-lib/math.moon53
-rw-r--r--alv-lib/midi.moon22
-rw-r--r--alv-lib/midi/core.moon14
-rw-r--r--alv-lib/midi/launchctl.moon22
-rw-r--r--alv-lib/osc.moon10
-rw-r--r--alv-lib/pilot.moon8
-rw-r--r--alv-lib/random.moon23
-rw-r--r--alv-lib/sc.moon6
-rw-r--r--alv-lib/string.moon6
-rw-r--r--alv-lib/time.moon42
-rw-r--r--alv-lib/util.moon22
-rw-r--r--alv/base/init.moon8
-rw-r--r--alv/base/input.moon30
-rw-r--r--alv/builtin.moon24
-rw-r--r--alv/cell.moon8
-rw-r--r--alv/copilot.moon2
-rw-r--r--alv/error.moon15
-rw-r--r--alv/init.moon8
-rw-r--r--alv/invoke.moon31
-rw-r--r--alv/module.moon2
-rw-r--r--alv/result/base.moon8
-rw-r--r--alv/result/const.moon43
-rw-r--r--alv/result/evt.moon9
-rw-r--r--alv/result/sig.moon27
-rw-r--r--alv/rtnode.moon19
-rw-r--r--alv/scope.moon4
-rw-r--r--alv/type.moon89
-rwxr-xr-xdocs/gen/index3
-rw-r--r--docs/gen/layout.moon6
-rw-r--r--spec/input_spec.moon112
-rw-r--r--spec/match_spec.moon6
-rw-r--r--spec/result/const_spec.moon45
-rw-r--r--spec/result/sig_spec.moon76
-rw-r--r--spec/rtnode_spec.moon27
-rw-r--r--spec/scope_spec.moon25
-rw-r--r--spec/type_spec.moon35
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, '): &ensp;&ndash;&ensp;'
+ label (a (code name), href: "##{id}"), ' (', typestr, '): &ensp;&ndash;&ensp;'
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, '): &ensp;&ndash;&ensp;'
+ label (a (code name), href: "##{id}"), ' (', typestr, '): &ensp;&ndash;&ensp;'
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