aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authors-ol <s-ol@users.noreply.github.com>2020-02-28 12:21:57 +0000
committers-ol <s-ol@users.noreply.github.com>2020-02-28 21:01:19 +0000
commitdf8141c3214a5fb8d447297be64bdf5619b7d8a7 (patch)
treef401303d36724c1055e25e0aaef9e0a27107c8a1 /core
parentlots of fixes (diff)
downloadalive-df8141c3214a5fb8d447297be64bdf5619b7d8a7.tar.gz
alive-df8141c3214a5fb8d447297be64bdf5619b7d8a7.zip
doc and tag spec
Diffstat (limited to 'core')
-rw-r--r--core/cell.moon42
-rw-r--r--core/parsing.moon8
-rw-r--r--core/registry.moon3
-rw-r--r--core/tag.moon36
4 files changed, 50 insertions, 39 deletions
diff --git a/core/cell.moon b/core/cell.moon
index 0cb8e9f..4b28a04 100644
--- a/core/cell.moon
+++ b/core/cell.moon
@@ -3,24 +3,9 @@ import Value from require 'core.value'
import op_invoke, fn_invoke from require 'core.invoke'
import Tag from require 'core.tag'
--- ALV Cell type
+-- An S-Expression with a head expression and any number of tail expressions,
+-- an optional tag, and optionally the internal whitespace as parsed.
class Cell
--- common
- -- tag: the parsed Tag
- -- children: sequence of child AST Nodes
- -- white: optional sequence of whitespace segments ([0 .. #@children])
- new: (@tag=Tag.blank!, @children, @white) =>
- if not @white
- @white = ['' for i=1,#@children]
- @white[0] = ''
-
- assert #@white == #@children, "mismatched whitespace length"
-
- head: => @children[1]
- tail: => [c for c in *@children[2,]]
-
- destroy: =>
-
-- AST interface
eval: (scope) =>
head = (@head!\eval scope)\const!
@@ -42,12 +27,15 @@ class Cell
Action\eval_cell scope, @tag, head, @tail!
+ -- quoting a Cell recursively quotes children, but preserves identity this
+ -- means that a quoted Cell may only be 'used' once. use :clone() otherwise.
quote: (scope) =>
children = [child\quote scope for child in *@children]
Cell @tag, children, @white
+ -- creates a clone of this Cell with its own identity by prepending a `parent`
+ -- tag and cloning all child expressoins recursively.
clone: (parent) =>
- @tag\ensure!
tag = @tag\clone parent
children = [child\clone parent for child in *@children]
Cell tag, children, @white
@@ -67,6 +55,20 @@ class Cell
'(' .. @tag\stringify! .. buf .. ')'
+-- internal
+ -- tag: the parsed Tag
+ -- children: sequence of child AST Nodes
+ -- white: optional sequence of whitespace segments ([0 .. #@children])
+ new: (@tag=Tag.blank!, @children, @white) =>
+ if not @white
+ @white = [' ' for i=1,#@children]
+ @white[0] = ''
+
+ assert #@white == #@children, "mismatched whitespace length"
+
+ head: => @children[1]
+ tail: => [c for c in *@children[2,]]
+
-- static
__tostring: => @stringify 2
@@ -85,9 +87,9 @@ class Cell
tag, children, white = parse_args ...
@ tag, children, white
--- A parenthesis-less Cell (root of an ALV document)
+-- A parenthesis-less Cell (root of an ALV document).
--
--- evaluates with an implicit 'do' in the head
+-- has an implicit head of 'do'.
class RootCell extends Cell
head: => Value.sym 'do'
tail: => @children
diff --git a/core/parsing.moon b/core/parsing.moon
index 0123469..ac4f878 100644
--- a/core/parsing.moon
+++ b/core/parsing.moon
@@ -44,13 +44,7 @@ cell = P {
:expr, :explist, :cell
}
-parse_error = (root, rest) ->
- if #rest > 0
- error "failed to parse, rest is:\n#{rest}"
-
- root
-
-program = root * (C (P 1)^0) * -1 / parse_error
+program = root * -1
{
:comment
diff --git a/core/registry.moon b/core/registry.moon
index e8272fa..2ac5825 100644
--- a/core/registry.moon
+++ b/core/registry.moon
@@ -73,9 +73,6 @@ class SimpleRegistry extends Registry
last: (index) =>
replace: (index, expr) =>
- finalize: =>
- assert @ == @@active_registry, "not the active registry!"
- @@active_registry, @prev = @prev, nil
{
:Registry
diff --git a/core/tag.moon b/core/tag.moon
index 122c67e..f38d36a 100644
--- a/core/tag.moon
+++ b/core/tag.moon
@@ -10,43 +10,59 @@ class DummyReg
dummy = DummyReg!
class Tag
- new: (@value) =>
-
- clone: (parent) => ClonedTag @, parent
-
+ -- obtain the value that was previously registered (using keep or replace) for
+ -- this tag
last: =>
if index = @index!
Registry.active!\last index
+ -- assert that `expr` is the value that was previously registered for this
+ -- tag, and keep it for the current eval cycle.
+ -- fails for blank tags.
keep: (expr) =>
index = assert @index!
assert expr == Registry.active!\last index
Registry.active!\replace index, expr
+ -- register `expr` for this tag for the current eval cycle.
+ -- registers blank tags.
replace: (expr) =>
if index = @index!
Registry.active!\replace index, expr
else
Registry.active!\init @, expr
- ensure: =>
+ -- create a copy of this tag scoped to a `parent` tag.
+ -- registers blank tags.
+ clone: (parent) =>
+ -- ensure this tag is registered for the current eval cycle,
+ -- even if it is blank and has no associated value
if index = @index!
Registry.active!\replace index, dummy, true
else
Registry.active!\init @, dummy
+ assert parent, "need parent to clone!"
+ ClonedTag @, parent
+
+-- internal
+ new: (@value) =>
+
index: => @value
+ -- callback from `Registry` when the eval cycle is ending and a tag value has
+ -- been generated
set: (value) =>
- assert not @value, "setting #{@} again"
+ assert not @value, "#{@} is not blank"
@value = value
+-- static
+
@blank: -> Tag!
@parse: (num) => @ tonumber num
stringify: => if @value then "[#{@value}]" else ''
-
- __tostring: => if @value then "#{@value}" else '[blank]'
+ __tostring: => if @value then "#{@value}" else '?'
class ClonedTag extends Tag
new: (@original, @parent) =>
@@ -57,7 +73,9 @@ class ClonedTag extends Tag
if orig and parent
"#{parent}.#{orig}"
- set: (value) => @original\set value
+ set: (value) =>
+ assert @parent.value, "cloned tag #{@} set before parent"
+ @original\set value
stringify: => error "cant stringify ClonedTag"