aboutsummaryrefslogtreecommitdiff
path: root/src/bootstrap/boot1.bqn
blob: 1a833abd8b6fd0a40104a2b95d8db969787d83b8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
# Comiler simplified once
# Full compiler minus error checking and index tracking
# Syntax simplified to avoid _ Β· β€Ώ ' π•π•Žπ”½π”Ύπ•— and double quote in comment
# Already didn't have . [] :;? ⇐ π•£π•€π•˜
# Blocks are functions; no empty list literals; no useless parentheses
na←¯1βŠ‘β‰’alph←("aA"+βŒœβ†•26)∾˘"Γ Γ€"+⌜(↕23)∾24+↕7
lf←@+⟨10,13⟩
⟨charSet,cglβŸ©β†(∾ β‹ˆ β‰ Β¨)⟨
  "+-Γ—Γ·β‹†βˆšβŒŠβŒˆ|¬∧∨<>β‰ =≀β‰₯β‰‘β‰’βŠ£βŠ’β₯ŠβˆΎβ‰β‹ˆβ†‘β†“β†•Β«Β»βŒ½β‰/β‹β’βŠβŠ‘βŠβŠ’βˆŠβ·βŠ”!" # Function
  mod1←"Λ™ΛœΛ˜Β¨βŒœβΌΒ΄Λ`"      # 1-modifier
  "βˆ˜β—‹βŠΈβŸœβŒΎβŠ˜β—ΆβŽ‰βš‡βŸβŽŠ"         # 2-modifier
  "β‹„,"∾lf               # Separator
  ":;?"                 # Header punctuation
  "⇐←↩"                 # Gets
  "(){}⟨⟩[]"            # Bracket
  "β€Ώ"                   # Ligature
  "Β·"                   # nOthing
  "π•Šπ•π•Žπ”½π”Ύπ•€π•©π•¨π•£π•—π•˜"         # Input
  ".Β―Ο€βˆž"                # Numeric
  (βŠ‘"0")+↕10            # Digit
  "_"∾˜β₯Šalph            # Alphabetic
  "β€’ "∾@+9              # Whitespace
  ⟨cc,qs,qd,ncβŸ©β†"#'""@" # Preprocessed characters
