diff options
| author | s-ol <s-ol@users.noreply.github.com> | 2020-01-29 22:41:05 +0000 |
|---|---|---|
| committer | s-ol <s-ol@users.noreply.github.com> | 2020-01-29 22:41:05 +0000 |
| commit | 4031b59b19152bb3e9e2d323caa7faffb7557c82 (patch) | |
| tree | 23bf32d4e45b810728dddda775b8ab71e1a08cbf /ast.moon | |
| parent | initial commit (diff) | |
| download | alive-4031b59b19152bb3e9e2d323caa7faffb7557c82.tar.gz alive-4031b59b19152bb3e9e2d323caa7faffb7557c82.zip | |
support tagging
Diffstat (limited to 'ast.moon')
| -rw-r--r-- | ast.moon | 66 |
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 +} |
