diff --git a/moonscript/transform.lua b/moonscript/transform.lua index 5bb4ec4..47444e8 100644 --- a/moonscript/transform.lua +++ b/moonscript/transform.lua @@ -602,15 +602,32 @@ local Statement = Transformer({ ["if"] = function(self, node, ret) if ntype(node[2]) == "assign" then local _, assign, body = unpack(node) - local name = assign[2][1] - return build["do"]({ - assign, - { - "if", - name, - unpack(node, 3) + if destructure.has_destructure(assign[2]) then + local name = NameProxy("des") + body = { + destructure.build_assign(assign[2][1], name), + build.group(node[3]) } - }) + return build["do"]({ + build.assign_one(name, assign[3][1]), + { + "if", + name, + body, + unpack(node, 4) + } + }) + else + local name = assign[2][1] + return build["do"]({ + assign, + { + "if", + name, + unpack(node, 3) + } + }) + end end node = expand_elseif_assign(node) if ret then @@ -668,8 +685,7 @@ local Statement = Transformer({ do local _with_0 = NameProxy("des") local proxy = _with_0 - local extracted = destructure.extract_assign_names(name) - insert(destructures, destructure.build_assign(extracted, proxy)) + insert(destructures, destructure.build_assign(name, proxy)) _value_0 = _with_0 end else diff --git a/moonscript/transform.moon b/moonscript/transform.moon index 8f5dad3..067845e 100644 --- a/moonscript/transform.moon +++ b/moonscript/transform.moon @@ -291,11 +291,24 @@ Statement = Transformer { -- expand assign in cond if ntype(node[2]) == "assign" _, assign, body = unpack node - name = assign[2][1] - return build["do"] { - assign - {"if", name, unpack node, 3} - } + if destructure.has_destructure assign[2] + name = NameProxy "des" + + body = { + destructure.build_assign assign[2][1], name + build.group node[3] + } + + return build.do { + build.assign_one name, assign[3][1] + {"if", name, body, unpack node, 4} + } + else + name = assign[2][1] + return build["do"] { + assign + {"if", name, unpack node, 3} + } node = expand_elseif_assign node @@ -341,8 +354,7 @@ Statement = Transformer { node.names = for i, name in ipairs node.names if ntype(name) == "table" with proxy = NameProxy "des" - extracted = destructure.extract_assign_names name - insert destructures, destructure.build_assign extracted, proxy + insert destructures, destructure.build_assign name, proxy else name diff --git a/moonscript/transform/destructure.lua b/moonscript/transform/destructure.lua index 903bbca..ca9fdac 100644 --- a/moonscript/transform/destructure.lua +++ b/moonscript/transform/destructure.lua @@ -46,47 +46,6 @@ has_destructure = function(names) end return false end -local build_assign -build_assign = function(extracted_names, receiver) - local names = { } - local values = { } - local inner = { - "assign", - names, - values - } - local obj - if mtype(receiver) == NameProxy then - obj = receiver - else - do - local _with_0 = NameProxy("obj") - obj = _with_0 - inner = build["do"]({ - build.assign_one(obj, receiver), - { - "assign", - names, - values - } - }) - obj = _with_0 - end - end - local _list_0 = extracted_names - for _index_0 = 1, #_list_0 do - local tuple = _list_0[_index_0] - insert(names, tuple[1]) - insert(values, obj:chain(unpack(tuple[2]))) - end - return build.group({ - { - "declare", - names - }, - inner - }) -end local extract_assign_names extract_assign_names = function(name, accum, prefix) if accum == nil then @@ -143,6 +102,48 @@ extract_assign_names = function(name, accum, prefix) end return accum end +local build_assign +build_assign = function(destruct_literal, receiver) + local extracted_names = extract_assign_names(destruct_literal) + local names = { } + local values = { } + local inner = { + "assign", + names, + values + } + local obj + if mtype(receiver) == NameProxy then + obj = receiver + else + do + local _with_0 = NameProxy("obj") + obj = _with_0 + inner = build["do"]({ + build.assign_one(obj, receiver), + { + "assign", + names, + values + } + }) + obj = _with_0 + end + end + local _list_0 = extracted_names + for _index_0 = 1, #_list_0 do + local tuple = _list_0[_index_0] + insert(names, tuple[1]) + insert(values, obj:chain(unpack(tuple[2]))) + end + return build.group({ + { + "declare", + names + }, + inner + }) +end local split_assign split_assign = function(assign) local names, values = unpack(assign, 2) @@ -182,8 +183,7 @@ split_assign = function(assign) end)() }) end - local extracted = extract_assign_names(n) - insert(g, build_assign(extracted, values[i])) + insert(g, build_assign(n, values[i])) start = i + 1 end end @@ -237,6 +237,5 @@ end return { has_destructure = has_destructure, split_assign = split_assign, - extract_assign_names = extract_assign_names, build_assign = build_assign } diff --git a/moonscript/transform/destructure.moon b/moonscript/transform/destructure.moon index c39bea7..7d73f4d 100644 --- a/moonscript/transform/destructure.moon +++ b/moonscript/transform/destructure.moon @@ -18,30 +18,6 @@ has_destructure = (names) -> return true if ntype(n) == "table" false -build_assign = (extracted_names, receiver) -> - names = {} - values = {} - - inner = {"assign", names, values} - - obj = if mtype(receiver) == NameProxy - receiver - else - with obj = NameProxy "obj" - inner = build.do { - build.assign_one obj, receiver - {"assign", names, values} - } - - for tuple in *extracted_names - insert names, tuple[1] - insert values, obj\chain unpack tuple[2] - - build.group { - {"declare", names} - inner - } - extract_assign_names = (name, accum={}, prefix={}) -> i = 1 for tuple in *name[2] @@ -70,6 +46,32 @@ extract_assign_names = (name, accum={}, prefix={}) -> accum +build_assign = (destruct_literal, receiver) -> + extracted_names = extract_assign_names destruct_literal + + names = {} + values = {} + + inner = {"assign", names, values} + + obj = if mtype(receiver) == NameProxy + receiver + else + with obj = NameProxy "obj" + inner = build.do { + build.assign_one obj, receiver + {"assign", names, values} + } + + for tuple in *extracted_names + insert names, tuple[1] + insert values, obj\chain unpack tuple[2] + + build.group { + {"declare", names} + inner + } + -- applies to destructuring to a assign node split_assign = (assign) -> names, values = unpack assign, 2 @@ -93,8 +95,7 @@ split_assign = (assign) -> values[i] } - extracted = extract_assign_names n - insert g, build_assign extracted, values[i] + insert g, build_assign n, values[i] start = i + 1 @@ -113,4 +114,4 @@ split_assign = (assign) -> build.group g -{ :has_destructure, :split_assign, :extract_assign_names, :build_assign } +{ :has_destructure, :split_assign, :build_assign } diff --git a/tests/inputs/destructure.moon b/tests/inputs/destructure.moon index 561f229..e011834 100644 --- a/tests/inputs/destructure.moon +++ b/tests/inputs/destructure.moon @@ -51,3 +51,28 @@ for {x,y} in *thing print x,y +-- + +with {a,b} = thing + print a, b + + +-- + +thing = nil +if {a} = thing + print a +else + print "nothing" + +thang = {1,2} +if {a,b} = thang + print a,b + +if {a,b} = thing + print a,b +elseif {c,d} = thang + print c,d +else + print "NO" + diff --git a/tests/outputs/destructure.lua b/tests/outputs/destructure.lua index bb99e75..b2da4c3 100644 --- a/tests/outputs/destructure.lua +++ b/tests/outputs/destructure.lua @@ -101,4 +101,47 @@ for _index_0 = 1, #_list_0 do local _des_0 = _list_0[_index_0] x, y = _des_0[1], _des_0[2] print(x, y) +end +do + local _with_0 = thing + a, b = _with_0[1], _with_0[2] + print(a, b) +end +thing = nil +do + local _des_0 = thing + if _des_0 then + a = _des_0[1] + print(a) + else + print("nothing") + end +end +local thang = { + 1, + 2 +} +do + local _des_0 = thang + if _des_0 then + a, b = _des_0[1], _des_0[2] + print(a, b) + end +end +do + local _des_0 = thing + if _des_0 then + a, b = _des_0[1], _des_0[2] + print(a, b) + else + do + local _des_1 = thang + if _des_1 then + c, d = _des_1[1], _des_1[2] + print(c, d) + else + return print("NO") + end + end + end end \ No newline at end of file diff --git a/todo b/todo index 07952e3..ae5ecb9 100644 --- a/todo +++ b/todo @@ -1,4 +1,9 @@ # TODO +# +# +# + +-- local * and local ^ -- seems like running in moon messes up require order @@ -8,19 +13,14 @@ - or= and= -- a do block for making a quick anon func and calling it - - error with stray comma at end of line -- ugly error if attempting to assign to rvalue like #hello - -- class expressions, x = class extends Hello do new: => print "hello" * multiline comments * table slices (almost) * combine for and if line decorators -* export later? +* export later? nah x = 232 export x