-- (but I wouldn't paralleize it right now anyway)
local line = 1
-function build_type(text, type_, color)
+function build_type(type_, color)
+ local text = ""
for _, t in ipairs(type_.param_types) do
- table.insert(text, { text = t .. " ", color = color })
+ text = text .. t .. " "
end
if #type_.param_types == 0 then
- table.insert(text, { text = "void ", color = color })
+ text = text .. "void "
end
- table.insert(text, { text = "-> " })
+ text = text .. "-> "
for _, t in ipairs(type_.result_types) do
- table.insert(text, { text = t .. " " })
+ text = text .. t .. " "
end
if #type_.result_types == 0 then
- table.insert(text, { text = "void" })
+ text = text .. "void"
end
+
+ return { text; fg = color }
end
-function build_header(func, mod, colors)
+-- Ctx -> List TextObj
+function build_header(ctx)
local text = {}
- if mod.start ~= nil and mod.start.contents.func == func.funcidx then
- table.insert(text, { text = "*START* ", color = colors.primary_text })
+ if ctx.mod.start ~= nil and ctx.mod.start.contents.func == ctx.func.funcidx then
+ table.insert(text, { "*START* ", fg = ctx.colors.primary_text })
end
- table.insert(text, { text = "func[" .. func.funcidx .. "] ", color = colors.code })
- table.insert(text, { text = func.name, color = colors.keyword })
- table.insert(text, { text = ": ", color = colors.code })
-
- build_type(text, func.type_, colors.code)
- table.insert(text, { newline = true })
+ table.insert(text, { "func[" .. ctx.func.funcidx .. "] ", fg = ctx.colors.code })
+ table.insert(text, { ctx.func.name, fg = ctx.colors.keyword })
+ table.insert(text, { ": ", fg = ctx.colors.code })
+ table.insert(text, build_type(ctx.func.type_, ctx.colors.code))
return text
end
+-- This will be moved into ui/text
function add_line_number(textlist, colors, newline)
if newline == nil then newline = true end
line = line + 1
end
-function instr_to_text(textlist, instr, func, mod, colors)
+-- Ctx -> Instr -> List List TextObj
+function instr_to_text(ctx, instr)
+ local lines = {}
+
if instr[1] == "block" then
- table.insert(textlist, { change_indent = 1 })
- for _, ins in ipairs(instr.instrs) do
- instr_to_text(textlist, ins, func, mod, colors)
+ table.insert(lines, { indent = 1 })
+ for i, ins in ipairs(instr.instrs) do
+ local res = instr_to_text(ctx, ins)
+ table.append(lines, res)
end
- table.insert(textlist, { change_indent = -1 })
- add_line_number(textlist, colors)
- table.insert(textlist, { text = "label ", color = colors.jumppoint })
- table.insert(textlist, { text = instr.label, color = colors.value })
+ table.insert(lines, {
+ indent = -1;
+ { "label ", fg = ctx.colors.jumppoint };
+ { instr.label, fg = ctx.colors.value };
+ })
elseif instr[1] == "loop" then
- add_line_number(textlist, colors)
- table.insert(textlist, { text = "loop ", color = colors.jumppoint })
- table.insert(textlist, { text = instr.label, color = colors.value, change_indent = 1 })
-
- for _, ins in ipairs(instr.instrs) do
- instr_to_text(textlist, ins, func, mod, colors)
+ table.insert(lines, {
+ { "loop ", fg = ctx.colors.jumppoint };
+ { instr.label, fg = ctx.colors.value };
+ })
+ table.insert(lines, { indent = 1 })
+ for i, ins in ipairs(instr.instrs) do
+ local res = instr_to_text(ctx, ins)
+ table.append(lines, res)
end
- table.insert(textlist, { change_indent = -1 })
+ table.insert(lines, { indent = -1 })
elseif instr[1] == "if" then
- add_line_number(textlist, colors)
- table.insert(textlist, { text = "if", color = colors.jumppoint, change_indent = 1 })
- for _, ins in ipairs(instr.instrs) do
- instr_to_text(textlist, ins, func, mod, colors)
+ table.insert(lines, {
+ { "if ", fg = ctx.colors.jumppoint };
+ { instr.label, fg = ctx.colors.value };
+ })
+ table.insert(lines, { indent = 1 })
+ for i, ins in ipairs(instr.instrs) do
+ local res = instr_to_text(ctx, ins)
+ table.append(lines, res)
end
- table.insert(textlist, { change_indent = -1 })
+ table.insert(lines, { indent = -1 })
if #instr.else_instrs > 0 then
- add_line_number(textlist, colors)
- table.insert(textlist, { text = "else", color = colors.jumppoint, change_indent = 1 })
- for _, ins in ipairs(instr.else_instrs) do
- instr_to_text(textlist, ins, func, mod, colors)
+ table.insert(lines, { "else", fg = ctx.colors.jumppoint })
+ table.insert(lines, { indent = 1 })
+ for i, ins in ipairs(instr.instrs) do
+ local res = instr_to_text(ctx, ins)
+ table.append(lines, res)
end
- table.insert(textlist, { change_indent = -1 })
+ table.insert(lines, { indent = -1 })
end
elseif instr[1] == "call" then
- add_line_number(textlist, colors)
- table.insert(textlist, { text = instr[1] .. " ", color = colors.keyword })
- table.insert(textlist, { text = mod.funcs[instr.x].name, color = colors.value })
+ table.insert(lines, {
+ { "call ", fg = ctx.colors.keyword },
+ { ctx.mod.funcs[instr.x].name, fg = ctx.colors.value }
+ })
elseif instr[1] == "call_indirect" then
- add_line_number(textlist, colors)
- table.insert(textlist, { text = ("%s [%d] "):format(instr[1], instr.table), color = colors.keyword })
- build_type(textlist, mod.types.contents[instr.x + 1], colors.code)
+ table.insert(lines, {
+ { ("%s [%d] "):format(instr[1], instr.table), fg = ctx.colors.keyword },
+ build_type(ctx.mod.types.contents[instr.x + 1], ctx.colors.code)
+ })
elseif instr[1]:match("local") then
- add_line_number(textlist, colors)
- table.insert(textlist, { text = instr[1] .. " ", color = colors.keyword })
- table.insert(textlist, { text = func.locals[instr.x + 1].name, color = colors.value })
+ table.insert(lines, {
+ { instr[1] .. " ", fg = ctx.colors.keyword },
+ { ctx.func.locals[instr.x + 1].name, fg = ctx.colors.value }
+ })
else
- add_line_number(textlist, colors)
- table.insert(textlist, { text = instr[1] .. " ", color = colors.keyword })
+ local line = {}
+ table.insert(line, { instr[1] .. " ", fg = ctx.colors.keyword })
if instr.x then
if type(instr.x) == "table" then
if instr.x[1] == "memarg" then
- table.insert(textlist, {
- text = ("align=0x%02x offset=0x%04x"):format(instr.x.align, instr.x.offset);
- color = colors.value
+ table.insert(line, {
+ ("align=0x%02x offset=0x%04x"):format(instr.x.align, instr.x.offset);
+ fg = ctx.colors.value
})
end
if instr.x[1] == "labelidx" then
if instr.x.block then
- table.insert(textlist, { text = instr.x.block.label .. " ", color = colors.value })
+ table.insert(line, { instr.x.block.label .. " ", fg = ctx.colors.value })
end
- table.insert(textlist, { text = ("[0x%02x]"):format(instr.x.labelidx), color = colors.code })
+ table.insert(line, { ("[0x%02x]"):format(instr.x.labelidx), fg = ctx.colors.code })
end
else
- table.insert(textlist, { text = tostring(instr.x), color = colors.value })
+ table.insert(line, { tostring(instr.x), fg = ctx.colors.value })
end
end
+
+ lines = { line }
end
- return line
+ return lines
end
-function build_body(func, mod, colors)
- if func.imported then
- return { { text = "Imported function", colors = colors.code } }
+
+function build_body(ctx)
+ if ctx.func.imported then
+ return { { "Imported function", fg = ctx.colors.code } }
end
- local text = {}
- table.insert(text, { text = " Locals:", color = colors.keyword, newline = true, change_indent = 2 })
- for _, loc in ipairs(func.locals) do
- table.insert(text, { text = loc.type_ .. " " .. loc.name, color = colors.code , newline = true })
+ local lines = {}
+ table.insert(lines, {
+ { " Locals:", fg = ctx.colors.keyword }
+ })
+ table.insert(lines, { indent = 1 })
+ for _, loc in ipairs(ctx.func.locals) do
+ table.insert(lines, {
+ { loc.type_ .. " " .. loc.name, fg = ctx.colors.code }
+ })
end
- if #func.locals == 0 then
- table.insert(text, { text = "no locals", color = colors.code, newline = true })
+ if #ctx.func.locals == 0 then
+ table.insert(lines, {
+ { "no locals", fg = ctx.colors.code }
+ })
end
- table.insert(text, { newline = true, change_indent = -2 })
- table.insert(text, { text = " Body:", color = colors.keyword })
+ table.insert(lines, { indent = -1 })
+ table.insert(lines, {
+ { " Body:", fg = ctx.colors.keyword }
+ })
- for _, instr in ipairs(func.body) do
- instr_to_text(text, instr, func, mod, colors)
+ local code_lines = {}
+ for _, instr in ipairs(ctx.func.body) do
+ table.append(code_lines, instr_to_text(ctx, instr))
end
- return text
+ return lines, code_lines
end
function generate_text_format(func, mod, colors, line_start)
- line = line_start or 1
- local heading = build_header(func, mod, colors)
- local body = build_body(func, mod, colors)
- return heading, body
+ local ctx = {
+ func = func;
+ mod = mod;
+ colors = colors;
+ }
+ local heading = build_header(ctx)
+ local body_preface, body = build_body(ctx)
+ return { heading }, body_preface, body
end
return module {
build_header = build_header;
build_body = build_body;
}
+
+
+-- function instr_to_text_old(textlist, instr, func, mod, colors)
+-- if instr[1] == "block" then
+-- table.insert(textlist, { change_indent = 1 })
+-- for _, ins in ipairs(instr.instrs) do
+-- instr_to_text(textlist, ins, func, mod, colors)
+-- end
+-- table.insert(textlist, { change_indent = -1 })
+-- add_line_number(textlist, colors)
+-- table.insert(textlist, { text = "label ", color = colors.jumppoint })
+-- table.insert(textlist, { text = instr.label, color = colors.value })
+--
+-- elseif instr[1] == "loop" then
+-- add_line_number(textlist, colors)
+-- table.insert(textlist, { text = "loop ", color = colors.jumppoint })
+-- table.insert(textlist, { text = instr.label, color = colors.value, change_indent = 1 })
+--
+-- for _, ins in ipairs(instr.instrs) do
+-- instr_to_text(textlist, ins, func, mod, colors)
+-- end
+-- table.insert(textlist, { change_indent = -1 })
+--
+-- elseif instr[1] == "if" then
+-- add_line_number(textlist, colors)
+-- table.insert(textlist, { text = "if", color = colors.jumppoint, change_indent = 1 })
+-- for _, ins in ipairs(instr.instrs) do
+-- instr_to_text(textlist, ins, func, mod, colors)
+-- end
+-- table.insert(textlist, { change_indent = -1 })
+--
+-- if #instr.else_instrs > 0 then
+-- add_line_number(textlist, colors)
+-- table.insert(textlist, { text = "else", color = colors.jumppoint, change_indent = 1 })
+-- for _, ins in ipairs(instr.else_instrs) do
+-- instr_to_text(textlist, ins, func, mod, colors)
+-- end
+-- table.insert(textlist, { change_indent = -1 })
+-- end
+--
+-- elseif instr[1] == "call" then
+-- add_line_number(textlist, colors)
+-- table.insert(textlist, { text = instr[1] .. " ", color = colors.keyword })
+-- table.insert(textlist, { text = mod.funcs[instr.x].name, color = colors.value })
+--
+-- elseif instr[1] == "call_indirect" then
+-- add_line_number(textlist, colors)
+-- table.insert(textlist, { text = ("%s [%d] "):format(instr[1], instr.table), color = colors.keyword })
+-- build_type(textlist, mod.types.contents[instr.x + 1], colors.code)
+--
+-- elseif instr[1]:match("local") then
+-- add_line_number(textlist, colors)
+-- table.insert(textlist, { text = instr[1] .. " ", color = colors.keyword })
+-- table.insert(textlist, { text = func.locals[instr.x + 1].name, color = colors.value })
+--
+-- else
+-- add_line_number(textlist, colors)
+-- table.insert(textlist, { text = instr[1] .. " ", color = colors.keyword })
+-- if instr.x then
+-- if type(instr.x) == "table" then
+-- if instr.x[1] == "memarg" then
+-- table.insert(textlist, {
+-- text = ("align=0x%02x offset=0x%04x"):format(instr.x.align, instr.x.offset);
+-- color = colors.value
+-- })
+-- end
+--
+-- if instr.x[1] == "labelidx" then
+-- if instr.x.block then
+-- table.insert(textlist, { text = instr.x.block.label .. " ", color = colors.value })
+-- end
+-- table.insert(textlist, { text = ("[0x%02x]"):format(instr.x.labelidx), color = colors.code })
+-- end
+-- else
+-- table.insert(textlist, { text = tostring(instr.x), color = colors.value })
+-- end
+-- end
+-- end
+--
+-- return line
+-- end