Fil-C on Nix

Filnix wiki

mbrock/filnix/nanofil

ir_text.pl

IR 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.

An IR file may also state runFn, Args: a call of Fn on the integer Args that difftest and the tests run. A small file:

runaddw, 3, 4
funcaddw, export, w, paramw, tmpa, paramw, tmpb, blockstart, [], lettmpr, w, add, tmpa, tmpb, rettmpr
datamsg, local, 1, itemb, str"hi\n", itemb, const0

The printer is ours rather than writeq/1, so the text is the same on both hosts and the layout stays stable:

  • a function's blocks, phis and instructions are one per line, and any other item is one line;
  • an atom is bare when it is a lowercase identifier, else quoted;
  • a list of characters in str/1 is a string (double_quotes is chars on both hosts).
useslists
usesdcgs
read_ir_file+File, -Module, -Runsdet

Module is the module(Items) of the IR clauses in File and Runs their run(Fn, Args) terms, each in file order. Throws nanofil_error(Msg) for a clause that is not an item or a run, or not ground. The module is not validated; see ir:valid_module/1.

39read_ir_fileFile, moduleItems, Runs ←
setup_call_cleanupopenFile, read, S, read_clausesS, File, Items, Runs, closeS
44read_clausesS, File, Items, Runs ←
catchread_termS, T, [], errorE, _,
formatatomMsg, '~w: cannot read IR: ~q', File, E
thrownanofil_errorMsg
T ≡ end_of_file
→
Items = []
Runs = []
else
ir_clauseT, File, Items, Items1, Runs, Runs1
read_clausesS, File, Items1, Runs1
ir_clause+T, +File, ?Items0, ?Items, ?Runs0, ?Runs

T adds itself to the items or the runs, as difference lists.

55ir_clauseT, File, _, _, _, _ ←
¬groundT
!
formatatomMsg, '~w: IR clause with a variable: ~q', File, T
thrownanofil_errorMsg
59ir_clauserunFn, Args, _, Is, Is, runFn, Args|Rs, Rs ←
!
60ir_clauseT, _, T|Is, Is, Rs, Rs ←
T = func_, _, _, _, _
or
T = data_, _, _, _
or
T = context_, _
!
62ir_clauseT, File, _, _, _, _ ←
formatatomMsg, '~w: not an IR clause: ~q', File, T
thrownanofil_errorMsg
module_text+Module//

The clauses of Module, each item ending in a full stop and a newline.

76module_textmoduleItems ⟶
itemsItems
78items[] ⟶
[]
79itemsItem|Items ⟶
".\n"
itemsItems
item_text+Item//

Item as a term, without its full stop: a function's blocks and instructions one per line, anything else on one line.

85item_textfuncName, Linkage, Ret, Params, Blocks ⟶
!
"func("
argsName, Linkage, Ret, Params
", [\n"
blocksBlocks
"])"
89item_textItem ⟶
termItem
91blocksB ⟶
!
"\n"
92blocksB|Bs ⟶
",\n"
94blockblockLabel, Phis, Insts, Jump ⟶
" block("
termLabel
", "
linesPhis
", "
linesInsts
", "
termJump
")"
lines+Xs//

the list Xs, one element per line, or [] when empty.

99lines[] ⟶
!
"[]"
100linesXs ⟶
"[\n"
" ]"
102elementsX ⟶
!
" "
"\n"
103elementsX|Xs ⟶
" "
",\n"
term+T//

the text of the ground term T, which read_term/3 reads back as T.

107termT ⟶
integerT
!
number_charsT, Cs
seqCs
108termT ⟶
atomT
!
109term[] ⟶
!
"[]"
110termX|Xs ⟶
!
"["
argsX|Xs
"]"
111termstrCs ⟶
is_listCs
!
"str(\""
"\")"
112termL−V ⟶
!
"-"
113termT ⟶
T =.. F|As
"("
")"
115argsA ⟶
116argsA|As ⟶
", "
atom_text+A//

A bare when it is a lowercase identifier, else quoted.

119atom_textA ⟶
atom_charsA, Cs
Cs = C|Rest
maplistident, Rest
→
seqCs
else
"'"
quoted_charsCs, '\''
"'"
125string_charsCs ⟶
quoted_chars+Cs, +Q//

Cs inside quotes Q, with Q, backslash and control characters escaped.

129quoted_chars[], _ ⟶
[]
130quoted_charsC|Cs, Q ⟶
132quoted_charC, Q ⟶
C ≡ Q
!
\, C
133quoted_char\, _ ⟶
!
"\\\\"
134quoted_char'\n', _ ⟶
!
"\\n"
135quoted_char'\t', _ ⟶
!
"\\t"
136quoted_charC, _ ⟶
char_codeC, N
N < 32
or
N =:= 127
!
formatcharsHex, "~16r", N
"\\x"
seqHex
"\\"
140quoted_charC, _ ⟶
C
142lowerC ←
char_codeC, N
N ≥ 0'a
N ≤ 0'z
143identC ←
144identC ←
char_codeC, N
N ≥ 0'A
N ≤ 0'Z
or
N ≥ 0'0
N ≤ 0'9
or
N =:= 0'_
!