feat(printer): indent generated code
This commit is contained in:
parent
c2e0da3ba6
commit
8928e67f24
|
@ -11,6 +11,7 @@
|
|||
"ansicolors",
|
||||
"awesomewm",
|
||||
"buildx",
|
||||
"concat",
|
||||
"dryrun",
|
||||
"getcontent",
|
||||
"gitea",
|
||||
|
@ -33,6 +34,7 @@
|
|||
"modname",
|
||||
"reportfile",
|
||||
"rockspec",
|
||||
"rstrip",
|
||||
"runreport",
|
||||
"setopt",
|
||||
"statsfile",
|
||||
|
|
|
@ -7,7 +7,7 @@ local printer = teal_type_definition_printer.printer
|
|||
|
||||
-- We need to remove the last newline inserted by Penlight's dedent
|
||||
local function dedent(str: string): string
|
||||
return (stringx.dedent(str):sub(1, -3):gsub("\n *", "\n")) -- we remove indentation for now, the printer should be fixed soon
|
||||
return (stringx.dedent(str):sub(1, -2))
|
||||
end
|
||||
|
||||
local function gen(ast: Node, expected_code: string): function()
|
||||
|
|
|
@ -9,97 +9,149 @@ local function render_types(types: { string }): string
|
|||
if not types or #types == 0 then
|
||||
return ""
|
||||
end
|
||||
return ": " .. table.concat(types, " | ")
|
||||
end
|
||||
|
||||
return ": " .. stringx.join(" | ", types)
|
||||
local function dedent(str: string): string
|
||||
return stringx.dedent(str):sub(1, -2)
|
||||
end
|
||||
|
||||
local function render_code(code: string, indent_level: integer): string
|
||||
if not code or code == "" then
|
||||
return ""
|
||||
end
|
||||
|
||||
local generated = ""
|
||||
for line in stringx.lines(dedent(code)) do
|
||||
generated = generated .. stringx.rstrip(string.rep(" ", 3 * indent_level) .. line) .. "\n"
|
||||
end
|
||||
return generated
|
||||
end
|
||||
|
||||
local record Node_Printer_Function
|
||||
on_node: function(node: Node): string
|
||||
before_node: nil | function(node: Node): string
|
||||
after_node: nil | function(node: Node): string
|
||||
on_node: function(node: Node, indent_level: integer): string, integer
|
||||
before_node: nil | function(node: Node, indent_level: integer): string, integer
|
||||
after_node: nil | function(node: Node, indent_level: integer): string, integer
|
||||
end
|
||||
|
||||
-- pre-declare functions to prevent forward reference errors
|
||||
local print_teal: function(node: Node): string
|
||||
local print_teal: function(node: Node, indent_level: integer | nil): string
|
||||
local print_children: function(node: Node): string
|
||||
|
||||
local node_printer <total>: { Node.Token : Node_Printer_Function } = {
|
||||
["module"] = {
|
||||
before_node = function(node: Node): string
|
||||
return "-- This file was auto-generated.\n\nlocal record " .. node.name .. "\n"
|
||||
before_node = function(node: Node, indent_level: integer): string, integer
|
||||
return render_code(
|
||||
string.format(
|
||||
[[
|
||||
-- This file was auto-generated.
|
||||
|
||||
local record %s
|
||||
]],
|
||||
node.name),
|
||||
indent_level), indent_level + 1
|
||||
end,
|
||||
on_node = function(node: Node): string
|
||||
return print_children(node)
|
||||
on_node = function(node: Node, indent_level: integer): string, integer
|
||||
return render_code(print_children(node), indent_level), indent_level
|
||||
end,
|
||||
after_node = function(node: Node): string
|
||||
return "end\n\nreturn " .. node.name
|
||||
after_node = function(node: Node, indent_level: integer): string, integer
|
||||
return render_code("end", indent_level - 1) ..
|
||||
"\n" ..
|
||||
render_code(
|
||||
string.format("return %s", node.name),
|
||||
indent_level - 1
|
||||
), indent_level - 1
|
||||
end,
|
||||
},
|
||||
["record"] = {
|
||||
before_node = function(node: Node): string
|
||||
return "record " .. node.name .. "\n"
|
||||
before_node = function(node: Node, indent_level: integer): string, integer
|
||||
return render_code(
|
||||
string.format(
|
||||
"record %s",
|
||||
node.name),
|
||||
indent_level), indent_level + 1
|
||||
end,
|
||||
on_node = function(node: Node): string
|
||||
return print_children(node)
|
||||
on_node = function(node: Node, indent_level: integer): string, integer
|
||||
return render_code(print_children(node), indent_level), indent_level
|
||||
end,
|
||||
after_node = function(): string
|
||||
return "end"
|
||||
after_node = function(_: Node, indent_level: integer): string, integer
|
||||
return render_code("end", indent_level - 1), indent_level - 1
|
||||
end,
|
||||
},
|
||||
["enum"] = {
|
||||
before_node = function(node: Node): string
|
||||
return "enum " .. node.name .. "\n"
|
||||
before_node = function(node: Node, indent_level: integer): string, integer
|
||||
return render_code(
|
||||
string.format(
|
||||
"enum %s",
|
||||
node.name),
|
||||
indent_level), indent_level + 1
|
||||
end,
|
||||
on_node = function(node: Node): string
|
||||
return print_children(node)
|
||||
on_node = function(node: Node, indent_level: integer): string, integer
|
||||
return render_code(print_children(node), indent_level), indent_level
|
||||
end,
|
||||
after_node = function(): string
|
||||
return "end"
|
||||
after_node = function(_: Node, indent_level: integer): string, integer
|
||||
return render_code("end", indent_level - 1), indent_level - 1
|
||||
end,
|
||||
},
|
||||
["identifier"] = {
|
||||
on_node = function(node: Node): string
|
||||
return "\"" .. node.name .. "\""
|
||||
on_node = function(node: Node, indent_level: integer): string, integer
|
||||
return render_code(string.format('"%s"', node.name), indent_level), indent_level
|
||||
end,
|
||||
},
|
||||
["variable"] = {
|
||||
on_node = function(node: Node): string
|
||||
return node.name .. render_types(node.types)
|
||||
on_node = function(node: Node, indent_level: integer): string, integer
|
||||
return render_code(
|
||||
string.format(
|
||||
"%s%s",
|
||||
node.name,
|
||||
render_types(node.types)),
|
||||
indent_level), indent_level
|
||||
end,
|
||||
},
|
||||
["function"] = {
|
||||
on_node = function(node: Node): string
|
||||
on_node = function(node: Node, indent_level: integer): string, integer
|
||||
local args = {}
|
||||
for _, parameter in ipairs(node.parameters) do
|
||||
table.insert(args, print_teal(parameter))
|
||||
table.insert(args, print_teal(parameter):sub(1, -2)) -- need to remove the newline ending
|
||||
end
|
||||
return node.name .. ": function(" .. table.concat(args, ", ") .. ")" .. render_types(node.return_types)
|
||||
return render_code(
|
||||
string.format(
|
||||
"%s: function(%s)%s",
|
||||
node.name,
|
||||
table.concat(args, ", "),
|
||||
render_types(node.return_types)),
|
||||
indent_level), indent_level
|
||||
end,
|
||||
},
|
||||
["metamethod"] = {
|
||||
on_node = function(): string
|
||||
on_node = function(): string, integer
|
||||
log:warn("Metamethods are not supported yet")
|
||||
end,
|
||||
}
|
||||
}
|
||||
|
||||
function print_teal(node: Node): string
|
||||
function print_teal(node: Node, indent_level: integer | nil): string
|
||||
indent_level = indent_level or 0
|
||||
local printer = node_printer[node.token]
|
||||
local generated = ""
|
||||
local full_generated = ""
|
||||
if printer.before_node then
|
||||
generated = (printer.before_node as function(node: Node): string)(node)
|
||||
generated, indent_level = (printer.before_node as function(Node, integer): string, integer)(node, indent_level)
|
||||
full_generated = generated
|
||||
end
|
||||
generated = generated .. printer.on_node(node)
|
||||
generated, indent_level = printer.on_node(node, indent_level)
|
||||
full_generated = full_generated .. generated
|
||||
if printer.after_node then
|
||||
generated = generated .. (printer.after_node as function(node: Node): string)(node)
|
||||
generated, indent_level = (printer.after_node as function(Node, integer): string, integer)(node, indent_level)
|
||||
full_generated = full_generated .. generated
|
||||
end
|
||||
return generated
|
||||
return full_generated
|
||||
end
|
||||
|
||||
function print_children(node: Node): string
|
||||
local generated = ""
|
||||
for _, child in ast.iter_children(node) do
|
||||
generated = generated .. print_teal(child) .. "\n"
|
||||
generated = generated .. print_teal(child)
|
||||
end
|
||||
return generated
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue