diff --git a/moonscript.lua b/moonscript.lua index f201165..de9ccd4 100644 --- a/moonscript.lua +++ b/moonscript.lua @@ -6,12 +6,21 @@ require"lpeg" require"moonscript.compile" +local function count_indent(str) + local sum = 0 + for v in str:gmatch("[\t ]") do + if v == ' ' then sum = sum + 1 end + if v == '\t' then sum = sum + 4 end + end + return sum +end + local R, S, V, P = lpeg.R, lpeg.S, lpeg.V, lpeg.P local C, Ct = lpeg.C, lpeg.Ct local Space = S" \t"^0 -local Indent = S"\t"^0 local Break = S"\n" + -1 +local Indent = C(S"\t "^0) / count_indent local ArgDelim = "," * Space local Name = C(R("az", "AZ", "__") * R("az", "AZ", "__")^0) * Space @@ -51,8 +60,20 @@ function flatten(tbl) return tbl end - local build_grammar = wrap(function() + local err_msg = "Failed to compile, line:\n [%d] >> %s" + local line = 1 + local function line_count(subject, pos, str) + for _ in str:gmatch("\n") do + line = line + 1 + end + -- print(line, util.dump(str)) + return true + end + + local Space = lpeg.Cmt(Space, line_count) + local Break = lpeg.Cmt(Break, line_count) + local g = lpeg.P{ Block, Block = Ct(Line^0), @@ -62,25 +83,42 @@ local build_grammar = wrap(function() Exp = Ct(Value * (FactorOp * Value)^0) / flatten, Value = Funcall + Num + Name } - return Space * g * Space * -1 + return { + _g = Space * g * Space * -1, + match = function(self, str, ...) + local function get_line(num) + for line in str:gmatch("(.-)[\n$]") do + if num == 1 then return line end + num = num - 1 + end + end + + local tree = self._g:match(str, ...) + if not tree then + return nil, err_msg:format(line, get_line(line)) + end + return tree + end + } + end) local grammar = build_grammar() local program = [[ -hello world nuts -eat 232, 343 +if gogo bozango + print hello_world ]] -- print hi + world + 2342 -- print 23424 -- ]] -local tree = grammar:match(program) -if not tree then error("failed to compile") end +local tree, err = grammar:match(program) +if not tree then error(err) end print(util.dump(tree)) -print(compile.tree(tree)) +-- print(compile.tree(tree)) local program2 = [[ if something