binary assignment operator shorthand + misc

This commit is contained in:
leaf corcoran 2011-06-13 08:23:09 -07:00
parent f5c5e9fde3
commit 133c9b058d
5 changed files with 76 additions and 6 deletions

View File

@ -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

View File

@ -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], ", "

View File

@ -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,

View File

@ -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

View File

@ -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)
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