Files
potatiat dff481597d [38] docs: add constructors for every AST kind
Only create_module existed. The other kinds in KIND had no
constructor, so nothing could build those nodes.

Signed-off-by: potatiat <potatiat@proton.me>
2026-09-03 10:10:31 -04:00

292 lines
8.8 KiB
Lua

local log = require("log")
local M = {}
M.KIND = {
-- Root node holding file-level documentation and all items.
MODULE = 1,
--- Struct declaration with fields and static asserts.
STRUCT = 2,
--- Union declaration with fields.
UNION = 3,
--- Single member of a struct or union.
FIELD = 4,
--- Enum declaration with variants.
ENUM = 5,
--- Single named constant inside an enum.
VARIANT = 6,
--- Function declaration with parameters and return type.
FUNCTION = 7,
--- Single parameter of a function.
PARAMETER = 8,
--- Typedef alias, optionally a function pointer.
TYPEDEF = 9,
--- #define numeric constant.
CONSTANT = 10,
--- static_assert verifying struct size of invariants.
STATIC_ASSERT = 11,
}
--- Creates a source location table that records where a declaration appears in the original header file. `filepath`
--- is the absolute or relative path to the header. `line_number` and `column_number` tracks where the declaration
--- starts in `filepath`.
---
--- Returns { filepath = filepath, line_number = line_number, column_number = column_number }
function M.create_location_table(filepath, line_number, column_number)
return {filepath = filepath, line_number = line_number, column_number = column_number}
end
--- Create a module node. This mirrors rustdoc's crate root.
--- Returns:
--- {
--- kind = ast.Kind.MODULE, -- integer enum discriminator
--- name = string, -- header filename (e.g. "bal_assembler.h")
--- filepath = string, -- absolute path to the parsed .h file
--- documentation = table|nil, -- parsed //! file-level doc (from doc.lua)
--- items = { -- ordered list of top-level AST nodes
--- { kind = ast.Kind.STRUCT, ... },
--- { kind = ast.Kind.UNION, ... },
--- { kind = ast.Kind.ENUM, ... },
--- { kind = ast.Kind.FUNCTION, ... },
--- { kind = ast.Kind.TYPEDEF, ... },
--- { kind = ast.Kind.CONSTANT, ... },
--- { kind = ast.Kind.STATIC_ASSERT, ... },
--- },
--- location = { filepath = string, line_number = number, column_number = number },
--- }
function M.create_module(name, filepath, documentation)
log.trace("Creating module node '%s' from %s.", name, filepath)
local line_number = 1
local column_number = 1
return
{
kind = M.KIND.MODULE,
name = name,
filepath = filepath,
documentation = documentation,
items = {},
location = M.create_location_table(filepath, line_number, column_number)
}
end
--- Single member of a struct or union.
--- Returns:
--- {
--- kind = ast.Kind.FIELD,
--- name = string,
--- type = string, -- clang type spelling
--- documentation = table|nil,
--- location = { filepath = string, line_number = number, column_number = number },
--- }
function M.create_field(name, type_name, documentation, location)
log.trace("Creating field node '%s'.", name)
return
{
kind = M.KIND.FIELD,
name = name,
type = type_name,
documentation = documentation,
location = location,
}
end
--- Single named constant inside an enum.
--- Returns:
--- {
--- kind = ast.Kind.VARIANT,
--- name = string,
--- value = string, -- enumerator value as text
--- documentation = table|nil,
--- location = { filepath = string, line_number = number, column_number = number },
--- }
function M.create_variant(name, value, documentation, location)
log.trace("Creating variant node '%s'.", name)
return
{
kind = M.KIND.VARIANT,
name = name,
value = value,
documentation = documentation,
location = location,
}
end
--- Single parameter of a function.
--- Returns:
--- {
--- kind = ast.Kind.PARAMETER,
--- name = string,
--- type = string,
--- }
function M.create_parameter(name, type_name)
log.trace("Creating parameter node '%s'.", name)
return
{
kind = M.KIND.PARAMETER,
name = name,
type = type_name,
}
end
--- Struct declaration with fields and static asserts.
--- Returns:
--- {
--- kind = ast.Kind.STRUCT,
--- name = string,
--- fields = { { kind = ast.Kind.FIELD, ... }, ... },
--- documentation = table|nil,
--- location = { filepath = string, line_number = number, column_number = number },
--- }
function M.create_struct(name, fields, documentation, location)
log.trace("Creating struct node '%s'.", name)
return
{
kind = M.KIND.STRUCT,
name = name,
fields = fields or {},
documentation = documentation,
location = location,
}
end
--- Union declaration with fields.
--- Returns:
--- {
--- kind = ast.Kind.UNION,
--- name = string,
--- fields = { { kind = ast.Kind.FIELD, ... }, ... },
--- documentation = table|nil,
--- location = { filepath = string, line_number = number, column_number = number },
--- }
function M.create_union(name, fields, documentation, location)
log.trace("Creating union node '%s'.", name)
return
{
kind = M.KIND.UNION,
name = name,
fields = fields or {},
documentation = documentation,
location = location,
}
end
--- Enum declaration with variants.
--- Returns:
--- {
--- kind = ast.Kind.ENUM,
--- name = string,
--- variants = { { kind = ast.Kind.VARIANT, ... }, ... },
--- documentation = table|nil,
--- location = { filepath = string, line_number = number, column_number = number },
--- }
function M.create_enum(name, variants, documentation, location)
log.trace("Creating enum node '%s'.", name)
return
{
kind = M.KIND.ENUM,
name = name,
variants = variants or {},
documentation = documentation,
location = location,
}
end
--- Function declaration with parameters and return type.
--- Returns:
--- {
--- kind = ast.Kind.FUNCTION,
--- name = string,
--- return_type = string,
--- parameters = { { kind = ast.Kind.PARAMETER, ... }, ... },
--- documentation = table|nil,
--- location = { filepath = string, line_number = number, column_number = number },
--- }
function M.create_function(name, return_type, parameters, documentation, location)
log.trace("Creating function node '%s'.", name)
return
{
kind = M.KIND.FUNCTION,
name = name,
return_type = return_type,
parameters = parameters or {},
documentation = documentation,
location = location,
}
end
--- Typedef alias, optionally a function pointer.
--- Returns:
--- {
--- kind = ast.Kind.TYPEDEF,
--- name = string,
--- underlying_type = string,
--- return_type = string|nil, -- set when the alias is a function pointer
--- parameters = { { kind = ast.Kind.PARAMETER, ... }, ... },
--- documentation = table|nil,
--- location = { filepath = string, line_number = number, column_number = number },
--- }
function M.create_typedef(name, underlying_type, return_type, parameters, documentation, location)
log.trace("Creating typedef node '%s'.", name)
return
{
kind = M.KIND.TYPEDEF,
name = name,
underlying_type = underlying_type,
return_type = return_type,
parameters = parameters or {},
documentation = documentation,
location = location,
}
end
--- #define numeric constant.
--- Returns:
--- {
--- kind = ast.Kind.CONSTANT,
--- name = string,
--- value = string,
--- documentation = table|nil,
--- location = { filepath = string, line_number = number, column_number = number },
--- }
function M.create_constant(name, value, documentation, location)
log.trace("Creating constant node '%s'.", name)
return
{
kind = M.KIND.CONSTANT,
name = name,
value = value,
documentation = documentation,
location = location,
}
end
--- static_assert verifying struct size of invariants.
--- Returns:
--- {
--- kind = ast.Kind.STATIC_ASSERT,
--- message = string,
--- documentation = table|nil,
--- location = { filepath = string, line_number = number, column_number = number },
--- }
function M.create_static_assert(message, documentation, location)
log.trace("Creating static_assert node.")
return
{
kind = M.KIND.STATIC_ASSERT,
message = message,
documentation = documentation,
location = location,
}
end
return M