|
|
|
@ -1,56 +1,116 @@
|
|
|
|
|
local Module_Doc = require "entity.Module_Doc"
|
|
|
|
|
local template = require "pl.template"
|
|
|
|
|
local utils = require "utils"
|
|
|
|
|
local snippets = require "generator.snippets"
|
|
|
|
|
local ast = require "ast"
|
|
|
|
|
local logger = require "logger"
|
|
|
|
|
local type Node = require "types.Node"
|
|
|
|
|
|
|
|
|
|
-- The long therm goal is to have so many `snippets.render_*` functions that
|
|
|
|
|
-- we can render the whole file with the smallest template possible.
|
|
|
|
|
local tmpl = [[
|
|
|
|
|
-- Auto generated file (Do not manually edit this file!)
|
|
|
|
|
local log = logger.log("scraper")
|
|
|
|
|
|
|
|
|
|
# if module.requires:len() ~= 0 then
|
|
|
|
|
$(snippets.render_requires(module.requires))
|
|
|
|
|
# end -- /requires
|
|
|
|
|
|
|
|
|
|
local record $(module.record_name)
|
|
|
|
|
# if #module.signals ~= 0 then
|
|
|
|
|
$(snippets.indent(snippets.render_enum("Signal", module.signals)))
|
|
|
|
|
|
|
|
|
|
# end -- /signals
|
|
|
|
|
# if #module.methods ~= 0 then
|
|
|
|
|
-- Object methods
|
|
|
|
|
$(snippets.indent(snippets.render_record_functions(module.methods)))
|
|
|
|
|
|
|
|
|
|
# end -- /methods
|
|
|
|
|
# if #module.properties ~= 0 then
|
|
|
|
|
-- Object properties
|
|
|
|
|
$(snippets.indent(snippets.render_record_properties(module.properties)))
|
|
|
|
|
|
|
|
|
|
# end -- /properties
|
|
|
|
|
# if #module.constructors ~= 0 then
|
|
|
|
|
-- Constructors
|
|
|
|
|
$(snippets.indent(snippets.render_record_functions(module.constructors)))
|
|
|
|
|
|
|
|
|
|
# end -- /constructors
|
|
|
|
|
# if #module.static_functions ~= 0 then
|
|
|
|
|
-- Static functions
|
|
|
|
|
$(snippets.indent(snippets.render_record_functions(module.static_functions)))
|
|
|
|
|
# end -- /static_functions
|
|
|
|
|
local function concatenate_strings(strings: { string }): string
|
|
|
|
|
local result = ""
|
|
|
|
|
for _, str in ipairs(strings) do
|
|
|
|
|
result = result .. str
|
|
|
|
|
end
|
|
|
|
|
return result
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
return $(module.record_name)
|
|
|
|
|
]]
|
|
|
|
|
local function render_types(types: { string }): string
|
|
|
|
|
if not types or #types == 0 then
|
|
|
|
|
return ""
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local module = {}
|
|
|
|
|
return ": " .. concatenate_strings(types)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function module.generate_teal(data: Module_Doc.Module_Doc): string
|
|
|
|
|
local tmpl_args = {
|
|
|
|
|
ipairs = ipairs,
|
|
|
|
|
module = data,
|
|
|
|
|
snippets = snippets,
|
|
|
|
|
local record Node_Generator_Function
|
|
|
|
|
on_node: function(node: Node): string
|
|
|
|
|
before_node: nil | function(node: Node): string
|
|
|
|
|
after_node: nil | function(node: Node): string
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- pre-declare functions to prevent forward reference errors
|
|
|
|
|
local generate_teal: function(node: Node): string
|
|
|
|
|
local generate_children: function(node: Node): string
|
|
|
|
|
|
|
|
|
|
local node_generator <total>: { Node.Token : Node_Generator_Function } = {
|
|
|
|
|
["module"] = {
|
|
|
|
|
before_node = function(node: Node): string
|
|
|
|
|
return "-- This file was auto-generated.\n\nlocal record " .. node.name .. "\n"
|
|
|
|
|
end,
|
|
|
|
|
on_node = function(node: Node): string
|
|
|
|
|
return generate_children(node)
|
|
|
|
|
end,
|
|
|
|
|
after_node = function(node: Node): string
|
|
|
|
|
return "end\n\nreturn " .. node.name
|
|
|
|
|
end,
|
|
|
|
|
},
|
|
|
|
|
["record"] = {
|
|
|
|
|
before_node = function(node: Node): string
|
|
|
|
|
return "local record " .. node.name
|
|
|
|
|
end,
|
|
|
|
|
on_node = function(node: Node): string
|
|
|
|
|
return generate_children(node)
|
|
|
|
|
end,
|
|
|
|
|
after_node = function(): string
|
|
|
|
|
return "end"
|
|
|
|
|
end,
|
|
|
|
|
},
|
|
|
|
|
["enum"] = {
|
|
|
|
|
before_node = function(node: Node): string
|
|
|
|
|
return "enum " .. node.name .. "\n"
|
|
|
|
|
end,
|
|
|
|
|
on_node = function(node: Node): string
|
|
|
|
|
return generate_children(node)
|
|
|
|
|
end,
|
|
|
|
|
after_node = function(): string
|
|
|
|
|
return "end"
|
|
|
|
|
end,
|
|
|
|
|
},
|
|
|
|
|
["identifier"] = {
|
|
|
|
|
on_node = function(node: Node): string
|
|
|
|
|
return "\"" .. node.name .. "\""
|
|
|
|
|
end,
|
|
|
|
|
},
|
|
|
|
|
["variable"] = {
|
|
|
|
|
on_node = function(node: Node): string
|
|
|
|
|
return node.name .. render_types(node.types)
|
|
|
|
|
end,
|
|
|
|
|
},
|
|
|
|
|
["function"] = {
|
|
|
|
|
on_node = function(node: Node): string
|
|
|
|
|
local args = {}
|
|
|
|
|
for _, parameter in ipairs(node.parameters) do
|
|
|
|
|
table.insert(args, generate_teal(parameter))
|
|
|
|
|
end
|
|
|
|
|
return node.name .. ": function(" .. table.concat(args, ", ") .. ")" .. render_types(node.return_types)
|
|
|
|
|
end,
|
|
|
|
|
},
|
|
|
|
|
["metamethod"] = {
|
|
|
|
|
on_node = function(): string
|
|
|
|
|
log:warn("Metamethods are not supported yet")
|
|
|
|
|
end,
|
|
|
|
|
}
|
|
|
|
|
return utils.do_or_fail(template.substitute, tmpl, tmpl_args)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function generate_teal(node: Node): string
|
|
|
|
|
local generator = node_generator[node.token]
|
|
|
|
|
local generated = ""
|
|
|
|
|
if generator.before_node then
|
|
|
|
|
generated = (generator.before_node as function(node: Node): string)(node)
|
|
|
|
|
end
|
|
|
|
|
generated = generated .. generator.on_node(node)
|
|
|
|
|
if generator.after_node then
|
|
|
|
|
generated = generated .. (generator.after_node as function(node: Node): string)(node)
|
|
|
|
|
end
|
|
|
|
|
return generated
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
return module
|
|
|
|
|
function generate_children(node: Node): string
|
|
|
|
|
local generated = ""
|
|
|
|
|
for _, child in ast.iter_children(node) do
|
|
|
|
|
generated = generated .. generate_teal(child) .. "\n"
|
|
|
|
|
end
|
|
|
|
|
return generated
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
generate_teal = generate_teal,
|
|
|
|
|
}
|
|
|
|
|