wip for new line rewriter

This commit is contained in:
leaf corcoran 2012-10-29 09:54:50 -07:00
parent 448c2e53d5
commit 6d52237380
7 changed files with 250 additions and 98 deletions

View File

@ -17,7 +17,7 @@ do
ntype = _table_0.ntype
end
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_line, get_closest_line, trim = util.pos_to_line, util.get_line, util.get_closest_line, util.trim
local mtype = util.moon.type
local Line
Line = (function()
@ -123,7 +123,7 @@ Line = (function()
return _class_0
end)()
Block = (function()
local add_to_buffer
local add_to_buffer, block_iterator
local _parent_0 = nil
local _base_0 = {
header = "do",
@ -260,54 +260,36 @@ Block = (function()
})
return name
end,
mark_pos = function(self, node)
if node[-1] then
self.last_pos = node[-1]
if not self._posmap[self.current_line] then
self._posmap[self.current_line] = self.last_pos
end
end
end,
add_raw = function(self, item)
return insert(self._lines, item)
end,
append_line_table = function(self, sub_table, offset)
offset = offset + self.current_line
for line, source in pairs(sub_table) do
line = line + offset
if not self._posmap[line] then
self._posmap[line] = source
end
end
end,
add_line_tables = function(self, line)
local _list_0 = line
for _index_0 = 1, #_list_0 do
local chunk = _list_0[_index_0]
if util.moon.type(chunk) == Block then
local current = chunk
while current do
if util.moon.type(current.header) == Line then
self:add_line_tables(current.header)
end
self:append_line_table(current:line_table(), 0)
self.current_line = self.current_line + current.current_line
current = current.next
mark_pos = function(self, line_no, node)
do
local pos = node[-1]
if pos then
self.last_pos = pos
if not (self._posmap[line_no]) then
self._posmap[line_no] = pos
end
end
end
end,
append_posmap = function(self, map)
print("appending pos", self)
self._posmap[#self._posmap + 1] = map
end,
add_raw = function(self, item)
return insert(self._lines, item)
end,
add = function(self, line)
local _exp_0 = util.moon.type(line)
if "string" == _exp_0 then
return insert(self._lines, line)
insert(self._lines, line)
elseif Block == _exp_0 then
return line:render(self._lines)
line:render(self._lines)
elseif Line == _exp_0 then
return line:render(self._lines)
line:render(self._lines)
else
return error("Adding unknown item")
error("Adding unknown item")
end
return line
end,
render = function(self, buffer)
add_to_buffer(buffer, self.header)
@ -361,7 +343,6 @@ Block = (function()
if type(node) ~= "table" then
action = "raw_value"
else
self:mark_pos(node)
action = node[1]
end
local fn = value_compile[action]
@ -393,26 +374,50 @@ Block = (function()
return
end
node = self.transform.statement(node)
local fn = line_compile[ntype(node)]
if not fn then
if has_value(node) then
self:stm({
"assign",
{
"_"
},
{
node
}
})
local before = #self._lines
local added
do
local fn = line_compile[ntype(node)]
if fn then
local out = fn(self, node, ...)
if out then
added = self:add(out)
end
else
self:add(self:value(node))
if has_value(node) then
added = self:stm({
"assign",
{
"_"
},
{
node
}
})
else
added = self:add(self:value(node))
end
end
else
self:mark_pos(node)
local out = fn(self, node, ...)
if out then
self:add(out)
end
if added then
print("added " .. tostring(#self._lines - before) .. " lines")
local list
if Line == mtype(added) then
list = added
else
list = {
added
}
end
local next_block = block_iterator(list)
for l = before + 1, #self._lines do
if "table" == type(self._lines[l]) then
local block = next_block()
block._posmap.num_lines = #block._lines
self._posmap[l] = block._posmap
else
self:mark_pos(l, node)
end
end
end
return nil
@ -444,7 +449,6 @@ Block = (function()
local _class_0 = setmetatable({
__init = function(self, parent, header, footer)
self.parent, self.header, self.footer = parent, header, footer
self.current_line = 1
self._lines = { }
self._posmap = { }
self._names = { }
@ -499,6 +503,17 @@ Block = (function()
end
return buffer
end
block_iterator = function(list)
return coroutine.wrap(function()
local _list_0 = list
for _index_0 = 1, #_list_0 do
local item = _list_0[_index_0]
if Block == mtype(item) then
coroutine.yield(item)
end
end
end)
end
if _parent_0 and _parent_0.__inherited then
_parent_0.__inherited(_parent_0, _class_0)
end
@ -534,6 +549,76 @@ flatten_lines = function(lines, indent, buffer)
end
return buffer
end
local flatten_posmap
flatten_posmap = function(posmap, dl, out)
if dl == nil then
dl = 0
end
if out == nil then
out = { }
end
for k, v in pairs(posmap) do
local _continue_0 = false
repeat
if "string" == type(k) then
_continue_0 = true
break
end
if "table" == type(v) then
flatten_posmap(v, k - 1 + dl, out)
dl = dl + (v.num_lines - 1)
else
out[k + dl] = v
end
_continue_0 = true
until true
if not _continue_0 then
break
end
end
return out
end
local debug_posmap
debug_posmap = function(posmap, fname, lua_code)
if fname == nil then
fname = error("pass in input file")
end
local moon_code = io.open(fname):read("*a")
local tuples = (function()
local _accum_0 = { }
local _len_0 = 0
for k, v in pairs(posmap) do
_len_0 = _len_0 + 1
_accum_0[_len_0] = {
k,
v
}
end
return _accum_0
end)()
table.sort(tuples, function(a, b)
return a[1] < b[1]
end)
local lines = (function()
local _accum_0 = { }
local _len_0 = 0
local _list_0 = tuples
for _index_0 = 1, #_list_0 do
local pair = _list_0[_index_0]
local lua_line, pos = unpack(pair)
local moon_line = pos_to_line(moon_code, pos)
local lua_text = get_line(lua_code, lua_line)
local moon_text = get_closest_line(moon_code, moon_line)
local _value_0 = tostring(pos) .. "\t " .. tostring(lua_line) .. ":[ " .. tostring(trim(lua_text)) .. " ] >> " .. tostring(moon_line) .. ":[ " .. tostring(trim(moon_text)) .. " ]"
if _value_0 ~= nil then
_len_0 = _len_0 + 1
_accum_0[_len_0] = _value_0
end
end
return _accum_0
end)()
return concat(lines, "\n") .. "\n"
end
RootBlock = (function()
local _parent_0 = Block
local _base_0 = {
@ -631,7 +716,11 @@ tree = function(tree, scope)
end
return nil, error_msg, scope.last_pos
else
local tbl = scope:line_table()
return result, tbl
local raw_posmap = scope:line_table()
local posmap = flatten_posmap(raw_posmap)
print(util.dump(raw_posmap))
print(util.dump(posmap))
print(debug_posmap(posmap, "scrap.moon", result))
return result, posmap
end
end

View File

@ -14,7 +14,7 @@ import Set from require "moonscript.data"
import ntype from require "moonscript.types"
import concat, insert from table
import pos_to_line, get_closest_line, trim from util
import pos_to_line, get_line, get_closest_line, trim from util
mtype = util.moon.type
@ -82,8 +82,6 @@ class Block
"Block<#{h}> <- " .. tostring @parent
new: (@parent, @header, @footer) =>
@current_line = 1
@_lines = {}
@_posmap = {}
@_names = {}
@ -104,6 +102,8 @@ class Block
else
@indent = 0
-- maps from a output (lua) line number to a character position in the
-- original moon file
line_table: =>
@_posmap
@ -177,35 +177,38 @@ class Block
@stm {"assign", {name}, {value}}
name
mark_pos: (node) =>
if node[-1]
@last_pos = node[-1]
if not @_posmap[@current_line]
@_posmap[@current_line] = @last_pos
mark_pos: (line_no, node) =>
if pos = node[-1]
@last_pos = pos
@_posmap[line_no] = pos unless @_posmap[line_no]
append_posmap: (map) =>
print "appending pos", self
@_posmap[#@_posmap + 1] = map
-- add raw text as new line
add_raw: (item) =>
insert @_lines, item
append_line_table: (sub_table, offset) =>
offset = offset + @current_line
-- append_line_table: (sub_table, offset) =>
-- offset = offset + @current_line
for line, source in pairs sub_table
line += offset
if not @_posmap[line]
@_posmap[line] = source
-- for line, source in pairs sub_table
-- line += offset
-- if not @_posmap[line]
-- @_posmap[line] = source
add_line_tables: (line) =>
for chunk in *line
if util.moon.type(chunk) == Block
current = chunk
while current
if util.moon.type(current.header) == Line
@add_line_tables current.header
-- add_line_tables: (line) =>
-- for chunk in *line
-- if util.moon.type(chunk) == Block
-- current = chunk
-- while current
-- if util.moon.type(current.header) == Line
-- @add_line_tables current.header
@append_line_table current\line_table!, 0
@current_line += current.current_line
current = current.next
-- @append_line_table current\line_table!, 0
-- @current_line += current.current_line
-- current = current.next
-- add a line object
add: (line) =>
@ -219,6 +222,7 @@ class Block
line\render @_lines
else
error "Adding unknown item"
line
add_to_buffer = (buffer, line) ->
switch mtype line
@ -269,7 +273,6 @@ class Block
action = if type(node) != "table"
"raw_value"
else
@mark_pos node
node[1]
fn = value_compile[action]
@ -281,20 +284,43 @@ class Block
with Line!
\append_list [@value v for v in *values], delim
block_iterator = (list) ->
coroutine.wrap ->
for item in *list
if Block == mtype item
coroutine.yield item
stm: (node, ...) =>
return if not node -- skip blank statements
node = @transform.statement node
fn = line_compile[ntype(node)]
if not fn
before = #@_lines
added = if fn = line_compile[ntype(node)]
out = fn self, node, ...
@add out if out
else
-- coerce value into statement
if has_value node
@stm {"assign", {"_"}, {node}}
else
@add @value node
else
@mark_pos node
out = fn self, node, ...
@add out if out
-- mark pos for each line added
if added
print "added #{#@_lines - before} lines"
list = if Line == mtype added then added else {added}
next_block = block_iterator list
for l=before + 1,#@_lines
if "table" == type @_lines[l]
block = next_block!
block._posmap.num_lines = #block._lines
@_posmap[l] = block._posmap
else
@mark_pos l, node
nil
stms: (stms, ret) =>
@ -307,7 +333,6 @@ class Block
@_lines = {}
@stms fn lines
flatten_lines = (lines, indent=nil, buffer={}) ->
for i = 1, #lines
l = lines[i]
@ -329,6 +354,35 @@ flatten_lines = (lines, indent=nil, buffer={}) ->
buffer
flatten_posmap = (posmap, dl=0, out={}) ->
for k,v in pairs posmap
continue if "string" == type k
if "table" == type v
flatten_posmap v, k - 1 + dl, out
dl += v.num_lines - 1
else
out[k + dl] = v
out
debug_posmap = (posmap, fname=error"pass in input file", lua_code) ->
moon_code = io.open(fname)\read "*a"
tuples = [{k, v} for k, v in pairs posmap]
table.sort tuples, (a, b) -> a[1] < b[1]
lines = for pair in *tuples
lua_line, pos = unpack pair
moon_line = pos_to_line moon_code, pos
lua_text = get_line lua_code, lua_line
moon_text = get_closest_line moon_code, moon_line
"#{pos}\t #{lua_line}:[ #{trim lua_text} ] >> #{moon_line}:[ #{trim moon_text} ]"
concat(lines, "\n") .. "\n"
class RootBlock extends Block
new: (...) =>
@root = self
@ -378,6 +432,10 @@ tree = (tree, scope=RootBlock!) ->
nil, error_msg, scope.last_pos
else
tbl = scope\line_table!
result, tbl
raw_posmap = scope\line_table!
posmap = flatten_posmap raw_posmap
print util.dump raw_posmap
print util.dump posmap
print debug_posmap posmap, "scrap.moon", result
result, posmap

View File

@ -73,6 +73,9 @@ rewrite_traceback = function(text, err)
fname,
":",
reverse_line_number(fname, tbl, line, cache),
"(",
line,
")",
": ",
msg
})

View File

@ -63,6 +63,7 @@ rewrite_traceback = (text, err) ->
concat {
fname, ":"
reverse_line_number(fname, tbl, line, cache)
"(", line, ")"
": ", msg
}
else

View File

@ -341,7 +341,7 @@ local build_grammar = wrap_env(function()
CheckIndent = Cmt(Indent, check_indent), -- validates line is in correct indent
Line = (CheckIndent * Statement + Space * #Stop),
Statement = (
Statement = pos(
Import + While + With + For + ForEach + Switch + Return + ClassDecl +
Local + Export + BreakLoop +
Ct(ExpList) * (Update + Assign)^-1 / format_assign

View File

@ -31,7 +31,7 @@ get_closest_line = function(str, line_num)
end
end
get_line = function(str, line_num)
for line in str:gmatch("(.-)[\n$]") do
for line in str:gmatch("([^\n]*)\n?") do
if line_num == 1 then
return line
end

View File

@ -33,7 +33,8 @@ get_closest_line = (str, line_num) ->
line, line_num
get_line = (str, line_num) ->
for line in str\gmatch "(.-)[\n$]"
-- todo: this returns an extra blank line at the end
for line in str\gmatch "([^\n]*)\n?"
return line if line_num == 1
line_num -= 1