diff --git a/moonscript/parse.lua b/moonscript/parse.lua index 7f86ab7..db9a32c 100644 --- a/moonscript/parse.lua +++ b/moonscript/parse.lua @@ -205,7 +205,7 @@ end -- the if statement only takes a single lhs, so we wrap in table to git to -- "assign" tuple format -local function format_assign_for_if(lhs, assign) +local function format_single_assign(lhs, assign) if assign then return format_assign({lhs}, assign) end @@ -413,7 +413,8 @@ local build_grammar = wrap_env(function() Return = key"return" * (ExpListLow/mark"explist" + C"") / mark"return", - With = key"with" * DisableDo * ensure(Exp, PopDo) * key"do"^-1 * Body / mark"with", + WithExp = Ct(ExpList) * Assign^-1 / format_assign, + With = key"with" * DisableDo * ensure(WithExp, PopDo) * key"do"^-1 * Body / mark"with", Switch = key"switch" * DisableDo * ensure(Exp, PopDo) * key"do"^-1 * Space^-1 * Break * SwitchBlock / mark"switch", @@ -421,7 +422,7 @@ local build_grammar = wrap_env(function() SwitchCase = key"when" * Exp * key"then"^-1 * Body / mark"case", SwitchElse = key"else" * Body / mark"else", - IfCond = Exp * Assign^-1 / format_assign_for_if, + IfCond = Exp * Assign^-1 / format_single_assign, If = key"if" * IfCond * key"then"^-1 * Body * ((Break * CheckIndent)^-1 * EmptyLine^0 * key"elseif" * pos(IfCond) * key"then"^-1 * Body / mark"elseif")^0 * diff --git a/moonscript/transform.lua b/moonscript/transform.lua index 4cab639..3066581 100644 --- a/moonscript/transform.lua +++ b/moonscript/transform.lua @@ -746,11 +746,26 @@ Statement = Transformer({ with = function(self, node, ret) local _, exp, block = unpack(node) local scope_name = NameProxy("with") + local named_assign + if ntype(exp) == "assign" then + local names, values = unpack(exp, 2) + local assign_name = names[1] + exp = values[1] + values[1] = scope_name + named_assign = { + "assign", + names, + values + } + end return build["do"]({ - build.assign_one(scope_name, exp), Run(function(self) return self:set("scope_var", scope_name) end), + build.assign_one(scope_name, exp), + build.group({ + named_assign + }), build.group(block), (function() if ret then diff --git a/moonscript/transform.moon b/moonscript/transform.moon index 374f4e2..791143f 100644 --- a/moonscript/transform.moon +++ b/moonscript/transform.moon @@ -347,11 +347,22 @@ Statement = Transformer { with: (node, ret) => _, exp, block = unpack node + scope_name = NameProxy "with" - build["do"] { - build.assign_one scope_name, exp + + named_assign = if ntype(exp) == "assign" + names, values = unpack exp, 2 + assign_name = names[1] + exp = values[1] + values[1] = scope_name + {"assign", names, values} + + build.do { Run => @set "scope_var", scope_name + build.assign_one scope_name, exp + build.group { named_assign } build.group block + if ret ret scope_name } diff --git a/tests/inputs/with.moon b/tests/inputs/with.moon index e9b35ac..2f0bcaf 100644 --- a/tests/inputs/with.moon +++ b/tests/inputs/with.moon @@ -36,3 +36,29 @@ with foo .prop\send(one) .prop\send one + +-- + +with a, b -- b is lost + print .world + +mod = with _M = {} + .Thing = "hi" + +-- operate on a only +with a, b = something, pooh + print .world + +x = with a, b = 1, 2 + print a + b + +print with a, b = 1, 2 + print a + b + +-- assignment lhs must be evaluated in the order they appear +p = with hello!.x, world!.y = 1, 2 + print a + b + + + + diff --git a/tests/outputs/with.lua b/tests/outputs/with.lua index 7d9ee76..469e434 100644 --- a/tests/outputs/with.lua +++ b/tests/outputs/with.lua @@ -45,5 +45,44 @@ do local _ = _with_0:prop("something").hello _with_0.prop:send(one) _with_0.prop:send(one) - return _with_0 +end +do + local _with_0 = a, b + print(_with_0.world) +end +local mod +do + local _with_0 = { } + local _M = _with_0 + _with_0.Thing = "hi" + mod = _with_0 +end +do + local _with_0 = something + local b + a, b = _with_0, pooh + print(_with_0.world) +end +do + local _with_0 = 1 + local b + a, b = _with_0, 2 + print(a + b) + x = _with_0 +end +print((function() + do + local _with_0 = 1 + local b + a, b = _with_0, 2 + print(a + b) + return _with_0 + end +end)()) +local p +do + local _with_0 = 1 + hello().x, world().y = _with_0, 2 + print(a + b) + p = _with_0 end \ No newline at end of file