⟩
⟨bF,b1,b2,bS,bH,bG,bB,bL,bO,bX,bN,bD,bA,bW,bPβŸ©β†β‹ˆΒ¨ΛœβŸœ(0Β»+`)cgl
M←1βŠΈβŠ‘(0βŠΈβ‰€βˆ§>)-βŸœβŠ‘   # ∊ for an init,length pair 𝕩 as above
sepβ†βŠ‘bS
pred←2+βŠ‘bH
bI←bX+β‹ˆβŸœ-5β‹„bR←8+βŠ‘bX
# Convert characters to numbers, mostly the same as tokens
cgf←(cgr←⍋charSet)⊏charSet
CharCode←cgr⊏˜1-˜1⌈cgfβ‹βŠ’
swapundo←CharCode∊⟜mod1⊸/"˜⁼"

vd←1+viβ†βŠ‘bN  # Start of identifier numbering (plus dot)
charRole←4∾˜∾β₯ŠΒ¨ΛœβŸœ(≠↑cglΛ™)⟨1,2,3,Β―1,Β―1,Β―3,⟨¯1,0⟩,Β―2,0,Β¬/⟨5,6⟩⟩ # For first vd chars
Tβ†βŒˆ`Γ— β‹„ ITβ†β†•βˆ˜β‰ βŠΈT β‹„ I1T←(1+β†•βˆ˜β‰ )⊸T
PN←1(∾/∾˜)(∨/⊣)  # Partitioned-none: partitions where 𝕨<𝕩 is never 1

# Source to ⟨tokens, roles, number of identifiers, literals⟩
# Identifiers then literal tokens are numbered starting at vi
Tokenize←{⟨System,varsβŸ©β†π•¨
  # Resolve comments and strings
  c←𝕩=ccβ‹„s←/⟨0,0⟩⊸«⊸∧sm←𝕩=qsβ‹„d←/dm←𝕩=qd
  g←⍋qβ†βˆΎβŸ¨  sβ‹„Β―1↓dβ‹„/c⟩ β‹„q↩g⊏q                # Open indices
  e← g⊏∾⟨2+sβ‹„ 1↓dβ‹„-⟜»∘⊏⟜(0∾+`c)⊸//(π•©βˆŠlf)∾1⟩ # Matching close indices
  Se←≠(>/⊒)βˆΎβŸœβ‰ {(βŠΛœπ•¨)π•ŠβŸ(β‰ β—‹(Β―1βŠΈβŠ‘))π•©βˆΎπ•©βŠπ•¨}⟨0βŸ©Λ™  # Find reachable openings
  St←(≠𝕩)↑(/⁼(Se q⍋e)⊸⊏)                    # All indices β†’ reached mask
  a←St qβ‹„b←St eβ‹„f←1β‰ `ab←a∨b                 # Open/close masks; filter

  # Extract character and string literals
  u←fβˆ§π•©=ncβ‹„ci←/u∨»a∧sm
  chr←(βŠβŸœπ•©-(nc-@)Γ—βŠβŸœu)ci                    # Characters (indices ci)
  f>↩qe←dm∧«aβˆ§β†©dm                           # Quote Escape
  strβ†π•©βŠ”Λœ1-˜(si←a>Β»qe)(⊣+`βŠΈΓ—β—‹(∾⟜1)<)β‰ `dm∧ab # Strings (indices /si)

  # Extract words: identifiers and numbers
  t←CharCode f/𝕩
  nd←(t=βŠ‘bN)>Β«t M bDβ‹„rr←t=bR                # Namespace dot; 𝕣
  wβ†Β»βŠΈ<l←rr∨nd<t M bN(βŠ£β‹ˆ-˜)β—‹βŠ‘bW             # Word chars l, start w
  us←t=Β―1++Β΄bAβ‹„sy←t=βŠ‘bW                     # Underscore, system dot
  wk←(Β¬w/rr)Γ—na⌊∘÷˜(βŠ‘bA)-˜w/t               # Kind of word from first char
  t-↩naΓ—l∧tβ‰₯na+βŠ‘bA                          # Case-insensitive
  wβ‰ β†©Β»βŠΈβˆ¨sy                                  # Start system word at dot
  wi←0<wt←(2Γ—wkβ‰₯0)(Γ—βŸœΒ¬+⊒)w/sy               # Type: 0 number, 1 system, 2 identifier
  i←l>n←l∧(+`w)⊏0∾¬wi                       # Identifier/Number masks
  num←ReadNumsβ—‹(((0∾us)<∨⟜«0∾n)/0⊸∾) tΓ—l    # Numbers
  ir←(us/˜«⊸<i)(⊒+∧⟜(2⊸=))wi/wk             # Identifier role
  if←(»⌈`)⊸<ig←(i>us)Γ—+`w>n                 # Identifier groups and first character
  fr←(1=wi/wt)<if/rr                        # Identifier is 𝕣-based
  w↩if∨n∧wβ‹„ws←1=0⊸<⊸/wt/Λœβ†©Β¬w/rr             # Don't produce an identifier for 𝕣
  igβŠβ†©1-˜0∾+`βŠΈΓ—Β¬fr
  id←varsβŠΈβˆΎβŒΎβŠ‘(ws∾2)βŠ”igβŠ”t⊏charSet            # ⟨Identifiers, system values⟩

  # Deduplicate literals and identifiers; other cleanup
  ki←(wtβ’βŠΈβŠ/w>rr)∾(ci∾/si)⊏+`Β»f             # Indices in t
  k←id∾⟨num,chr,strβŸ©β‹„k(⊒>Β―1»⌈`)⊸/Β¨Λœβ†©jβ†βŠΒ¨k   # IDs j into uniques k
  k↩System⌾(1βŠΈβŠ‘)k                           # System value lookup
  wf←¬l∨t M bW                              # Index management for...
  t↩(w∨wf)/(varsβ‰ βŠΈβ†“βˆΎj++`vdΒ»kk←≠¨k)⌾(ki⊸⊏)t  # Add IDs; remove words/whitespace
  t-↩t(MΓ—-βŸœβŠ‘)bS                             # Separators are equivalent
  p←≠`1Β¨sb←¯1↓1↓/1(βˆΎβ‰ βˆΎΛœ)t=sep               # Separator group boundaries (excludes leading and trailing)
  ebβ†βŸ¨3,5,7⟩+βŠ‘bB                            # End brackets that allow separators
  sk←sb/˜p>∨⟜«(M⟜bH∨eb∊˜p⊸+)(sb-p)⊏t        # Keep the first of each group that's not just inside a bracket
  t/Λœβ†©1¨⌾(sk⊸⊏)tβ‰ sep      # Remove the rest
  im←(t=bR)∨t M vdβ‹ˆ+Β΄2↑kk                   # Identifier (or 𝕣) mask
  r←ir⌾(im⊸/)(vd⌊t)⊏charRole∾0              # Role
  t+↩(βŠ‘bX)((⊒Mβ‹ˆβŸœ5)Γ—5+3⊸+βŠΈβ‰€)t                # Case-insensitive special names
  t-↩vi(<+10Γ—=)t                            # Shift . to bX and variables back one
  ⟨t,r,k⟩
}

# 𝕩 is a list of tokens that contains the numeric literals, each
# preceded by 0. Return the numbers.
ReadNums←{
  ⟨e,d,n,p,iβŸ©β†=βŸœπ•©Β¨((βŠ‘bA)+-Β΄"ea")∾+βŸœβ†•Β΄bN     # Masks for e.Β―Ο€βˆž
  c←e∨z←0=𝕩⋄m←¬n∨c
  f←(17β‰₯Β¬(⊒-T)+`)⊸∧g←(«≀(d<π•©β‰ βŠ‘bD)>β—‹I1TΒ¬)⊸∧m # No leading 0s; max 17 digits
  l←(Β―1βˆΎβŸ¨Ο€,1βŸ©βˆΎβ†•10)⊏˜(Β¬d)/f×𝕩-1+βŠ‘bN          # Digit lookup, with ∞ as 1 to avoid βˆžΓ—0
  v←(>⟜«0≀l)/0(0βŠΈβ‰€Γ—Γ—βŸœ10⊸+)`l                # Numeric valuesβ€”mantissas and exponents
  vΓ—β†©βŸ¨1,Β―1⟩⊏˜(r←>⟜»m)/Β»n                    # Negate if Β―
  vm←c/z                                    # Mask of mantissas in l
  dp←vm/f(--»⊸-(<Γ—βŠ’)⊏⟜(I1TΒ«d)⊸-)β—‹(/>⟜«)g    # Decimal position
  t←10⋆|ee←dp-˜vm/Β«vΓ—Β¬vm                    # Power of 10
  t÷˜⌾((0>ee)⊸/)tΓ—βŒΎ((0<ee)⊸/)vm/vΓ—(r/i)⊏1β‹ˆβˆž # Correct ∞ then Γ—10⋆ee
}


Parse ← {⟨r,vn,defβŸ©β†π•¨β‹„nv←≠vn
  # Bracket and ligature validation and handling
  # Open brackets have role Β―1 and closed ones have role 0
  g←⍋+`p←(Β―1-2Γ—r)×𝕩 M bB                    # Paren (actually any bracket type) depth and grade
  dlβ†Β«βŠΈβˆ¨dc←r=4                              # Dot left
  r-↩(𝕩=βŠ‘bG)>Β«dc<0≀r+p                      # Role Β―4 for exports: βŠ‘bG is ⇐
  srβ†Β»βŒΎ(((β‹βŠβŸœdl)⊸⊏g)⊸⊏)slβ†Β«βŠΈβˆ¨r=Β―2β‹„ns←¬sl∨sr # Strand right and left; not stranded
  cp←𝕩=1+βŠ‘bB                                # Closed paren
  nr←(ITΒ¬cp)⊏(𝕩=2+βŠ‘bI)+2×𝕩=βŠ‘bO              # Nothingness role: 1 for 𝕨, 2 for Β·
  nx←0
  gβŠΛœβ†©β‹g⊏sdl←sl∨dl                          # Avoid reordering strands and dots in rev
  rpβ†β‰ βŠΈΒ»βŒΎ(g⊸⊏)↕≠r                           # Position of previous, for roles
  # Permutation to reverse each expression: *more* complicated than it looks
  rev←⍋+`Β―1↓(Β―1∾g)(βŠ£β‹βŠΈβŠβŠΛœβŸœβ‹Β¬βŠΛœ)⍋+`⊸+1∾g⊏sdl∨r=Β―1
  gf←⍋fd←+`br←rev⊏p×𝕩M⟨2+βŠ‘bB,2⟩             # Order by brace depth fd to de-nest blocks
  revβŠΛœβ†©gfβ‹„fdβŠΛœβ†©gfβ‹„brβŠΛœβ†©gf
  π•©βŠΛœβ†©revβ‹„dcβŠΛœβ†©rev

  # Compute parsing ordering gr≑g⊏rev
  BE←=∨+⟜2⊸=                                # Bracket equals: match ⟨[ or ⟩] given ⟨ or ⟩ only
  g↩⍋+`p↩br-˜rev⊏pβ‹„bp←0(<β‹ˆβ—‹(/⟜g)>)g⊏p       # Order by non-brace bracket depth
  gβŠΛœβ†©β‹g⊏«⊸∨dcβ‹„gr←g⊏rev                     # Now by dots
  sll←1+2÷˜0(<-β—‹/>)gr⊏sr-slβ‹„l←/gβŠπ•©BE˜5+βŠ‘bB  # Strand length; list starts
  b←br>0β‹„c←/br<0β‹„bpβˆΎΒ¨β†©βŸ¨/b,c⟩                # Block Begin (mask) and Close (index), in matching order
  gβŠΛœβ†©gs←⍋gr⊏slβ‹„gr↩g⊏revβ‹„gi←⍋g              # Send strand prefixes *β€Ώ to the end

  # Headers
  hh←𝕩=βŠ‘bHβ‹„cs←𝕩=1+βŠ‘bH                       # Case header : and separator ;
  fi←+`cb←b∨csβ‹„H←cb¬∘PN⊒                    # Body index fi; which bodies Have a property
  cq←(H𝕩=pred)∨ch←H hh                      # ch: body has : header ; cq: or ? predicate
  cf←1∾¬co←cb/csβ‹„cm←0∾∨⟜«co                 # cf: body is first; cm: body is one of multiple
  cc←(⍋⍋«co)⊏c∾/cs                          # Case close
  hi←/hf←hh⊏˜⟜IT⌾((⌽g)⊸⊏)cb∨hh              # Header component indices
  un←0=us←swapundo(β‰ βˆ˜βŠ£-⊐)hiβŠπ•©
  ut←un/Β»usβ‹„hi/Λœβ†©0=us                       # Undo type: 0 normal, 1 ⁼, 2 ˜⁼
  hr←(⊏⟜nsΓ—βŠβŸœr)rev⊏˜hi                      # Header component roles
  hl←2=hn←(1⊸»+Β«)hc←¯1=hr                   # hl: is label, hc: is :
  ho←(»∨(Β«(hr=3)∧⊒))hl<2≀hr                 # Header operands
  hm←¬ho∨ha←ho<(0=hr)∧1=hn                  # Mask for main name; header arguments
  hk←3|1-˜(+`bI∾nv)⍋hiβŠπ•©Γ—Β¬rev⊏sr            # Kind: 0 special, 1 name, 2 compound
  hma←hm>hla←hl∧(0=hr)∧1β‰ hkβ‹„hr+↩hlaβ‹„hl>↩hla # Lone non-name subject is 𝕩 with π•Š omitted
  hv←(hla+haΓ—1+Β«hc)+(hoΓ—4+Β«3=hr)+hmaΓ—3Γ—1-˜2⌊hr # Special name for position
  hk×↩¬hc∨hl∧0=hr                           # Treat subject labels like special names
  hm>↩hcβ‹„hr/Λœβ†©hmβ‹„hx←(1Β»hc)/ha               # Header-derived role hr and immediacy Β¬hx
  ut-↩-⟜»utΓ—ho                              # Shift ⁼ from right operand to main name
  ut/Λœβ†©hmβ‹„hxβˆ¨β†©1=hr
  cwh←hc/Β»hl⌈haΓ—1+he←0β‰ hk                   # Body 𝕨 for just headers
  ut2←2=ut
  cw←(cwh⌈2Γ—ut2)⌾(ch⊸/)1+-⟜«(Β»cq)<1(⊒<Β«)cf  # Body 𝕨: 0 no, 1 allowed, 2 required
  hl/Λœβ†©hmβ‹„hu←(Β¬he)⌾(hi⊸⊏)hf                 # hu: mask of header special names
  hj←gi⊏˜he/hiβ‹„hd←2=he/hk                   # hj: header assignments; hd: which ones destructure

  # Block properties
  ssβ†βŸ¨0,3,5,6βŸ©β‹(⊒+(0<hk)Γ—hv⊸-)⌾(hi⊸⊏)𝕩-βŠ‘bI  # Special name
  ss+↩(rev⊏r=3)βˆ§π•©=3+βŠ‘bI                     # Treat _𝕣_ as 3, like π•˜
  HS←(Β―1+`cf)⊏b¬∘PN=⟜ssβ‹„sp←/hu<𝕩 M bI       # Has-special (𝕀𝕩𝕨/𝕣𝕗/π•˜); indices of specials
  fx←HS 1β‹„fr←(fx∨0⊸<)⊸+ft←2(⊣⌈2Γ—βŠ’)β—‹HS 3     # Body immediacy Β¬fx, type ft, role fr
  ftβŒˆβ†©1-˜fr↩hr⌾(ch⊸/)frβ‹„fx↩hx⊸⌈⌾(ch⊸/)fx
  fsc←(ft⊏⟨0,2,3⟩)+3Γ—fx                     # Special name count
  hv-↩(Β»+`hc)⊏3Γ—Β¬ch/fx                      # Header variable slot

  # Propagate roles through parentheses
  # ir is the role of the expression ending at each position (truncated to the right)
  r↩sl-˜nsΓ—(1↓cf/fr)⌾((c⊏rev)⊸⊏)r           # Add block roles; make strand elements Β―1
  pt←cp∧ns                                  # Pass-through parentheses: not in strands
  pp←pt∧»es←rp⊏1∾˜r<0                       # Parens enclosing one object (maybe with assignment) don't change roles
  ir←((rp⊏0∾˜(1+es)Γ—3=⊒)⌈⊒-es<2β‰€βŠ’)r+ppΓ—(ITΒ¬pp)⊏r # Propagate modifier roles
  irβŒˆβ†©(ITΒ¬pt∧ir=0)((⊏-⊒)⟜(+`Β¬pp)(⊒⌊1⌈+)⊏)ir # ...and function roles
  r+↩ptΓ—Β»ir                                 # Roles at pt were 0; set them now
  nr×↩¬nxβˆ¨β†©(0β‰ ir)∧1=nr                      # Assume π•Ž can't be Nothing
  ir↩(irΓ—0=nr)-nr                           # Include nothingness
  r-↩(r=Β―4)∧1Β»r=Β―1                          # Lone ⇐ to role Β―5
  r(Γ—βŸœΒ¬-⊒)↩dl                               # Namespace and dot to Β―1

  # Reorder for parsing
  xv←𝕩-vi                                   # Save for lexical resolution
  π•©βŠΛœβ†©gβ‹„hg←g⊏hfβ‹„rβŠΛœβ†©grβ‹„nsβŠΛœβ†©grβ‹„irβŠΛœβ†©gr
  l↩(l0←lβŠβ‹gs)∾/gr⊏sr>sl                    # Indices of list literals
  lm←(0Β¨sll)∾˜(5+βŠ‘bB)-˜l0βŠπ•©                 # List merge, adding 2 for []

  # Parsing part 1
  a←(Β―5⊸<βˆ§β‰€βŸœΒ―3)rβ‹„ps←a<r<0                   # a: assignment, ps: part separator
  tr←1≀er←ir⊏˜ITΒ»ps                         # er: expression role; tr: train or modifier expression
  no←0⌈-irβ‹„ne←0⌈-erβ‹„nxβŠΛœβ†©gr                 # Nothing value; expression
  nxβŒˆβ†©neΓ—a
  nxβŒˆβ†©ne×𝕩=pred
  oaβ†βŒ½/hg<op←(er<2)∧rβ‰₯2β‹„ro←op∨«op∧m2←r=3    # op: active modifiers; ro: mod or right operand
  nxβŒˆβ†©opΓ—2(«⌈m2Γ—Β»)no⌈2Γ—m2β‰₯ro∨rβˆŠβ†•2
  s←𝕩=sepβ‹„foβ†π•©βˆŠβŸ¨2+βŠ‘bB,1+βŠ‘bH⟩                # Separators, function open { or ;
  ls←s∧fo<β—‹IT lo←𝕩BE˜4+βŠ‘bB                  # List Separators: after ⟨lo, not {fo
  mm←𝕩=2+βŠ‘bGβ‹„ma←tr<mm∧«irβ‰₯1β‹„mmβˆ§β†©1Β»ps        # Modified assignment; monadic modified
  osβ†β†•βˆ˜β‰ βŠΈ(⊣-T)⌾⌽¬ro∨ma                      # Operator skip: distance rightward to derived function start
  at←1+⊏⟜os⊸+ai←/a                          # Assignment target
  af←¯4β‰ ai⊏rβ‹„ar←at⊏r                        # af for actual (non-export) assignment; assignment role
  ak←af+(0≀ar)+(ai⊏ma)+(βŠ‘bG)-˜aiβŠπ•©          # Class of assignment: 1⇐ 2⇐? 3←? 4↩? 5+↩?
  atβˆΎβ†©hjβ‹„acβ†Β«βŠΈ-(ak∾6Β¨hj)⌾(at⊸⊏)0¨𝕩          # Header assignment is 6 temporarily
  aa←0<gac←g⊏ac↩»+`(1⊸»⊸∨0=+`)βŠΈΓ—gi⊏ac       # Broadcast ac to the entire target
  api←/(𝕩=βŠ‘bO)∧ap←aa∧2=no                   # Assignment placeholder
  nxβŒˆβ†©noΓ—ap<ns≀»lo∨ls
  ac-↩3Γ—6=acβ‹„ah←6=gac                       # Assignment is header; 6β†’3
  nxβŒˆβ†©aaΓ—1=no                               # Prevent assignment to 𝕨 if it's Β·
  nf←H ac<xv=vi-ΛœβŠ‘bG                        # Namespace bodies
  fw←H gi⊏nx                                # Bodies where 𝕨 must be defined
  fwβŒˆβ†©nfΒ¬βŠΈΓ—(1-˜0∾cc⊏rev)⊏nr
  fwβ‰₯β—‹I1T↩cf                                # If a body fails on 𝕨, later ones won't see 𝕨
  cwβŒˆβ†©2Γ—fwβ‹„cw×↩fx
  nn←g⊏fi⊏2=cwβ‹„no(⊣-=)↩nnβ‹„ne(⊣-=)↩nn        # 2=cw indicates 𝕨 is never Nothing
  hq←/ahβˆ§π•©β‰₯nv+vi                            # Header constant
  af>↩alm←ai⊏aaβ‹„al←alm/ai                   # aliases al
  ai/Λœβ†©afβ‹„at/Λœβ†©af∾1Β¨hj

  # Lexical resolution (independent of parsing part 2 below)
  di←/dm←»dc                                # Dots aren't scoped
  id←/(hu∨dm∨gi⊏«aa∧a)<(0βŠΈβ‰€βˆ§<⟜nv)xv         # Identifier indices in xv
  sa←0<sp⊏acβ‹„d←(ic←id⊏ac)M⟨2,2⟩             # Which accesses are definitions
  idf←id⊏fiβ‹„idv←id⊏xv                       # Function index and name ID
  dp←d∧(0=idf)∧idv<β‰ def                     # Definitions of vars in def
  dpf←(dp/idv)⊏def
  d↩(0≀dpf)⌾(dp⊸/)dβ‹„zda←0Β¨da←/def≀0         # Turn def Β―1 ← into ↩
  dn←(dg←zda∾(df←d/idf)βˆΎβ‰ fsc)βŠ”da∾dv←d/idv   # Identifier name ID, per-block
  # Order every referenced identifier, and an undeclaration for each declaration
  ixf←((1=ic)+idf⊏¯1∾cb/gf)∾df⊏(≠𝕩)∾1-˜cc⊏gf# First order by block index, open for real and closed for virtual
  ig←(β‹βŠβŸœ(idv∾dv))βŠΈβŠβ‹ixf                    # Then order by name
  ig↩<⟜(β‰ d)⊸/(⍋ds←+`ig⊏d∾¯1Β¨dv)⊏ig          # Last order by declaration depth
  dβŠΛœβ†©igβ‹„idβŠΛœβ†©igβ‹„icβŠΛœβ†©ig
  du←+´¬»⊸∨0<dsβ‹„uv←(du↑ig)⊏idv              # Number undefined (always sorted to front)
  ix←(ic<3)∧ia←0<ic                         # Which are exports, assignments
  idd←(⊒-(uv⊏ded←-0⌈def)∾(du↓IT d)⊸⊏)id⊏fd  # Identifier frame depth
  dx←dgβŠ”zda∾(dig←⍋d/ig)⊏ixa←d(/β‰₯1↓PN)ix     # Exported identifier mask
  idi←(uv⊸⊏∾(Β―1+`du↓d)⊏digβ‹βŠΈβŠdaβ‰ βŠΈβ†“βŠ’)(⊏⟜fsc+βŠ’)ded∾df # Slot within frame
  uu←(ia<1Β«d)∧d(⊣+`⊸⊏(1∾ixa)<PN)0<idd       # Unused marker
  spi←((spf←sp⊏fi)⊏3Γ—fx)+3+sp⊏xv            # Special name index
  uuβˆΎβ†©βˆŠβŒΎβŒ½spi+6Γ—spf                          # and unused marker
  idorβ†βˆΎβŸ¨3,2,3⟩/⟨1+g⊏˜hj-1, di, id∾sp⟩      # Identifier bytecode ordering
  ido←32+uu(⊒+2Γ—>)ia∾sa                     # Opcode
  idocβ†βŸ¨32Β¨hj,0Β¨hj,he/hv
        64¨di,di⊏xv, ido,idd∾0¨sp,idi∾spi⟩  # Identifier bytecode: instruction, depth, slot

  # Parsing part 2
  ta←tr∧2(>∨|)ps(⊒-T)+`Β¬ro                  # Train argument (first-level)
  fa←/(hg∨ta∨ro∨«⊸∨ps<aa)<(r=1)∨»op         # Active functions: cases fe are excluded
  dy←2β‰ ny←fa⊏2Β«no⌈2Γ—Β¬(tr∧rβ‰₯0)∨ro<r=0        # Dyadic
  ob←pr⊏/Β―1(⊒-Β»)uβ†β·βˆ§prβ†π•©βŠΛœpi←/hg<𝕩<sep      # Objects to be loaded
  cn←pi∾lt←/𝕩β‰₯cl←vi+nvβ‹„obβˆΎβ†©(cl-Λœβ‰ u)+ltβŠπ•©    # Constants
  bk←c⊏gi                                   # Block loads
  ll←sll∾˜(Β¬lo/1Β«ps)+-⟜»1↓(lo∾1)/+`ls∾0     # List Length
  dr←(hd¬⊸/hj)∾/s>(2=ne)∨ls∨»r=Β―5β‹„rt←/fo    # Drop (block separator) and return
  qp←/𝕩=pred                                # Predicate
  fl←(dyΓ—βŠβŸœos)⊸+fa+dy                       # Function application site
  drβˆΎβ†©((1+dy)Γ—fn←2=fm←fa⊏ne)/fl             # Turn function applications on Β· to drops
  fn↩¬fnβ‹„fa/Λœβ†©fnβ‹„fl/Λœβ†©fn                    # And remove them

  # Object code generation: numbers oc ordered by source location (after rev) oi
  ao←48+(0⌈(1+βŠ‘bG)-˜aiβŠπ•©+ma+mm)∾-hd         # Assignment opcode
  or←⍋idor∾g⊏˜∾⟨cn,cn,bk,bk,hq,api,2/l,at,dr,qp,al+1,al+1,oa+1⌈oa⊏os,fl,rt⟩
  oc←or⊏∾idoc∾⟨0Β¨cn,ob,1Β¨bk,1+↕≠bk,43Β¨hq,44Β¨api,β₯Šβ‰(11+lm+l⊏aa)≍ll,ao,6Β¨dr,42Β¨qp,66Β¨al,vi-˜(al-1)βŠπ•©
               24+oa⊏r,16+(fn/dy+2Γ—fm⌈1=ny)+4Γ—0<fa⊏er,Β―1↓rc←7+nf⟩
  # Indices for multi-body blocks
  cmβˆ¨β†©(fx∧1β‰ cw)∨0<ut↩ut⌾(ch⊸/)ch            # Dyad- and inverse-only generate as multiple
  cj←/cv←1+1=ciw←cw⊏˜ci←/cm                 # Number of copies
  ck←4⌊(2Γ—ci⊏ut)+1<ciw                      # Position
  cg←¯1+`cif←ci⊏cf                          # Which block
  ckt←(2-Β¬(cf∧cm)/fx)⌈(cif/β‹βˆ˜βŠβŸœcg)βŠΈβŠβˆ˜β’βŠΈβŠcv+ck
  ci↩ckt/βŠΈβŠ”(Β―1(β†‘βˆΎΛœcj(βŠ’βˆ˜βŠ£+⊏)ck+cgβŠβ†“)0∾+`ckt)βŠ”cj⊏ci
  # Output
  fzβ†βŸ¨cf/ft,cf/Β¬fx,ci⌾((cf/cm)⊸/)/cf⟩       # Per-function data
  czβ†βŸ¨/1∾orβ‰₯oc-β—‹β‰ rt,fsc+β‰ Β¨dn,dn,dx⟩         # Per-body data
  ⟨oc∾¯1βŠ‘rc,u,fz,cz⟩                        # Overall output
}

Compile←{
  defaultsβ†βŸ¨β†•0,(!∘"System values not supported"Β¨),↕0,↕0⟩
  ⟨prims,Sys,vars,redef⟩ ← ∾⟜(≠↓defaultsΛ™) β‹ˆβŸ(4<β‰ )𝕨
  ⟨tok,role,valβŸ©β†βŸ¨sys,vars⟩ Tokenize 𝕩
  ⟨oc,prim,blk,bdyβŸ©β†βŸ¨role,βŠ‘val,redefΒ»0Β¨vars⟩ Parse tok
  ⟨oc, ∾⟨prim⊏prims⟩∾1↓val, <Λ˜β‰>blk, <Λ˜β‰>bdy⟩
}