aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s-ol@users.noreply.github.com>2020-05-08 11:41:56 +0000
committers-ol <s+removethis@s-ol.nu>2025-03-02 14:23:21 +0000
commitbec1ebf1209c5a56ad4208d820222cb497b5f98c (patch)
tree0663fbbd99d580b55b7aa611b415afd946b738bb
parentfix docs (diff)
downloadalive-bec1ebf1209c5a56ad4208d820222cb497b5f98c.tar.gz
alive-bec1ebf1209c5a56ad4208d820222cb497b5f98c.zip
rename RTNode.value to RTNode.result (to match Result class)
-rw-r--r--alv/ast.moon4
-rw-r--r--alv/base/builtin.moon6
-rw-r--r--alv/base/input.moon13
-rw-r--r--alv/base/match.moon10
-rw-r--r--alv/base/op.moon14
-rw-r--r--alv/builtin.moon42
-rw-r--r--alv/cell.moon2
-rw-r--r--alv/copilot.moon2
-rw-r--r--alv/invoke.moon10
-rw-r--r--alv/module.moon4
-rw-r--r--alv/registry.moon2
-rw-r--r--alv/result/base.moon44
-rw-r--r--alv/result/const.moon27
-rw-r--r--alv/result/evt.moon63
-rw-r--r--alv/result/init.moon6
-rw-r--r--alv/result/sig.moon60
-rw-r--r--alv/rtnode.moon49
-rw-r--r--alv/scope.moon8
-rw-r--r--docs/gen/layout.moon18
-rwxr-xr-xdocs/gen/module8
-rw-r--r--docs/internals/extensions.md49
-rw-r--r--spec/input_spec.moon2
-rw-r--r--spec/match_spec.moon21
-rw-r--r--spec/result/const_spec.moon6
-rw-r--r--spec/rtnode_spec.moon97
-rw-r--r--spec/scope_spec.moon40
26 files changed, 291 insertions, 316 deletions
diff --git a/alv/ast.moon b/alv/ast.moon
index cff8947..b8c14e6 100644
--- a/alv/ast.moon
+++ b/alv/ast.moon
@@ -10,11 +10,11 @@
--- evaluate this AST Node.
--
- -- Evaluate this node and return a `Result`.
+ -- Evaluate this node and return a `RTNode`.
--
-- @function eval
-- @tparam Scope scope the scope to evaluate in
- -- @treturn Result the evaluation result
+ -- @treturn RTNode the evaluation result
--- create a clone with its own identity.
--
diff --git a/alv/base/builtin.moon b/alv/base/builtin.moon
index f675207..5f46f37 100644
--- a/alv/base/builtin.moon
+++ b/alv/base/builtin.moon
@@ -31,7 +31,7 @@ class Builtin
--
-- @tparam Scope scope the active scope
-- @tparam {AST,...} tail the arguments to this expression
- -- @treturn Result the result of this evaluation
+ -- @treturn RTNode the result of this evaluation
eval: (scope, tail) => error "not implemented"
--- free resources
@@ -62,12 +62,12 @@ class Builtin
-- Create a new instance using `tag` and `head` and call `setup` on it.
-- If a previous instance with the same `tag` exists and has the same `head`,
-- it pass it to `setup`. Register the `Builtin` with `tag`, evaluate it
- -- and return the `Result`.
+ -- and return the `RTNode`.
--
-- @tparam Cell cell the `Cell` being evaluated
-- @tparam Scope scope the active scope
-- @tparam Value head the (`AST:eval`d) head of the `Cell` being evaluated
- -- @treturn Result the result of evaluation
+ -- @treturn RTNode the result of evaluation
@eval_cell: (cell, scope, head) =>
last = cell.tag\last!
compatible = last and (last.__class == @) and last.head == head
diff --git a/alv/base/input.moon b/alv/base/input.moon
index dea91c9..a9f0e32 100644
--- a/alv/base/input.moon
+++ b/alv/base/input.moon
@@ -35,7 +35,7 @@ class Input
--- create a new Input.
--
-- @classmethod
- -- @tparam Stream stream
+ -- @tparam Result stream
new: (@stream) =>
assert @stream, "nil passed to Input: #{value}"
@@ -98,26 +98,27 @@ class Input
-- Never marked dirty. Use this for input streams that are only read when
-- another `Input` is dirty.
--
- -- @tparam Stream|RTNode value
+ -- @tparam Result|RTNode value
@cold: (value) ->
if value.__class == RTNode
- value = assert value.value, "Input from result without value!"
+ value = assert value.result, "Input from node without result!"
ColdInput value
--- Create a `hot` `Input`.
--
- -- Behaviour depends on what kind of `Stream` `value` is:
+ -- Behaviour depends on what kind of `Result` `value` is:
--
+ -- - `Constant`: treated like `cold`.
-- - `SigStream`: Marked dirty only if old and new `SigStream` differ.
-- - `EvtStream` and `IOStream`: Marked dirty only if the current
-- `EvtStream` is dirty.
--
-- This is the most common `Input` strategy.
--
- -- @tparam Stream|RTNode value
+ -- @tparam Result|RTNode value
@hot: (value) ->
if value.__class == RTNode
- value = assert value.value, "Input from result without value!"
+ value = assert value.result, "Input from node without result!"
InputType = match_parent value, mapping
assert InputType, "Input from unknown value: #{value}"
diff --git a/alv/base/match.moon b/alv/base/match.moon
index 3a2b3d5..926c970 100644
--- a/alv/base/match.moon
+++ b/alv/base/match.moon
@@ -49,14 +49,12 @@ import Primitive from require 'alv.type'
local Repeat, Sequence, Choice, Optional
-typestr = (result) -> tostring result.value
-
class Pattern
match: (seq) =>
@reset!
num, cap = @capture seq, 1
if num != #seq
- args = table.concat [typestr arg for arg in *seq], ' '
+ args = table.concat [arg.result\fulltype! for arg in *seq], ' '
msg = "couldn't match arguments (#{args}) against pattern #{@}"
error Error 'argument', msg
cap
@@ -86,15 +84,15 @@ class Pattern
cls.__base.__div or= @__div
cls.__base.__unm or= @__unm
---- Base Stream Pattern.
+--- Base Result Pattern.
--
--- When instantiated with `type`, only succeeds for `Stream`s whose value and
+-- When instantiated with `type`, only succeeds for `Result`s whose value and
-- meta types match.
--
-- Otherwise, matches Streams based only on `metatype` for the first match, but
-- using both afterwards (recall mode).
--
--- @function Stream
+-- @function Type
-- @tparam string metatype "value" or "event"
-- @tparam ?string type type name
class Type extends Pattern
diff --git a/alv/base/op.moon b/alv/base/op.moon
index b0a83dc..da90288 100644
--- a/alv/base/op.moon
+++ b/alv/base/op.moon
@@ -46,9 +46,9 @@ class Op
--
-- @tfield table state
- --- `Stream` instance representing this Op's computed output value.
+ --- `Result` instance representing this Op's computed output value.
--
- -- Must be set to a `Stream` instance once `setup` finishes. Must not change
+ -- Must be set to a `Result` instance once `setup` finishes. Must not change
-- type, be removed or replaced outside of `new` and `setup`. If it is a
-- `ValueStream`, it should have a value assigned via `set` or the
-- constructor once `tick` is called the first time. If `out`'s value is not
@@ -56,7 +56,7 @@ class Op
-- `tick``(true)` is called at least on the first eval-cycle the Op goes
-- through, e.g. by using an `Input.hot` with a `ValueStream`.
--
- -- @tfield Stream out
+ -- @tfield Result out
--- table containing `Input`s to this Op.
--
@@ -79,18 +79,18 @@ class Op
--
-- @function new
-- @classmethod
- -- @tparam ?Stream out `out`
+ -- @tparam ?Result out `out`
-- @tparam ?table state `state`
--- parse arguments and patch self.
--
- -- Called once every eval-cycle. `inputs` is a list of `Result`s that are the
+ -- Called once every eval-cycle. `inputs` is a list of `RTNode`s that are the
-- argument to this op. The `inputs` have to be wrapped in `Input` instances
-- to define update behaviour. Use `base.match` to parse them, then delegate to
-- `super:setup` to patch the `Input` instances.
--
-- @function setup
- -- @tparam {Result,...} inputs a sequence of `Result`s
+ -- @tparam {RTNode,...} inputs a sequence of `RTNode`s
-- @tparam Scope scope the active scope
--- handle incoming events and update `out` (optional).
@@ -120,7 +120,7 @@ class Op
-- type is not known at this time.
--
-- @classmethod
- -- @tparam ?Stream out `out`
+ -- @tparam ?Result out `out`
-- @tparam ?table state `state`
new: (@out, @state) =>
diff --git a/alv/builtin.moon b/alv/builtin.moon
index 58a1ecc..740da25 100644
--- a/alv/builtin.moon
+++ b/alv/builtin.moon
@@ -35,9 +35,9 @@ doc = Constant.meta
eval: (scope, tail) =>
assert #tail == 1, "'doc' takes exactly one parameter"
- result = L\push tail[1]\eval, scope
+ node = L\push tail[1]\eval, scope
with RTNode children: { def }
- meta = result.value.meta
+ meta = node.result.meta
L\print "(doc #{tail[1]}):\n#{format_meta meta}\n"
def = Constant.meta
@@ -78,8 +78,8 @@ All arguments have to be evaltime constant."
eval: (scope, tail) =>
L\trace "evaling #{@}"
for child in *tail
- result = L\push child\eval, scope
- value = result\const!
+ node = L\push child\eval, scope
+ value = node\const!
scope\use value\unwrap 'scope', "'use' only works on scopes"
RTNode!
@@ -96,8 +96,8 @@ require_ = Constant.meta
L\trace "evaling #{@}"
assert #tail == 1, "'require' takes exactly one parameter"
- result = L\push tail[1]\eval, scope
- name = result\const!\unwrap 'str'
+ node = L\push tail[1]\eval, scope
+ name = node\const!\unwrap 'str'
L\trace @, "loading module #{name}"
COPILOT\require name
@@ -148,11 +148,11 @@ export_ = Constant.meta
description: "
Evaluate `expr1`, `expr2`, … in a new Scope and return scope."
- value: class extends Builtin
+ value: class extends Builtin
eval: (scope, tail) =>
new_scope = Scope scope
children = [expr\eval new_scope for expr in *tail]
- RTNode :children, value: Constant.wrap new_scope
+ RTNode :children, result: Constant.wrap new_scope
export_star = Constant.meta
meta:
@@ -170,16 +170,16 @@ Copies the containing scope if no symbols are given."
new_scope = Scope!
children = if #tail == 0
- for k,result in pairs scope.values
- new_scope\set k, result
- result
+ for k,node in pairs scope.values
+ new_scope\set k, node
+ node
else
for child in *tail
name = child\unwrap 'sym'
- with result = scope\get name
- new_scope\set name, result
+ with node = scope\get name
+ new_scope\set name, node
- RTNode :children, value: Constant.wrap new_scope
+ RTNode :children, result: Constant.wrap new_scope
fn = Constant.meta
meta:
@@ -201,7 +201,7 @@ function is invoked."
assert param.type == 'sym', "function parameter declaration has to be a symbol"
param
- RTNode value: with Constant.wrap FnDef param_symbols, body, scope
+ RTNode result: with Constant.wrap FnDef param_symbols, body, scope
.meta = {
summary: "(user defined function)"
examples: { "(??? #{table.concat [p! for p in *param_symbols], ' '})" }
@@ -229,13 +229,13 @@ function is invoked."
assert param.type == 'sym', "function parameter declaration has to be a symbol"
param
- value = with Constant.wrap FnDef param_symbols, body, scope
+ result = with Constant.wrap FnDef param_symbols, body, scope
.meta =
:name
summary: "(user defined function)"
examples: { "(#{name} #{table.concat [p! for p in *param_symbols], ' '})" }
- scope\set name, RTNode :value
+ scope\set name, RTNode :result
RTNode!
do_expr = Constant.meta
@@ -246,11 +246,11 @@ do_expr = Constant.meta
description: "
Evaluate `expr1`, `expr2`, … and return the value of the last expression."
- value: class extends Builtin
+ value: class extends Builtin
eval: (scope, tail) =>
scope = Scope scope
children = [expr\eval scope for expr in *tail]
- RTNode :children, value: children[#children].value
+ RTNode :children, result: children[#children].result
if_ = Constant.meta
meta:
@@ -288,8 +288,8 @@ trace_ = Constant.meta
L\trace "evaling #{@}"
assert #tail == 1, "'trace!' takes exactly one parameter"
- with result = L\push tail[1]\eval, scope
- L\print "trace! #{tail[1]\stringify!}: #{result.value}"
+ with node = L\push tail[1]\eval, scope
+ L\print "trace! #{tail[1]\stringify!}: #{node.result}"
trace = Constant.meta
meta:
diff --git a/alv/cell.moon b/alv/cell.moon
index 933d292..a61f8de 100644
--- a/alv/cell.moon
+++ b/alv/cell.moon
@@ -69,7 +69,7 @@ class Cell
-- then calls `Builtin:eval_cell` on it.
--
-- @tparam Scope scope the scope to evaluate in
- -- @treturn Result the evaluation result
+ -- @treturn RTNode the evaluation result
eval: (scope) =>
head = assert @head!, Error 'syntax', "cannot evaluate empty expr"
head = (head\eval scope)\const!
diff --git a/alv/copilot.moon b/alv/copilot.moon
index d9b674f..55e00c8 100644
--- a/alv/copilot.moon
+++ b/alv/copilot.moon
@@ -46,7 +46,7 @@ class Copilot
Error.wrap "loading module '#{name}'", ->
ok, lua = pcall require, "alv-lib.#{name}"
if ok
- RTNode value: Constant.wrap lua
+ RTNode result: Constant.wrap lua
else
assert @modules, "no current eval cycle?"
if mod = @modules[name]
diff --git a/alv/invoke.moon b/alv/invoke.moon
index 03cf08e..0629b59 100644
--- a/alv/invoke.moon
+++ b/alv/invoke.moon
@@ -64,7 +64,7 @@ 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, [result for result in *children], scope
+ Error.wrap frame, @op\setup, [node for node in *children], scope
any_dirty = false
for input in @op\all_inputs!
@@ -78,7 +78,7 @@ class op_invoke extends Builtin
for input in @op\all_inputs!
input\finish_setup!
- RTNode :children, value: @op.out, op: @op
+ RTNode :children, result: @op.out, op: @op
--- The `Op` instance.
--
@@ -123,10 +123,10 @@ class fn_invoke extends Builtin
fn_scope\set name, \make_ref!
clone = body\clone @tag
- result = Error.wrap frame, clone\eval, fn_scope
+ node = Error.wrap frame, clone\eval, fn_scope
- table.insert children, result
- RTNode :children, value: result.value
+ table.insert children, node
+ RTNode :children, result: node.result
{
:op_invoke, :fn_invoke
diff --git a/alv/module.moon b/alv/module.moon
index 8fc3ba7..7179ab6 100644
--- a/alv/module.moon
+++ b/alv/module.moon
@@ -67,8 +67,8 @@ class Module
--- the last updated AST tree for this module.
-- @tfield ?AST ast
- --- the root Result of this module.
- -- @tfield ?Result root
+ --- the runtime graph root of this module.
+ -- @tfield ?RTNode root
{
:Module
diff --git a/alv/registry.moon b/alv/registry.moon
index 1b24e9a..0d37a5c 100644
--- a/alv/registry.moon
+++ b/alv/registry.moon
@@ -2,8 +2,6 @@
-- `Tag` Registry.
--
-- @classmod Registry
-import Result from require 'alv.result'
-import Error from require 'alv.error'
class Registry
--- internals for `Tag`
diff --git a/alv/result/base.moon b/alv/result/base.moon
index 26af4b4..bbbbeac 100644
--- a/alv/result/base.moon
+++ b/alv/result/base.moon
@@ -1,55 +1,45 @@
----
--- base Stream interface.
+-- base Result interface.
--
-- implemented by `Constant`, `SigStream`, `EvtStream`, and `IOStream`.
--
--- @classmod Stream
+-- @classmod Result
-class Stream
---- Stream interface.
+class Result
+--- Result interface.
--
--- Methods that have to be implemented by `Stream` implementations
+-- Methods that have to be implemented by `Result` implementations
-- (`SigStream`, `EvtStream`, `IOStream`).
--
-- @section interface
- --- return whether this Stream was changed in the current tick.
- --
+ --- return whether this Result was changed in the current tick.
-- @function dirty
-- @treturn boolean
- --- create a mutable copy of this Stream.
+ --- create a mutable copy of this Result.
--
-- Used to insulate eval-cycles from each other.
--
-- @function fork
- -- @treturn Stream
+ -- @treturn Result
__tostring: => "<#{@type}#{@metatype} #{@type\pp @value}>"
__inherited: (cls) => cls.__base.__tostring or= @__tostring
- --- the type name of this Stream's value.
- --
- -- the following builtin typenames are used:
- --
- -- - `str` - strings, `value` is a Lua string
- -- - `sym` - symbols, `value` is a Lua string
- -- - `num` - numbers, `value` is a Lua number
- -- - `bool` - booleans, `value` is a Lua boolean
- -- - `bang` - trigger signals, `value` is a Lua boolean
- -- - `opdef` - `value` is an `Op` subclass
- -- - `builtin` - `value` is a `Builtin` subclass
- -- - `fndef` - `value` is a `FnDef` instance
- -- - `scope` - `value` is a `Scope` instance
- --
+ --- the type name of this Result's value.
-- @tfield string type
- --- the metatype string for this Stream.
+ --- the metatype string for this Result.
--
-- one of `=` (`Constant`), `~` (`SigStream`),
-- `!` (`EvtStream` and `IOStream`).
--
- -- @tfield string type
+ -- @tfield string metatype
+
+ --- get the full typestring.
+ -- @treturn string `type .. metatype`
+ fulltype: => (tostring @type) .. @metatype
--- documentation metadata.
--
@@ -66,7 +56,7 @@ class Stream
--- static functions
-- @section static
- --- construct a new Stream.
+ --- construct a new Result.
--
-- @classmethod
-- @tparam string type the type name
@@ -74,5 +64,5 @@ class Stream
new: (@type, @meta={}) =>
{
- :Stream
+ :Result
}
diff --git a/alv/result/const.moon b/alv/result/const.moon
index b9a7cf4..615e426 100644
--- a/alv/result/const.moon
+++ b/alv/result/const.moon
@@ -1,10 +1,10 @@
----
-- Constant Value.
--
--- Implements the `Stream` and `AST` inteface.
+-- Implements the `Result` and `AST` inteface.
--
-- @classmod Constant
-import Stream from require 'alv.result.base'
+import Result from require 'alv.result.base'
import Primitive from require 'alv.type'
import RTNode from require 'alv.rtnode'
import Error from require 'alv.error'
@@ -21,10 +21,14 @@ ancestor = (klass) ->
klass = klass.__parent
klass
-class Constant extends Stream
- --- Whether this Result is dirty.
- --
- -- @treturn bool always `false`.
+class Constant extends Result
+--- Result interface
+--
+-- `Constant` implements the `Result` interface.
+-- @section result
+
+ --- return whether this Result was changed in the current tick.
+ -- @treturn bool
dirty: => false
--- unwrap to the Lua type.
@@ -53,14 +57,13 @@ class Constant extends Stream
-- Compares two `SigStream`s by comparing their types and their Lua values.
__eq: (other) => other.type == @type and other.value == @value
- --- Stream metatype.
- --
+ --- Result metatype.
-- @tfield string metatype (`=`)
metatype: '='
--- AST interface
--
--- `SignStream` implements the `AST` interface.
+-- `Constant` implements the `AST` interface.
-- @section ast
--- evaluate this literal constant.
@@ -72,11 +75,11 @@ class Constant extends Stream
-- @tparam Scope scope the scope to evaluate in
-- @treturn RTNode the evaluation result
eval: (scope) =>
- return RTNode value: @ if @literal
+ return RTNode result: @ if @literal
switch @type
when num, str
- RTNode value: @
+ RTNode result: @
when sym
Error.wrap "resolving symbol '#{@value}'", scope\get, @value
else
@@ -140,7 +143,7 @@ class Constant extends Stream
switch ancestor val.__class
when scope.Scope then 'scope'
when base.FnDef then 'fndef'
- when Stream then return val
+ when Result then return val
else
error "#{name}: cannot wrap '#{val.__class.__name}' instance"
else
diff --git a/alv/result/evt.moon b/alv/result/evt.moon
index 0559a70..fdec85e 100644
--- a/alv/result/evt.moon
+++ b/alv/result/evt.moon
@@ -2,29 +2,18 @@
-- Stream of momentary events.
--
-- @classmod EvtStream
-import Stream from require 'alv.result.base'
+import Result from require 'alv.result.base'
-class EvtStream extends Stream
---- members
--- @section members
+class EvtStream extends Result
+--- Result interface
+--
+-- `EvtStream` implements the `Result` interface.
+-- @section result
- --- return whether this stream was changed in the current tick.
- --
+ --- return whether this Result was changed in the current tick.
-- @treturn bool
dirty: => @updated == COPILOT.T
- --- push an event value into the stream.
- --
- -- Marks this stream as dirty for the remainder of the current tick.
- --
- -- @tparam any event
- add: (event) =>
- if not @dirty!
- @events = {}
-
- @updated = COPILOT.T
- table.insert @events, event
-
--- get the sequence of current events (if any).
--
-- Returns `events` if `dirty`, or an empty table otherwise.
@@ -48,27 +37,13 @@ class EvtStream extends Stream
__call: (...) => @unwrap ...
__tostring: => "<#{@type}#{@metatype} #{@type\pp @value}>"
- --- Stream metatype.
- --
+ --- the type name of this Result's value.
+ -- @tfield string type
+
+ --- the metatype string for this Result.
-- @tfield string metatype (`!`)
metatype: '!'
- --- the type name of the stream.
- --
- -- the following builtin typenames are used:
- --
- -- - `str` - strings, `value` is a Lua string
- -- - `sym` - symbols, `value` is a Lua string
- -- - `num` - numbers, `value` is a Lua number
- -- - `bool` - booleans, `value` is a Lua boolean
- -- - `bang` - trigger signals, `value` is a Lua boolean
- -- - `opdef` - `value` is an `Op` subclass
- -- - `builtin` - `value` is a `Builtin` subclass
- -- - `fndef` - `value` is a `FnDef` instance
- -- - `scope` - `value` is a `Scope` instance
- --
- -- @tfield string type
-
--- documentation metadata.
--
-- an optional table containing metadata for error messages and
@@ -81,6 +56,22 @@ class EvtStream extends Stream
--
-- @tfield ?table meta
+--- members
+-- @section members
+
+ --- push an event value into the stream.
+ --
+ -- Marks this stream as dirty for the remainder of the current tick.
+ --
+ -- @tparam any event
+ add: (event) =>
+ if not @dirty!
+ @events = {}
+
+ @updated = COPILOT.T
+ table.insert @events, event
+
+
--- static functions
-- @section static
diff --git a/alv/result/init.moon b/alv/result/init.moon
index aa7a115..200e4e1 100644
--- a/alv/result/init.moon
+++ b/alv/result/init.moon
@@ -1,13 +1,13 @@
----
--- `Stream` interface and implementations.
+-- `Result` interface and implementations.
--
--- @see Stream
+-- @see Result
-- @see Constant
-- @see SigStream
-- @see EvtStream
-- @see IOStream
--
--- @module stream
+-- @module result
import Constant from require 'alv.result.const'
import SigStream from require 'alv.result.sig'
import EvtStream from require 'alv.result.evt'
diff --git a/alv/result/sig.moon b/alv/result/sig.moon
index 6bcba65..8ca59b7 100644
--- a/alv/result/sig.moon
+++ b/alv/result/sig.moon
@@ -2,26 +2,19 @@
-- Continuous stream of values.
--
-- @classmod SigStream
-import Stream from require 'alv.result.base'
+import Result from require 'alv.result.base'
import Primitive from require 'alv.type'
-class SigStream extends Stream
---- members
--- @section members
+class SigStream extends Result
+--- Result interface
+--
+-- `SigStream` implements the `Result` interface.
+-- @section result
- --- return whether this stream was changed in the current tick.
- --
+ --- return whether this Result was changed in the current tick.
-- @treturn bool
dirty: => @updated == COPILOT.T
- --- update this stream's value.
- --
- -- Marks this stream as dirty for the remainder of the current tick.
- set: (value) =>
- if value != @value
- @value = value
- @updated = COPILOT.T
-
--- unwrap to the Lua type.
--
-- Asserts `@type == type` if `type` is given.
@@ -50,29 +43,12 @@ class SigStream extends Stream
-- Compares two `SigStream`s by comparing their types and their Lua values.
__eq: (other) => other.type == @type and other.value == @value
- --- Stream metatype.
- --
- -- @tfield string metatype (`~`)
- metatype: '~'
-
- --- the type name of this stream.
- --
- -- the following builtin typenames are used:
- --
- -- - `str` - strings, `value` is a Lua string
- -- - `sym` - symbols, `value` is a Lua string
- -- - `num` - numbers, `value` is a Lua number
- -- - `bool` - booleans, `value` is a Lua boolean
- -- - `bang` - trigger signals, `value` is a Lua boolean
- -- - `opdef` - `value` is an `Op` subclass
- -- - `builtin` - `value` is a `Builtin` subclass
- -- - `fndef` - `value` is a `FnDef` instance
- -- - `scope` - `value` is a `Scope` instance
- --
+ --- the type name of this Result's value.
-- @tfield string type
- --- the wrapped Lua value.
- -- @tfield any value
+ --- the metatype string for this Result.
+ -- @tfield string metatype (`~`)
+ metatype: '~'
--- documentation metadata.
--
@@ -86,6 +62,20 @@ class SigStream extends Stream
--
-- @tfield ?table meta
+--- members
+-- @section members
+
+ --- update this stream's value.
+ --
+ -- Marks this stream as dirty for the remainder of the current tick.
+ set: (value) =>
+ if value != @value
+ @value = value
+ @updated = COPILOT.T
+
+ --- the wrapped Lua value.
+ -- @tfield any value
+
--- static functions
-- @section static
diff --git a/alv/rtnode.moon b/alv/rtnode.moon
index dab4507..a8ebec3 100644
--- a/alv/rtnode.moon
+++ b/alv/rtnode.moon
@@ -9,33 +9,33 @@ class RTNode
--- members
-- @section members
- --- return whether this RTNode's value is const.
+ --- return whether this RTNode's result is const.
is_const: => not next @side_inputs
- --- assert value-constness and return the value.
+ --- assert result-constness and return the result.
-- @tparam[opt] string msg the error message to throw
-- @treturn any
const: (msg) =>
assert not (next @side_inputs), msg or "eval-time const expected"
- @value
+ @result
- --- assert this result has a value, return its type.
+ --- assert this result has a result, return its type.
-- @treturn string
type: =>
- assert @value, "RTNode with value expected"
- @value.type
+ assert @result, "RTNode with result expected"
+ @result.type
- --- assert this result has a value, returns its metatype.
- -- @treturn string `"value"` or `"event"`
+ --- assert this result has a result, returns its metatype.
+ -- @treturn string `"result"` or `"event"`
metatype: =>
- assert @value, "RTNode with value expected"
- @value.metatype
+ assert @result, "RTNode with result expected"
+ @result.metatype
- --- create a copy of this result with value-copy semantics.
- -- the copy has the same @value and @side_inputs, but will not update
+ --- create a copy of this result with result-copy semantics.
+ -- the copy has the same @result and @side_inputs, but will not update
-- anything on \tick.
make_ref: =>
- with RTNode value: @value
+ with RTNode result: @result
.side_inputs = @side_inputs
--- poll all IOStream instances that are effecting this (sub)tree.
@@ -73,15 +73,15 @@ class RTNode
@op\tick!
__tostring: =>
- buf = "<RT=#{@value}"
+ buf = "<RT=#{@result}"
buf ..= " #{@op}" if @op
buf ..= " (#{#@children} children)" if #@children > 0
buf ..= ">"
buf
- --- the `Stream` result
+ --- the `Result` result
--
- -- @tfield ?Stream value
+ -- @tfield ?Result result
--- an Op
--
@@ -91,21 +91,21 @@ class RTNode
--
-- @tfield {}|{RTNode,...} children
- --- cached mapping of all `Stream`/`Input` pairs affecting this RTNode.
+ --- cached mapping of all `Result`/`Input` pairs affecting this RTNode.
--
-- This is the union of all `children`s `side_inputs` and all `Input`s from
- -- `op` that are not the `value` of any child.
+ -- `op` that are not the `result` of any child.
--
- -- @tfield {[Stream]=Input,...} side_inputs
+ -- @tfield {[Result]=Input,...} side_inputs
--- static functions
-- @section static
--- create a new RTNode.
-- @classmethod
- -- @param params table with optional keys op, value, children. default: {}
+ -- @param params table with optional keys op, result, children. default: {}
new: (params={}) =>
- @value = params.value
+ @result = params.result
@op = params.op
@children = params.children or {}
@@ -113,14 +113,17 @@ class RTNode
for child in *@children
for stream, input in pairs child.side_inputs
@side_inputs[stream] = input
- if child.value
- is_child[child.value] = true
+ 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 @result and @result.metatype == '='
+ assert not (next @side_inputs), "Const result has side_inputs"
+
{
:RTNode
}
diff --git a/alv/scope.moon b/alv/scope.moon
index c2c91e1..462d7a6 100644
--- a/alv/scope.moon
+++ b/alv/scope.moon
@@ -18,8 +18,8 @@ class Scope
-- @tparam string key
-- @tparam any val
set_raw: (key, val) =>
- value = Constant.wrap val, key
- @values[key] = RTNode :value
+ result = Constant.wrap val, key
+ @values[key] = RTNode :result
--- set a symbol to a `RTNode`.
--
@@ -28,7 +28,7 @@ class Scope
set: (key, val) =>
L\trace "setting #{key} = #{val} in #{@}"
assert val.__class == RTNode, "expected #{key}=#{val} to be RTNode"
- assert val.value, Error 'type', "cannot define symbol to nil"
+ assert val.result, Error 'type', "cannot define symbol to nil"
assert not @values[key], Error 'type', "cannot redefine symbol '#{key}'!"
@values[key] = val
@@ -59,7 +59,7 @@ class Scope
error Error 'reference', "undefined symbol '#{start}'"
if child\type! != (Primitive 'scope')
error Error 'reference', "'#{start}' is not a scope"
- child.value!\get rest, while_msg
+ child.result!\get rest, while_msg
--- copy definitions from another scope.
--
diff --git a/docs/gen/layout.moon b/docs/gen/layout.moon
index ee0f359..60ee80d 100644
--- a/docs/gen/layout.moon
+++ b/docs/gen/layout.moon
@@ -16,14 +16,14 @@ render_meta = (meta) ->
contents
--- render an ALV Value to a HTML string
-render = (name, value, prefix=nil, index=false) ->
+-- render a Result to a HTML string
+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 value.type
- assert value.meta, "#{id} doesn't have any metadata!"
- summary = assert value.meta.summary, "#{id} doesn't have a summary!"
+ type = 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 {
@@ -31,12 +31,12 @@ render = (name, value, prefix=nil, index=false) ->
summary
}
else
- content = switch value.type
+ content = switch tostring result.type
when 'scope'
- ul for k, result in opairs value!.values
- li render k, result.value, id
+ ul for k, node in opairs result!.values
+ li render k, node.result, id
else
- render_meta value.meta
+ render_meta result.meta
content.class = 'nest'
div {
diff --git a/docs/gen/module b/docs/gen/module
index 4d8c18d..d726845 100755
--- a/docs/gen/module
+++ b/docs/gen/module
@@ -33,9 +33,9 @@ spit OUT, layout
body: section {
h2 (code name), ' module reference'
h3 'index'
- ul for key, res in opairs module.values
- li render key, res.value, nil, true
+ ul for key, node in opairs module.values
+ li render key, node.result, nil, true
h3 'details'
- ul for key, res in opairs module.values
- li render key, res.value
+ ul for key, node in opairs module.values
+ li render key, node.result
}
diff --git a/docs/internals/extensions.md b/docs/internals/extensions.md
index 358aa7e..bc07e58 100644
--- a/docs/internals/extensions.md
+++ b/docs/internals/extensions.md
@@ -11,13 +11,13 @@ these are exported in the `base` module.
## documentation metadata
The lua module should return a `Scope` or a table that will be converted using
-`Scope.from_table`. All exports should be documented using `ValueStream.meta`,
+`Scope.from_table`. All exports should be documented using `Constant.meta`,
which attaches a `meta` table to the value that is used for error messages,
documentation generation and [`(doc)`][builtins-doc].
- import ValueStream from require 'alv.base'
+ import Constant from require 'alv.base'
- two = ValueStream.meta
+ two = Constant.meta
meta:
name: 'two'
summary: "the number two"
@@ -43,9 +43,9 @@ Most extensions will want to define a number of *Op*s to be used by the user.
They are implemented by deriving from the `Op` class and implementing at least
the `Op:setup` and `Op:tick` methods.
- import ValueStream, Op, Input, evt from require 'alv.base'
+ import Constant, SigStream, Op, Input, evt from require 'alv.base'
- total_sum = ValueStream.meta
+ total_sum = Constant.meta
meta:
name: 'total-sum'
summary: "Keep a total of incoming numbers."
@@ -56,7 +56,7 @@ the `Op:setup` and `Op:tick` methods.
new: (...) =>
super ...
@state or= { total: 0 }
- @out or= ValueStream 'num', @state.total
+ @out or= SigStream 'num', @state.total
setup: (inputs, scope) =>
num = evt.num\match inputs
@@ -89,9 +89,9 @@ for more information).
pattern = evt.bang + val.str + val.num*3 + -evt!
{ trig, str, numbers, optional } = pattern\match inputs
-This example matches first an `EventStream` of type `bang`, then a `ValueStream`
+This example matches first an `EvtStream` of type `bang`, then a `SigStream`
of type `str`, followed by one, two or three `num`-values and finally an
-optional argument `EventStream` of any type. `:match` will throw an error if it
+optional argument `EvtStream` of any type. `:match` will throw an error if it
couldn't (fully) match the arguments and otherwise return a structured mapping
of the inputs.
@@ -111,12 +111,12 @@ update when the value changes, it's enough to update only when the trigger
input changes and simply read the value in that moment.
*Hot* inputs on the other hand mark the input stream as a dependency for the
-Op. Depending on the type of `Stream`, the semantics are a little different:
+Op. Depending on the type of `Result`, the semantics are a little different:
-- For `ValueStream`s, the Op updates whenever the current value changes. When
+- For `SigStream`s, the Op updates whenever the current value changes. When
an input stream is swapped out for another one at evaltime, but their values
are momentarily equal, the input is not considered dirty.
-- For `EventStream`s and `IOStream`s, the Op updates whenever the stream is
+- For `EvtStream`s and `IOStream`s, the Op updates whenever the stream is
dirty. There is no special handling when the stream is swapped out at
evaltime.
@@ -142,26 +142,29 @@ long as all 'leaf values' are `Input` instances. The following are both valid:
values: { (Inputs.cold a), (Inputs.cold b), (Inputs.cold c) }
#### output setup
-When `Op:setup` finishes, `@out` has to be set to a `Stream` instance. The
+When `Op:setup` finishes, `@out` has to be set to a `Result` instance. The
instance can be created in `Op:setup`, or by overriding the constructor and
delegating to the original one using `super`. In general setting it in the
constructor is preferred, and it is only moved to `Op:setup` if the output
type depends on the arguments received.
-There are three types of `Stream`s that can be created:
+There are four types of `Result`s that can be created:
-- `ValueStream`s track *continuous values*. They can only have one value per
- tick, and downstream Ops will not update when a *ValueStream* has been set
- to the same value it already had. They are updated using `ValueStream:set`.
-- `EventStream`s transmit *momentary events*. They can transmit multiple events
- in a single tick. `EventStream`s do not keep a value set on the last tick on
- the next tick. They are updated using `EventStream:add`.
-- `IOStream`s are like `EventStream`s, but their `IOStream:poll` method is
+- `SigStream`s track *continuous values*. They can only have one value per
+ tick, and downstream Ops will not update when a *SigStream* has been set
+ to the same value it already had. They are updated using `SigStream:set`.
+- `EvtStream`s transmit *momentary events*. They can transmit multiple events
+ in a single tick. `EvtStream`s do not keep a value set on the last tick on
+ the next tick. They are updated using `EvtStream:add`.
+- `IOStream`s are like `EvtStream`s, but their `IOStream:poll` method is
polled by the event loop at the start of every tick. This gives them a chance
to effectively create changes 'out of thin air' and kickstart the execution
of the dataflow engine. All *runtime* execution is due to an `IOStream`
becoming dirty somewhere. See the section on implementing `IOStream`s below
for more information.
+- `Constant`s do not change in-between evalcycles. Usually Ops do not output
+ `Constant`s directly, althrough `SigStream`s outputs are automatically
+ 'downgraded' to `Constant`s when the Op has no reactive inputs.
### Op:tick
`Op:tick` is called whenever any of the inputs are *dirty*. This is where the
@@ -179,7 +182,7 @@ familiar with the relevant internal interfaces (especially `AST`, `Result`, and
`Scope`).
## defining `IOStream`s
-`IOStream`s are `EventStream`s that can 'magically' create events out of
+`IOStream`s are `EvtStream`s that can 'magically' create events out of
nothing. They are the source of all processing in alv. Whenever you want to
bring events into alv from an external protocol or application, an IOStream
will be necessary.
@@ -196,7 +199,7 @@ To implement a custom IOStream, create it as a class that inherits from the
if math.random! < 0.1
@add true
-In the constructor, you should call the super-constructor `EventStream.new` to
+In the constructor, you should call the super-constructor `EvtStream.new` to
set the event type. Often this will be a custom event that is only used inside
your extension (such as e.g. the `midi/port` type in the [midi][modules-midi]
module), but it can also be a primitive type like `'num'` in this example. In
@@ -209,7 +212,7 @@ them this way in a real extension.
### using `IOStream`s
There's a couple of ways IOStreams can be used and exposed to the user of your
extension. You can either expose an instance of your IOStream directly
-(documented using `ValueStream.meta`), or offer an Op that creates and returns
+(documented using `SigStream.meta`), or offer an Op that creates and returns
an instance in `Op.out` - that way the IOStream can be created only on demand
and take parameters. It is also possible to not exepose the IOStream at all,
and rather pass it as a hardcoded input into an Op's `Op.inputs`.
diff --git a/spec/input_spec.moon b/spec/input_spec.moon
index 371a3ee..8a8defe 100644
--- a/spec/input_spec.moon
+++ b/spec/input_spec.moon
@@ -12,7 +12,7 @@ class MyIO extends IOStream
dirty: => @is_dirty
basic_tests = (stream, input) ->
- it 'gives access to the Stream', ->
+ it 'gives access to the Result', ->
assert.is.equal stream, input.stream
it 'forwards :unwrap', ->
diff --git a/spec/match_spec.moon b/spec/match_spec.moon
index e3483e3..1e2ce61 100644
--- a/spec/match_spec.moon
+++ b/spec/match_spec.moon
@@ -1,14 +1,14 @@
import val, evt from require 'alv.base.match'
-import RTNode, Primitive, SigStream, EvtStream from require 'alv'
+import RTNode, Primitive, SigStream, EvtStream, Error from require 'alv'
mk_val = (type, const) ->
- value = SigStream Primitive type
- with RTNode :value
+ result = SigStream Primitive type
+ with RTNode :result
.side_inputs = { 'fake' } unless const
mk_evt = (type, const) ->
- value = EvtStream Primitive type
- with RTNode :value
+ result = EvtStream Primitive type
+ with RTNode :result
.side_inputs = { 'fake' } unless const
describe 'val and evt', ->
@@ -224,11 +224,13 @@ describe 'complex nesting', ->
bang = mk_evt 'bang'
str = mk_val 'str'
num = mk_val 'num'
- pattern = -evt.bang + val.num*4 + (val.str + (val.num / val.str))\named('key', 'val')^0
+ pattern = -evt.bang + val.num*4 +
+ (val.str + (val.num / val.str))\named('key', 'val')^0
it 'just works', ->
assert.is.same { bang, { num, num }, {} }, pattern\match { bang, num, num }
- assert.is.same { nil, { num }, { { key: str, val: num }, { key: str, val: str } } },
+ assert.is.same { nil, { num }, { { key: str, val: num },
+ { key: str, val: str } } },
pattern\match { num, str, num, str, str }
assert.has.error -> pattern\match { num, str }
assert.has.error -> pattern\match { bang, num, num, num, num, num, num }
@@ -238,3 +240,8 @@ describe 'complex nesting', ->
it 'stringifies well', ->
assert.is.equal '(bang!? num{1-4} (str (num | str)){0-*})', tostring pattern
+
+ it 'gives useful error feedback', ->
+ msg = "couldn't match arguments (num~ str~ bool~) against pattern #{pattern}"
+ err = Error 'argument', msg
+ assert.has.error (-> pattern\match { num, str, mk_val 'bool' }), err
diff --git a/spec/result/const_spec.moon b/spec/result/const_spec.moon
index 55d5175..31eec4e 100644
--- a/spec/result/const_spec.moon
+++ b/spec/result/const_spec.moon
@@ -111,9 +111,9 @@ describe 'Constant', ->
it 'looks up symbols in the scope', ->
scope = with Scope!
- \set 'number', RTNode value: Constant.num 3
- \set 'hello', RTNode value: Constant.str "world"
- \set 'goodbye', RTNode value: Constant.sym "again"
+ \set 'number', RTNode result: Constant.num 3
+ \set 'hello', RTNode result: Constant.str "world"
+ \set 'goodbye', RTNode result: Constant.sym "again"
assert_eval = (sym, val) ->
const = Constant.sym sym
diff --git a/spec/rtnode_spec.moon b/spec/rtnode_spec.moon
index a842a74..a6cd63d 100644
--- a/spec/rtnode_spec.moon
+++ b/spec/rtnode_spec.moon
@@ -1,6 +1,7 @@
import do_setup from require 'spec.test_setup'
import RTNode, Scope, SimpleRegistry from require 'alv'
-import Primitive, Input, Op, Constant, EvtStream, IOStream from require 'alv.base'
+import Primitive, Input, Op, Constant, SigStream, EvtStream, IOStream
+ from require 'alv.base'
setup do_setup
num = Primitive 'num'
@@ -10,99 +11,99 @@ op_with_inputs = (inputs) ->
with Op!
\setup inputs if inputs
-result_with_sideinput = (value, input) ->
- with RTNode :value
- .side_inputs = { [value]: input }
+node_with_sideinput = (result, input) ->
+ with RTNode :result
+ .side_inputs = { [result]: input }
class DirtyIO extends IOStream
new: => super Primitive 'dirty-io'
dirty: => true
describe 'RTNode', ->
- it 'wraps value, children', ->
- value = Constant.num 3
+ it 'wraps result, children', ->
+ result = Constant.num 3
a = RTNode!
b = RTNode!
children = { a, b }
- result = RTNode :value, :children
+ node = RTNode :result, :children
- assert.is.equal value, result.value
- assert.is.same children, result.children
+ assert.is.equal result, node.result
+ assert.is.same children, node.children
it ':type gets type and assets value', ->
- result = RTNode value: Constant.num 2
- assert.is.equal num, result\type!
+ node = RTNode result: Constant.num 2
+ assert.is.equal num, node\type!
- result = RTNode!
- assert.has.error -> result\type!
+ node = RTNode!
+ assert.has.error -> node\type!
it ':is_const', ->
- value = Constant.num 2
- pure = RTNode :value
- impure = result_with_sideinput value, {}
+ result = Constant.num 2
+ pure = RTNode :result
+ impure = node_with_sideinput result, {}
assert.is.true pure\is_const!
assert.is.false impure\is_const!
- assert.is.equal value, pure\const!
+ assert.is.equal result, pure\const!
assert.has.error -> impure\const!
assert.has.error (-> impure\const 'test'), 'test'
it ':make_ref', ->
- value = Constant.num 2
- input = Input.hot value
+ result = SigStream.num 2
+ input = Input.hot result
op = op_with_inputs { input }
- thick = RTNode :value, :op, children: { RTNode!, RTNode! }
+ thick = RTNode :result, :op, children: { RTNode!, RTNode! }
ref = thick\make_ref!
assert ref
- assert.is.equal thick.value, ref.value
+ assert.is.equal thick.result, ref.result
assert.is.same thick.side_inputs, ref.side_inputs
assert.is.same {}, ref.children
assert.is.nil ref.op
it 'lifts up inputs from op', ->
- event = Constant bang, false
+ event = EvtStream bang
event_input = Input.hot event
- value = Constant num, 4
+ value = SigStream num, 4
value_input = Input.hot value
op = op_with_inputs { event_input, value_input }
- result = RTNode op: op, :value
+ node = RTNode op: op, result: value
- assert.is.equal op, result.op
+ assert.is.equal op, node.op
assert.is.same { [event]: event_input, [value]: value_input },
- result.side_inputs
+ node.side_inputs
it 'does not lift up op inputs that are also child values', ->
- event = Constant bang, false
+ event = EvtStream bang
event_input = Input.hot event
- value = Constant num, 4
- value_input = Input.hot value
+ result = SigStream num, 4
+ value_input = Input.hot result
op = op_with_inputs { event_input, value_input }
- result = RTNode op: op, :value, children: { RTNode :value }
+ node = RTNode op: op, :result, children: { RTNode :result }
- assert.is.same { [event]: event_input }, result.side_inputs
+ assert.is.same { [event]: event_input }, node.side_inputs
it 'lifts up side_inputs from children', ->
- event_value = Constant bang, false
+ event_value = EvtStream bang
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 = Constant num, 4
+ value_value = SigStream num, 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
- result = RTNode children: { event, value }
+ node = RTNode children: { event, value }
assert.is.same { [event_value]: event_input, [value_value]: value_input },
- result.side_inputs
+ node.side_inputs
describe ':tick', ->
local a_value, a_child, a_input
@@ -110,11 +111,11 @@ describe 'RTNode', ->
before_each ->
a_value = EvtStream num
a_input = Input.hot a_value
- a_child = result_with_sideinput a_value, a_input
+ a_child = node_with_sideinput a_value, a_input
b_value = EvtStream num
b_input = Input.hot b_value
- b_child = result_with_sideinput b_value, b_input
+ b_child = node_with_sideinput b_value, b_input
it 'updates children when a side_input is dirty', ->
a_value\add 1
@@ -124,8 +125,8 @@ describe 'RTNode', ->
a = spy.on a_child, 'tick'
b = spy.on b_child, 'tick'
- result = RTNode children: { a_child, b_child }
- result\tick!
+ node = RTNode children: { a_child, b_child }
+ node\tick!
assert.spy(a).was_called_with match.ref a_child
assert.spy(b).was_called_with match.ref b_child
@@ -137,8 +138,8 @@ describe 'RTNode', ->
a = spy.on a_child, 'tick'
b = spy.on b_child, 'tick'
- result = RTNode children: { a_child, b_child }
- result\tick!
+ node = RTNode children: { a_child, b_child }
+ node\tick!
assert.spy(a).was_not_called!
assert.spy(b).was_not_called!
@@ -151,8 +152,8 @@ describe 'RTNode', ->
op = op_with_inputs a: Input.hot a_value
s = spy.on op, 'tick'
- result = RTNode :op, children: { a_child, b_child }
- result\tick!
+ node = RTNode :op, children: { a_child, b_child }
+ node\tick!
assert.spy(s).was_called_with match.ref op
@@ -164,8 +165,8 @@ describe 'RTNode', ->
op = op_with_inputs { Input.hot b_value }
s = spy.on op, 'tick'
- result = RTNode :op, children: { a_child, b_child }
- result\tick!
+ node = RTNode :op, children: { a_child, b_child }
+ node\tick!
assert.spy(s).was_not_called!
@@ -174,10 +175,10 @@ describe 'RTNode', ->
io = DirtyIO!
input = Input.hot io
op = op_with_inputs { input }
- result = RTNode :op
+ node = RTNode :op
s = spy.on io, 'poll'
- assert.is.same { [io]: input }, result.side_inputs
- result\poll_io!
+ assert.is.same { [io]: input }, node.side_inputs
+ node\poll_io!
assert.spy(s).was_called_with match.ref io
diff --git a/spec/scope_spec.moon b/spec/scope_spec.moon
index 4798391..7278b9e 100644
--- a/spec/scope_spec.moon
+++ b/spec/scope_spec.moon
@@ -6,7 +6,7 @@ Logger\init 'silent'
class TestOp extends Op
new: (...) => super ...
-wrap_res = (value) -> RTNode :value
+wrap_res = (result) -> RTNode :result
num = Primitive 'num'
str = Primitive 'str'
@@ -21,36 +21,31 @@ describe 'Scope', ->
scope\set_raw 'num', 3
got = (scope\get 'num')\const!
- assert.is.equal num, got.type
- assert.is.equal 3, got.value
+ assert.is.equal (Constant.num 3), got
test 'strings', ->
scope\set_raw 'str', "im a happy string"
got = (scope\get 'str')\const!
- assert.is.equal str, got.type
- assert.is.equal "im a happy string", got.value
+ assert.is.equal (Constant.str "im a happy string"), got
test 'Values', ->
pi = Constant.num 3.14
scope\set_raw 'pi', pi
-
assert.is.equal pi, (scope\get 'pi')\const!
test 'Opdefs', ->
scope\set_raw 'test', TestOp
got = (scope\get 'test')\const!
- assert.is.equal opdef, got.type
- assert.is.equal TestOp, got.value
+ assert.is.equal TestOp, got opdef
test 'Scopes', ->
sub = Scope!
scope\set_raw 'sub', sub
got = (scope\get 'sub')\const!
- assert.is.equal scope_t, got.type
- assert.is.equal sub, got.value
+ assert.is.equal sub, got scope_t
test 'tables', ->
pi = Constant.num 3.14
@@ -73,18 +68,15 @@ describe 'Scope', ->
}
got = (scope\get 'num')\const!
- assert.is.equal num, got.type
- assert.is.equal 3, got.value
+ assert.is.equal 3, got num
got = (scope\get 'str')\const!
- assert.is.equal str, got.type
- assert.is.equal "im a happy string", got.value
+ assert.is.equal "im a happy string", got str
assert.is.equal pi, (scope\get 'pi')\const!
got = (scope\get 'test')\const!
- assert.is.equal opdef, got.type
- assert.is.equal TestOp, got.value
+ assert.is.equal TestOp, got opdef
got = (scope\get 'math')\const!
assert.is.equal scope_t, got.type
@@ -124,15 +116,13 @@ describe 'Scope', ->
it 'allows access', ->
got = (scope\get 'inherited')\const!
- assert.is.equal str, got.type
- assert.is.equal "inherited string", got.value
+ assert.is.equal "inherited string", got str
it 'can be shadowed', ->
scope\set_raw 'hidden', "overwritten"
got = (scope\get 'hidden')\const!
- assert.is.equal str, got.type
- assert.is.equal "overwritten", got.value
+ assert.is.equal "overwritten", got str
describe 'dynamic inheritance', ->
root = Scope!
@@ -147,18 +137,18 @@ describe 'Scope', ->
it 'follows a different parent', ->
merged = Scope root, dyn_root
- assert.is.equal 'normal', (merged\get 'normal').value!
- assert.is.equal 'dynamic', (merged\get '*dynamic*').value!
+ assert.is.equal 'normal', (merged\get 'normal').result!
+ assert.is.equal 'dynamic', (merged\get '*dynamic*').result!
it 'falls back to the immediate parent', ->
merged = Scope root
- assert.is.equal 'normal', (merged\get '*dynamic*').value!
+ assert.is.equal 'normal', (merged\get '*dynamic*').result!
it 'looks in self first', ->
merged = Scope root
merged\set_raw '*dynamic*', 'merged'
- assert.is.equal 'merged', (merged\get '*dynamic*').value!
+ assert.is.equal 'merged', (merged\get '*dynamic*').result!
it 'can resolve nested', ->
merged = Scope root, dyn_root
- assert.is.equal 3, (merged\get '*nested*/value').value!
+ assert.is.equal 3, (merged\get '*nested*/value').result!