aboutsummaryrefslogtreecommitdiffstats
path: root/ast.moon
diff options
context:
space:
mode:
authors-ol <s-ol@users.noreply.github.com>2020-01-29 22:41:05 +0000
committers-ol <s-ol@users.noreply.github.com>2020-01-29 22:41:05 +0000
commit4031b59b19152bb3e9e2d323caa7faffb7557c82 (patch)
tree23bf32d4e45b810728dddda775b8ab71e1a08cbf /ast.moon
parentinitial commit (diff)
downloadalive-4031b59b19152bb3e9e2d323caa7faffb7557c82.tar.gz
alive-4031b59b19152bb3e9e2d323caa7faffb7557c82.zip
support tagging
Diffstat (limited to 'ast.moon')
-rw-r--r--ast.moon66
1 files changed, 66 insertions, 0 deletions
diff --git a/ast.moon b/ast.moon
new file mode 100644
index 0000000..39e2f21
--- /dev/null
+++ b/ast.moon
@@ -0,0 +1,66 @@
+class Atom
+ new: (@raw, @style='', @value) =>
+
+ _walk_sexpr: =>
+
+ stringify: =>
+ switch @style
+ when ''
+ @raw
+ when '"'
+ "\"#{@raw}\""
+ else
+ error!
+
+ @make_num: (match) -> Atom match, '', tonumber match
+ @make_sym: (match) -> Atom match, '', match
+ @make_str: (match) -> Atom match, '"', match
+
+class Xpr
+ new: (parts, @style='(', tag) =>
+ @white = {}
+ @white[0] = parts[1]
+
+ for i = 2,#parts,2
+ @[i/2] = parts[i]
+ @white[i/2] = parts[i+1]
+
+ if tag
+ @tag = tag.value
+
+ _walk_sexpr: =>
+ if @style == '('
+ coroutine.yield @
+
+ for frag in *@
+ frag\_walk_sexpr!
+
+ walk_sexpr: =>
+ coroutine.wrap -> @_walk_sexpr!
+
+ stringify: =>
+ buf = ''
+ buf ..= @white[0]
+ for i, frag in ipairs @
+ buf ..= frag\stringify!
+ buf ..= @white[i]
+
+ switch @style
+ when 'naked'
+ buf
+ else
+ tag = if @tag then "[#{@tag}]" else ''
+ '(' .. tag .. buf .. ')'
+
+ make_sexpr: (tag, parts) ->
+ if parts
+ Xpr parts, '(', tag
+ else
+ Xpr tag, '('
+
+ make_nexpr: (parts) -> Xpr parts, 'naked'
+
+{
+ :Atom
+ :Xpr
+}