diff options
Diffstat (limited to 'parsing.moon')
| -rw-r--r-- | parsing.moon | 52 |
1 files changed, 7 insertions, 45 deletions
diff --git a/parsing.moon b/parsing.moon index f9efef4..d4fba0b 100644 --- a/parsing.moon +++ b/parsing.moon @@ -1,47 +1,7 @@ lpeg = require 'lpeg' +import Atom, Xpr from require 'ast' -class Atom - new: (@raw, @style='', @value) => - - 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='(') => - @white = {} - @white[0] = parts[1] - - for i = 2,#parts,2 - @[i/2] = parts[i] - @white[i/2] = parts[i+1] - - stringify: => - buf = '' - buf ..= @white[0] - for i, frag in ipairs @ - buf ..= frag\stringify! - buf ..= @white[i] - - switch @style - when 'naked' - buf - else - '(' .. buf .. ')' - - make_sexpr: (parts) -> Xpr parts, '(' - make_nexpr: (parts) -> Xpr parts, 'naked' - -space = (lpeg.S ' \t\r\n') ^ 1 / 1 +space = (lpeg.S ' \t\r\n') ^ 1 / 1 mspace = (lpeg.S ' \t\r\n') ^ 0 / 1 sym = ((lpeg.R 'az', 'AZ') + (lpeg.S '-_+*')) ^ 1 / Atom.make_sym @@ -50,8 +10,10 @@ num = (lpeg.R '09', 'AZ') ^ 1 / Atom.make_num atom = sym + num + str expr = (lpeg.V 'sexpr') + atom -explist = lpeg.Ct mspace * (lpeg.V 'expr') * (space * atom) ^ 0 * mspace -sexpr = (lpeg.P '(') * (lpeg.V 'explist') * (lpeg.P ')') / Xpr.make_sexpr +explist = lpeg.Ct mspace * (lpeg.V 'expr') * (space * (lpeg.V 'expr')) ^ 0 * mspace + +tag = (lpeg.P '[') * num * (lpeg.P ']') +sexpr = (lpeg.P '(') * tag^-1 * (lpeg.V 'explist') * (lpeg.P ')') / Xpr.make_sexpr nexpr = lpeg.P { (lpeg.V 'explist') / Xpr.make_nexpr @@ -63,7 +25,7 @@ sexpr = lpeg.P { :expr, :explist, :sexpr } -program = nexpr +program = nexpr * -1 { :space |
