nanofil, read as Prolog
nanofil is a C compiler written in Prolog that emits Fil-C ABI assembly. It aims to read like the standards it implements: each fact about C, the IR or Fil-C stated once, as a relation everything else reads (the campaign). These pages draw its source as terms: clause heads over their goals, conditionals as tables, fact tables as tables, PlDoc as signatures. Compile C with it in the browser, or compare how terms are set in the workbench.
alias.plAddress expressions for milestone 5: alias_facts/2 writes each address of a strict SSA function as a base plus a constant offset. The facts are not a no-alias or bounds proof.amd64.plThe naive x86-64 SysV backend for the phase-one IR in plain (non-Fil-C) mode (milestone 2). It is the reference the later instruction selection and register allocation milestones are checked against, so it favours being obviously right over being fast.amd64_cache.plOpt-in block-local caching of private integer frame homes in r10/r11. This is not instruction selection or general register allocation. All eight bytes of a home stay together, even when a read uses only its low word. Every alias must be w/l. Pointers, roots, phi shadows, local storage and ABI bookkeeping retain their original homes.amd64_cache_check.plIndependent translation validation for the block-local scalar cache. There are no allocation intervals, slot assignments or eviction plans here. The two streams execute together on symbolic register and home contents; only the three eligible moves may differ, and a load may be absent when its complete result is already in its destination. All other lines match exactly, including flags, failure arguments and control flow.amd64_contract.plAudited machine forms for the scalar stack cache. Unknown forms fail, selecting the unchanged implementation, rather than guessing effects. Reads name register families. write(Family,Bits) records partial writes: 32 bits zero-extend, 8/16 preserve the rest. Memory effects include addressing-register reads; flags and control/frame effects are separate. This describes selected instructions, not IR liveness or GC roots. Calls are unconditional cache boundaries; their ABI argument reads are not enumerated. Do not use this as a general call-liveness contract. asm.plx86-64 assembly as terms, and their printer as GNU as (AT&T) text. The backends build a list of lines; this module is the only place that knows AT&T syntax.c_lex.plThe C lexer (milestone 4a): it turns preprocessed C text into a list of tokens, each with its file and line.c_lower.plLowering from C to IR (milestone 4b), in the style of cproc: it turns the parsed translation unit into an IR module for the Fil-C backend.c_parse.plThe C parser (milestone 4a): it turns the tokens from c_lex into a syntax tree.c_pp.plThe C preprocessor (milestone 4e): it expands a C file's macros, includes and conditionals and hands the result to c_lex as tokens.c_types.plC's types as terms: specifiers and declarators become type terms, and from those come sizes and layouts, the integer conversions and the values of constant expressions (milestone 4a).cfg.plControl-flow analyses over one function's blocks, as pure functions from IR terms to assocs keyed by block label.cfg_tabled.plThe analyses of cfg.pl as tabled relations over IR facts, in the two styles the handoff proposed. They exist to answer PLAN's open question by measurement (tests/bench-cfg.pl, docs/m5.md); passes use cfg.pl.copy.plCopy propagation, run after promote: copy_module/2 removes copies and trivial phis from each function in strict SSA form, replacing every use by the value it copies.escape.plEscape classification of allocs: alloc_classes/2 tells, for each alloc of a function, whether its address is only used for loads and stores at known offsets. Prior art: QBE's ALoc/AEsc.filc_abi.plFil-C ABI lowering, before AMD64 placement and instruction selection.filc_amd64.plThe Fil-C backend for x86-64: filc_abi.pl lowers checked functions to frame, call and entry products; this module places their words and emits asm.pl lines whose GNU as text links with code clang builds for filnix staging Fil-C 0.687. Checked pointer-memory emission remains here, as does global-data serialization and getter initialization.frame_slots.plConservative stack-slot allocation for the Fil-C backend: temp_slots/6 assigns each temporary a frame slot, and temporaries whose live intervals are disjoint may share one.ieee.plIEEE 754 binary32 and binary64 arithmetic with integers only, rounding to nearest, ties to even.interp.plRelational semantics of the IR (ir.pl): the outcome of running a function of a module, as a relation that runs in every direction, so that arguments and outcome can both be partially unknown.ir.plThe nanofil IR: modules of functions and data as ground Prolog terms, the contract between the frontend, the middle end, the interpreter and the backends. This module states its grammar and checks that a module is well formed.ir_text.plIR text: a module written as Prolog clauses, one func/5 or data/4 term (ir.pl) per item in module order, and read back with read_term/3.local_storage.plNonescaping memory that remains after scalar promotion.main.plThe nanofil command line: the impure driver that reads a C or IR file, runs it through the compiler's stages and prints the result.opt.plThe middle end's entry points for the driver, and the comparison the interpreter uses to validate it.pizlonate.plPizlonation: from the unchecked IR to the checked IR (ir.pl), the form the Fil-C backend compiles, named after Fil-C's LLVM pass.promote.plPromotion of memory slots to SSA temporaries, by promote_module/2 and promote_func/3. Prior art: QBE's promote and ssa passes, LLVM's mem2reg.provenance.plExplanatory context, separate from executable IR and safety evidence.