macro librarylibs/Bits/src/Bits.xtlm
Bits: its macro library -- f_ields<, named bit fields. Imported with the functions, under one alias: "b:" u_se< "Bits". A macro is a function from the source text written left and right of its call to the source that replaces the call, run before the program is compiled (X_eTaL MC10). Names with m: are macros; those under h: are private to this file.
Parsing fields
ʰn̲ame : Char -> Int
A field's name and width, from "name:width".
ʰn̲ame ← { f → (f̲irst w̲here f = f̲irst ":") − 1 }
ʰf̲ieldWidth : Char -> Int
ʰf̲ieldWidth ← { f → f̲loor f̲irst n̲umbers (1 + ʰn̲ame f) d̲rop f }
ʰf̲ield? : Truthy a => Char -> a
Whether a field is "name:width": a lowercase name of letters and digits, a whole width.
ʰf̲ield? ← { f → 1 ≠ t̲ally w̲here f = f̲irst ":" ? 0 = 1 n ← ʰf̲ieldName f w ← (1 + ʰn̲ame f) d̲rop f (0 < t̲ally n) ∧ ((f̲irst n) m̲ember? lowers) ∧ ('∧ r̲/ n m̲ember? letters) ∧ (0 < t̲ally w) ∧ '∧ r̲/ w m̲ember? ⎕D }
The macro
ʰg̲etter : Char -> Char
The function names for a field: m_ode and s_etMode for "mode".
ʰg̲etter ← { n → "u:" c̲at (1 t̲ake n) c̲at "_" c̲at 1 d̲rop n }
ʰs̲etter : Char -> Char
ʰs̲etter ← { n → up ← f̲irst (lowers i̲ndexOf 1 t̲ake n) s̲elect uppers◆ "u:s_et" c̲at up c̲at 1 d̲rop n }
ᵐf̲ields< : Unit -> Char -> Char
@ b:f_ields< "flag:1 mode:3 count:12": named fields of a packed whole number, lowest bits first. When the program is compiled it writes, for each field, a getter (u:m_ode x: the field of x) and a setter (v u:s_etMode x: x with the field set to v), their offsets and sizes worked out as plain numbers, so nothing is computed about the layout at run time. A malformed field, or more than 62 bits, stops the compiler: error[bad-fields]. Nothing goes on the left (@).
ᵐf̲ields< ← { none t → ({ @ → 0 })_ none ⍝ the left side takes only @ (MC22) fs ← ᵗw̲ords t 0 = t̲ally fs ? "bad-fields right" ⎕R̲EJECT "no fields: write them name:width, lowest bits first" bad ← (n̲ot '{ ʰf̲ield? d̲isclose ⍵ } e̲ach fs) r̲eplicate fs 0 < t̲ally bad ? "bad-fields right" ⎕R̲EJECT (d̲isclose f̲irst bad) c̲at " is not a field: write name:width (a lowercase name, a whole width)" ws ← '{ ʰf̲ieldWidth d̲isclose ⍵ } e̲ach fs (0 < t̲ally w̲here ws = 0) ∨ 62 < '+ r̲/ ws ? "bad-fields right" ⎕R̲EJECT "the fields take " c̲at (f̲ormat '+ r̲/ ws) c̲at " bits: each 1 or more, 62 in all at most" offs ← (0 c̲at -1 d̲rop '+ s̲\ ws) "\n" ᵗj̲oin '{ i → f ← d̲isclose i s̲elect fs n ← ʰf̲ieldName f div ← f̲ormat 2 ^ f̲irst i s̲elect offs size ← f̲ormat 2 ^ f̲irst i s̲elect ws (ʰg̲etter n) c̲at " := { x -> (x d_iv " c̲at div c̲at ") m_od " c̲at size c̲at " }\n" c̲at (ʰs̲etter n) c̲at " := { v x -> x + (" c̲at div c̲at " * v m_od " c̲at size c̲at ") - " c̲at div c̲at " * (x d_iv " c̲at div c̲at ") m_od " c̲at size c̲at " }" } m̲ap r̲ange t̲ally fs }