diff --git a/moonscript/transform.lua b/moonscript/transform.lua index edb2bcb..67d0b49 100644 --- a/moonscript/transform.lua +++ b/moonscript/transform.lua @@ -10,6 +10,9 @@ do NameProxy, LocalName = _table_0.NameProxy, _table_0.LocalName end local destructure = require("moonscript.transform.destructure") +local NOOP = { + "noop" +} local implicitly_return local Run do @@ -683,28 +686,38 @@ local Statement = Transformer({ return node end, with = function(self, node, ret) - local _, exp, block = unpack(node) - local scope_name = NameProxy("with") - local named_assign + local exp, block = unpack(node, 2) + local copy_scope = true + local scope_name, 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 - } + local first_name = names[1] + if ntype(first_name) == "value" then + scope_name = first_name + named_assign = exp + exp = values[1] + copy_scope = false + else + scope_name = NameProxy("with") + exp = values[1] + values[1] = scope_name + named_assign = { + "assign", + names, + values + } + end + elseif self:is_local(exp) then + scope_name = exp + copy_scope = false end + scope_name = scope_name or NameProxy("with") return build["do"]({ Run(function(self) return self:set("scope_var", scope_name) end), - build.assign_one(scope_name, exp), - build.group({ - named_assign - }), + copy_scope and build.assign_one(scope_name, exp) or NOOP, + named_assign or NOOP, build.group(block), (function() if ret then @@ -1363,9 +1376,7 @@ implicitly_return = function(scope) return scope.transform.statement(stm, fn) elseif types.manual_return[t] or not types.is_value(stm) then if is_top and t == "return" and stm[2] == "" then - return { - "noop" - } + return NOOP else return stm end diff --git a/moonscript/transform.moon b/moonscript/transform.moon index 1544adc..49b896a 100644 --- a/moonscript/transform.moon +++ b/moonscript/transform.moon @@ -9,6 +9,7 @@ import insert from table import NameProxy, LocalName from require "moonscript.transform.names" destructure = require "moonscript.transform.destructure" +NOOP = {"noop"} local implicitly_return @@ -339,21 +340,36 @@ Statement = Transformer { node with: (node, ret) => - _, exp, block = unpack node + exp, block = unpack node, 2 - scope_name = NameProxy "with" + copy_scope = true + local scope_name, named_assign - named_assign = if ntype(exp) == "assign" + if ntype(exp) == "assign" names, values = unpack exp, 2 - assign_name = names[1] - exp = values[1] - values[1] = scope_name - {"assign", names, values} + first_name = names[1] + + if ntype(first_name) == "value" + scope_name = first_name + named_assign = exp + exp = values[1] + copy_scope = false + else + scope_name = NameProxy "with" + exp = values[1] + values[1] = scope_name + named_assign = {"assign", names, values} + + elseif @is_local exp + scope_name = exp + copy_scope = false + + scope_name or= NameProxy "with" build.do { Run => @set "scope_var", scope_name - build.assign_one scope_name, exp - build.group { named_assign } + copy_scope and build.assign_one(scope_name, exp) or NOOP + named_assign or NOOP build.group block if ret @@ -747,7 +763,7 @@ implicitly_return = (scope) -> elseif types.manual_return[t] or not types.is_value stm -- remove blank return statement if is_top and t == "return" and stm[2] == "" - {"noop"} + NOOP else stm else diff --git a/spec/inputs/with.moon b/spec/inputs/with.moon index 2f0bcaf..54aa509 100644 --- a/spec/inputs/with.moon +++ b/spec/inputs/with.moon @@ -1,63 +1,97 @@ -a = -> - with something - print .hello - print hi - print "world" +do + a = -> + with something + print .hello + print hi + print "world" -with leaf - .world! - .world 1,2,3 +do + with leaf + .world! + .world 1,2,3 - g = .what.is.this + g = .what.is.this - .hi 1,2,3 + .hi 1,2,3 - \hi(1,2).world 2323 + \hi(1,2).world 2323 - \hi "yeah", "man" - .world = 200 + \hi "yeah", "man" + .world = 200 -zyzyzy = with something - .set_state "hello world" +do + zyzyzy = with something + .set_state "hello world" + +do + x = 5 + with Something! + \write "hello world" -x = 5 + with Something! - \write "hello world" +do + x = { + hello: with yeah + \okay! + } - -x = { - hello: with yeah - \okay! -} - -with foo - \prop"something".hello - .prop\send(one) - .prop\send one +do + with foo + \prop"something".hello + .prop\send(one) + .prop\send one -- -with a, b -- b is lost - print .world +do + with a, b -- b is lost + print .world -mod = with _M = {} - .Thing = "hi" + mod = with _M = {} + .Thing = "hi" --- operate on a only -with a, b = something, pooh - print .world + -- operate on a only + with a, b = something, pooh + print .world -x = with a, b = 1, 2 - print a + b + x = with a, b = 1, 2 + print a + b -print 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 + -- assignment lhs must be evaluated in the order they appear + p = with hello!.x, world!.y = 1, 2 + print a + b + +-- + +do + x = "hello" + with x + x\upper! + +do + with k = "jo" + print \upper! + +do + with a,b,c = "", "", "" + print \upper! + +do + a = "bunk" + with a,b,c = "", "", "" + print \upper! + +do + with j + print \upper! + +do + with k.j = "jo" + print \upper! diff --git a/spec/outputs/export.lua b/spec/outputs/export.lua index 44ac1e8..20b7531 100644 --- a/spec/outputs/export.lua +++ b/spec/outputs/export.lua @@ -76,7 +76,6 @@ do local hallo = 3434 end do - local _with_0 = tmp local j = 2000 end end diff --git a/spec/outputs/with.lua b/spec/outputs/with.lua index 469e434..d1d104a 100644 --- a/spec/outputs/with.lua +++ b/spec/outputs/with.lua @@ -1,88 +1,136 @@ -local a -a = function() +do + local a + a = function() + do + local _with_0 = something + print(_with_0.hello) + print(hi) + print("world") + return _with_0 + end + end +end +do + do + local _with_0 = leaf + _with_0.world() + _with_0.world(1, 2, 3) + local g = _with_0.what.is.this + _with_0.hi(1, 2, 3) + _with_0:hi(1, 2).world(2323) + _with_0:hi("yeah", "man") + _with_0.world = 200 + end +end +do + local zyzyzy do local _with_0 = something - print(_with_0.hello) - print(hi) - print("world") - return _with_0 + _with_0.set_state("hello world") + zyzyzy = _with_0 end end do - local _with_0 = leaf - _with_0.world() - _with_0.world(1, 2, 3) - local g = _with_0.what.is.this - _with_0.hi(1, 2, 3) - _with_0:hi(1, 2).world(2323) - _with_0:hi("yeah", "man") - _with_0.world = 200 -end -local zyzyzy -do - local _with_0 = something - _with_0.set_state("hello world") - zyzyzy = _with_0 -end -local x = 5 + (function() - do - local _with_0 = Something() - _with_0:write("hello world") - return _with_0 - end -end)() -x = { - hello = (function() + local x = 5 + (function() do - local _with_0 = yeah - _with_0:okay() + local _with_0 = Something() + _with_0:write("hello world") return _with_0 end end)() -} -do - local _with_0 = foo - local _ = _with_0:prop("something").hello - _with_0.prop:send(one) - _with_0.prop:send(one) 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 + local x = { + hello = (function() + do + local _with_0 = yeah + _with_0:okay() + return _with_0 + end + end)() + } end do - local _with_0 = something - local b - a, b = _with_0, pooh - print(_with_0.world) + do + local _with_0 = foo + local _ = _with_0:prop("something").hello + _with_0.prop:send(one) + _with_0.prop:send(one) + end 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 = a, b + print(_with_0.world) + end + local mod + do + local _M = { } + _M.Thing = "hi" + mod = _M + end + do + local a, b = something, pooh + print(a.world) + end + local x + do + local a, b = 1, 2 + print(a + b) + x = a + end + print((function() + do + local a, b = 1, 2 + print(a + b) + return a + end + end)()) + local p do local _with_0 = 1 - local b - a, b = _with_0, 2 + hello().x, world().y = _with_0, 2 print(a + b) + p = _with_0 + end +end +do + local x = "hello" + do + x:upper() + end +end +do + do + local k = "jo" + print(k:upper()) + end +end +do + do + local a, b, c = "", "", "" + print(a:upper()) + end +end +do + local a = "bunk" + do + local b, c + a, b, c = "", "", "" + print(a:upper()) + end +end +do + do + local _with_0 = j + print(_with_0:upper()) + end +end +do + do + local _with_0 = "jo" + k.j = _with_0 + print(_with_0:upper()) 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