main.pl
The nanofil command line: the impure driver that reads a C or IR file, runs it through the compiler's stages and prints the result.
Commands
| Command | Does |
|---|---|
check FILE | read and validate; prints ok |
print FILE | read, validate, print the IR (ir_text.pl) |
compile FILE | read, validate, print x86-64 assembly |
cc FILE | compile C (.c, or preprocessed .i) to Fil-C assembly |
cc-ir FILE | compile C, print the IR (unchecked; the Fil-C backend's input is pizlonated) |
tokens FILE | print C token terms, without locations |
run FILE FN ARG... | interpret FN on integer arguments |
difftest FILE OUTDIR | write OUTDIR/expected.txt, OUTDIR/harness.c and OUTDIR/mode for the file's runFn, Args facts |
A FILE ending in .c or .i goes through the C frontend; any other FILE is IR text. A .c file is preprocessed with the predefined macros and include paths of $FILCC (default filcc).
┌──────┐ ┌─────────┐ ┌─────────┐ │ c_pp │─▶│ c_parse │─▶│ c_lower │──┐ └──────┘ └─────────┘ └─────────┘ │ ┌─────────────────────────────────┘ ▼ ┌──────────┐ ┌───────────┐ ┌────────────┐ │ opt (-O) │─▶│ pizlonate │─▶│ filc_amd64 │ └──────────┘ └───────────┘ └────────────┘
cc runs the whole pipeline; c_pp lexes with c_lex. IR text enters at the middle end, and a module in plain mode goes to amd64.pl instead of pizlonate and filc_amd64.
-O
-O before the command runs the middle end (opt.pl) after loading. Without it the IR goes to the backend as loaded, which is the reference the optimized path is checked against. With -O, difftest also runs every run line on the unoptimized module and fails unless each optimized outcome refines the original one (translation validation), and prints how many allocs promote removed.
--registers=stack|local independently selects reference emission or validated block-local scalar caching in the Fil-C backend. The default is stack; NANOFIL_REGISTERS supplies the same choice to build harnesses. The plain backend is unchanged. Options precede the command.
difftest
expected.txt holds the interpreter's result for every run line whose outcome a native run can reproduce: a known return value, or for a Fil-C module a trap, written just trap. harness.c prints the same lines from native code; for a Fil-C module it makes one call per process, chosen by argv[1], since a trap ends the process. mode holds plain or filc. Other outcomes are reported on stdout and left out of the comparison.
For a Fil-C module, difftest also runs every run line on the pizlonated module and fails unless each outcome is the same, traps and their reasons included.
Compile-only commands do not need the interpreter or its CLP(Z) solver.
Loading
Module is the valid IR module in File. A .c or .i file goes through the C frontend, anything else is IR text.
Module is the valid IR module of the C file.
Tokens are the C tokens of File. A .i file is already preprocessed; anything else goes through c_pp with the predefined macros and include paths of $FILCC (default filcc).
Commands
Only native emission needs Registers; other commands consume Opt.
carry out the command line Args (without options), running the middle end when Opt is o1 (-O given) and not when o0. Fails or throws when the command does.
Asm is the asm.pl lines of Module by the backend for Mode, filc or plain.
Checked is Module pizlonated, which must be valid checked IR (ir.pl): the validator verifies the pass.
mode_pizlonation_agrees(+Mode, +File, +Module-Prepared, +Runs): for a filc module, the pizlonated Module has the same outcome as Module on every run, traps and their reasons included, or the command throws: the explicit checks are exactly the implicit ones. A missing or too weak check shows as the outcome unchecked(Why). Both run with the same fuel, since pizlonate keeps every block.
with -O (o1), the optimized Module is valid. valid_module's clauses leave choice points that throw on retry.
with -O (o1), report_validation/4.
print the -O difftest report: promote's effect, then every validation failure, which together make the command throw.
Running and validating
Fuel (blocks run) for a command-line run and the last validation step.
validated_run(+Opt, +Original, +Optimized, +Run, -Result, -Verdict): Result is Run's r/3 on the module that difftest compares, and Verdict ok or bad(CallText, OriginalText, OptimizedText).
Translation validation: the unoptimized module's outcome on the same run must allow the optimized one's. Both runs happen in the same findall step, so an unknown result keeps its constraints. Promote keeps every block and branch, so a correct result needs exactly the blocks the original needs: both run with the same fuel, starting small and growing until the original finishes. A broken pass that loops then ends as out_of_fuel, cheaply (the interpreter's memory grows quickly with the number of blocks run, so a looping run at full fuel would exhaust it).
Fuel is one of the growing fuel limits, smallest first, ending at max_fuel.
Result is the r(Fn, Args, Outcome) of the "# run:" line Run on a module and the interpreter's preparation of it, with Fuel. Throws if the line does not fit the module or the interpreter finds no outcome.
Text is the atom 'Fn(A1, A2, ...)'.
difftest output files
write the characters Body2 (a DCG body) describes to File.
one "CALL = OUTCOME" line per result, a trap's outcome shown as just "trap" (the native run cannot tell why).
a C program that calls Module's functions as Results do and prints what expected_lines//1 prints.
Fil-C: one run per process, selected by argv[1], since a trap ends the process. The call text is printed first, so a trap leaves it unfinished.
Fns is the ordset of the functions Results call.
the switch cases I, I+1, ... of the Fil-C harness, one per result.
an extern C declaration of each of Fns.
Style labelled prints "CALL = ret N" lines from one main; bare prints "ret N" inside a case.
the line of harness_calls//3 for one call of Fn, which returns Ret.
as harness_call//5, for a call with Result.
main's line for a call of Fn.
Runs
Runs are the run(Fn, Args) facts of IR File, in order.
library(format)'s format_//2 raises type_error(list, '') for an argument of '' (Trealla 12f4cbd), which a call with no arguments produces. fmt(+Format, +Args)//: the characters format/3 makes of Format and Args.