From f8c2e0b3abe0583e7b569c8c3c2cd432e192ef2d Mon Sep 17 00:00:00 2001 From: leaf corcoran Date: Mon, 10 Jun 2013 19:57:01 -0700 Subject: [PATCH] avoid creating function for basic list comprehension assign --- moonscript/transform.lua | 51 +++++---- moonscript/transform.moon | 33 ++++-- spec/outputs/bubbling.lua | 89 +++++++-------- spec/outputs/comprehension.lua | 110 ++++++++----------- spec/outputs/lists.lua | 192 +++++++++++++++------------------ 5 files changed, 223 insertions(+), 252 deletions(-) diff --git a/moonscript/transform.lua b/moonscript/transform.lua index ae57a2d..00d89fe 100644 --- a/moonscript/transform.lua +++ b/moonscript/transform.lua @@ -13,8 +13,7 @@ local destructure = require("moonscript.transform.destructure") local NOOP = { "noop" } -local implicitly_return -local Run +local Run, apply_to_last, is_singular, extract_declarations, expand_elseif_assign, constructor_name, with_continue_listener, Transformer, construct_comprehension, Statement, Accumulator, default_accumulator, implicitly_return, Value do local _parent_0 = nil local _base_0 = { @@ -55,7 +54,6 @@ do end Run = _class_0 end -local apply_to_last apply_to_last = function(stms, fn) local last_exp_id = 0 for i = #stms, 1, -1 do @@ -83,7 +81,6 @@ apply_to_last = function(stms, fn) return _accum_0 end)() end -local is_singular is_singular = function(body) if #body ~= 1 then return false @@ -94,7 +91,6 @@ is_singular = function(body) return body[1] end end -local extract_declarations extract_declarations = function(self, body, start, out) if body == nil then body = self.current_stms @@ -135,7 +131,6 @@ extract_declarations = function(self, body, start, out) end return out end -local expand_elseif_assign expand_elseif_assign = function(ifstm) for i = 4, #ifstm do local case = ifstm[i] @@ -159,8 +154,7 @@ expand_elseif_assign = function(ifstm) end return ifstm end -local constructor_name = "new" -local with_continue_listener +constructor_name = "new" with_continue_listener = function(body) local continue_name = nil return { @@ -223,7 +217,6 @@ with_continue_listener = function(body) end) } end -local Transformer do local _parent_0 = nil local _base_0 = { @@ -294,7 +287,6 @@ do end Transformer = _class_0 end -local construct_comprehension construct_comprehension = function(inner, clauses) local current_stms = inner for _, clause in reversed(clauses) do @@ -337,7 +329,7 @@ construct_comprehension = function(inner, clauses) end return current_stms[1] end -local Statement = Transformer({ +Statement = Transformer({ transform = function(self, tuple) local _, node, fn _, node, fn = tuple[1], tuple[2], tuple[3] @@ -379,8 +371,24 @@ local Statement = Transformer({ end, assign = function(self, node) local names, values = unpack(node, 2) + local num_values = #values + local num_names = #values + if num_names == 1 and num_values == 1 then + local first_value = values[1] + local _exp_0 = ntype(first_value) + if "comprehension" == _exp_0 then + local first_name = names[1] + local a = Accumulator(first_name) + node = self.transform.statement(first_value, function(exp) + return a:mutate_body({ + exp + }) + end) + return a:wrap(node, "group") + end + end local transformed - if #values == 1 then + if num_values == 1 then local value = values[1] local t = ntype(value) if t == "decorated" then @@ -1254,7 +1262,6 @@ local Statement = Transformer({ return value end }) -local Accumulator do local _parent_0 = nil local _base_0 = { @@ -1268,12 +1275,15 @@ do node[index] = self:mutate_body(node[index]) return self:wrap(node) end, - wrap = function(self, node) - return build.block_exp({ + wrap = function(self, node, group_type) + if group_type == nil then + group_type = "block_exp" + end + return build[group_type]({ build.assign_one(self.accum_name, build.table()), build.assign_one(self.len_name, 1), node, - self.accum_name + group_type == "block_exp" and self.accum_name or NOOP }) end, mutate_body = function(self, body) @@ -1301,7 +1311,7 @@ do val = self.value_name end local update = { - build.assign_one(self.accum_name:index(self.len_name), val), + build.assign_one(NameProxy.index(self.accum_name, self.len_name), val), { "update", self.len_name, @@ -1318,8 +1328,8 @@ do setmetatable(_base_0, _parent_0.__base) end local _class_0 = setmetatable({ - __init = function(self) - self.accum_name = NameProxy("accum") + __init = function(self, accum_name) + self.accum_name = accum_name or NameProxy("accum") self.value_name = NameProxy("value") self.len_name = NameProxy("len") end, @@ -1347,7 +1357,6 @@ do end Accumulator = _class_0 end -local default_accumulator default_accumulator = function(self, node) return Accumulator():convert(node) end @@ -1382,7 +1391,7 @@ implicitly_return = function(scope) end return fn end -local Value = Transformer({ +Value = Transformer({ ["for"] = default_accumulator, ["while"] = default_accumulator, foreach = default_accumulator, diff --git a/moonscript/transform.moon b/moonscript/transform.moon index 973c66a..07706b0 100644 --- a/moonscript/transform.moon +++ b/moonscript/transform.moon @@ -11,7 +11,7 @@ import NameProxy, LocalName from require "moonscript.transform.names" destructure = require "moonscript.transform.destructure" NOOP = {"noop"} -local implicitly_return +local * class Run new: (@fn) => @@ -171,8 +171,23 @@ Statement = Transformer { assign: (node) => names, values = unpack node, 2 + num_values = #values + num_names = #values + + if num_names == 1 and num_values == 1 + first_value = values[1] + switch ntype first_value + when "comprehension" + first_name = names[1] + + a = Accumulator first_name + node = @transform.statement first_value, (exp) -> + a\mutate_body { exp } + + return a\wrap node, "group" + -- bubble cascading assigns - transformed = if #values == 1 + transformed = if num_values == 1 value = values[1] t = ntype value @@ -194,11 +209,9 @@ Statement = Transformer { node = transformed or node - if destructure.has_destructure names return destructure.split_assign @, node - -- print util.dump node node continue: (node) => @@ -697,8 +710,8 @@ Statement = Transformer { class Accumulator body_idx: { for: 4, while: 3, foreach: 4 } - new: => - @accum_name = NameProxy "accum" + new: (accum_name) => + @accum_name = accum_name or NameProxy "accum" @value_name = NameProxy "value" @len_name = NameProxy "len" @@ -709,12 +722,12 @@ class Accumulator @wrap node -- wrap the node into a block_exp - wrap: (node) => - build.block_exp { + wrap: (node, group_type="block_exp") => + build[group_type] { build.assign_one @accum_name, build.table! build.assign_one @len_name, 1 node - @accum_name + group_type == "block_exp" and @accum_name or NOOP } -- mutates the body of a loop construct to save last value into accumulator @@ -737,7 +750,7 @@ class Accumulator @value_name update = { - build.assign_one @accum_name\index(@len_name), val + build.assign_one NameProxy.index(@accum_name, @len_name), val {"update", @len_name, "+=", 1} } diff --git a/spec/outputs/bubbling.lua b/spec/outputs/bubbling.lua index 651b0e2..4d83336 100644 --- a/spec/outputs/bubbling.lua +++ b/spec/outputs/bubbling.lua @@ -18,25 +18,22 @@ dont_bubble = function() return _accum_0 end)() end -local k = (function() - local _accum_0 = { } - local _len_0 = 1 - for x in (function(...) - return print(...) - end)("hello") do - _accum_0[_len_0] = x - _len_0 = _len_0 + 1 - end - return _accum_0 -end)() +local k = { } +local _len_0 = 1 +for x in (function(...) + return print(...) +end)("hello") do + k[_len_0] = x + _len_0 = _len_0 + 1 +end local j = (function() local _accum_0 = { } - local _len_0 = 1 + local _len_1 = 1 for i = 1, 10 do - _accum_0[_len_0] = function(...) + _accum_0[_len_1] = function(...) return print(...) end - _len_0 = _len_0 + 1 + _len_1 = _len_1 + 1 end return _accum_0 end)() @@ -44,15 +41,15 @@ local m m = function(...) return (function(...) local _accum_0 = { } - local _len_0 = 1 + local _len_1 = 1 local _list_0 = { ... } for _index_0 = 1, #_list_0 do local x = _list_0[_index_0] if f(...) > 4 then - _accum_0[_len_0] = x - _len_0 = _len_0 + 1 + _accum_0[_len_1] = x + _len_1 = _len_1 + 1 end end return _accum_0 @@ -60,58 +57,52 @@ m = function(...) end local x = (function(...) local _accum_0 = { } - local _len_0 = 1 + local _len_1 = 1 local _list_0 = { ... } for _index_0 = 1, #_list_0 do local i = _list_0[_index_0] - _accum_0[_len_0] = i - _len_0 = _len_0 + 1 + _accum_0[_len_1] = i + _len_1 = _len_1 + 1 end return _accum_0 end)(...) -local y = (function(...) - local _accum_0 = { } - local _len_0 = 1 - local _list_0 = { - ... - } - for _index_0 = 1, #_list_0 do - x = _list_0[_index_0] - _accum_0[_len_0] = x - _len_0 = _len_0 + 1 +local y = { } +local _len_1 = 1 +local _list_0 = { + ... +} +for _index_0 = 1, #_list_0 do + x = _list_0[_index_0] + y[_len_1] = x + _len_1 = _len_1 + 1 +end +local z = { } +local _len_2 = 1 +for x in hallo do + if f(...) > 4 then + z[_len_2] = x + _len_2 = _len_2 + 1 end - return _accum_0 -end)(...) -local z = (function(...) - local _accum_0 = { } - local _len_0 = 1 - for x in hallo do - if f(...) > 4 then - _accum_0[_len_0] = x - _len_0 = _len_0 + 1 - end - end - return _accum_0 -end)(...) +end local a = (function(...) local _accum_0 = { } - local _len_0 = 1 + local _len_3 = 1 for i = 1, 10 do - _accum_0[_len_0] = ... - _len_0 = _len_0 + 1 + _accum_0[_len_3] = ... + _len_3 = _len_3 + 1 end return _accum_0 end)(...) local b = (function() local _accum_0 = { } - local _len_0 = 1 + local _len_3 = 1 for i = 1, 10 do - _accum_0[_len_0] = function() + _accum_0[_len_3] = function() return print(...) end - _len_0 = _len_0 + 1 + _len_3 = _len_3 + 1 end return _accum_0 end)() \ No newline at end of file diff --git a/spec/outputs/comprehension.lua b/spec/outputs/comprehension.lua index 4ac5530..7224b8e 100644 --- a/spec/outputs/comprehension.lua +++ b/spec/outputs/comprehension.lua @@ -79,79 +79,61 @@ _ = (function() end return _tbl_0 end)() -local n1 = (function() - local _accum_0 = { } - local _len_0 = 1 +local n1 = { } +local _len_0 = 1 +for i = 1, 10 do + n1[_len_0] = i + _len_0 = _len_0 + 1 +end +local n2 = { } +local _len_1 = 1 +for i = 1, 10 do + if i % 2 == 1 then + n2[_len_1] = i + _len_1 = _len_1 + 1 + end +end +local aa = { } +local _len_2 = 1 +for x = 1, 10 do + for y = 5, 14 do + aa[_len_2] = { + x, + y + } + _len_2 = _len_2 + 1 + end +end +local bb = { } +local _len_3 = 1 +for thing in y do for i = 1, 10 do - _accum_0[_len_0] = i - _len_0 = _len_0 + 1 + bb[_len_3] = y + _len_3 = _len_3 + 1 end - return _accum_0 -end)() -local n2 = (function() - local _accum_0 = { } - local _len_0 = 1 - for i = 1, 10 do - if i % 2 == 1 then - _accum_0[_len_0] = i - _len_0 = _len_0 + 1 - end - end - return _accum_0 -end)() -local aa = (function() - local _accum_0 = { } - local _len_0 = 1 - for x = 1, 10 do - for y = 5, 14 do - _accum_0[_len_0] = { - x, - y - } - _len_0 = _len_0 + 1 - end - end - return _accum_0 -end)() -local bb = (function() - local _accum_0 = { } - local _len_0 = 1 +end +local cc = { } +local _len_4 = 1 +for i = 1, 10 do for thing in y do - for i = 1, 10 do - _accum_0[_len_0] = y - _len_0 = _len_0 + 1 - end + cc[_len_4] = y + _len_4 = _len_4 + 1 end - return _accum_0 -end)() -local cc = (function() - local _accum_0 = { } - local _len_0 = 1 - for i = 1, 10 do +end +local dd = { } +local _len_5 = 1 +for i = 1, 10 do + if cool then for thing in y do - _accum_0[_len_0] = y - _len_0 = _len_0 + 1 - end - end - return _accum_0 -end)() -local dd = (function() - local _accum_0 = { } - local _len_0 = 1 - for i = 1, 10 do - if cool then - for thing in y do - if x > 3 then - if c + 3 then - _accum_0[_len_0] = y - _len_0 = _len_0 + 1 - end + if x > 3 then + if c + 3 then + dd[_len_5] = y + _len_5 = _len_5 + 1 end end end end - return _accum_0 -end)() +end _ = (function() local _tbl_0 = { } for i = 1, 10 do diff --git a/spec/outputs/lists.lua b/spec/outputs/lists.lua index e5ce514..9566c90 100644 --- a/spec/outputs/lists.lua +++ b/spec/outputs/lists.lua @@ -1,17 +1,14 @@ -local hi = (function() - local _accum_0 = { } - local _len_0 = 1 - for _, x in ipairs({ - 1, - 2, - 3, - 4 - }) do - _accum_0[_len_0] = x * 2 - _len_0 = _len_0 + 1 - end - return _accum_0 -end)() +local hi = { } +local _len_0 = 1 +for _, x in ipairs({ + 1, + 2, + 3, + 4 +}) do + hi[_len_0] = x * 2 + _len_0 = _len_0 + 1 +end local items = { 1, 2, @@ -20,40 +17,34 @@ local items = { 5, 6 } -local mm = (function() - local _accum_0 = { } - local _len_0 = 1 - for self.x in ipairs(items) do - _accum_0[_len_0] = self.x - _len_0 = _len_0 + 1 - end - return _accum_0 -end)() +local mm = { } +local _len_1 = 1 +for self.x in ipairs(items) do + mm[_len_1] = self.x + _len_1 = _len_1 + 1 +end for z in ipairs(items) do if z > 4 then local _ = z end end -local rad = (function() - local _accum_0 = { } - local _len_0 = 1 - for a in ipairs({ - 1, - 2, - 3, - 4, - 5, - 6 - }) do - if good_number(a) then - _accum_0[_len_0] = { - a - } - _len_0 = _len_0 + 1 - end +local rad = { } +local _len_2 = 1 +for a in ipairs({ + 1, + 2, + 3, + 4, + 5, + 6 +}) do + if good_number(a) then + rad[_len_2] = { + a + } + _len_2 = _len_2 + 1 end - return _accum_0 -end)() +end for z in items do for j in list do if z > 4 then @@ -78,44 +69,41 @@ range = function(count) end dump((function() local _accum_0 = { } - local _len_0 = 1 + local _len_3 = 1 for x in range(10) do - _accum_0[_len_0] = x - _len_0 = _len_0 + 1 + _accum_0[_len_3] = x + _len_3 = _len_3 + 1 end return _accum_0 end)()) dump((function() local _accum_0 = { } - local _len_0 = 1 + local _len_3 = 1 for x in range(5) do if x > 2 then for y in range(5) do - _accum_0[_len_0] = { + _accum_0[_len_3] = { x, y } - _len_0 = _len_0 + 1 + _len_3 = _len_3 + 1 end end end return _accum_0 end)()) -local things = (function() - local _accum_0 = { } - local _len_0 = 1 - for x in range(10) do - if x > 5 then - for y in range(10) do - if y > 7 then - _accum_0[_len_0] = x + y - _len_0 = _len_0 + 1 - end +local things = { } +local _len_3 = 1 +for x in range(10) do + if x > 5 then + for y in range(10) do + if y > 7 then + things[_len_3] = x + y + _len_3 = _len_3 + 1 end end end - return _accum_0 -end)() +end for x in ipairs({ 1, 2, @@ -137,15 +125,12 @@ end for x in x do local _ = x end -local x = (function() - local _accum_0 = { } - local _len_0 = 1 - for x in x do - _accum_0[_len_0] = x - _len_0 = _len_0 + 1 - end - return _accum_0 -end)() +local x = { } +local _len_4 = 1 +for x in x do + x[_len_4] = x + _len_4 = _len_4 + 1 +end for x in ipairs({ 1, 2, @@ -161,45 +146,36 @@ for x in ipairs({ end end end -local double = (function() - local _accum_0 = { } - local _len_0 = 1 - for _index_0 = 1, #items do - x = items[_index_0] - _accum_0[_len_0] = x * 2 - _len_0 = _len_0 + 1 - end - return _accum_0 -end)() +local double = { } +local _len_5 = 1 +for _index_0 = 1, #items do + x = items[_index_0] + double[_len_5] = x * 2 + _len_5 = _len_5 + 1 +end for _index_0 = 1, #double do x = double[_index_0] print(x) end -local cut = (function() - local _accum_0 = { } - local _len_0 = 1 - for _index_0 = 1, #items do - x = items[_index_0] - if x > 3 then - _accum_0[_len_0] = x - _len_0 = _len_0 + 1 - end +local cut = { } +local _len_6 = 1 +for _index_0 = 1, #items do + x = items[_index_0] + if x > 3 then + cut[_len_6] = x + _len_6 = _len_6 + 1 end - return _accum_0 -end)() -local hello = (function() - local _accum_0 = { } - local _len_0 = 1 - for _index_0 = 1, #items do - x = items[_index_0] - for _index_1 = 1, #items do - local y = items[_index_1] - _accum_0[_len_0] = x + y - _len_0 = _len_0 + 1 - end +end +local hello = { } +local _len_7 = 1 +for _index_0 = 1, #items do + x = items[_index_0] + for _index_1 = 1, #items do + local y = items[_index_1] + hello[_len_7] = x + y + _len_7 = _len_7 + 1 end - return _accum_0 -end)() +end for _index_0 = 1, #hello do local z = hello[_index_0] print(z) @@ -251,10 +227,10 @@ local normal normal = function(hello) return (function() local _accum_0 = { } - local _len_0 = 1 + local _len_8 = 1 for x in yeah do - _accum_0[_len_0] = x - _len_0 = _len_0 + 1 + _accum_0[_len_8] = x + _len_8 = _len_8 + 1 end return _accum_0 end)() @@ -281,11 +257,11 @@ end return function() return (function() local _accum_0 = { } - local _len_0 = 1 + local _len_8 = 1 for _index_0 = 1, #things do x = things[_index_0] - _accum_0[_len_0] = x - _len_0 = _len_0 + 1 + _accum_0[_len_8] = x + _len_8 = _len_8 + 1 end return _accum_0 end)()