diff --git a/moonscript/compile.lua b/moonscript/compile.lua index 7e9c2e8..7de29aa 100644 --- a/moonscript/compile.lua +++ b/moonscript/compile.lua @@ -30,7 +30,7 @@ local concat, insert = table.concat, table.insert local pos_to_line, get_closest_line, trim, unpack = util.pos_to_line, util.get_closest_line, util.trim, util.unpack local mtype = util.moon.type local indent_char = " " -local Line, Lines, Block, RootBlock +local Line, DelayedLine, Lines, Block, RootBlock do local _parent_0 = nil local _base_0 = { @@ -62,13 +62,13 @@ do end local posmap = self.posmap for i, l in ipairs(self) do - local _exp_0 = type(l) - if "table" == _exp_0 then - local _ - _, line_no = l:flatten_posmap(line_no, out) - elseif "string" == _exp_0 then + local _exp_0 = mtype(l) + if "string" == _exp_0 or DelayedLine == _exp_0 then line_no = line_no + 1 out[line_no] = posmap[i] + elseif "table" == _exp_0 then + local _ + _, line_no = l:flatten_posmap(line_no, out) end end return out, line_no @@ -82,7 +82,12 @@ do end for i = 1, #self do local l = self[i] - local _exp_0 = type(l) + local t = mtype(l) + if t == DelayedLine then + l = l:render() + t = "string" + end + local _exp_0 = t if "string" == _exp_0 then if indent then insert(buffer, indent) @@ -264,6 +269,47 @@ do end Line = _class_0 end +do + local _parent_0 = nil + local _base_0 = { + prepare = function() end, + render = function(self) + self:prepare() + return concat(self) + end + } + _base_0.__index = _base_0 + if _parent_0 then + setmetatable(_base_0, _parent_0.__base) + end + local _class_0 = setmetatable({ + __init = function(self, fn) + self.prepare = fn + end, + __base = _base_0, + __name = "DelayedLine", + __parent = _parent_0 + }, { + __index = function(cls, name) + local val = rawget(_base_0, name) + if val == nil and _parent_0 then + return _parent_0[name] + else + return val + end + end, + __call = function(cls, ...) + local _self_0 = setmetatable({}, _base_0) + cls.__init(_self_0, ...) + return _self_0 + end + }) + _base_0.__class = _class_0 + if _parent_0 and _parent_0.__inherited then + _parent_0.__inherited(_parent_0, _class_0) + end + DelayedLine = _class_0 +end do local _parent_0 = nil local _base_0 = { diff --git a/moonscript/compile.moon b/moonscript/compile.moon index a74f74d..9f4b3eb 100644 --- a/moonscript/compile.moon +++ b/moonscript/compile.moon @@ -17,7 +17,7 @@ mtype = util.moon.type indent_char = " " -local Line, Lines, Block, RootBlock +local Line, DelayedLine, Lines, Block, RootBlock -- a buffer for building up lines class Lines @@ -34,26 +34,32 @@ class Lines item\render self when Block item\render self - else + else -- also captures DelayedLine @[#@ + 1] = item @ flatten_posmap: (line_no=0, out={}) => posmap = @posmap for i, l in ipairs @ - switch type l - when "table" - _, line_no = l\flatten_posmap line_no, out - when "string" + switch mtype l + when "string", DelayedLine line_no += 1 out[line_no] = posmap[i] + when "table" + _, line_no = l\flatten_posmap line_no, out out, line_no flatten: (indent=nil, buffer={}) => for i = 1, #@ l = @[i] - switch type l + t = mtype l + + if t == DelayedLine + l = l\render! + t = "string" + + switch t when "string" insert buffer, indent if indent insert buffer, l @@ -66,7 +72,7 @@ class Lines insert buffer, "\n" last = l - when "table" + when "table" -- Lines l\flatten indent and indent .. indent_char or indent_char, buffer buffer @@ -134,6 +140,16 @@ class Line __tostring: => "Line<#{util.dump(@)\sub 1, -2}>" +class DelayedLine + new: (fn) => + @prepare = fn + + prepare: -> + + render: => + @prepare! + concat @ + class Block header: "do" footer: "end" diff --git a/moonscript/data.moon b/moonscript/data.moon index 52df3d5..a9fbf32 100644 --- a/moonscript/data.moon +++ b/moonscript/data.moon @@ -33,7 +33,5 @@ lua_keywords = Set{ 'until', 'while' } - { :Set, :Stack, :lua_keywords } -