Fil-C on Nix

Filnix wiki

the formal campaign

rocq/backend/NfbTerm.v

NFB, the bytecode of a nanofil module (docs/nfb.md), read and written at the level of Prolog terms: the Gallina twin of src/nfb.pl, which must write the very same words.

As in nfb.pl, one table (forms) states every instruction: its opcode, its term as a pattern with numbered holes, and the fields its words hold, each naming a hole. The writer matches an instruction against the patterns and writes the fields of the hole values; the reader reads the fields of the opcode's form and fills the holes of its pattern. A list of the term, such as a call's arguments or a phi's pairs, is written element by element, each element by a smaller pattern and its own fields.

The words are integers below 2^32 (Z). The ids are as the document says: a temporary's is its place among first definitions, parameters first; a block's and a named local's their place in the stream. Without the NAMES section the reader names each by its id, an integer term.

From Stdlib Require Import String ZArith List Bool Ascii
From Nanofil Require Import Term Maps Cfg
From Backend Require Import Order
Import ListNotations
Open Scope string_scope
Open Scope list_scope
Open Scope Z_scope

Words

2^32, 2^64 and 2^96, hoisted so that extracted code does not rebuild them.

32Definition two32: Z ≔
4294967296
33Definition two64: Z ≔
18446744073709551616
34Definition two96: Z ≔
79228162514264337593543950336

Whether n is a word, from 0 to 2^32 - 1.

37Definition u32okn : Z : bool ≔
0 ≤? n && n <? two32

Whether n is a signed 64-bit integer.

40Definition i64okn : Z : bool ≔
−two64 / 2 ≤? n && n <? two64 / 2

Whether n is a signed 96-bit integer, what CONSTANTS can hold.

43Definition wideokn : Z : bool ≔
−two96 / 2 ≤? n && n <? two96 / 2

The signed 64-bit n as two words, low first, in two's complement.

46Definition i64_wordsn : Z : listZ ≔
let u ≔ n mod two64 in
u mod two32; u / two32

The signed 96-bit n as three words, low first.

49Definition wide_wordsn : Z : listZ ≔
let u ≔ n mod two96 in
u mod two32; u / two32 mod two32; u / two64

The integer two words, low first, stand for as a signed 64-bit one.

53Definition i64_oflo hi : Z : Z ≔
let u ≔ lo + hi × two32 in
u <? two64 / 2
→
u
else
u − two64

The integer three words stand for as a signed 96-bit one.

57Definition wide_ofw0 w1 w2 : Z : Z ≔
let u ≔ w0 + w1 × two32 + w2 × two64 in
u <? two96 / 2
→
u
else
u − two96

2^29: a constant from -2^29 to 2^29 - 1 is written inside its operand word.

62Definition inline_bound: Z ≔
536870912

Whether the constant n is written inline.

65Definition inlinen : Z : bool ≔
−inline_bound ≤? n && n <? inline_bound

Bytes

The bytes bs four to a word, low byte first, the last word padded with zero bytes.

71Fixpoint packbs : listZ : listZ ≔
match bs with
b0 :: b1 :: b2 :: b3 :: r
⇒
b0 + b1 × 256 + b2 × 65536 + b3 × 16777216 :: packr
b0; b1; b2
⇒
b0 + b1 × 256 + b2 × 65536
b0; b1
⇒
b0 + b1 × 256
b0
⇒
b0
[ ]
⇒
[ ]

The four bytes of each word, low first.

81Fixpoint unpackws : listZ : listZ ≔
match ws with
[ ]
⇒
[ ]
w :: ws′
⇒
w mod 256 :: w / 256 mod 256 :: w / 65536 mod 256 :: w / 16777216 :: unpackws′

The length of bs, then bs packed: a string's or a str item's words.

90Definition bytes_wordsbs : listZ : listZ ≔
Z.of_natlengthbs :: packbs

The bytes of the string s.

93Definition string_bytess : string : listZ ≔
mapλc ⇒ Z.of_natnat_of_asciic list_ascii_of_strings

The string of the bytes bs.

97Definition bytes_stringbs : listZ : string ≔
string_of_list_asciimapλb ⇒ ascii_of_natZ.to_natb bs

The one-character atom of the code b, below 256, as the term reader makes it: one byte below 128, else two of UTF-8.

102Definition code_charb : Z : term ≔
b <? 128
→
TAtomStringascii_of_natZ.to_natb EmptyString
else
TAtomStringascii_of_natZ.to_nat192 + b / 64 Stringascii_of_natZ.to_nat128 + b mod 64 EmptyString

Small helpers

The arguments of t when it is the compound f with n arguments.

110Definition app_argsf : string n : nat t : term : optionlistterm ≔
match t with
TAppg ts
⇒
String.eqbf g && Nat.eqbn lengthts
→
Somets
else
None
_
⇒
None

Whether t is the atom a.

117Definition is_atoma : string t : term : bool ≔
match t with
⇒
String.eqba b
_
⇒
false

The value of the string key s in the association list xs.

121Fixpoint sassocs : string xs : liststring × Z : optionZ ≔
match xs with
[ ]
⇒
None
k, v :: xs′
⇒
String.eqbs k
→
Somev
else
sassocs xs′

The key of the value z in the association list xs.

128Fixpoint srassocz : Z xs : liststring × Z : optionstring ≔
match xs with
[ ]
⇒
None
k, v :: xs′
⇒
Z.eqbz v
→
Somek
else
srassocz xs′

Each element of xs through the partial f, or none if f fails on one.

136Fixpoint mapoX Y : Type f : X → optionY xs : listX : optionlistY ≔
match xs with
[ ]
⇒
Some[ ]
x :: xs′
⇒
let* y ≔ fx in
let* ys ≔ mapof xs′ in
Somey :: ys

The first n elements of xs and the rest, if xs has n.

143Fixpoint taken : nat xs : listZ : optionlistZ × listZ ≔
match n with
O
⇒
Some[ ], xs
Sn′
⇒
match xs with
[ ]
⇒
None
x :: xs′
⇒
let* p ≔ taken′ xs′ in
Somex :: fstp, sndp

Insert x into the sorted list xs, by the order le; an x equal to an element (by eqb) is dropped.

154Fixpoint insert_uniqX : Type lt eqb : X → X → bool x : X xs : listX : listX ≔
match xs with
[ ]
⇒
x
y :: ys
⇒
eqbx y
→
xs
ltx y
→
x :: xs
else
y :: insert_uniqlt eqb x ys

Merge two sorted lists without duplicates.

161Fixpoint merge_uniqX : Type lt eqb : X → X → bool xs : listX : listX → listX ≔
fix go ys ≔
match xs, ys with
[ ], _
⇒
ys
_, [ ]
⇒
xs
x :: xs′, y :: ys′
⇒
eqbx y
→
x :: merge_uniqlt eqb xs′ ys′
ltx y
→
x :: merge_uniqlt eqb xs′ ys
else
y :: goys′

The runs of one element each, for sort_uniq.

173Definition singletonsX : Type xs : listX : listlistX ≔
mapλx ⇒ x xs

Merge the runs rs in pairs.

176Fixpoint merge_pairsX : Type lt eqb : X → X → bool rs : listlistX : listlistX ≔
match rs with
r1 :: r2 :: rs′
⇒
merge_uniqlt eqb r1 r2 :: merge_pairslt eqb rs′
_
⇒
rs

Merge the runs until one is left, at most fuel rounds.

183Fixpoint merge_allX : Type lt eqb : X → X → bool fuel : nat rs : listlistX : listX ≔
match rs with
[ ]
⇒
[ ]
r
⇒
r
_
⇒
match fuel with
O
⇒
concatrs
Sf
⇒
merge_alllt eqb f merge_pairslt eqb rs

xs sorted by lt, each element once, as Prolog's sort/2 does with the order lt.

195Definition sort_uniqX : Type lt eqb : X → X → bool xs : listX : listX ≔
merge_alllt eqb lengthxs singletonsxs

The byte order of strings.

199Definition str_lta b : string : bool ≔
match atom_comparea b with
_
⇒
false

The enumerations

