diff options
| author | s-ol <s-ol@users.noreply.github.com> | 2020-02-13 09:07:05 +0000 |
|---|---|---|
| committer | s-ol <s-ol@users.noreply.github.com> | 2020-02-13 09:07:05 +0000 |
| commit | 9f80c8b41ef2e42f9bc2cce0c2172e879d308dbc (patch) | |
| tree | 3b075136c22c090e9610eb51dd7e1a70bdb3c64e | |
| parent | add logic lib (diff) | |
| download | alive-9f80c8b41ef2e42f9bc2cce0c2172e879d308dbc.tar.gz alive-9f80c8b41ef2e42f9bc2cce0c2172e879d308dbc.zip | |
no more @registry juggling
| -rw-r--r-- | copilot.moon | 12 | ||||
| -rw-r--r-- | core/base.moon | 1 | ||||
| -rw-r--r-- | core/builtin.moon | 34 | ||||
| -rw-r--r-- | core/cell.moon | 11 | ||||
| -rw-r--r-- | core/init.moon | 18 | ||||
| -rw-r--r-- | core/invoke.moon | 8 | ||||
| -rw-r--r-- | core/parsing.moon | 2 | ||||
| -rw-r--r-- | core/registry.moon | 102 | ||||
| -rw-r--r-- | core/tag.moon | 71 |
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 +} |
