diff --git a/src/awesomewm.d.tl/ast.tl b/src/awesomewm.d.tl/ast.tl index b4a469f..0f8a608 100644 --- a/src/awesomewm.d.tl/ast.tl +++ b/src/awesomewm.d.tl/ast.tl @@ -58,6 +58,11 @@ local function create_node(token: Node.Token, name: string): Node return node end +local function iter_children(node: Node): function(): integer, Node + return ipairs(node.children) +end + return { create_node = create_node, + iter_children = iter_children, } diff --git a/src/awesomewm.d.tl/generator/teal_type_definitions.tl b/src/awesomewm.d.tl/generator/teal_type_definitions.tl index 0a1d31a..39393d1 100644 --- a/src/awesomewm.d.tl/generator/teal_type_definitions.tl +++ b/src/awesomewm.d.tl/generator/teal_type_definitions.tl @@ -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 : { 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, +} diff --git a/src/awesomewm.d.tl/init.tl b/src/awesomewm.d.tl/init.tl index 5f228eb..605b341 100644 --- a/src/awesomewm.d.tl/init.tl +++ b/src/awesomewm.d.tl/init.tl @@ -142,7 +142,7 @@ end -- end local module_ast, other_nodes = scraper.module_doc.get_doc_from_page( - crawler.fetch(property.base_url .. "/widgets/wibox.widget.imagebox.html"), + crawler.fetch(property.base_url .. "/core_components/tag.html"), "awful.tag" ) @@ -150,3 +150,8 @@ log:info(logger.message_with_metadata("Finished", { module_ast = module_ast, other_nodes = other_nodes, })) + +filesystem.file_writer.write( + generator.teal_type_definitions.generate_teal(module_ast), + property.out_directory .. "/" .. "generated_from_ast" .. ".d.tl" +)