aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s+removethis@s-ol.nu>2025-09-03 21:31:55 +0000
committers-ol <s+removethis@s-ol.nu>2025-09-03 21:31:55 +0000
commit75718cc129803d1b6d63fa27499f5f5b916560fb (patch)
tree09e0b618e30e3b63dfd48094c833a75ec21088bf
parentrelease v0.2 (diff)
downloadalive-75718cc129803d1b6d63fa27499f5f5b916560fb.tar.gz
alive-75718cc129803d1b6d63fa27499f5f5b916560fb.zip
expose Tag to Ops
-rw-r--r--alv/base/builtin.moon2
-rw-r--r--alv/invoke.moon2
-rw-r--r--alv/module.moon2
-rw-r--r--alv/registry.moon57
-rw-r--r--alv/result/const.moon2
-rw-r--r--alv/tag.moon18
-rw-r--r--spec/test_setup.moon1
7 files changed, 41 insertions, 43 deletions
diff --git a/alv/base/builtin.moon b/alv/base/builtin.moon
index 558a65a..02f551c 100644
--- a/alv/base/builtin.moon
+++ b/alv/base/builtin.moon
@@ -19,7 +19,7 @@ class Builtin
-- @tparam Value head the (`AST:eval`d) `head` of the Cell to evaluate
new: (@cell, @head) =>
@tag = @cell.tag
- @tag\register @
+ @tag.builtin = @
--- perform the actual evaluation.
--
diff --git a/alv/invoke.moon b/alv/invoke.moon
index 56e6511..02479df 100644
--- a/alv/invoke.moon
+++ b/alv/invoke.moon
@@ -38,6 +38,8 @@ class op_invoke extends Builtin
def = @head\unwrap T.opdef, "cant op-invoke #{@head}"
@op = def!
+ @op.tag = @tag
+
--- `Builtin:destroy` implementation.
--
-- calls `op`:@{Op:destroy|destroy}.
diff --git a/alv/module.moon b/alv/module.moon
index ab98436..2fa24d9 100644
--- a/alv/module.moon
+++ b/alv/module.moon
@@ -42,6 +42,8 @@ class Module
@ast = Error.wrap "parsing '#{@name true}'", -> program\match @slurp!
assert @ast, Error 'syntax', "failed to parse"
+ @registry\scan_ast @ast
+
scope = Scope builtins!, parent_scope
@root = Error.wrap "evaluating '#{@name true}'", @ast\eval, scope, @registry
diff --git a/alv/registry.moon b/alv/registry.moon
index 0d37a5c..35f396d 100644
--- a/alv/registry.moon
+++ b/alv/registry.moon
@@ -11,27 +11,25 @@ class Registry
--
-- @tparam number|string index the registration index
-- @treturn any
- last: (index) => @last_map[index]
+ last: (index) => if tag = @last_map[index] then tag.builtin
--- set the current registration.
--
-- @tparam Tag tag the Tag to register
-- @tparam any expr the registration value
-- @tparam[default=false] boolean ignore_dup ignore duplicate registrations
- register: (tag, expr, ignore_dup=false) =>
+ register: (tag, ignore_dup=false) =>
index = tag\index!
- if index
- if not @map[index] or ignore_dup
- L\trace "reg: setting #{index} to #{expr}"
- @map[index] = expr
- else
+ if index and not @map[index] or ignore_dup
+ @map[index] = tag
+ else
+ if index
L\warn "duplicate tag [#{index}], reassigning repeated occurrence"
tag\set nil
- table.insert @pending, { :tag, :expr }
- else
- L\trace "reg: init #{tag} to #{expr}"
- table.insert @pending, { :tag, :expr }
+
+ table.insert @pending, tag
+ L\trace "reg: setting #{index} to #{expr}"
--- members
-- @section members
@@ -47,20 +45,24 @@ class Registry
--- abort an evaluation cycle.
rollback_eval: =>
assert @map, "no eval cycle to abort"
- for { :tag, :expr } in *@pending
- expr\destroy!
+ for tag in *@pending
+ if builtin = tag.builtin
+ builtin\destroy!
@map, @pending = nil, nil
- --- end an evaluation cycle.
- --
- -- Register all pending `Tag`s and destroy all orphaned registrations.
- -- @treturn bool whether any changes to the AST were made
- end_eval: =>
- for tag, val in pairs @last_map
- val\destroy!
+ scan_ast_node: (ast) =>
+ if ast.tag
+ @register ast.tag
- for { :tag, :expr } in *@pending
+ if ast.children
+ for child in *ast.children
+ @scan_ast_node child
+
+ scan_ast: (ast) =>
+ @scan_ast_node ast
+
+ for tag in *@pending
-- tag was solved by another pending registration
-- (e.g. first [A] is solved, then [5.A] is solved)
continue if tag\index!
@@ -68,7 +70,14 @@ class Registry
next_tag = #@map + 1
L\trace "assigned new tag #{next_tag} to #{tag} #{expr}"
tag\set next_tag
- @map[tag\index!] = expr
+
+ --- end an evaluation cycle.
+ --
+ -- Register all pending `Tag`s and destroy all orphaned registrations.
+ -- @treturn bool whether any changes to the AST were made
+ end_eval: =>
+ for index, tag in pairs @last_map
+ tag.builtin\destroy!
dirty = #@pending > 0
@last_map, @map, @pending = @map, nil, nil
@@ -79,8 +88,8 @@ class Registry
-- needs to be called *after* `:eval`.
destroy: =>
assert not @tag, "unfinished evaluation cycle"
- for tag, val in pairs @last_map
- val\destroy!
+ for index, tag in pairs @last_map
+ tag.builtin\destroy!
@last_map = {}
diff --git a/alv/result/const.moon b/alv/result/const.moon
index 43f97a0..fae47c4 100644
--- a/alv/result/const.moon
+++ b/alv/result/const.moon
@@ -53,6 +53,8 @@ class Constant extends Result
-- `Constant` implements the `AST` interface.
-- @section ast
+ register: =>
+
--- evaluate this literal constant.
--
-- Throws an error if `type` is not a literal (`num`, `str` or `sym`).
diff --git a/alv/tag.moon b/alv/tag.moon
index d46bf0a..ed59be6 100644
--- a/alv/tag.moon
+++ b/alv/tag.moon
@@ -11,13 +11,6 @@ import Registry from require 'alv.registry'
local ClonedTag
-class DummyReg
- destroy: =>
-
- __tostring: => "<dummy>"
-
-dummy = DummyReg!
-
class Tag
--- members
-- @section members
@@ -32,13 +25,6 @@ class Tag
if index = @index!
COPILOT.active_module.registry\last index
- --- register `expr` for this tag for the current eval cycle.
- --
- -- Will mark blank tags for auto-assignment at the end of the eval cycle.
- --
- -- @tparam any expr the value to register
- register: (expr) => COPILOT.active_module.registry\register @, expr
-
--- create a copy of this tag scoped to a `parent` tag.
--
-- Will mark blank tags for auto-assignment at the end of the eval cycle.
@@ -46,10 +32,6 @@ class Tag
-- @tparam Tag parent the parent tag
-- @treturn Tag the cloned tag
clone: (parent) =>
- -- ensure this tag is registered for the current eval cycle,
- -- even if it is blank and has no associated value
- COPILOT.active_module.registry\register @, dummy, true
-
assert parent, "need parent to clone!"
ClonedTag @, parent
diff --git a/spec/test_setup.moon b/spec/test_setup.moon
index 678cfb7..53d1451 100644
--- a/spec/test_setup.moon
+++ b/spec/test_setup.moon
@@ -90,5 +90,6 @@ class TestPilot extends Copilot
tail: -> tail
tag: Tag.blank!
+ COPILOT.active_module.registry\scan_ast fake_cell
op_invoke\eval_cell fake_cell, Scope!, Constant.wrap op
}