Source: src/codegen/codegen.lx
Top-level codegen driver for the C backend.
Pass A builds the symbol registries from the AST; Pass B emits the C translation unit (enums, structs, prototypes, globals, function bodies). The driver then transpiles the result to a .c file and compiles it with an external C compiler.
Returns true if name is one of the libc/libm names in known_libc_names.
is_known_libc_name -> fn(
name: *byte
) bool
Writes string s to the output FILE* out (an fputs wrapper).
IOWRITE -> fn(
out: *void,
s: *byte
) void
Emits the static C helper functions backing input<T>(...): one raw
__luma_read_byte primitive plus a type-specific wrapper per supported T,
all reading through that un-buffered primitive.
write_input_helpers -> fn(
out: *void,
is_windows: bool
) void
Emits the generated file's C preamble: _GNU_SOURCE, the standard
headers (platform-conditional), the __luma_range_t typedef, and the
input helpers.
write_preamble -> fn(
out: *void,
os: *byte
) void
Registers a struct's method member (a field holding a function value) into the function registry, skipping generic templates and embedded members.
register_method -> fn(
ctx: *CG::CodegenContext,
module_name: *byte,
struct_name: *byte,
member: *AST::AstNode
) void
Registers a concrete generic-method instantiation (a standalone FuncDeclNode with a mangled name) as a method, carrying its owner struct name and static flag.
register_generated_method -> fn(
ctx: *CG::CodegenContext,
module_name: *byte,
owner: *byte,
is_static: i64,
decl: *AST::AstNode
) void
Pass A workhorse: registers one module-level declaration (struct, enum,
function, global, @os arm, or @use alias) into the appropriate
registry, skipping generic templates.
register_decl -> fn(
ctx: *CG::CodegenContext,
os: *byte,
module_name: *byte,
decl: *AST::AstNode
) void
Pass A driver: walks every module in the program (plus the typechecker's generic instantiations) and registers all top-level declarations into the context's registries.
run_pass_a -> fn(
ctx: *CG::CodegenContext,
prog: *AST::ProgramNode,
os: *byte
) void
Emits a typedef enum {...} Name; for every registered enum, using mangled
member names.
emit_enums -> fn(
ctx: *CG::CodegenContext,
buf: *CG::Buf
) void
Emits a forward typedef struct Name Name; for every registered struct.
emit_struct_typedefs -> fn(
ctx: *CG::CodegenContext,
buf: *CG::Buf
) void
Emits one struct's struct Name {...}; body, first recursively emitting
any structs it embeds by value (cycle-guarded). Skips already-defined
structs.
emit_struct_body -> fn(
ctx: *CG::CodegenContext,
buf: *CG::Buf,
s: *CG::StructInfo
) void
Emits the C body for every registered struct.
emit_all_struct_bodies -> fn(
ctx: *CG::CodegenContext,
buf: *CG::Buf
) void
Emits one function's C prototype: main is the fixed
int main(int, char**), methods gain a leading Struct *self parameter,
and names are mangled per the FuncInfo. Known-libc and body-less extern
declarations produce no prototype.
emit_func_prototype -> fn(
ctx: *CG::CodegenContext,
buf: *CG::Buf,
f: *CG::FuncInfo
) void
Emits a C prototype for every registered function that needs one.
emit_all_prototypes -> fn(
ctx: *CG::CodegenContext,
buf: *CG::Buf
) void
Emits one mangled C global definition per registered global, with its initializer if any.
emit_globals -> fn(
ctx: *CG::CodegenContext,
buf: *CG::Buf
) void
Emits one function's C definition: signature with self/param bindings,
then the body statements. Skips externs and body-less declarations; main
binds its fixed argc/argv under __luma_argc/__luma_argv.
emit_func_body -> fn(
ctx: *CG::CodegenContext,
buf: *CG::Buf,
f: *CG::FuncInfo
) void
Emits the C body for every non-extern registered function, main last (cosmetic; prototypes make ordering unnecessary).
emit_all_func_bodies -> fn(
ctx: *CG::CodegenContext,
buf: *CG::Buf
) void
Returns a pointer to the final /-separated segment of path (the
basename), or path itself if it has no slash.
basename_of -> fn(
path: *byte
) *byte
Prefix for the compile command: host cc -w by default, or a mingw-w64
cross compiler when a Windows target was explicitly requested.
target_cc_prefix -> fn(
os: *byte,
target_explicit: bool
) *byte
Returns the output executable name: .exe appended on Windows targets
unless already present. Caller owns the result.
#returns_ownership
target_output_name -> fn(
name: *byte,
os: *byte
) *byte
Transpiles program to C, writes it to output/.c (creating
output/ if needed), and returns the .c path — caller owns it. Returns
null on a null/non-program input or if the file can't be opened.
pub #returns_ownership
codegen_transpile -> fn(
program: *AST::AstNode,
config: CONST::LumaBuildConfig
) *byte
Walks every module of prog and appends each @linked library name to
out, as *byte values owned by the AST (valid as long as prog is).
Both module-level @links and those inside the @os arm matching os
are honored.
pub collect_link_libs -> fn(
prog: *AST::ProgramNode,
os: *byte,
out: *VEC::Vector
) void
Appends the library names reachable from one top-level declaration decl —
a direct @link, or @links nested in the @os arm matching os.
collect_link_decl -> fn(
decl: *AST::AstNode,
os: *byte,
out: *VEC::Vector
) void
Converts a @link library name (libSDL3.so, libc.so.6,
libSDL3.dylib) into a -l<name> cc/ld flag (-lSDL3, -lc, ...) by
stripping a leading lib prefix and cutting at the first extension dot.
Caller owns the result.
#returns_ownership
link_flag_for -> fn(
lib: *byte
) *byte
Compiles/links the C at c_path per config via an external C compiler,
freeing c_path either way (kept on disk when config.save). Returns true
on success.
pub #takes_ownership
codegen_compile -> fn(
c_path: *byte,
config: CONST::LumaBuildConfig
) bool
KNOWN_LIBC_NAME_COUNT: i64 (const) — Number of names in known_libc_names; must match the array size below byknown_libc_names: [*byte; 67] (const) — libc/libm symbol names already declared by the preamble's includes;