aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authors-ol <s-ol@users.noreply.github.com>2020-03-02 11:41:33 +0000
committers-ol <s-ol@users.noreply.github.com>2020-03-02 11:41:33 +0000
commit03853b35a473161f377fb74a05723cacc5cbf36b (patch)
tree2e3df044cc0ff3ed24a07d6b5ee31682f077e5fa /core
parentnew op interface part one (diff)
downloadalive-03853b35a473161f377fb74a05723cacc5cbf36b.tar.gz
alive-03853b35a473161f377fb74a05723cacc5cbf36b.zip
IO system
Diffstat (limited to 'core')
-rw-r--r--core/base.moon25
-rw-r--r--core/init.moon8
-rw-r--r--core/pattern.moon11
-rw-r--r--core/registry.moon8
-rw-r--r--core/value.moon6
5 files changed, 48 insertions, 10 deletions
diff --git a/core/base.moon b/core/base.moon
index 0a88cc1..6af4913 100644
--- a/core/base.moon
+++ b/core/base.moon
@@ -5,6 +5,7 @@ unpack or= table.unpack
class Input
new: (value) =>
+ assert value, "nil passed to Input: #{value}"
@stream = switch value.__class
when Result
assert value.value, "Input from result without value!"
@@ -19,8 +20,12 @@ class Input
dirty: => @stream\dirty!
unwrap: => @stream\unwrap!
type: => @stream.type
+
__call: => @stream\unwrap!
- __inherited: (cls) => cls.__base.__call = @__call
+ __tostring: => "#{@@__name}:#{@stream}"
+ __inherited: (cls) =>
+ cls.__base.__call = @__call
+ cls.__base.__tostring = @__tostring
-- ValueInput scheduling policy
--
@@ -35,6 +40,19 @@ class ValueInput extends Input
-- only marked dirty if the input stream itself is dirty
class EventInput extends Input
+-- IOInput scheduling policy
+--
+-- lifts streams of IO objects to events
+class IOInput extends Input
+ dirty: => @stream\unwrap!\dirty!
+
+class IO
+ -- called in the main event loop
+ tick: =>
+
+ -- whether a tree update is necessary
+ dirty: =>
+
-- a persistent expression Operator
--
-- accepts Const or Stream inputs and produces a Stream output
@@ -61,7 +79,7 @@ class Op
if cur_plain and old_plain
-- both are tables, recurse
do_merge old_val, cur_val
- elseif cur_plain == old_plain
+ elseif not (cur_plain or old_plain)
-- both are streams (or nil), merge them
cur_val\merge old_val
@@ -191,8 +209,9 @@ class FnDef
"(fn (#{table.concat [p\stringify! for p in *@params], ' '}) ...)"
{
- :ValueInput, :EventInput
+ :ValueInput, :EventInput, :IOInput
:Dispatcher
+ :IO
:Op
:Action
:FnDef
diff --git a/core/init.moon b/core/init.moon
index a309722..6b5bdd0 100644
--- a/core/init.moon
+++ b/core/init.moon
@@ -1,6 +1,8 @@
L or= setmetatable {}, __index: => ->
-import Op, Action, FnDef from require 'core.base'
+import Op, IO, Action, FnDef, EventInput, ValueInput, IOInput
+ from require 'core.base'
+import match from require 'core.pattern'
import Value, Result, load_ from require 'core.value'
import Scope from require 'core.scope'
@@ -17,7 +19,9 @@ globals = Scope.from_table require 'core.builtin'
{
:Value, :Result
:Cell, :RootCell
- :Op, :Action, :FnDef
+
+ :Op, :IO, :Action, :FnDef
+ :EventInput, :ValueInput, :IOInput, :match
:Scope
:Registry, :Tag
diff --git a/core/pattern.moon b/core/pattern.moon
index 64b53b8..13497af 100644
--- a/core/pattern.moon
+++ b/core/pattern.moon
@@ -35,13 +35,20 @@ class Pattern
matched = while @matches results[1]
table.remove results, 1
- assert @opt or #matched > 0, "expected at least one argument for spread!"
+ assert @opt or #matched > 0, "expected at least one argument for spread"
matched
else
matches = @matches results[1]
- assert @opt or matches, "couldn't match argument #{results[1]} as type #{@type}!"
+ assert @opt or matches, "couldn't match argument #{results[1]} as #{@}"
if matches then table.remove results, 1
+ __tostring: =>
+ str = @type
+ str = '*' .. str if @splat
+ str = '=' .. str if @const
+ str = str .. '?' if @opt
+ str
+
match = (pattern, results) ->
patterns = while pattern
pat, rest = pattern\match '^([^ ]+) (.*)$'
diff --git a/core/registry.moon b/core/registry.moon
index 2a83f7e..ac1943a 100644
--- a/core/registry.moon
+++ b/core/registry.moon
@@ -3,6 +3,7 @@ import Result, Value from require 'core.value'
class Registry
new: () =>
@map = {}
+ @io = {}
@tick = 0
@kr = Result value: Value.bool true
@@ -22,6 +23,10 @@ class Registry
active: -> assert Registry.active_registry, "no active Registry!"
+-- IO
+ add_io: (io) => @io[io] = true
+ remove_io: (io) => @io[io] = nil
+
-- public methods
wrap_eval: (fn) => (...) ->
@@ -50,6 +55,9 @@ class Registry
@tick += 1
@kr.value\set true
+ for io in pairs @io
+ io\tick!
+
with fn ...
@release!
diff --git a/core/value.moon b/core/value.moon
index 0d44320..0e72486 100644
--- a/core/value.moon
+++ b/core/value.moon
@@ -36,8 +36,8 @@ class Result
if @op
for input in @op\all_inputs!
- continue if is_child[input]
- @side_inputs[input] = true
+ continue if is_child[input.stream]
+ @side_inputs[input.stream] = true
is_const: => not next @side_inputs
@@ -97,7 +97,7 @@ class Value
-- * scope, opdef, fndef, builtin
-- @value - Lua value - access through :unwrap()
new: (@type, @value, @raw) =>
- @updated = 0
+ @updated = nil
dirty: => @updated == Registry.active!.tick