replace render for Line and Block

This commit is contained in:
leaf corcoran 2012-10-28 01:14:55 -07:00
parent 52655cf199
commit ec6b22239a
7 changed files with 244 additions and 129 deletions

View File

@ -18,6 +18,19 @@ do
end end
local concat, insert = table.concat, table.insert local concat, insert = table.concat, table.insert
local pos_to_line, get_closest_line, trim = util.pos_to_line, util.get_closest_line, util.trim local pos_to_line, get_closest_line, trim = util.pos_to_line, util.get_closest_line, util.trim
local mtype = util.moon.type
local insert_many
insert_many = function(tbl, ...)
local i = #tbl + 1
local _list_0 = {
...
}
for _index_0 = 1, #_list_0 do
local val = _list_0[_index_0]
tbl[i] = val
i = i + 1
end
end
local Line local Line
Line = (function() Line = (function()
local _parent_0 = nil local _parent_0 = nil
@ -53,19 +66,41 @@ Line = (function()
return nil return nil
end, end,
render = function(self) render = function(self)
local buff = { } local parts = { }
for i = 1, #self do local current = { }
local c = self[i] local add_current
insert(buff, (function() add_current = function()
if util.moon.type(c) == Block then return insert(parts, table.concat(current))
c:bubble() end
return c:render() local _list_0 = self
for _index_0 = 1, #_list_0 do
local chunk = _list_0[_index_0]
local _exp_0 = mtype(chunk)
if Block == _exp_0 then
local _list_1 = {
chunk:render()
}
for _index_1 = 1, #_list_1 do
local block_chunk = _list_1[_index_1]
if "string" == type(block_chunk) then
insert(current, block_chunk)
else else
return c add_current()
insert(parts, block_chunk)
current = { }
end end
end)())
end end
return concat(buff) else
insert(current, chunk)
end
end
if #current > 0 then
add_current()
end
return unpack(parts)
end,
__tostring = function(self)
return "Line<" .. tostring(self:render()) .. ">"
end end
} }
_base_0.__index = _base_0 _base_0.__index = _base_0
@ -103,6 +138,7 @@ Line = (function()
return _class_0 return _class_0
end)() end)()
Block = (function() Block = (function()
local flatten
local _parent_0 = nil local _parent_0 = nil
local _base_0 = { local _base_0 = {
header = "do", header = "do",
@ -251,8 +287,8 @@ Block = (function()
end end
end end
end, end,
add_line_text = function(self, text) add_raw = function(self, item)
return insert(self._lines, text) return insert(self._lines, item)
end, end,
append_line_table = function(self, sub_table, offset) append_line_table = function(self, sub_table, offset)
offset = offset + self.current_line offset = offset + self.current_line
@ -281,62 +317,48 @@ Block = (function()
end end
end, end,
add = function(self, line) add = function(self, line)
local t = util.moon.type(line) local _exp_0 = util.moon.type(line)
if t == "string" then if "string" == _exp_0 then
self:add_line_text(line) return insert(self._lines, line)
elseif t == Block then elseif Block == _exp_0 then
self:add(self:line(line)) return insert_many(self._lines, line:render())
elseif t == Line then elseif Line == _exp_0 then
self:add_line_tables(line) return insert_many(self._lines, line:render())
self:add_line_text(line:render())
self.current_line = self.current_line + 1
else else
error("Adding unknown item") return error("Adding unknown item")
end
return nil
end,
_insert_breaks = function(self)
for i = 1, #self._lines - 1 do
local left, right = self._lines[i], self._lines[i + 1]
local lc = left:sub(-1)
if (lc == ")" or lc == "]") and right:sub(1, 1) == "(" then
self._lines[i] = self._lines[i] .. ";"
end
end end
end, end,
render = function(self) render = function(self)
local flatten local out = {
flatten = function(line) flatten(self.header)
if type(line) == "string" then }
return line local lines = (function()
else local _accum_0 = { }
return line:render() local _len_0 = 0
local _list_0 = self._lines
for _index_0 = 1, #_list_0 do
local line = _list_0[_index_0]
local _value_0 = flatten(line)
if _value_0 ~= nil then
_len_0 = _len_0 + 1
_accum_0[_len_0] = _value_0
end end
end end
local header = flatten(self.header) return _accum_0
if #self._lines == 0 then
local footer = flatten(self.footer)
return concat({
header,
footer
}, " ")
end
local indent = indent_char:rep(self.indent)
if not self.delim then
self:_insert_breaks()
end
local body = indent .. concat(self._lines, (self.delim or "") .. "\n" .. indent)
return concat({
header,
body,
indent_char:rep(self.indent - 1) .. (function()
if self.next then
return self.next:render()
else
return flatten(self.footer)
end
end)() end)()
}, "\n") if self.next then
insert(out, lines)
insert_many(out, self.next:render())
else
local footer = flatten(self.footer)
if #lines == 0 and #out == 1 then
out[1] = out[1] .. (" " .. footer)
else
insert(out, lines)
insert(out, footer)
end
end
return unpack(out)
end, end,
block = function(self, header, footer) block = function(self, header, footer)
return Block(self, header, footer) return Block(self, header, footer)
@ -492,11 +514,50 @@ Block = (function()
end end
}) })
_base_0.__class = _class_0 _base_0.__class = _class_0
local self = _class_0
flatten = function(line)
local _exp_0 = mtype(line)
if Line == _exp_0 then
return line:render()
else
return line
end
end
if _parent_0 and _parent_0.__inherited then if _parent_0 and _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0) _parent_0.__inherited(_parent_0, _class_0)
end end
return _class_0 return _class_0
end)() end)()
local flatten_lines
flatten_lines = function(lines, indent, buffer)
if indent == nil then
indent = nil
end
if buffer == nil then
buffer = { }
end
for i = 1, #lines do
local l = lines[i]
local _exp_0 = type(l)
if "string" == _exp_0 then
if indent then
insert(buffer, indent)
end
insert(buffer, l)
if "string" == type(lines[i + 1]) then
local lc = l:sub(-1)
if (lc == ")" or lc == "]") and lines[i + 1]:sub(1, 1) == "(" then
insert(buffer, ";")
end
end
insert(buffer, "\n")
local last = l
elseif "table" == _exp_0 then
flatten_lines(l, indent and indent .. indent_char or indent_char, buffer)
end
end
return buffer
end
RootBlock = (function() RootBlock = (function()
local _parent_0 = Block local _parent_0 = Block
local _base_0 = { local _base_0 = {
@ -504,8 +565,11 @@ RootBlock = (function()
return "RootBlock<>" return "RootBlock<>"
end, end,
render = function(self) render = function(self)
self:_insert_breaks() local buffer = flatten_lines(self._lines)
return concat(self._lines, "\n") if buffer[#buffer] == "\n" then
buffer[#buffer] = nil
end
return table.concat(buffer)
end end
} }
_base_0.__index = _base_0 _base_0.__index = _base_0

View File

@ -16,9 +16,17 @@ import ntype from require "moonscript.types"
import concat, insert from table import concat, insert from table
import pos_to_line, get_closest_line, trim from util import pos_to_line, get_closest_line, trim from util
mtype = util.moon.type
export tree, value, format_error export tree, value, format_error
export Block, RootBlock export Block, RootBlock
insert_many = (tbl, ...) ->
i = #tbl + 1
for val in *{...}
tbl[i] = val
i += 1
-- buffer for building up a line -- buffer for building up a line
class Line class Line
_append_single: (item) => _append_single: (item) =>
@ -37,16 +45,34 @@ class Line
@_append_single item for item in *{...} @_append_single item for item in *{...}
nil nil
-- todo: remove concats from here
render: => render: =>
buff = {} parts = {}
for i = 1,#self current = {}
c = self[i]
insert buff, if util.moon.type(c) == Block add_current = ->
c\bubble! insert parts, table.concat current
c\render!
for chunk in *@
switch mtype chunk
when Block
for block_chunk in *{chunk\render!}
if "string" == type block_chunk
insert current, block_chunk
else else
c add_current!
concat buff insert parts, block_chunk
current = {}
else
insert current, chunk
if #current > 0
add_current!
unpack parts
__tostring: => "Line<#{@render!}>"
class Block class Block
header: "do" header: "do"
@ -168,8 +194,8 @@ class Block
@_posmap[@current_line] = @last_pos @_posmap[@current_line] = @last_pos
-- add raw text as new line -- add raw text as new line
add_line_text: (text) => add_raw: (item) =>
insert @_lines, text insert @_lines, item
append_line_table: (sub_table, offset) => append_line_table: (sub_table, offset) =>
offset = offset + @current_line offset = offset + @current_line
@ -193,52 +219,43 @@ class Block
-- add a line object -- add a line object
add: (line) => add: (line) =>
t = util.moon.type line -- print "adding", line
switch util.moon.type line
if t == "string" when "string"
@add_line_text line insert @_lines, line
elseif t == Block when Block
@add @line line insert_many @_lines, line\render!
elseif t == Line when Line
@add_line_tables line insert_many @_lines, line\render!
@add_line_text line\render!
@current_line += 1
else else
error "Adding unknown item" error "Adding unknown item"
nil
_insert_breaks: =>
for i = 1, #@_lines - 1
left, right = @_lines[i], @_lines[i+1]
lc = left\sub(-1)
if (lc == ")" or lc == "]") and right\sub(1,1) == "("
@_lines[i] = @_lines[i]..";"
render: =>
flatten = (line) -> flatten = (line) ->
if type(line) == "string" switch mtype line
line when Line
else
line\render! line\render!
else
line
header = flatten @header -- todo: pass in buffer as argument
render: =>
out = { flatten @header }
if #@_lines == 0 lines = for line in *@_lines
flatten line
if @next
insert out, lines
insert_many out, @next\render!
else
footer = flatten @footer footer = flatten @footer
return concat {header, footer}, " " if #lines == 0 and #out == 1
out[1] ..= " " ..footer
else
insert out, lines
insert out, footer
indent = indent_char\rep @indent unpack out
-- inject semicolons for ambiguous lines
if not @delim then @_insert_breaks!
body = indent .. concat @_lines, (@delim or "") .. "\n" .. indent
concat {
header,
body,
indent_char\rep(@indent - 1) .. if @next then @next\render! else flatten @footer
}, "\n"
block: (header, footer) => block: (header, footer) =>
Block self, header, footer Block self, header, footer
@ -299,6 +316,28 @@ class Block
@_lines = {} @_lines = {}
@stms fn lines @stms fn lines
flatten_lines = (lines, indent=nil, buffer={}) ->
for i = 1, #lines
l = lines[i]
switch type l
when "string"
insert buffer, indent if indent
insert buffer, l
-- insert breaks between ambiguous statements
if "string" == type lines[i + 1]
lc = l\sub(-1)
if (lc == ")" or lc == "]") and lines[i + 1]\sub(1,1) == "("
insert buffer, ";"
insert buffer, "\n"
last = l
when "table"
flatten_lines l, indent and indent .. indent_char or indent_char, buffer
buffer
class RootBlock extends Block class RootBlock extends Block
new: (...) => new: (...) =>
@root = self @root = self
@ -307,8 +346,13 @@ class RootBlock extends Block
__tostring: => "RootBlock<>" __tostring: => "RootBlock<>"
render: => render: =>
@_insert_breaks! -- @_insert_breaks!
concat @_lines, "\n" -- concat @_lines, "\n"
-- print util.dump @_lines
buffer = flatten_lines @_lines
buffer[#buffer] = nil if buffer[#buffer] == "\n"
table.concat buffer
format_error = (msg, pos, file_str) -> format_error = (msg, pos, file_str) ->
line = pos_to_line file_str, pos line = pos_to_line file_str, pos

View File

@ -19,7 +19,7 @@ line_compile = {
local _list_0 = node[2] local _list_0 = node[2]
for _index_0 = 1, #_list_0 do for _index_0 = 1, #_list_0 do
local line = _list_0[_index_0] local line = _list_0[_index_0]
self:add(line) self:add_raw(line)
end end
end, end,
declare = function(self, node) declare = function(self, node)

View File

@ -18,7 +18,7 @@ line_compile =
lines: (node) => lines: (node) =>
for line in *node[2] for line in *node[2]
@add line @add_raw line
declare: (node) => declare: (node) =>
names = node[2] names = node[2]

View File

@ -8,6 +8,7 @@ do
ntype = _table_0.ntype ntype = _table_0.ntype
end end
local concat, insert = table.concat, table.insert local concat, insert = table.concat, table.insert
local table_delim = ","
value_compile = { value_compile = {
exp = function(self, node) exp = function(self, node)
local _comp local _comp
@ -226,7 +227,6 @@ value_compile = {
local _, items = unpack(node) local _, items = unpack(node)
do do
local _with_0 = self:block("{", "}") local _with_0 = self:block("{", "}")
_with_0.delim = ","
local format_line local format_line
format_line = function(tuple) format_line = function(tuple)
if #tuple == 2 then if #tuple == 2 then
@ -253,10 +253,13 @@ value_compile = {
end end
end end
if items then if items then
local _list_0 = items local count = #items
for _index_0 = 1, #_list_0 do for i, tuple in ipairs(items) do
local line = _list_0[_index_0] local line = format_line(tuple)
_with_0:add(format_line(line)) if not (count == i) then
line:append(table_delim)
end
_with_0:add(line)
end end
end end
return _with_0 return _with_0

View File

@ -11,6 +11,8 @@ import concat, insert from table
export value_compile export value_compile
table_delim = ","
value_compile = value_compile =
-- list of values separated by binary operators -- list of values separated by binary operators
exp: (node) => exp: (node) =>
@ -129,8 +131,6 @@ value_compile =
table: (node) => table: (node) =>
_, items = unpack node _, items = unpack node
with @block "{", "}" with @block "{", "}"
.delim = ","
format_line = (tuple) -> format_line = (tuple) ->
if #tuple == 2 if #tuple == 2
key, value = unpack tuple key, value = unpack tuple
@ -152,7 +152,11 @@ value_compile =
@line \value tuple[1] @line \value tuple[1]
if items if items
\add format_line line for line in *items count = #items
for i, tuple in ipairs items
line = format_line tuple
line\append table_delim unless count == i
\add line
minus: (node) => minus: (node) =>
@line "-", @value node[2] @line "-", @value node[2]