aboutsummaryrefslogtreecommitdiffstats
path: root/alv
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 /alv
parentmore internal doc fixes (diff)
downloadalive-61eb86951287667ca0ee305baa5c3cd6ad29ba36.tar.gz
alive-61eb86951287667ca0ee305baa5c3cd6ad29ba36.zip
add types.T, fix spec + docs
Diffstat (limited to 'alv')
-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
16 files changed, 159 insertions, 168 deletions
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