The tables of codes a field can hold, each a list of atoms and their words (nfb.pl's nfb_code/3).

206Inductive enum: Type ≔
|EClass
|EWidth
|ELoad
|EExt
|ECas
|ECond
|ERights
|EBound
|ESetjmp
|EEffect
|EFlight
|EMnemonic
|ERegister
210Definition class_codes: liststring × Z ≔
"w", 1; "l", 2; "s", 3; "d", 4; "x", 5; "p", 6; "a", 7; "f", 8
212Definition width_codes: liststring × Z ≔
"w", 1; "l", 2; "s", 3; "d", 4; "x", 5; "p", 6; "b", 9; "h", 10
214Definition narrow_codes: liststring × Z ≔
"sw", 16; "uw", 17; "sh", 18; "uh", 19; "sb", 20; "ub", 21
216Definition load_codes: liststring × Z ≔
"l", 2; "s", 3; "d", 4; "x", 5; "p", 6 ++ narrow_codes
218Definition ext_codes: liststring × Z ≔
"s", 3; "d", 4 ++ narrow_codes
219Definition cas_codes: liststring × Z ≔
"l", 2; "p", 6 ++ narrow_codes
220Definition cond_codes: liststring × Z ≔
"eq", 0; "ne", 1; "sle", 2; "slt", 3; "sge", 4; "sgt", 5; "ule", 6; "ult", 7; "uge", 8; "ugt", 9; "le", 10; "lt", 11; "ge", 12; "gt", 13; "o", 14; "uo", 15
224Definition rights_codes: liststring × Z ≔
"read", 0; "write", 1
225Definition bound_codes: liststring × Z ≔
"upper", 0; "lower", 1
226Definition setjmp_codes: liststring × Z ≔
"setjmp", 0; "_setjmp", 1; "sigsetjmp", 2
227Definition effect_codes: liststring × Z ≔
"aux_read", 0; "lower_resolve", 1; "address_read", 2; "aux_ensure", 3; "lower_barrier", 4; "rooted_reload", 5; "lower_write", 6; "address_write", 7; "atomic_read", 8; "atomic_write", 9; "atomic_cas", 10
231Definition flight_codes: liststring × Z ≔
"copy", 0; "add", 1; "sub", 2
232Definition mnemonic_codes: liststring × Z ≔
"cpuid", 0; "xgetbv", 1; "rdtsc", 2; "rdtscp", 3; "lfence", 4; "sfence", 5; "pause", 6
235Definition register_codes: liststring × Z ≔
"a", 0; "b", 1; "c", 2; "d", 3
236Definition func_linkage_codes: liststring × Z ≔
"export", 0; "local", 1; "weak", 2
237Definition alias_linkage_codes: liststring × Z ≔
"export", 0; "weak", 2

The table of the enumeration e.

The word of the atom t in the enumeration e.

250Definition enc_codee : enum t : term : optionZ ≔
match t with
_
⇒
None

The atom of the word z in the enumeration e.

254Definition dec_codee : enum z : Z : optionterm ≔
let* s ≔ srassocz codese in
SomeTAtoms

The table of instructions

A pattern of a term: a numbered hole, an atom, a compound, or a list of a fixed length.

261Inductive pat: Type ≔
|PH
i : nat
|PA
s : string
|PC
f : string ps : listpat
|PL
ps : listpat

The values of a pattern's holes.

268Definition env ≔
listnat × term

The value of the hole i.

271Fixpoint env_geti : nat e : env : optionterm ≔
match e with
[ ]
⇒
None
j, t :: e′
⇒
Nat.eqbi j
→
Somet
else
env_geti e′

The holes' values that make the pattern p the term t, added to e.

278Fixpoint match_patp : pat t : term e : env {struct p} : optionenv ≔
match p with
⇒
Somei, t :: e
⇒
→
Somee
else
None
PCf ps
⇒
match t with
TAppg ts
⇒
String.eqbf g
→
fix go ps : listpat ts : listterm e : env : optionenv ≔
match ps, ts with
[ ], [ ]
⇒
Somee
p :: ps′, t :: ts′
⇒
let* e′ ≔ match_patp t e in
gops′ ts′ e′
_, _
⇒
None
ps ts e
else
None
_
⇒
None
PLps
⇒
match t with
⇒
fix go ps : listpat ts : listterm e : env : optionenv ≔
match ps, ts with
[ ], [ ]
⇒
Somee
p :: ps′, t :: ts′
⇒
let* e′ ≔ match_patp t e in
gops′ ts′ e′
_, _
⇒
None
ps ts e
_
⇒
None

The term of the pattern p with its holes filled from e.

309Fixpoint fill_patp : pat e : env {struct p} : optionterm ≔
match p with
⇒
⇒
SomeTAtoms
PCf ps
⇒
let* ts ≔
fix go ps : listpat : optionlistterm ≔
match ps with
[ ]
⇒
Some[ ]
p :: ps′
⇒
let* t ≔ fill_patp e in
let* ts ≔ gops′ in
Somet :: ts
ps
in
SomeTAppf ts
PLps
⇒
let* ts ≔
fix go ps : listpat : optionlistterm ≔
match ps with
[ ]
⇒
Some[ ]
p :: ps′
⇒
let* t ≔ fill_patp e in
let* ts ≔ gops′ in
Somet :: ts
ps
in
SomeTListts

A field of an instruction, holding the value of one hole:

FieldWords
FDefnone: the temporary takes the next id
FClass, FEnumone code
FU32, FI64one word, or two, signed
FOpndan operand word
FLabel, FTargeta block index; a target's shifted, bit 0 for poll
FLocal, FLocalDefa local's id; the definition writes none
FStra STRINGS id
FResulta call's result word, defining its temporaries
FLower0 for none, or 1 and the operand of lower(P)
FFlightArg1 and the operand of address(P), or 0 and a value's
FCount, FResta list: its length then its elements, or its elements to the end

An element of a list is a smaller pattern with its own holes and fields.

347Inductive field: Type ≔
|FDef
i : nat
|FClass
i : nat
|FEnum
e : enum i : nat
|FU32
i : nat
|FI64
i : nat
|FOpnd
i : nat
|FLabel
i : nat
|FTarget
i : nat
|FLocal
i : nat
|FLocalDef
i : nat
|FStr
i : nat
|FResult
i : nat
|FLower
i : nat
|FFlightArg
i : nat

A field, or a list of elements.

353Inductive lfield: Type ≔
|FOne
f : field
|FCount
i : nat el : pat fs : listfield
|FRest
i : nat el : pat fs : listfield

An instruction's form: its opcode, its pattern and its fields.

359Record form: Type ≔ mkForm
f_code
 : Z
f_pat
 : pat
f_fields
 : listlfield

The pattern of a let(tmp(D), K, Op, Args), D hole 0 and K hole 1.

363Definition pleto : pat args : listpat : pat ≔
PC"let" PC"tmp" PH0; PH1; o; PLargs

The fields of a let's definition and class, then fs.

367Definition fletfs : listfield : listlfield ≔
mapFOne FDef0 :: FClass1 :: fs
369Definition binary_ops: liststring ≔
"add"; "sub"; "mul"; "div"; "udiv"; "rem"; "urem"; "and"; "or"; "xor"; "sar"; "shr"; "shl"
371Definition unary_ops: liststring ≔
"neg"; "copy"; "cast"; "truncd"; "truncx"; "ptoi"; "itop"; "stosi"; "stoui"; "dtosi"; "dtoui"; "xtosi"; "xtoui"; "swtof"; "uwtof"; "sltof"; "ultof"

The forms of the ops named ns, from the opcode c up, each made by mk.

377Fixpoint op_formsc : Z ns : liststring mk : Z → string → form : listform ≔
match ns with
[ ]
⇒
[ ]
n :: ns′
⇒
mkc n :: op_formsc + 1 ns′ mk

The form of a let of a range op f: f(Lo, Hi, Rights, Align) on the operands of holes 6 on.

382Definition range_formc : Z f : string n : nat : form ≔
mkFormc pletPCf PH2; PH3; PH4; PH5 mapPH seq6 n fletFI642; FI643; FEnumERights 4; FU325 ++ mapFOpnd seq6 n

A call's or raw call's form.

387Definition call_formc : Z f : string : form ≔

Every form, in nfb.pl's order.

392Definition forms: listform ≔
mkForm8 PC"phi" PC"tmp" PH0; PH1; PH2 FOneFDef0; FOneFClass1; FRest2 PC"-" PH0; PH1 FLabel0; FOpnd1 ++ op_forms16 binary_ops λc n ⇒ mkFormc pletPAn PH2; PH3 fletFOpnd2; FOpnd3 ++ op_forms32 unary_ops λc n ⇒ mkFormc pletPAn PH2 fletFOpnd2 ++ mkForm56 pletPC"cmp" PH2; PH3 PH4; PH5 fletFEnumECond 2; FClass3; FOpnd4; FOpnd5; mkForm57 pletPC"ext" PH2 PH3 fletFEnumEExt 2; FOpnd3; mkForm58 pletPC"load" PH2 PH3 fletFEnumELoad 2; FOpnd3; mkForm59 pletPC"alloc" PH2 PH3 fletFU322; FOpnd3; mkForm60 pletPA"va_args" PH2 fletFOpnd2; mkForm61 pletPA"va_arg" PH2 fletFOpnd2; mkForm62 pletPC"setjmp" PH2 PH3; PH4 fletFEnumESetjmp 2; FOpnd3; FOpnd4; mkForm63 pletPC"atomic_load" PA"p" PH2 fletFOpnd2; mkForm64 pletPC"cas" PH2 PH3; PH4; PH5 fletFEnumECas 2; FOpnd3; FOpnd4; FOpnd5; range_form80 "check" 1; mkForm81 pletPC"check_ahead" PH2; PH3; PH4; PH5; PH6 PH7 fletFI642; FI643; FEnumERights 4; FU325; FI646; FOpnd7; range_form82 "renew" 2; range_form83 "renew_hull" 3; mkForm84 pletPC"half_check" PH2; PH3; PH4; PH5; PH6 PH7; PH8 fletFEnumEBound 2; FI643; FI644; FEnumERights 5; FU326; FOpnd7; FOpnd8; mkForm85 pletPC"span_test" PH2; PH3 PH4 fletFI642; FI643; FOpnd4; range_form86 "renew_if" 2; mkForm87 pletPC"limit" PH2 PH3 fletFU322; FOpnd3; range_form88 "check_limit" 2; mkForm89 pletPC"check_local" PH2; PH3; PH4; PH5; PH6 [ ] fletFLocal2; FI643; FI644; FEnumERights 5; FU326; mkForm90 pletPA"check_function" PH2 fletFOpnd2; mkForm91 pletPC"raw_load" PH2; PH3 PH4 fletFEnumELoad 2; FI643; FOpnd4; mkForm92 pletPC"raw_load_pointer" PH2; PH3 PH4 fletFI642; FOpnd4 ++ FRest3 PH0 FEnumEEffect 0; mkForm93 pletPC"raw_cas" PH2; PH3 PH4; PH5; PH6 fletFEnumECas 2; FI643; FOpnd4; FOpnd5; FOpnd6; mkForm96 PC"store" PH0; PH1; PH2 mapFOne FEnumEWidth 0; FOpnd1; FOpnd2; mkForm97 PC"atomic_store" PA"p"; PH0; PH1 mapFOne FOpnd0; FOpnd1; mkForm98 PA"fence" [ ]; mkForm99 PC"access" PH0; PH1; PH2; PH3 mapFOne FEnumERights 0; FU322; FU323; FOpnd1; mkForm100 PC"local_alloc" PH0; PH1 mapFOne FLocalDef0; FI641; mkForm101 PC"local_load" PC"tmp" PH0; PH1; PH2; PH3; PH4 mapFOne FDef0; FClass1; FEnumELoad 2; FLocal3; FI644; mkForm102 PC"local_store" PH0; PH1; PH2; PH3 mapFOne FEnumEWidth 0; FLocal2; FI643; FOpnd1; call_form103 "call"; mkForm104 PC"asm_fixed" PH0; PH1; PH2 FOneFEnumEMnemonic 0; FCount1 PC"-" PH0; PH1 FEnumERegister 0; FOpnd1; FRest2 PC"-" PH0; PC"tmp" PH1 FEnumERegister 0; FDef1; mkForm105 PC"loc" PH0; PH1 mapFOne FStr0; FU321; mkForm112 PC"touch" PH0 FOneFOpnd0; call_form113 "raw_call"; mkForm114 PC"flight" PC"tmp" PH0; PH1; PH2; PH3 FOneFDef0; FOneFEnumEFlight 1; FOneFLower3; FRest2 PH0 FFlightArg0; mkForm115 PC"raw_store" PH0; PH1; PH2; PH3 mapFOne FEnumEWidth 0; FI641; FOpnd2; FOpnd3; mkForm116 PC"raw_store_pointer" PH0; PH1; PH2; PH3 FOneFI640; FOneFOpnd1; FOneFOpnd2; FRest3 PH0 FEnumEEffect 0; mkForm128 PC"goto" PH0 FOneFTarget0; mkForm129 PC"branch" PH0; PH1; PH2 mapFOne FOpnd0; FTarget1; FTarget2; mkForm130 PC"ret" PH0 FOneFOpnd0; mkForm131 PC"rets" PH0 FRest0 PH0 FOpnd0; mkForm132 PA"ret" [ ]; mkForm133 PA"unreachable" [ ]

The opcode that prefixes an instruction defining a temporary again.

460Definition rebind_code: Z ≔
1

The group of an opcode: 0 a phi, 2 a jump, 1 any other.

463Definition groupc : Z : Z ≔
Z.eqbc 8
→
0
128 ≤? c
→
2
else
1

The first form whose pattern t matches, with the holes' values.

466Fixpoint find_formfs : listform t : term : optionform × env ≔
match fs with
[ ]
⇒
None
f :: fs′
⇒
match match_patf_patf t [ ] with
Somee
⇒
Somef, e
None
⇒
find_formfs′ t

The form of the opcode c.

476Fixpoint form_of_codefs : listform c : Z : optionform ≔
match fs with
[ ]
⇒
None
f :: fs′
⇒
Z.eqbf_codef c
→
Somef
else

What an instruction holds

The temporaries a call's result term r defines.

485Definition result_defsr : term : optionlistterm ≔
is_atom"void" r
→
Some[ ]
else
match app_args"result" 2 r with
Somed; _
⇒
let* xs ≔ app_args"tmp" 1 d in
Somexs
_
⇒
let* xs ≔ app_args"tuple" 1 r in
match xs with
⇒
λ r  ⇒
let* ys ≔ app_args"result" 2 r in
match ys with
d; _
⇒
let* zs ≔ app_args"tmp" 1 d in
match zs with
z
⇒
Somez
_
⇒
None
_
⇒
None
rs
_
⇒
None

What a field holds besides words: the temporaries it defines, the symbols, constants and files it names.

505Record parts: Type ≔ mkParts
p_defs
 : listterm
p_globals
 : listterm
p_consts
 : listZ
p_files
 : listterm
508Definition no_parts: parts ≔
mkParts[ ] [ ] [ ] [ ]
509Definition parts_appa b : parts : parts ≔

The symbols and constants a value names.

514Definition value_partsv : term : parts ≔
match v with
TAppf x
⇒
String.eqbf "global"
→
mkParts[ ] x [ ] [ ]
String.eqbf "const"
→
match x with
⇒
mkParts[ ] [ ] n [ ]

What the field f holds, the holes' values e.

525Definition field_partse : env f : field : optionparts ≔
match f with
⇒
let* d ≔ env_geti e in
SomemkPartsd [ ] [ ] [ ]
⇒
let* r ≔ env_geti e in
let* ds ≔ result_defsr in
SomemkPartsds [ ] [ ] [ ]
⇒
let* v ≔ env_geti e in
⇒
let* a ≔ env_geti e in
SomemkParts[ ] [ ] [ ] a
⇒
let* t ≔ env_geti e in
match app_args"lower" 1 t with
Somev
⇒
_
⇒
⇒
let* t ≔ env_geti e in
match app_args"address" 1 t with
Somev
⇒
_
⇒
_
⇒

What the fields fs hold.

541Definition fields_partse : env fs : listfield : optionparts ≔
let* ps ≔ mapofield_partse fs in
Somefold_rightparts_app no_parts ps

What the elements ts of a list hold, each the pattern el.

545Definition elems_partsel : pat fs : listfield ts : listterm : optionparts ≔
let* ps ≔
λ t  ⇒
let* e ≔ match_patel t [ ] in
ts
in
Somefold_rightparts_app no_parts ps

What an instruction of the form whose fields are fs holds.

550Definition inst_partse : env fs : listlfield : optionparts ≔
let* ps ≔
λ lf  ⇒
match lf with
FCounti el fs′ | FResti el fs′
⇒
let* t ≔ env_geti e in
match t with
⇒
elems_partsel fs′ ts
_
⇒
None
fs
in
Somefold_rightparts_app no_parts ps

What the instruction, phi or jump t holds.

561Definition term_partst : term : optionparts ≔
let* fe ≔ find_formforms t in

Writing an instruction

The tables a function's instructions are written with: the ids of its temporaries, labels and locals, and of the module's symbols, strings and wide constants.

569Record wtab: Type ≔ mkWtab
w_syms
 : nmapZ
w_strs
 : nmapZ
w_consts
 : ZMap.tZ
w_temps
 : nmapZ
w_labels
 : nmapZ
w_locals
 : nmapZ

The words a field writes, the temporaries it defines, the ids of the temporaries it reads, and its targets' block indices with their poll bits.

577Record wout: Type ≔ mkWout
o_words
 : listZ
o_defs
 : listterm
o_uses
 : listZ
o_targets
 : listZ × Z
580Definition wnil: wout ≔
mkWout[ ] [ ] [ ] [ ]
581Definition wappa b : wout : wout ≔
584Definition wwordsws : listZ : wout ≔
mkWoutws [ ] [ ] [ ]

The word of the constant n: inline, or a CONSTANTS index.

587Definition const_wordc : ZMap.tZ n : Z : optionZ ≔
→
Somen mod 2 × inline_bound × 4 + 1
else
let* i ≔ ZMap.findn c in
Somei × 4 + 2

The operand word of the value v.

592Definition opnd_outw : wtab v : term : optionwout ≔
match v with
TAppf x
⇒
String.eqbf "tmp"
→
let* i ≔ nm_findx w_tempsw in
SomemkWouti × 4 [ ] i [ ]
String.eqbf "const"
→
match x with
⇒
let* z ≔ const_wordw_constsw n in
Somewwordsz
_
⇒
None
String.eqbf "global"
→
let* i ≔ nm_findx w_symsw in
Somewwordsi × 4 + 3
else
None
_
⇒
None

The word of a call's result term r, and what it defines.

606Definition result_outr : term : optionwout ≔
let* ds ≔ result_defsr in
is_atom"void" r
→
SomemkWout0 [ ] [ ] [ ]
else
match app_args"result" 2 r with
Some_; k
⇒
let* c ≔ enc_codeEClass k in
SomemkWoutc ds [ ] [ ]
_
⇒
match app_args"tuple" 1 r with
SomeTListr1; r2
⇒
match app_args"result" 2 r1, app_args"result" 2 r2 with
Some_; k1, Some_; k2
⇒
let* c1 ≔ enc_codeEClass k1 in
let* c2 ≔ enc_codeEClass k2 in
SomemkWout256 + 16 × c1 + c2 ds [ ] [ ]
_, _
⇒
None
_
⇒
None

The words of the field f, the holes' values e.

625Definition field_outw : wtab e : env f : field : optionwout ≔
match f with
⇒
let* d ≔ env_geti e in
SomemkWout[ ] d [ ] [ ]
⇒
let* t ≔ env_geti e in
let* z ≔ enc_codeEClass t in
Somewwordsz
FEnumen i
⇒
let* t ≔ env_geti e in
let* z ≔ enc_codeen t in
Somewwordsz
⇒
let* t ≔ env_geti e in
match t with
⇒
→
Somewwordsn
else
None
_
⇒
None
⇒
let* t ≔ env_geti e in
match t with
⇒
else
None
_
⇒
None
⇒
let* v ≔ env_geti e in
⇒
let* l ≔ env_geti e in
let* z ≔ nm_findl w_labelsw in
Somewwordsz
⇒
let* t ≔ env_geti e in
match app_args"poll" 1 t with
Somel
⇒
let* z ≔ nm_findl w_labelsw in
SomemkWoutz × 2 + 1 [ ] [ ] z, 1
_
⇒
let* z ≔ nm_findt w_labelsw in
SomemkWoutz × 2 [ ] [ ] z, 0
⇒
let* x ≔ env_geti e in
let* z ≔ nm_findx w_localsw in
Somewwordsz
⇒
let* a ≔ env_geti e in
match a with
⇒
let* z ≔ nm_finda w_strsw in
Somewwordsz
_
⇒
None
⇒
let* r ≔ env_geti e in
⇒
let* t ≔ env_geti e in
is_atom"none" t
→
Somewwords0
else
match app_args"lower" 1 t with
Somev
⇒
let* o ≔ opnd_outw v in
Somewappwwords1 o
_
⇒
None
⇒
let* t ≔ env_geti e in
match app_args"address" 1 t with
Somev
⇒
let* o ≔ opnd_outw v in
Somewappwwords1 o
_
⇒
let* o ≔ opnd_outw t in
Somewappwwords0 o

The words of the fields fs.

666Fixpoint fields_outw : wtab e : env fs : listfield : optionwout ≔
match fs with
[ ]
⇒
Somewnil
f :: fs′
⇒
let* a ≔ field_outw e f in
let* b ≔ fields_outw e fs′ in
Somewappa b

The words of the elements ts of a list, each the pattern el.

673Fixpoint elems_outw : wtab el : pat fs : listfield ts : listterm : optionwout ≔
match ts with
[ ]
⇒
Somewnil
t :: ts′
⇒
let* e ≔ match_patel t [ ] in
let* a ≔ fields_outw e fs in
let* b ≔ elems_outw el fs ts′ in
Somewappa b

The words of an instruction's fields fs.

682Fixpoint lfields_outw : wtab e : env fs : listlfield : optionwout ≔
match fs with
[ ]
⇒
Somewnil
lf :: fs′
⇒
let* a ≔
match lf with
⇒
FCounti el fs1
⇒
let* t ≔ env_geti e in
match t with
⇒
let* o ≔ elems_outw el fs1 ts in
SomewappwwordsZ.of_natlengthts o
_
⇒
None
FResti el fs1
⇒
let* t ≔ env_geti e in
match t with
⇒
elems_outw el fs1 ts
_
⇒
None
in
let* b ≔ lfields_outw e fs′ in
Somewappa b

Reading an instruction

The tables a function's instructions are read with: names by id.

705Record rtab: Type ≔ mkRtab
r_syms
 : ZMap.tterm
r_strs
 : ZMap.tterm
r_consts
 : ZMap.tZ
r_temps
 : ZMap.tterm
r_labels
 : ZMap.tterm
r_locals
 : ZMap.tterm

The reader's state within an instruction: the words left, the rebind words left (none when there is no rebind prefix), the next temporary id and the next local id.

713Record rst: Type ≔ mkRst
s_words
 : listZ
s_rebinds
 : optionlistZ
s_next
 : Z
s_local
 : Z

The next word.

716Definition next_words : rst : optionZ × rst ≔
match s_wordss with
[ ]
⇒
None
x :: xs
⇒

The constant of the word z, an inline or CONSTANTS one.

723Definition const_ofr : rtab z : Z : optionZ ≔
Z.eqbz mod 4 1
→
let p ≔ z / 4 in
Some
→
p
else
p − 2 × inline_bound
Z.eqbz mod 4 2
→
ZMap.findz / 4 r_constsr
else
None

The value of the operand word z.

730Definition value_ofr : rtab z : Z : optionterm ≔
let tag ≔ z mod 4 in
Z.eqbtag 0
→
let* n ≔ ZMap.findz / 4 r_tempsr in
SomeTApp"tmp" n
Z.eqbtag 3
→
let* s ≔ ZMap.findz / 4 r_symsr in
SomeTApp"global" s
else
let* n ≔ const_ofr z in
SomeTApp"const" TIntn

The name the next definition takes: the next id's, or the rebound id's.

738Definition def_namer : rtab s : rst : optionterm × rst ≔
let take_id w : Z rb : optionlistZ ≔
Z.eqbw 0
→
let* n ≔ ZMap.finds_nexts r_tempsr in
Somen, mkRsts_wordss rb s_nexts + 1 s_locals
w − 1 <? s_nexts
→
let* n ≔ ZMap.findw − 1 r_tempsr in
else
None
in
match s_rebindss with
None
⇒
take_id0 None
Somew :: ws
⇒
take_idw Somews
Some[ ]
⇒
None

The call result term of the word z, its temporaries named in turn.

753Definition read_resultr : rtab z : Z s : rst : optionterm × rst ≔
Z.eqbz 0
→
SomeTAtom"void", s
256 ≤? z
→
let* k1 ≔ dec_codeEClass z − 256 / 16 in
let* k2 ≔ dec_codeEClass z mod 16 in
z − 256 / 16 <? 16
→
let* p1 ≔ def_namer s in
let* p2 ≔ def_namer sndp1 in
SomeTApp"tuple" TListTApp"result" TApp"tmp" fstp1; k1; TApp"result" TApp"tmp" fstp2; k2, sndp2
else
None
else
let* k ≔ dec_codeEClass z in
let* p ≔ def_namer s in
SomeTApp"result" TApp"tmp" fstp; k, sndp

Read the field f into the hole it names.

767Definition read_fieldr : rtab f : field e : env s : rst : optionenv × rst ≔
match f with
⇒
let* p ≔ def_namer s in
Somei, fstp :: e, sndp
⇒
let* p ≔ next_words in
let* t ≔ dec_codeEClass fstp in
Somei, t :: e, sndp
FEnumen i
⇒
let* p ≔ next_words in
let* t ≔ dec_codeen fstp in
Somei, t :: e, sndp
⇒
let* p ≔ next_words in
Somei, TIntfstp :: e, sndp
⇒
let* p ≔ next_words in
let* q ≔ next_wordsndp in
Somei, TInti64_offstp fstq :: e, sndq
⇒
let* p ≔ next_words in
let* v ≔ value_ofr fstp in
Somei, v :: e, sndp
⇒
let* p ≔ next_words in
let* l ≔ ZMap.findfstp r_labelsr in
Somei, l :: e, sndp
⇒
let* p ≔ next_words in
let* l ≔ ZMap.findfstp / 2 r_labelsr in
Some
i
Z.eqbfstp mod 2 1
→
TApp"poll" l
else
l
::
e
sndp
⇒
let* p ≔ next_words in
let* x ≔ ZMap.findfstp r_localsr in
Somei, x :: e, sndp
⇒
let* x ≔ ZMap.finds_locals r_localsr in
Somei, x :: e, mkRsts_wordss s_rebindss s_nexts s_locals + 1
⇒
let* p ≔ next_words in
let* a ≔ ZMap.findfstp r_strsr in
Somei, a :: e, sndp
⇒
let* p ≔ next_words in
let* q ≔ read_resultr fstp sndp in
Somei, fstq :: e, sndq
⇒
let* p ≔ next_words in
Z.eqbfstp 0
→
Somei, TAtom"none" :: e, sndp
Z.eqbfstp 1
→
let* q ≔ next_wordsndp in
let* v ≔ value_ofr fstq in
Somei, TApp"lower" v :: e, sndq
else
None
⇒
let* p ≔ next_words in
let* q ≔ next_wordsndp in
let* v ≔ value_ofr fstq in
Z.eqbfstp 1
→
Somei, TApp"address" v :: e, sndq
Z.eqbfstp 0
→
Somei, v :: e, sndq
else
None

Read the fields fs.

802Fixpoint read_fieldsr : rtab fs : listfield e : env s : rst : optionenv × rst ≔
match fs with
[ ]
⇒
Somee, s
f :: fs′
⇒
let* p ≔ read_fieldr f e s in
read_fieldsr fs′ fstp sndp

Read n elements of the pattern el.

809Fixpoint read_countr : rtab el : pat fs : listfield n : nat s : rst : optionlistterm × rst ≔
match n with
O
⇒
Some[ ], s
Sn′
⇒
let* p ≔ read_fieldsr fs [ ] s in
let* t ≔ fill_patel fstp in
let* q ≔ read_countr el fs n′ sndp in
Somet :: fstq, sndq

Read elements of the pattern el until no word is left, at most fuel of them.

820Fixpoint read_restr : rtab el : pat fs : listfield fuel : nat s : rst : optionlistterm × rst ≔
match s_wordss with
[ ]
⇒
Some[ ], s
_
⇒
match fuel with
O
⇒
None
Sf
⇒
let* p ≔ read_fieldsr fs [ ] s in
let* t ≔ fill_patel fstp in
let* q ≔ read_restr el fs f sndp in
Somet :: fstq, sndq

Read an instruction's fields fs into its holes.

834Fixpoint read_lfieldsr : rtab fs : listlfield e : env s : rst : optionenv × rst ≔
match fs with
[ ]
⇒
Somee, s
FOnef :: fs′
⇒
let* p ≔ read_fieldr f e s in
read_lfieldsr fs′ fstp sndp
FCounti el fs1 :: fs′
⇒
let* p ≔ next_words in
Z.of_natlengths_wordss <? fstp
→
None
else
let* q ≔ read_countr el fs1 Z.to_natfstp sndp in
read_lfieldsr fs′ i, TListfstq :: e sndq
FResti el fs1 :: fs′
⇒
let* q ≔ read_restr el fs1 lengths_wordss s in
read_lfieldsr fs′ i, TListfstq :: e sndq

Instructions

The rebind words of the definitions ds, n temporaries defined before them: 0 for a first definition, which takes the id n, or the id plus one; and the count after them.

853Fixpoint rebindstemps : nmapZ n : Z ds : listterm : optionlistZ × Z ≔
match ds with
[ ]
⇒
Some[ ], n
d :: ds′
⇒
let* i ≔ nm_findd temps in
Z.eqbi n
→
let* p ≔ rebindstemps n + 1 ds′ in
Some0 :: fstp, sndp
else
let* p ≔ rebindstemps n ds′ in
Somei + 1 :: fstp, sndp

The words of the instruction t, which must be of the group g, in the block b, n temporaries defined before it; the count after it; and whether it keeps the stream ordered: no temporary read before its first definition, outside a phi, and no edge to an earlier or the same block without a poll.

867Definition inst_wordsw : wtab g b n : Z t : term : optionlistZ × Z × bool ≔
let* fe ≔ find_formforms t in
let f ≔ fstfe in
negbZ.eqbgroupf_codef g
→
None
else
let* o ≔ lfields_outw sndfe f_fieldsf in
let* rb ≔ rebindsw_tempsw n o_defso in
let len ≔ Z.of_natlengtho_wordso + 1 in
65536 ≤? len
→
None
else
let ordered ≔ Z.eqbg 0 || forallbλu ⇒ u <? n o_useso && forallbλp ⇒ b <? fstp || Z.eqbsndp 1 o_targetso in
let pre ≔
existsbλz ⇒ negbZ.eqbz 0 fstrb
→
rebind_code + Z.of_natlengthfstrb + 1 × 65536 :: fstrb
else
[ ]
in
Somepre ++ f_codef + len × 65536 :: o_wordso, sndrb, ordered

The words of the instructions ts, all of the group g.

882Fixpoint insts_wordsw : wtab g b n : Z ts : listterm : optionlistZ × Z × bool ≔
match ts with
[ ]
⇒
Some[ ], n, true
t :: ts′
⇒
let* x ≔ inst_wordsw g b n t in
let 'ws1, n1, o1 ≔ x in
let* y ≔ insts_wordsw g b n1 ts′ in
let 'ws2, n2, o2 ≔ y in
Somews1 ++ ws2, n2, o1 && o2

The parts of a block block(L, Phis, Insts, Jump).

894Definition block_partst : term : optionterm × listterm × listterm × term ≔
match app_args"block" 4 t with
Somel; TListphis; TListinsts; j
⇒
Somel, phis, insts, j
_
⇒
None

The words of the blocks bs from the index b.

901Fixpoint blocks_wordsw : wtab b n : Z bs : listterm : optionlistZ × Z × bool ≔
match bs with
[ ]
⇒
Some[ ], n, true
bt :: bs′
⇒
let* p ≔ block_partsbt in
let '_, phis, insts, j ≔ p in
Z.eqbb 0 && negbNat.eqblengthphis 0
→
None
else
let* x1 ≔ insts_wordsw 0 b n phis in
let 'ws1, n1, o1 ≔ x1 in
let* x2 ≔ insts_wordsw 1 b n1 insts in
let 'ws2, n2, o2 ≔ x2 in
let* x3 ≔ inst_wordsw 2 b n2 j in
let 'ws3, n3, o3 ≔ x3 in
let* y ≔ blocks_wordsw b + 1 n3 bs′ in
let 'ws4, n4, o4 ≔ y in
Somews1 ++ ws2 ++ ws3 ++ ws4, n4, o1 && o2 && o3 && o4

The names ns numbered from n in the map m, a name already there keeping its number; the names newly numbered, in order.

921Fixpoint numberns : listterm m : nmapZ n : Z acc : listterm : nmapZ × Z × listterm ≔
match ns with
[ ]
⇒
m, n, revacc
x :: xs
⇒
→
numberxs m n acc
else
numberxs nm_addx n m n + 1 x :: acc

The temporary of a parameter param(K, tmp(D)), and K's code.

928Definition param_partst : term : optionterm × Z ≔
match app_args"param" 2 t with
Somek; d
⇒
let* ds ≔ app_args"tmp" 1 d in
match ds with
x
⇒
existsbλa ⇒ is_atoma k "w"; "l"; "p"; "s"; "d"
→
let* c ≔ enc_codeEClass k in
Somex, c
else
None
_
⇒
None
_
⇒
None

The word of a function's return type.

941Definition ret_wordr : term : optionZ ≔
is_atom"void" r
→
Some0
else
match app_args"tuple" 1 r with
SomeTListk1; k2
⇒
let* c1 ≔ enc_codeEClass k1 in
let* c2 ≔ enc_codeEClass k2 in
Some256 + 16 × c1 + c2

The names of a function: its temporaries', labels' and locals', in id order.

951Record fnames: Type ≔ mkFnames
n_temps
 : listterm
n_labels
 : listterm
n_locals
 : listterm

The words of a function's body, whether it is ordered, and its names; the module's tables are those of w.

955Definition body_wordsw : wtab ret : term params blocks : listterm : optionlistZ × bool × fnames ≔
let* rw ≔ ret_wordret in
let* ps ≔ mapoparam_parts params in
let np ≔ Z.of_natlengthps in
let* bps ≔ mapoblock_parts blocks in
let defs_of t : term ≔
let* p ≔ term_partst in
Somep_defsp
in
let* dss ≔
λ bp  ⇒
let '_, phis, insts, _ ≔ bp in
mapodefs_of phis ++ insts
bps
in
let 'm0, n0, firsts0 ≔ numbermapfst ps nm_empty 0 [ ] in
negbZ.eqbn0 np
→
None
else
let 'temps, nt, firsts ≔ numberconcatconcatdss m0 n0 [ ] in
let labels ≔
map
λ bp  ⇒
let 'l, _, _, _ ≔ bp in
l
bps
in
let 'lmap, nb, _ ≔ numberlabels nm_empty 0 [ ] in
negbZ.eqbnb Z.of_natlengthlabels
→
None
else
let locals ≔
flat_map
λ bp  ⇒
let '_, _, insts, _ ≔ bp in
flat_map
λ t  ⇒
match app_args"local_alloc" 2 t with
Somex; _
⇒
x
_
⇒
[ ]
insts
bps
in
let 'xmap, nl, _ ≔ numberlocals nm_empty 0 [ ] in
negbZ.eqbnl Z.of_natlengthlocals
→
None
else
let w′ ≔ mkWtabw_symsw w_strsw w_constsw temps lmap xmap in
let* x ≔ blocks_wordsw′ 0 np blocks in
let 'stream, _, ordered ≔ x in
Somerw; np ++ mapsnd ps ++ nb; nt; nl ++ stream, ordered, mkFnamesfirsts0 ++ firsts labels locals

Stage and mode

The names of the ops of the checked stage, with their arities; check_function is an atom.

986Definition checked_ops: liststring × nat ≔
"check", 4%nat; "check_ahead", 5%nat; "renew", 4%nat; "renew_hull", 4%nat; "half_check", 5%nat; "span_test", 2%nat; "renew_if", 4%nat; "limit", 1%nat; "check_limit", 4%nat; "check_local", 5%nat; "raw_load", 2%nat; "raw_load_pointer", 2%nat; "raw_cas", 2%nat

Whether t is the compound f of n arguments.

993Definition is_appf : string n : nat t : term : bool ≔
match app_argsf n t with
Some_
⇒
true
None
⇒
false

As ir.pl's checked_inst/1: the instruction is of the checked stage's vocabulary.

998Definition checked_instt : term : bool ≔
match app_args"let" 4 t with
Some_; _; o; _
⇒
is_atom"check_function" o || existsbλp ⇒ is_appfstp sndp o checked_ops
_
⇒
is_app"raw_store" 4 t || is_app"raw_store_pointer" 4 t || is_app"raw_call" 3 t || is_app"flight" 4 t || is_app"touch" 1 t

As checked_jump/1: the jump has a poll edge.

1006Definition checked_jumpt : term : bool ≔
match app_args"goto" 1 t with
Somel
⇒
is_app"poll" 1 l
_
⇒
match app_args"branch" 3 t with
Some_; l1; l2
⇒
is_app"poll" 1 l1 || is_app"poll" 1 l2
_
⇒
false

The blocks of a function term, if it is one.

1016Definition func_blockst : term : listterm ≔
match app_args"func" 5 t with
Some_; _; _; _; TListbs
⇒
bs
_
⇒
[ ]

As module_stage/2: checked when a function uses the checked vocabulary.

1021Definition module_checkeditems : listterm : bool ≔
existsb
λ it  ⇒
existsb
λ bt  ⇒
match block_partsbt with
Some_, _, insts, j
⇒
existsbchecked_inst insts || checked_jumpj
None
⇒
false
items

Whether the class term k is one of the atoms ks.

1028Definition class_inks : liststring k : term : bool ≔
existsbλa ⇒ is_atoma k ks

As pointer_inst/1: the instruction produces, stores, passes or calls through a pointer, or converts one.

1032Definition pointer_instt : term : bool ≔
match app_args"let" 4 t with
Some_; k; o; _
⇒
class_in"p"; "x"; "a"; "f" k || is_atom"ptoi" o || is_app"setjmp" 1 o || is_app"raw_load_pointer" 2 o
_
⇒
match app_args"store" 3 t with
Somewd; _; _
⇒
class_in"x"; "p" wd
_
⇒
match app_args"call" 3 t with
Somer; c; TListargs
⇒
match app_args"result" 2 r with
Some_; k
⇒
is_atom"p" k
_
⇒
false
||
is_app"tuple" 1 r
||
is_app"tmp" 1 c
||
existsb
λ a  ⇒
match app_args"arg" 2 a with
Somek; _
⇒
is_atom"p" k
_
⇒
false
args
_
⇒
is_app"atomic_store" 3 t || is_app"raw_store" 4 t || is_app"raw_store_pointer" 4 t || is_app"raw_call" 3 t || is_app"flight" 4 t || is_app"local_alloc" 2 t || is_app"local_load" 5 t || is_app"local_store" 4 t

As pointer_item/1: the item has a pointer somewhere, or is of a linkage only the filc mode models.

1054Definition pointer_itemit : term : bool ≔
match app_args"func" 5 it with
Some_; lk; ret; TListps; TListbs
⇒
is_atom"weak" lk || is_atom"p" ret || is_app"tuple" 1 ret
||
existsb
λ p  ⇒
match app_args"param" 2 p with
Somek; _
⇒
is_atom"p" k
_
⇒
false
ps
||
existsb
λ bt  ⇒
match block_partsbt with
Some_, phis, insts, _
⇒
existsb
λ ph  ⇒
match app_args"phi" 3 ph with
Some_; k; _
⇒
is_atom"p" k
_
⇒
false
phis
||
existsbpointer_inst insts
None
⇒
false
bs
_
⇒
match app_args"data" 4 it with
Some_; lk; _; TListits
⇒
is_app"ro" 1 lk || is_app"tls" 1 lk || is_atom"weak" lk || is_app"extern" 1 lk
||
existsb
λ x  ⇒
match app_args"item" 2 x with
Somek; _
⇒
is_atom"p" k
_
⇒
false
its
_
⇒
is_app"alias" 3 it

As module_mode/2: filc when an item has a pointer, or a function calls one the module does not define.

1078Definition module_filcitems : listterm : bool ≔
let funcs ≔
flat_map
λ it  ⇒
match app_args"func" 5 it with
Somen :: _
⇒
n
_
⇒
[ ]
items
in
existsbpointer_item items
||
existsb
λ it  ⇒
existsb
λ bt  ⇒
match block_partsbt with
Some_, _, insts, _
⇒
existsb
λ i  ⇒
match app_args"call" 3 i with
Some_; c; _
⇒
match app_args"global" 1 c with
Somes
⇒
negbexistsbterm_eqbs funcs
_
⇒
false
_
⇒
false
insts
None
⇒
false
items

The module's tables

The name a function, data object or alias defines, and its symbol kind: 0, 1 or 2.

1100Definition item_symbolit : term : optionterm × Z ≔
match it with
TAppf n :: _
⇒
String.eqbf "func"
→
Somen, 0
String.eqbf "data"
→
Somen, 1
String.eqbf "alias"
→
Somen, 2
else
None
_
⇒
None

What an item names: its instructions' parts, its data's symbols and constants, its alias's target.

1112Definition item_partsit : term : optionparts ≔
match app_args"func" 5 it with
Some_; _; _; _; TListbs
⇒
let* bps ≔ mapoblock_parts bs in
let* ps ≔
flat_map
λ bp  ⇒
let '_, phis, insts, j ≔ bp in
phis ++ insts ++ j
bps
in
Somefold_rightparts_app no_parts ps
_
⇒
match app_args"data" 4 it with
Some_; _; _; TListits
⇒
Some
map
λ x  ⇒
match app_args"item" 2 x with
Some_; v
⇒
match app_args"sym" 2 v with
Somes; _
⇒
mkParts[ ] s [ ] [ ]
its
_
⇒
match app_args"alias" 3 it with
Some_; _; tg
⇒
SomemkParts[ ] tg [ ] [ ]
_
⇒
None

The string of an atom.

1138Definition atom_stringt : term : optionstring ≔
match t with
⇒
Somes
_
⇒
None

A module's tables: its strings, wide constants and symbols (each a name, a kind, and the item that defines it, if any), and the ids of each.

1143Record mtab: Type ≔ mkMtab
m_strs
 : liststring
m_consts
 : listZ
m_syms
 : listterm × Z × optionterm
m_symids
 : nmapZ
m_strids
 : nmapZ
m_constids
 : ZMap.tZ

The tables of the items.

1149Definition module_tablesitems : listterm : optionmtab ≔
let* defined ≔
λ it  ⇒
let* p ≔ item_symbolit in
Somefstp, sndp, Someit
items
in
let* pss ≔ mapoitem_parts items in
let ps ≔ fold_rightparts_app no_parts pss in
let defmap ≔
fold_left
λ m d  ⇒
let 'n, _, _ ≔ d in
nm_addn 0 m
defined
in
let* defnames ≔
λ d  ⇒
let 'n, _, _ ≔ d in
defined
in
let* named ≔ mapoatom_string filterλg ⇒ negbnm_memg defmap p_globalsps in
let named ≔ sort_uniqstr_lt String.eqb named in
let syms ≔ defined ++ mapλs ⇒ TAtoms, 3, None named in
let 'symids, _, _ ≔
map
λ d  ⇒
let 'n, _, _ ≔ d in
n
syms
0
[ ]
in
let* files ≔ mapoatom_string p_filesps in
let strs ≔ sort_uniqstr_lt String.eqb defnames ++ named ++ files in
let 'strids, _, _ ≔ numbermapTAtom strs nm_empty 0 [ ] in
let consts ≔ sort_uniqZ.ltb Z.eqb filterλc ⇒ negbinlinec p_constsps in
negbforallbwideok consts
→
None
else
let constids ≔ fstfold_leftλp c ⇒ ZMap.addc sndp fstp, sndp + 1 consts ZMap.emptyZ, 0 in
SomemkMtabstrs consts syms symids strids constids

The codes of the data linkages other than init(_, P) with an integer P.

1169Definition data_linkage_codes: listterm × Z ≔
TAtom"export", 0; TAtom"local", 1; TAtom"weak", 2; TApp"ro" TAtom"export", 3; TApp"ro" TAtom"local", 4; TApp"ro" TAtom"weak", 5; TApp"tls" TAtom"export", 6; TApp"tls" TAtom"local", 7; TApp"init" TAtom"ctor"; TAtom"none", 10; TApp"init" TAtom"dtor"; TAtom"none", 11; TApp"extern" TAtom"weak", 12

The value of the term key t in the association list xs.

1177Fixpoint tassoct : term xs : listterm × Z : optionZ ≔
match xs with
[ ]
⇒
None
k, v :: xs′
⇒
→
Somev
else
tassoct xs′

The key of the value z.

1184Fixpoint trassocz : Z xs : listterm × Z : optionterm ≔
match xs with
[ ]
⇒
None
k, v :: xs′
⇒
Z.eqbz v
→
Somek
else
trassocz xs′

A data linkage's code and the word beside it, a priority's.

1191Definition data_linkage_wordlk : term : optionZ × Z ≔
match app_args"init" 2 lk with
Somewh; TIntp
⇒
→
is_atom"ctor" wh
→
Some8, p
is_atom"dtor" wh
→
Some9, p
else
None
else
None
_
⇒
let* c ≔ tassoclk data_linkage_codes in
Somec, 0

A symbol's three words.

1201Definition symbol_wordst : mtab s : term × Z × optionterm : optionlistZ ≔
let 'n, k, it ≔ s in
let* sid ≔ nm_findn m_stridst in
match k, it with
0, Somei
⇒
let* xs ≔ app_args"func" 5 i in
let* lk ≔ nth_errorxs 1 in
let* s ≔ atom_stringlk in
let* c ≔ sassocs func_linkage_codes in
Somesid; c × 256; 0
1, Somei
⇒
let* xs ≔ app_args"data" 4 i in
let* lk ≔ nth_errorxs 1 in
let* p ≔ data_linkage_wordlk in
Somesid; 1 + fstp × 256; sndp
2, Somei
⇒
let* xs ≔ app_args"alias" 3 i in
match xs with
_; lk; tg
⇒
let* s ≔ atom_stringlk in
let* c ≔ sassocs alias_linkage_codes in
let* tid ≔ nm_findtg m_symidst in
Somesid; 2 + c × 256; tid
_
⇒
None
3, None
⇒
Somesid; 3; 0
_, _
⇒
None

The words of a data item.

1226Definition data_item_wordst : mtab x : term : optionlistZ ≔
match app_args"item" 2 x with
Somewd; v
⇒
match app_args"str" 1 v with
SomeTListcs
⇒
is_atom"b" wd
→
let* bs ≔
λ c  ⇒
let* b ≔ char_codec in
b <? 256
→
Someb
else
None
cs
in
Some1 :: bytes_wordsbs
else
None
_
⇒
match app_args"const" 1 v with
SomeTIntn
⇒
let* c ≔ enc_codeEWidth wd in
let* z ≔ const_wordm_constidst n in
Some0; c; z
_
⇒
match app_args"sym" 2 v with
Somes; TIntoff
⇒
is_atom"l" wd || is_atom"p" wd && i64okoff
→
let* c ≔ enc_codeEWidth wd in
let* sid ≔ nm_finds m_symidst in
Some2; c; sid ++ i64_wordsoff
else
None
_
⇒
None
_
⇒
match app_args"zero" 1 x with
SomeTIntn
⇒
→
Some3 :: i64_wordsn
else
None
_
⇒
None

The DATA words of a data item data(N, Lk, Align, Items), or none for another item.

1257Definition data_wordst : mtab it : term : optionlistZ ≔
match app_args"data" 4 it with
Some_; _; TIntal; TListits
⇒
→
let* ws ≔ mapodata_item_wordst its in
Someal; Z.of_natlengthits ++ concatws
else
None
Some_
⇒
None
None
⇒
Some[ ]

The FUNCTIONS words of a function, whether it is ordered, and its names; nothing for another item.

1270Definition func_wordst : mtab it : term : optionlistZ × bool × listfnames ≔
match app_args"func" 5 it with
Some_; _; ret; TListps; TListbs
⇒
let* x ≔ body_wordsw ret ps bs in
let 'body, ordered, names ≔ x in
SomeZ.of_natlengthbody :: body, ordered, names
Some_
⇒
None
None
⇒
Some[ ], true, [ ]

Side sections

Every atom and functor of the term t.

1284Fixpoint term_atomst : term : liststring ≔
match t with
⇒
[ ]
⇒
a
TAppf ts
⇒
f :: flat_mapterm_atoms ts
⇒
flat_mapterm_atoms ts

The words of a string table: the count, then each string.

1293Definition strings_wordsss : liststring : listZ ≔
Z.of_natlengthss :: flat_mapλs ⇒ bytes_wordsstring_bytess ss

The words of the term t in a side section whose pool ids are ids: 0 and an integer, 1 and an atom, 2 and a compound's functor, arity and arguments, 3 and a list's length and elements.

1299Fixpoint side_term_wordsids : nmapZ t : term : optionlistZ ≔
match t with
⇒
→
Some0 :: wide_wordsn
else
None
⇒
let* i ≔ nm_findt ids in
Some1; i
TAppf ts
⇒
let* i ≔ nm_findTAtomf ids in
let* ws ≔
fix go ts : listterm : optionlistZ ≔
match ts with
[ ]
⇒
Some[ ]
t :: ts′
⇒
let* a ≔ side_term_wordsids t in
let* b ≔ gots′ in
Somea ++ b
ts
in
Some2; i; Z.of_natlengthts ++ ws
⇒
let* ws ≔
fix go ts : listterm : optionlistZ ≔
match ts with
[ ]
⇒
Some[ ]
t :: ts′
⇒
let* a ≔ side_term_wordsids t in
let* b ≔ gots′ in
Somea ++ b
ts
in
Some3; Z.of_natlengthts ++ ws

The NAMES words of the functions' names: the pool, then each function's temporaries, labels and locals, each list its length and its terms.

1323Definition names_wordsns : listfnames : optionlistZ ≔
let all ≔ flat_mapλf ⇒ n_tempsf ++ n_labelsf ++ n_localsf ns in
let pool ≔ sort_uniqstr_lt String.eqb flat_mapterm_atoms all in
let 'ids, _, _ ≔ numbermapTAtom pool nm_empty 0 [ ] in
let list_words ts : listterm ≔
let* ws ≔ maposide_term_wordsids ts in
SomeZ.of_natlengthts :: concatws
in
let* recs ≔
λ f  ⇒
let* a ≔ list_wordsn_tempsf in
let* b ≔ list_wordsn_labelsf in
let* c ≔ list_wordsn_localsf in
Somea ++ b ++ c
ns
in
Somestrings_wordspool ++ concatrecs

A module's words

1335Definition magic: Z ≔
4343374
1336Definition version: Z ≔
1

The words of the sections ss, each its id, length and payload.

1339Definition sections_wordsss : listZ × listZ : listZ ≔
flat_mapλs ⇒ fsts :: Z.of_natlengthsnds :: snds ss

The NFB of the module term module(Items) without context/2 items, with the NAMES section when names is true.

1344Definition encode_termnames : bool m : term : optionlistZ ≔
let* xs ≔ app_args"module" 1 m in
match xs with
TListitems
⇒
let* t ≔ module_tablesitems in
let* syms ≔ maposymbol_wordst m_symst in
let* datas ≔ mapodata_wordst items in
let* fs ≔ mapofunc_wordst items in
let fws ≔
concat
map
λ x  ⇒
let 'ws, _, _ ≔ x in
ws
fs
in
let ordered ≔
forallb
λ x  ⇒
let '_, o, _ ≔ x in
o
fs
in
let fnames ≔
concat
map
λ x  ⇒
let '_, _, n ≔ x in
n
fs
in
let dws ≔ concatdatas in
let* nws ≔
names && negbNat.eqblengthfnames 0
→
let* ws ≔ names_wordsfnames in
Some256, ws
else
Some[ ]
in
let core ≔
Nat.eqblengthm_strst 0
→
[ ]
++
Nat.eqblengthm_constst 0
→
[ ]
else
2, Z.of_natlengthm_constst :: flat_mapwide_words m_constst
++
Nat.eqblengthm_symst 0
→
[ ]
else
3, Z.of_natlengthm_symst :: concatsyms
++
Nat.eqblengthdws 0
→
[ ]
else
4, dws
++
Nat.eqblengthfws 0
→
[ ]
else
5, fws
in
let secs ≔ core ++ nws in
let flags ≔
else
0
+
→
2
else
0
+
ordered
→
4
else
0
in
Somemagic; version; flags; Z.of_natlengthsecs ++ sections_wordssecs
_
⇒
None

Reading a module

A reader of words: a value and the words after it, or none.

1376Definition readerX : Type : Type ≔
listZ → optionX × listZ

Read n of what r reads.

1379Fixpoint read_nX : Type n : nat r : readerX : readerlistX ≔
λ ws  ⇒
match n with
O
⇒
Some[ ], ws
Sn′
⇒
let* p ≔ rws in
let* q ≔ read_nn′ r sndp in
Somefstp :: fstq, sndq

Read a count, then that many of what r reads; a count beyond the words left is refused before anything is read.

1387Definition read_countedX : Type r : readerX : readerlistX ≔
λ ws  ⇒
match ws with
n :: ws′
⇒
Z.of_natlengthws′ <? n
→
None
else
read_nZ.to_natn r ws′
[ ]
⇒
None

Read one word.

1394Definition read_word: readerZ ≔
λ ws  ⇒
match ws with
x :: xs
⇒
Somex, xs
[ ]
⇒
None

Read a byte string: its length, then its words.

1397Definition read_bytes: readerlistZ ≔
λ ws  ⇒
match ws with
n :: ws′
⇒
n <? 0 || Z.of_natlengthws′ × 4 <? n
→
None
else
let* p ≔ takeZ.to_natn + 3 / 4 ws′ in
SomefirstnZ.to_natn unpackfstp, sndp
[ ]
⇒
None

Read a string table.

1407Definition read_strings: readerliststring ≔
λ ws  ⇒
let* p ≔ read_bytesws in
Somebytes_stringfstp, sndp

Read a signed 96-bit integer.

1411Definition read_wide: readerZ ≔
λ ws  ⇒
match ws with
w0 :: w1 :: w2 :: ws′
⇒
Somewide_ofw0 w1 w2, ws′
_
⇒
None

Read a signed 64-bit integer.

1415Definition read_i64: readerZ ≔
λ ws  ⇒
match ws with
lo :: hi :: ws′
⇒
Somei64_oflo hi, ws′
_
⇒
None

Read a side section's term, at most fuel deep.

1419Fixpoint read_side_termpool : ZMap.tterm fuel : nat : readerterm ≔
λ ws  ⇒
match fuel with
O
⇒
None
Sf
⇒
match ws with
0 :: ws′
⇒
let* p ≔ read_widews′ in
SomeTIntfstp, sndp
1 :: i :: ws′
⇒
let* a ≔ ZMap.findi pool in
Somea, ws′
2 :: i :: ws′
⇒
let* fa ≔ ZMap.findi pool in
let* fn ≔ atom_stringfa in
let* p ≔ read_countedread_side_termpool f ws′ in
match fstp with
[ ]
⇒
None
_
⇒
SomeTAppfn fstp, sndp
3 :: ws′
⇒
let* p ≔ read_countedread_side_termpool f ws′ in
SomeTListfstp, sndp
_
⇒
None

The map from 0, 1, ... to the elements of xs.

1438Definition index_mapX : Type xs : listX : ZMap.tX ≔
fstfold_leftλp x ⇒ ZMap.addsndp x fstp, sndp + 1 xs ZMap.emptyX, 0

Read the NAMES section: the pool, then each function's names, as many as the words hold.

1443Fixpoint read_name_recspool : ZMap.tterm fuel : nat ws : listZ : optionlistfnames ≔
match ws with
[ ]
⇒
Some[ ]
_
⇒
match fuel with
O
⇒
None
Sf
⇒
let rt ≔ read_side_termpool lengthws in
let* a ≔ read_countedrt ws in
let* b ≔ read_countedrt snda in
let* c ≔ read_countedrt sndb in
let* rest ≔ read_name_recspool f sndc in
SomemkFnamesfsta fstb fstc :: rest

The NAMES of the section's words.

1459Definition read_namesws : listZ : optionlistfnames ≔
let* p ≔ read_stringsws in
read_name_recsindex_mapmapTAtom fstp lengthsndp sndp

The opcode of the next instruction, after its rebind prefix, if any.

1463Definition next_opcodews : listZ : optionZ ≔
match ws with
h :: ws′
⇒
Z.eqbh mod 65536 rebind_code
→
let* x ≔ nth_errorws′ Z.to_nath / 65536 − 1 in
Somex mod 65536
else
Someh mod 65536
[ ]
⇒
None

Read one instruction of the group g, n temporaries and x locals defined before it; the counts after it.

1474Definition read_instr : rtab g : Z n x : Z : readerterm × Z × Z ≔
λ ws  ⇒
let* pre ≔
match ws with
h :: ws′
⇒
Z.eqbh mod 65536 rebind_code
→
h / 65536 <? 2
→
None
else
let* p ≔ takeZ.to_nath / 65536 − 1 ws′ in
SomeSomefstp, sndp
else
SomeNone, ws
[ ]
⇒
None
in
let 'rb, ws1 ≔ pre in
match ws1 with
h :: ws2
⇒
let c ≔ h mod 65536 in
let len ≔ h / 65536 in
len <? 1 || negbZ.eqbgroupc g
→
None
else
let* f ≔ form_of_codeforms c in
let* p ≔ takeZ.to_natlen − 1 ws2 in
let* q ≔ read_lfieldsr f_fieldsf [ ] mkRstfstp rb n x in
let 'e, s ≔ q in
match s_wordss, s_rebindss with
[ ], None | Some[ ]
⇒
let* t ≔ fill_patf_patf e in
Somet, s_nexts, s_locals, sndp
_, _
⇒
None
[ ]
⇒
None

Read the instructions of the group g that come next, at most fuel.

1501Fixpoint read_groupr : rtab g : Z fuel : nat n x : Z : readerlistterm × Z × Z ≔
λ ws  ⇒
match next_opcodews with
Somec
⇒
Z.eqbgroupc g
→
match fuel with
O
⇒
None
Sf
⇒
let* p ≔ read_instr g n x ws in
let 't, n1, x1, ws1 ≔ p in
let* q ≔ read_groupr g f n1 x1 ws1 in
let 'ts, n2, x2, ws2 ≔ q in
Somet :: ts, n2, x2, ws2
else
Some[ ], n, x, ws
None
⇒
Some[ ], n, x, ws

Read the blocks from the index i, k of them, fuel bounding each group.

1521Fixpoint read_blocksr : rtab fuel : nat i : Z k : nat n x : Z : readerlistterm × Z × Z ≔
λ ws  ⇒
match k with
O
⇒
Some[ ], n, x, ws
Sk′
⇒
let* l ≔ ZMap.findi r_labelsr in
let* p ≔ read_groupr 0 fuel n x ws in
let 'phis, n1, x1, ws1 ≔ p in
Z.eqbi 0 && negbNat.eqblengthphis 0
→
None
else
let* q ≔ read_groupr 1 fuel n1 x1 ws1 in
let 'insts, n2, x2, ws2 ≔ q in
let* u ≔ read_instr 2 n2 x2 ws2 in
let 'j, n3, x3, ws3 ≔ u in
let* v ≔ read_blocksr fuel i + 1 k′ n3 x3 ws3 in
let 'bs, n4, x4, ws4 ≔ v in
SomeTApp"block" l; TListphis; TListinsts; j :: bs, n4, x4, ws4

The return type of its word.

1540Definition read_retz : Z : optionterm ≔
Z.eqbz 0
→
SomeTAtom"void"
256 ≤? z
→
z − 256 / 16 <? 16
→
let* k1 ≔ dec_codeEClass z − 256 / 16 in
let* k2 ≔ dec_codeEClass z mod 16 in
SomeTApp"tuple" TListk1; k2
else
None

The integers from 0 below n, as terms: the names without NAMES.

1550Definition id_namesn : Z : listterm ≔
mapλi ⇒ TIntZ.of_nati seq0 Z.to_natn

Read a function's body, of the symbol name n and linkage lk, its names from nm if NAMES has them.

1554Definition read_bodyr : rtab nm : optionfnames name lk : term ws : listZ : optionterm ≔
match ws with
rw :: np :: ws1
⇒
let* ret ≔ read_retrw in
let* p ≔ takeZ.to_natnp ws1 in
np <? 0
→
None
else
let* pks ≔
λ c  ⇒
let* k ≔ dec_codeEClass c in
class_in"w"; "l"; "p"; "s"; "d" k
→
Somek
else
None
fstp
in
match sndp with
nb :: nt :: nl :: stream
⇒
let left ≔ Z.of_natlengthstream in
nb <? 0 || nt <? np || nl <? 0 || left <? nb || left <? nt − np || left <? nl
→
None
else
let 'tn, ln, xn ≔
match nm with
None
⇒
in
negbZ.eqbZ.of_natlengthtn nt && Z.eqbZ.of_natlengthln nb && Z.eqbZ.of_natlengthxn nl
→
None
else
let params ≔ mapλq ⇒ TApp"param" fstq; TApp"tmp" sndq combinepks firstnlengthpks tn in
let* q ≔ read_blocksr′ lengthstream 0 Z.to_natnb np 0 stream in
let 'bs, n1, x1, rest ≔ q in
match rest with
[ ]
⇒
Z.eqbn1 nt && Z.eqbx1 nl
→
SomeTApp"func" name; lk; ret; TListparams; TListbs
else
None
_
⇒
None
_
⇒
None
_
⇒
None

Read a data item.

1588Definition read_data_itemr : rtab : readerterm ≔
λ ws  ⇒
match ws with
1 :: ws′
⇒
let* p ≔ read_bytesws′ in
SomeTApp"item" TAtom"b"; TApp"str" TListmapcode_char fstp, sndp
0 :: c :: z :: ws′
⇒
let* wd ≔ dec_codeEWidth c in
let* n ≔ const_ofr z in
SomeTApp"item" wd; TApp"const" TIntn, ws′
2 :: c :: sid :: ws′
⇒
let* wd ≔ dec_codeEWidth c in
let* s ≔ ZMap.findsid r_symsr in
let* p ≔ read_i64ws′ in
SomeTApp"item" wd; TApp"sym" s; TIntfstp, sndp
3 :: ws′
⇒
let* p ≔ read_i64ws′ in
SomeTApp"zero" TIntfstp, sndp
_
⇒
None

The linkage of a data symbol, from its code and extra word.

1605Definition read_data_linkagec extra : Z : optionterm ≔
Z.eqbc 8
→
SomeTApp"init" TAtom"ctor"; TIntextra
Z.eqbc 9
→
SomeTApp"init" TAtom"dtor"; TIntextra

Read the items of the symbols syms, in order: a function's body from fws and its names from nms, a data object's from dws, an alias from the symbol itself.

1613Fixpoint read_itemsr : rtab syms : listterm × Z × Z dws fws : listZ nms : optionlistfnames : optionlistterm ≔
match syms with
[ ]
⇒
match dws, fws, nms with
[ ], [ ], None | Some[ ]
⇒
Some[ ]
_, _, _
⇒
None
name, kw, extra :: syms′
⇒
let k ≔ kw mod 256 in
let lc ≔ kw / 256 in
Z.eqbk 0
→
let* lks ≔ srassoclc func_linkage_codes in
negbZ.eqbextra 0
→
None
else
match fws with
len :: fws1
⇒
let* p ≔ takeZ.to_natlen fws1 in
let* nm ≔
match nms with
None
⇒
SomeNone, None
Somef :: fs
⇒
SomeSomef, Somefs
Some[ ]
⇒
None
in
let* f ≔ read_bodyr fstnm name TAtomlks fstp in
let* rest ≔ read_itemsr syms′ dws sndp sndnm in
Somef :: rest
[ ]
⇒
None
Z.eqbk 1
→
let* lk ≔ read_data_linkagelc extra in
match dws with
al :: ni :: dws1
⇒
Z.of_natlengthdws1 <? ni
→
None
else
let* p ≔ read_nZ.to_natni read_data_itemr dws1 in
let* rest ≔ read_itemsr syms′ sndp fws nms in
SomeTApp"data" name; lk; TIntal; TListfstp :: rest
_
⇒
None
Z.eqbk 2
→
let* lks ≔ srassoclc alias_linkage_codes in
let* tg ≔ ZMap.findextra r_symsr in
let* rest ≔ read_itemsr syms′ dws fws nms in
SomeTApp"alias" name; TAtomlks; tg :: rest
Z.eqbk 3
→
read_itemsr syms′ dws fws nms
else
None

Split the words into sections, each id with its payload.

1654Fixpoint read_sectionsfuel : nat ws : listZ : optionlistZ × listZ ≔
match ws with
[ ]
⇒
Some[ ]
id :: len :: ws′
⇒
match fuel with
O
⇒
None
Sf
⇒
let* p ≔ takeZ.to_natlen ws′ in
let* rest ≔ read_sectionsf sndp in
Someid, fstp :: rest
_
⇒
None

Whether the section ids increase, each known: a core one from 1 to 5, NAMES, CONTEXT, or a tool's from 0x200.

1668Fixpoint ids_okprev : Z ss : listZ × listZ : bool ≔
match ss with
[ ]
⇒
true
id, _ :: ss′
⇒
prev <? id && 1 ≤? id && id ≤? 5 || Z.eqbid 256 || Z.eqbid 257 || 512 ≤? id && ids_okid ss′

The payload of the section id, or none.

1677Fixpoint sectionid : Z ss : listZ × listZ : optionlistZ ≔
match ss with
[ ]
⇒
None
i, ws :: ss′
⇒
Z.eqbi id
→
Somews
else
sectionid ss′

The module term of the words ws, without its context items, and whether it had NAMES; the words are not yet checked against the module's own encoding (decode_term does that).

1686Definition read_termws : listZ : optionterm × bool ≔
match ws with
m :: v :: flags :: nsecs :: ws′
⇒
negbZ.eqbm magic && Z.eqbv version && 0 ≤? flags && flags <? 8
→
None
else
let* ss ≔ read_sectionslengthws′ ws′ in
negbZ.eqbZ.of_natlengthss nsecs && ids_ok0 ss
→
None
else
let or_empty o : optionlistZ d : listZ ≔
match o with
Somex
⇒
x
None
⇒
d
in
let* sp ≔ read_stringsor_emptysection1 ss 0 in
let* cp ≔ read_countedread_wide or_emptysection2 ss 0 in
let* yp ≔
λ ws  ⇒
match ws with
a :: b :: c :: ws′
⇒
Somea, b, c, ws′
_
⇒
None
or_emptysection3 ss 0
in
match sndsp, sndcp, sndyp with
[ ], [ ], [ ]
⇒
let strs ≔ index_mapmapTAtom fstsp in
let* syms ≔
λ y  ⇒
let 'sid, kw, extra ≔ y in
let* n ≔ ZMap.findsid strs in
Somen, kw, extra
fstyp
in
let symt ≔
map
λ y  ⇒
let 'n, _, _ ≔ y in
n
syms
in
let* nms ≔
match section256 ss with
Somews
⇒
let* ns ≔ read_namesws in
SomeSomens
None
⇒
SomeNone
in
let r ≔ mkRtabsymt strs index_mapfstcp ZMap.emptyterm ZMap.emptyterm ZMap.emptyterm in
let* items ≔ read_itemsr syms or_emptysection4 ss [ ] or_emptysection5 ss [ ] nms in
Some
TApp"module" TListitems
match nms with
Some_
⇒
true
None
⇒
false
_, _, _
⇒
None
_
⇒
None

The words ws without their CONTEXT section and the sections of tools: those that do not say what the module is.

1719Definition module_wordsws : listZ : optionlistZ ≔
match ws with
m :: v :: flags :: _ :: ws′
⇒
let* ss ≔ read_sectionslengthws′ ws′ in
let kept ≔ filterλs ⇒ fsts <? 257 ss in
Somem; v; flags; Z.of_natlengthkept ++ sections_wordskept
_
⇒
None

Equality of two lists of words.

1729Fixpoint words_eqbxs ys : listZ : bool ≔
match xs, ys with
[ ], [ ]
⇒
true
x :: xs′, y :: ys′
⇒
Z.eqbx y && words_eqbxs′ ys′
_, _
⇒
false

The module term the NFB ws encode, provided ws are exactly its encoding, CONTEXT and tools' sections aside.

1738Definition decode_termws : listZ : optionterm ≔
let* p ≔ read_termws in
let* ws1 ≔ encode_termsndp fstp in
let* ws2 ≔ module_wordsws in
words_eqbws1 ws2
→
Somefstp
else
None