aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s-ol@users.noreply.github.com>2020-02-13 09:07:05 +0000
committers-ol <s-ol@users.noreply.github.com>2020-02-13 09:07:05 +0000
commit9f80c8b41ef2e42f9bc2cce0c2172e879d308dbc (patch)
tree3b075136c22c090e9610eb51dd7e1a70bdb3c64e
parentadd logic lib (diff)
downloadalive-9f80c8b41ef2e42f9bc2cce0c2172e879d308dbc.tar.gz
alive-9f80c8b41ef2e42f9bc2cce0c2172e879d308dbc.zip
no more @registry juggling
-rw-r--r--copilot.moon12
-rw-r--r--core/base.moon1
-rw-r--r--core/builtin.moon34
-rw-r--r--core/cell.moon11
-rw-r--r--core/init.moon18
-rw-r--r--core/invoke.moon8
-rw-r--r--core/parsing.moon2
-rw-r--r--core/registry.moon102
-rw-r--r--core/tag.moon71
9 files changed, 130 insertions, 129 deletions
diff --git a/copilot.moon b/copilot.moon
index 0d562f3..78848e5 100644
--- a/copilot.moon
+++ b/copilot.moon
@@ -28,24 +28,14 @@ class Copilot
L\error "error parsing: #{err}"
return
- ok, err = pcall @registry\prepare
- if not ok
- L\error "error preparing: #{err}"
- return
-
scope = Scope ast, globals
- ok, err = pcall ast\eval, scope, @registry
+ ok, err = pcall (@registry\wrap ast\eval), scope, @registry
if not ok
L\error "error evaluating: #{err}"
return
@root = err
- ok, err = pcall @registry\finalize
- if not ok
- L\error "error finalizing: #{err}"
- return
-
spit @file, ast\stringify!
update: (dt) =>
diff --git a/core/base.moon b/core/base.moon
index 3be2a98..dcf600a 100644
--- a/core/base.moon
+++ b/core/base.moon
@@ -23,7 +23,6 @@ class Op
class Action
-- common
new: (head, @tag) =>
- @registry = @tag.registry -- @TODO: remove
@patch head
-- AST interface
diff --git a/core/builtin.moon b/core/builtin.moon
index 833f7a0..97f4457 100644
--- a/core/builtin.moon
+++ b/core/builtin.moon
@@ -12,7 +12,7 @@ prints the docstring for sym in the console"
eval: (scope, tail) =>
assert #tail == 1, "'doc' takes exactly one parameter"
- def = L\push tail[1]\eval, scope, @registry
+ def = L\push tail[1]\eval, scope
L\print "(doc #{tail[1]\stringify!}):\n#{def\getc!.doc}\n"
nil
@@ -31,9 +31,9 @@ updates all val-exprs."
values = L\push ->
return for i=1,#tail,2
name, val_expr = tail[i], tail[i+1]
- name = (name\quote scope, @registry)\getc 'sym'
+ name = (name\quote scope)\getc 'sym'
- val = val_expr\eval scope, @registry
+ val = val_expr\eval scope
scope\set name, Const.wrap_ref val
val
@@ -48,7 +48,7 @@ all scopes have to be eval-time constants."
eval: (scope, tail) =>
L\trace "evaling #{@}"
for child in *tail
- value = L\push child\eval, scope, @registry
+ value = L\push child\eval, scope
L\trace @, "merging #{value} into #{scope}"
assert value.type == 'scope', "'use' only works on scopes"
scope\use value\getc 'scope'
@@ -65,7 +65,7 @@ name-str has to be an eval-time constant."
L\trace "evaling #{@}"
assert #tail == 1, "'require' takes exactly one parameter"
- name = L\push tail[1]\eval, scope, @registry
+ name = L\push tail[1]\eval, scope
L\trace @, "loading module #{name}"
Const.wrap require "lib.#{name\getc 'str'}"
@@ -81,7 +81,7 @@ requires modules sym1, sym2, ... and defines them as sym1, sym2, ... in the curr
for child in *tail
- name = (child\quote scope, @registry)\getc 'sym'
+ name = (child\quote scope)\getc 'sym'
scope\set name, Const.wrap require "lib.#{name}"
nil
@@ -97,7 +97,7 @@ requires modules sym1, sym2, ... and merges them into the current scope"
for child in *tail
- name = (child\quote scope, @registry)\getc 'sym'
+ name = (child\quote scope)\getc 'sym'
scope\use (Const.wrap require "lib.#{name}")\getc 'scope'
nil
@@ -115,9 +115,9 @@ the symbols p1, p2, ... will resolve to the arguments passed to the function."
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"
- param\quote scope, @registry
+ param\quote scope
- body = body\quote scope, @registry
+ body = body\quote scope
Const.wrap FnDef param_symbols, body, scope
class defn extends Action
@@ -130,13 +130,13 @@ declares a lambda (see (doc fn)) and defines it in the current scope"
assert #tail == 3, "'defn' takes exactly three arguments"
{ name, params, body } = tail
- name = (name\quote scope, @registry)\getc 'sym'
+ name = (name\quote scope)\getc '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"
- param\quote scope, @registry
+ param\quote scope
- body = body\quote scope, @registry
+ body = body\quote scope
fn = FnDef param_symbols, body, scope
scope\set name, Const.wrap fn
@@ -150,7 +150,7 @@ evaluates and continously updates expr1, expr2, ...
the last expression's value is returned."
eval: (scope, tail) =>
- UpdateChildren [(expr\eval scope, @registry) or Const.empty! for expr in *tail]
+ UpdateChildren [(expr\eval scope) or Const.empty! for expr in *tail]
class if_ extends Action
@doc: "(if bool then-expr [else-xpr]) - make an eval-time const choice
@@ -165,13 +165,13 @@ to then-expr, otherwise it is equivalent to else-xpr if given, or nil otherwise.
{ xif, xthen, xelse } = tail
- xif = L\push xif\eval, scope, @registry
+ xif = L\push xif\eval, scope
xif = xif\getc!
if xif
- xthen\eval scope, @registry
+ xthen\eval scope
elseif xelse
- xelse\eval scope, @registry
+ xelse\eval scope
class trace extends Action
@doc: "(trace expr) - print an eval-time constant to the console"
@@ -180,7 +180,7 @@ class trace extends Action
L\trace "evaling #{@}"
assert #tail == 1, "'trace' takes exactly one parameter"
- with val = L\push tail[1]\eval, scope, @registry
+ with val = L\push tail[1]\eval, scope
L\print "trace:", val
{
diff --git a/core/cell.moon b/core/cell.moon
index 65273d8..81409c3 100644
--- a/core/cell.moon
+++ b/core/cell.moon
@@ -1,6 +1,6 @@
import Const from require 'core.const'
import op_invoke, fn_invoke from require 'core.invoke'
-import Tag from require 'core.registry'
+import Tag from require 'core.tag'
class Cell
-- common
@@ -17,8 +17,8 @@ class Cell
destroy: =>
-- AST interface
- eval: (scope, registry) =>
- head = @head!\eval scope, registry
+ eval: (scope) =>
+ head = @head!\eval scope
Action = switch head.type
when 'opdef'
-- scope\get 'op-invoke'
@@ -35,12 +35,11 @@ class Cell
print head.__class.__name
error "cannot evaluate expr with head #{head}"
- @tag.registry = registry
action = Action\get_or_create head, @tag
action\eval scope, @tail!
- quote: (scope, registry) =>
- children = [child\quote scope, registry for child in *@children]
+ quote: (scope) =>
+ children = [child\quote scope for child in *@children]
Cell @tag, children, @white
clone: (parent) =>
diff --git a/core/init.moon b/core/init.moon
index c8f0265..f9a3b9e 100644
--- a/core/init.moon
+++ b/core/init.moon
@@ -22,24 +22,10 @@ globals = Scope.from_table require 'core.builtin'
:globals
parse: program\match
- eval: do
- class BuiltinRegistry
- new: =>
- @cnt = 1
-
- init: (tag, expr) =>
- tag\set @cnt
- @cnt += 1
-
- last: (index) =>
- replace: (index, expr) =>
-
- registry = BuiltinRegistry!
-
- (str, inject) ->
+ eval: (str, inject) ->
scope = Scope nil, globals
scope\use inject if inject
ast = assert (cell\match str), "failed to parse: #{str}"
- Const.wrap ast\eval scope, registry
+ Const.wrap ast\eval scope
}
diff --git a/core/invoke.moon b/core/invoke.moon
index 9c324e1..5ec4a82 100644
--- a/core/invoke.moon
+++ b/core/invoke.moon
@@ -29,7 +29,7 @@ class op_invoke extends Action
eval: (scope, tail) =>
L\trace "evaling #{@}"
- args = L\push -> [L\push expr\eval, scope, @registry for expr in *tail]
+ args = L\push -> [L\push expr\eval, scope for expr in *tail]
-- Const 'op', with @op
with @op
@@ -58,15 +58,15 @@ class fn_invoke extends Action
for i=1,#params
name = params[i]\getc!
argm = tail[i]
- fn_scope\set name, L\push argm\eval, outer_scope, @registry
+ fn_scope\set name, L\push argm\eval, outer_scope
body = body\clone @tag
- body\eval fn_scope, @registry
+ body\eval fn_scope
class do_expr extends Action
eval: (scope, tail) =>
- UpdateChildren [(expr\eval scope, @registry) or Const.empty! for expr in *tail]
+ UpdateChildren [(expr\eval scope) or Const.empty! for expr in *tail]
{
:op_invoke, :fn_invoke
diff --git a/core/parsing.moon b/core/parsing.moon
index c23b7b7..58dbf62 100644
--- a/core/parsing.moon
+++ b/core/parsing.moon
@@ -1,6 +1,6 @@
import Const from require 'core.const'
import Cell, RootCell from require 'core.cell'
-import Tag from require 'core.registry'
+import Tag from require 'core.tag'
import R, S, P, V, C, Ct from require 'lpeg'
-- whitespace
diff --git a/core/registry.moon b/core/registry.moon
index 7c89fa4..6afd361 100644
--- a/core/registry.moon
+++ b/core/registry.moon
@@ -1,75 +1,3 @@
-import Const from require 'core.const'
-import Scope from require 'core.scope'
-
-local ClonedTag
-
-class Tag
- new: (@value) =>
-
- clone: (parent) => ClonedTag @, parent
-
- last: =>
- if index = @index!
- @registry\last index
-
- keep: (expr) =>
- index = assert @index!
- assert expr == @registry\last index
- @registry\replace index, expr
-
- replace: (expr) =>
- if index = @index!
- @registry\replace index, expr
- else
- @registry\init @, expr
-
-index: => @value
-
- set: (value) =>
- assert not @value, "setting #{@} again"
- @value = value
-
- @blank: -> Tag!
- @parse: (num) => @ tonumber num
-
- stringify: => if @value then "[#{@value}]" else ''
-
- __tostring: => if @value then "#{@value}" else '[blank]'
-
-class ClonedTag extends Tag
- class DummyReg
- destroy: =>
-
- new: (@original, @parent) =>
- @registry = @original.registry
- @dummy = DummyReg!
-
- keep: (expr) =>
- super\keep expr
- @original.registry or= @registry
- @original\replace @dummy
-
- replace: (expr) =>
- super\replace expr
- @original.registry or= @registry
- @original\replace @dummy
-
- index: =>
- orig = @original\index!
- parent = @parent\index!
- if orig and parent
- "#{parent}.#{orig}"
-
- set: (value) => @original\set value
-
- stringify: => error "cant stringify ClonedTag"
-
- __tostring: =>
- if @parent
- "#{@parent}.#{@original}"
- else
- tostring @original
-
class Registry
new: () =>
@map = {}
@@ -87,9 +15,20 @@ class Registry
L\trace "reg: init pending to #{expr}"
table.insert @pending, { :tag, :expr }
+ active: ->
+ assert Registry.active_registry, "no active Registry!"
+
-- public methods
+ wrap: (fn) =>
+ (...) ->
+ @prepare!
+ with fn ...
+ @finalize!
+
prepare: =>
+ assert not @prev, "already have a previous registry? #{@prev}"
+ @prev, @@active_registry = @@active_registry, @
@last_map, @map, @pending = @map, {}, {}
finalize: =>
@@ -106,9 +45,26 @@ class Registry
tag\set @next_tag!
@map[tag\index!] = expr
+ assert @ == @@active_registry, "not the active registry!"
+ @@active_registry, @prev = @prev, nil
+
next_tag: => #@map + 1
+class SimpleRegistry extends Registry
+ new: =>
+ @cnt = 1
+
+ init: (tag, expr) =>
+ tag\set @cnt
+ @cnt += 1
+
+ last: (index) =>
+ replace: (index, expr) =>
+ finalize: =>
+ assert @ == @@active_registry, "not the active registry!"
+ @@active_registry, @prev = @prev, nil
+
{
- :Tag
:Registry
+ :SimpleRegistry
}
diff --git a/core/tag.moon b/core/tag.moon
new file mode 100644
index 0000000..47c43fa
--- /dev/null
+++ b/core/tag.moon
@@ -0,0 +1,71 @@
+import Registry from require 'core.registry'
+
+local ClonedTag
+
+class Tag
+ new: (@value) =>
+
+ clone: (parent) => ClonedTag @, parent
+
+ last: =>
+ if index = @index!
+ Registry.active!\last index
+
+ keep: (expr) =>
+ index = assert @index!
+ assert expr == Registry.active!\last index
+ Registry.active!\replace index, expr
+
+ replace: (expr) =>
+ if index = @index!
+ Registry.active!\replace index, expr
+ else
+ Registry.active!\init @, expr
+
+ index: => @value
+
+ set: (value) =>
+ assert not @value, "setting #{@} again"
+ @value = value
+
+ @blank: -> Tag!
+ @parse: (num) => @ tonumber num
+
+ stringify: => if @value then "[#{@value}]" else ''
+
+ __tostring: => if @value then "#{@value}" else '[blank]'
+
+class ClonedTag extends Tag
+ class DummyReg
+ destroy: =>
+
+ new: (@original, @parent) =>
+ @dummy = DummyReg!
+
+ keep: (expr) =>
+ super\keep expr
+ @original\replace @dummy
+
+ replace: (expr) =>
+ super\replace expr
+ @original\replace @dummy
+
+ index: =>
+ orig = @original\index!
+ parent = @parent\index!
+ if orig and parent
+ "#{parent}.#{orig}"
+
+ set: (value) => @original\set value
+
+ stringify: => error "cant stringify ClonedTag"
+
+ __tostring: =>
+ if @parent
+ "#{@parent}.#{@original}"
+ else
+ tostring @original
+
+{
+ :Tag
+}