mirror of
https://github.com/leafo/moonscript.git
synced 2024-11-22 02:44:23 +00:00
wip for new line rewriter
This commit is contained in:
parent
448c2e53d5
commit
6d52237380
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -73,6 +73,9 @@ rewrite_traceback = function(text, err)
|
||||
fname,
|
||||
":",
|
||||
reverse_line_number(fname, tbl, line, cache),
|
||||
"(",
|
||||
line,
|
||||
")",
|
||||
": ",
|
||||
msg
|
||||
})
|
||||
|
@ -63,6 +63,7 @@ rewrite_traceback = (text, err) ->
|
||||
concat {
|
||||
fname, ":"
|
||||
reverse_line_number(fname, tbl, line, cache)
|
||||
"(", line, ")"
|
||||
": ", msg
|
||||
}
|
||||
else
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user