sourcelibs/Bits/src/Bits.xtlm

1⍝# Bits: its macro library -- f_ields<, named bit fields. 2⍝# Imported with the functions, under one alias: "b:" u_se< "Bits". 3⍝# A macro is a function from the source text written left and right of 4⍝# its call to the source that replaces the call, run before the program 5⍝# is compiled (X_eTaL MC10). Names with m: are macros; those under h: are 6⍝# private to this file. 7 8ᵗ⁼u̲se< "Strings" 9 10lowers ← "abcdefghijklmnopqrstuvwxyz" 11uppers ← ⎕A 12letters ← lowers c̲at uppers c̲at ⎕D 13 14⍝## Parsing fields 15 16⍝# A field's name and width, from "name:width". 17ʰn̲ame ← { f → (f̲irst w̲here f = f̲irst ":") − 1 } 18ʰf̲ieldName ← { f → (ʰn̲ame f) t̲ake f } 19ʰf̲ieldWidth ← { f → f̲loor f̲irst n̲umbers (1 + ʰn̲ame f) d̲rop f } 20 21⍝# Whether a field is "name:width": a lowercase name of letters and 22⍝# digits, a whole width. 23ʰf̲ield? ← { f → 24 1 ≠ t̲ally w̲here f = f̲irst ":" ? 0 = 1 25 n ← ʰf̲ieldName f 26 w ← (1 + ʰn̲ame f) d̲rop f 27 (0 < t̲ally n) ∧ ((f̲irst n) m̲ember? lowers) ∧ ('∧ r̲/ n m̲ember? letters) ∧ (0 < t̲ally w) ∧ '∧ r̲/ w m̲ember? ⎕D 28} 29 30⍝## The macro 31 32⍝# The function names for a field: m_ode and s_etMode for "mode". 33ʰg̲etter ← { n → "u:" c̲at (1 t̲ake n) c̲at "_" c̲at 1 d̲rop n } 34ʰ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 } 35 36⍝# @ b:f_ields< "flag:1 mode:3 count:12": named fields of a packed whole 37⍝# number, lowest bits first. When the program is compiled it writes, 38⍝# for each field, a getter (u:m_ode x: the field of x) and a setter 39⍝# (v u:s_etMode x: x with the field set to v), their offsets and sizes 40⍝# worked out as plain numbers, so nothing is computed about the layout 41⍝# at run time. A malformed field, or more than 62 bits, stops the 42⍝# compiler: error[bad-fields]. Nothing goes on the left (@). 43ᵐf̲ields< ← { none t → 44 ({ @ → 0 })_ none ⍝ the left side takes only @ (MC22) 45 fs ← ᵗw̲ords t 46 0 = t̲ally fs ? "bad-fields right" ⎕R̲EJECT "no fields: write them name:width, lowest bits first" 47 bad ← (n̲ot '{ ʰf̲ield? d̲isclose ⍵ } e̲ach fs) r̲eplicate fs 48 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)" 49 ws ← '{ ʰf̲ieldWidth d̲isclose ⍵ } e̲ach fs 50 (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" 51 offs ← (0 c̲at -1 d̲rop '+ s̲\ ws) 52 "\n" ᵗj̲oin '{ i → 53 f ← d̲isclose i s̲elect fs 54 n ← ʰf̲ieldName f 55 div ← f̲ormat 2 ^ f̲irst i s̲elect offs 56 size ← f̲ormat 2 ^ f̲irst i s̲elect ws 57 (ʰ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 " }" 58 } m̲ap r̲ange t̲ally fs 59}