From 133c9b058d9eed9631c4d788eb05efe29b892d4b Mon Sep 17 00:00:00 2001 From: leaf corcoran Date: Mon, 13 Jun 2011 08:23:09 -0700 Subject: [PATCH] binary assignment operator shorthand + misc --- moonscript/compile2.lua | 29 ++++++++++++++++++++++++++++- moonscript/compile2.moon | 27 ++++++++++++++++++++++++++- moonscript/parse.lua | 10 +++++++--- tests/inputs/syntax.moon | 8 ++++++++ tests/outputs/syntax.lua | 8 +++++++- 5 files changed, 76 insertions(+), 6 deletions(-) diff --git a/moonscript/compile2.lua b/moonscript/compile2.lua index 2ee2601..cc2dffd 100644 --- a/moonscript/compile2.lua +++ b/moonscript/compile2.lua @@ -61,6 +61,7 @@ local moonlib = { bind = function(tbl, name) return concat({ ")" }) end } local cascading = Set({ "if" }) +local non_atomic = Set({ "update" }) local has_value has_value = function(node) if ntype(node) == "chain" then @@ -70,6 +71,8 @@ has_value = function(node) return true end end +local is_non_atomic +is_non_atomic = function(node) return non_atomic[ntype(node)] end local line_compile = { assign = function(self, node) local _, names, values = unpack(node) @@ -145,7 +148,21 @@ local line_compile = { end end end, + update = function(self, node) + local _, name, op, exp = unpack(node) + local op_final = op:match("(.)=") + if not op_final then + _ = error("unknown op: ") .. op + end + return self:stm({ "assign", { name }, { { + "exp", + name, + op_final, + exp + } } }) + end, ["return"] = function(self, node) return self:add_line("return", self:value(node[2])) end, + ["break"] = function(self, node) return self:add_line("break") end, ["import"] = function(self, node) local _, names, source = unpack(node) local to_bind = { } @@ -237,8 +254,13 @@ local line_compile = { end, ["while"] = function(self, node) local _, cond, block = unpack(node) - self:add_line("while", self:value(cond), "do") local inner = self:block() + if is_non_atomic(cond) then + self:add_line("while", "true", "do") + inner:stm({ "if", { "not", cond }, { { "break" } } }) + else + self:add_line("while", self:value(cond), "do") + end inner:stms(block) self:add_line(inner:render()) return self:add_line("end") @@ -315,6 +337,11 @@ local value_compile = { return _moon_0 end)(), " ") end, + update = function(self, node) + local _, name = unpack(node) + self:stm(node) + return self:name(name) + end, explist = function(self, node) return concat((function() local _moon_0 = {} for i, v in ipairs(node) do diff --git a/moonscript/compile2.moon b/moonscript/compile2.moon index aba632a..ef73dcd 100644 --- a/moonscript/compile2.moon +++ b/moonscript/compile2.moon @@ -43,6 +43,9 @@ moonlib = cascading = Set{ "if" } +-- an action that can't be completed in a single line +non_atomic = Set{ "update" } + -- does this always return a value has_value = (node) -> if ntype(node) == "chain" @@ -51,6 +54,9 @@ has_value = (node) -> else true +is_non_atomic = (node) -> + non_atomic[ntype(node)] + line_compile = assign: (node) => _, names, values = unpack node @@ -89,9 +95,18 @@ line_compile = @add_line declare if #undeclared > 0 @add_line concat([@value n for n in *names], ", ").." = "..values + update: (node) => + _, name, op, exp = unpack node + op_final = op:match"(.)=" + error"unknown op: "..op if not op_final + @stm {"assign", {name}, {{"exp", name, op_final, exp}}} + ["return"]: (node) => @add_line "return", @value node[2] + ["break"]: (node) => + @add_line "break" + ["import"]: (node) => _, names, source = unpack node @@ -162,8 +177,13 @@ line_compile = ["while"]: (node) => _, cond, block = unpack node - @add_line "while", @value(cond), "do" inner = @block() + if is_non_atomic cond + @add_line "while", "true", "do" + inner:stm {"if", {"not", cond}, {{"break"}}} + else + @add_line "while", @value(cond), "do" + inner:stms block @add_line inner:render() @@ -231,6 +251,11 @@ value_compile = -- ugly concat [_comp i,v for i,v in ipairs node when i > 1], " " + update: (node) => + _, name = unpack node + @stm node + @name name + explist: (node) => concat [@value v for i,v in ipairs node when i > 1], ", " diff --git a/moonscript/parse.lua b/moonscript/parse.lua index ab1b446..6e9c2f0 100644 --- a/moonscript/parse.lua +++ b/moonscript/parse.lua @@ -227,7 +227,7 @@ local build_grammar = wrap(function() Block = Ct(Line * (Break^1 * Line)^0), Line = Cmt(Indent, check_indent) * Statement + _Space * Comment, - Statement = (Import + If + While + Ct(ExpList) / flatten_or_mark"explist" * Space) * ( + Statement = (Import + While + BreakLoop + Ct(ExpList) / flatten_or_mark"explist" * Space) * ( -- statement decorators key"if" * Exp * (key"else" * Exp)^-1 * Space / mark"if" + CompInner / mark"comprehension" @@ -244,6 +244,8 @@ local build_grammar = wrap(function() NameList = Name * (sym"," * Name)^0, + BreakLoop = Ct(key"break"/trim), + If = key"if" * Exp * key"then"^-1 * Body * ((Break * Cmt(Indent, check_indent))^-1 * key"elseif" * Exp * key"then"^-1 * Body / mark"elseif")^0 * ((Break * Cmt(Indent, check_indent))^-1 * key"else" * Body / mark"else")^-1 / mark"if", @@ -256,7 +258,8 @@ local build_grammar = wrap(function() CompFor = key"for" * Ct(NameList) * key"in" * (sym"*" * Exp / mark"unpack" + Exp) / mark"for", CompClause = CompFor + key"when" * Exp / mark"when", - Assign = Ct(AssignableList) * sym"=" * (Ct(TableBlock + ExpListLow) + If) / mark"assign", + Assign = Ct(AssignableList) * sym"=" * (If + Ct(TableBlock + ExpListLow)) / mark"assign", + Update = Assignable * ((sym"+=" + sym"-=" + sym"*=" + sym"/=" + sym"%=")/trim) * Exp / mark"update", -- we can ignore precedence for now OtherOps = op"or" + op"and" + op"<=" + op">=" + op"~=" + op"!=" + op"==" + op".." + op"<" + op">", @@ -271,6 +274,7 @@ local build_grammar = wrap(function() -- Term = Ct(Value * (TermOp * Value)^0) / flatten_or_mark"exp", Value = + If + sym"-" * Exp / mark"minus" + sym"#" * Exp / mark"length" + sym"not" * Exp / mark"not" + @@ -278,7 +282,7 @@ local build_grammar = wrap(function() Comprehension + ColonChain * Ct(ExpList^0) / flatten_func + -- have precedence over open table Ct(KeyValueList) / mark"table" + - Assign + FunLit + String + + Assign + Update + FunLit + String + ((Chain + Callable) * Ct(ExpList^0)) / flatten_func + Num, diff --git a/tests/inputs/syntax.moon b/tests/inputs/syntax.moon index 41d81f3..69210ad 100644 --- a/tests/inputs/syntax.moon +++ b/tests/inputs/syntax.moon @@ -139,3 +139,11 @@ something:hello what something.hello:world a,b something.hello:world(1,2,3) a,b +x = 1232 +x += 10 + 3 +j -= "hello" +y *= 2 +y /= 100 +m %= 2 + + diff --git a/tests/outputs/syntax.lua b/tests/outputs/syntax.lua index 895cc45..7ddffdf 100644 --- a/tests/outputs/syntax.lua +++ b/tests/outputs/syntax.lua @@ -94,4 +94,10 @@ _ = hello, world something:hello(what)(a, b) something:hello(what) something.hello:world(a, b) -something.hello:world(1, 2, 3)(a, b) \ No newline at end of file +something.hello:world(1, 2, 3)(a, b) +x = 1232 +x = x + 10 + 3 +local j = j - "hello" +y = y * 2 +y = y / 100 +local m = m % 2 \ No newline at end of file