@ohm-js/wasm 0.2.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1,11 +1,2234 @@
1
1
  #!/usr/bin/env node
2
+ var __defProp = Object.defineProperty;
3
+ var __export = (target, all) => {
4
+ for (var name2 in all)
5
+ __defProp(target, name2, { get: all[name2], enumerable: true });
6
+ };
2
7
 
3
8
  // src/cli.js
4
- import * as ohm from "ohm-js";
9
+ import * as ohm2 from "ohm-js";
5
10
  import fs from "node:fs";
6
11
  import { basename } from "node:path";
7
12
  import { parseArgs } from "node:util";
8
- import { Compiler } from "./index.js";
13
+
14
+ // ../../node_modules/.pnpm/@wasmgroundup+emit@1.0.2/node_modules/@wasmgroundup/emit/index.js
15
+ var emit_exports = {};
16
+ __export(emit_exports, {
17
+ CONTINUATION_BIT: () => CONTINUATION_BIT,
18
+ CUSTOM_NAME_SUB_SEC_FUNC: () => CUSTOM_NAME_SUB_SEC_FUNC,
19
+ CUSTOM_NAME_SUB_SEC_LOCAL: () => CUSTOM_NAME_SUB_SEC_LOCAL,
20
+ CUSTOM_NAME_SUB_SEC_MODULE: () => CUSTOM_NAME_SUB_SEC_MODULE,
21
+ I32_NEG_OFFSET: () => I32_NEG_OFFSET,
22
+ MAX_I32: () => MAX_I32,
23
+ MAX_U32: () => MAX_U32,
24
+ MIN_I32: () => MIN_I32,
25
+ MIN_U32: () => MIN_U32,
26
+ SECTION_ID_CODE: () => SECTION_ID_CODE,
27
+ SECTION_ID_CUSTOM: () => SECTION_ID_CUSTOM,
28
+ SECTION_ID_DATA: () => SECTION_ID_DATA,
29
+ SECTION_ID_ELEMENT: () => SECTION_ID_ELEMENT,
30
+ SECTION_ID_EXPORT: () => SECTION_ID_EXPORT,
31
+ SECTION_ID_FUNCTION: () => SECTION_ID_FUNCTION,
32
+ SECTION_ID_GLOBAL: () => SECTION_ID_GLOBAL,
33
+ SECTION_ID_IMPORT: () => SECTION_ID_IMPORT,
34
+ SECTION_ID_MEMORY: () => SECTION_ID_MEMORY,
35
+ SECTION_ID_START: () => SECTION_ID_START,
36
+ SECTION_ID_TABLE: () => SECTION_ID_TABLE,
37
+ SECTION_ID_TYPE: () => SECTION_ID_TYPE,
38
+ SEVEN_BIT_MASK_BIG_INT: () => SEVEN_BIT_MASK_BIG_INT,
39
+ blocktype: () => blocktype,
40
+ code: () => code,
41
+ codesec: () => codesec,
42
+ custom: () => custom,
43
+ customsec: () => customsec,
44
+ data: () => data,
45
+ datasec: () => datasec,
46
+ elem: () => elem,
47
+ elemsec: () => elemsec,
48
+ elemtype: () => elemtype,
49
+ export_: () => export_,
50
+ exportdesc: () => exportdesc,
51
+ exportsec: () => exportsec,
52
+ func: () => func,
53
+ funcidx: () => funcidx,
54
+ funcnamesubsec: () => funcnamesubsec,
55
+ funcsec: () => funcsec,
56
+ functype: () => functype,
57
+ global: () => global,
58
+ globalidx: () => globalidx,
59
+ globalsec: () => globalsec,
60
+ globaltype: () => globaltype,
61
+ i32: () => i32,
62
+ import_: () => import_,
63
+ importdesc: () => importdesc,
64
+ importsec: () => importsec,
65
+ indirectnameassoc: () => indirectnameassoc,
66
+ indirectnamemap: () => indirectnamemap,
67
+ instr: () => instr,
68
+ int32ToBytes: () => int32ToBytes,
69
+ labelidx: () => labelidx,
70
+ leb128: () => leb128,
71
+ limits: () => limits,
72
+ localidx: () => localidx,
73
+ localnamesubsec: () => localnamesubsec,
74
+ locals: () => locals,
75
+ magic: () => magic,
76
+ mem: () => mem,
77
+ memarg: () => memarg,
78
+ memidx: () => memidx,
79
+ memsec: () => memsec,
80
+ memtype: () => memtype,
81
+ module: () => module,
82
+ modulenamesubsec: () => modulenamesubsec,
83
+ mut: () => mut,
84
+ name: () => name,
85
+ nameassoc: () => nameassoc,
86
+ namedata: () => namedata,
87
+ namemap: () => namemap,
88
+ namesec: () => namesec,
89
+ namesubsection: () => namesubsection,
90
+ section: () => section,
91
+ sleb128: () => sleb128,
92
+ start: () => start,
93
+ startsec: () => startsec,
94
+ stringToBytes: () => stringToBytes,
95
+ table: () => table,
96
+ tableidx: () => tableidx,
97
+ tablesec: () => tablesec,
98
+ tabletype: () => tabletype,
99
+ typeidx: () => typeidx,
100
+ typesec: () => typesec,
101
+ u32: () => u32,
102
+ valtype: () => valtype,
103
+ vec: () => vec,
104
+ version: () => version
105
+ });
106
+ function stringToBytes(s) {
107
+ const bytes = new TextEncoder().encode(s);
108
+ return Array.from(bytes);
109
+ }
110
+ function magic() {
111
+ return stringToBytes("\0asm");
112
+ }
113
+ function version() {
114
+ return [1, 0, 0, 0];
115
+ }
116
+ var CONTINUATION_BIT = 128;
117
+ var SEVEN_BIT_MASK_BIG_INT = 0b01111111n;
118
+ function leb128(v) {
119
+ let val = BigInt(v);
120
+ let more = true;
121
+ const r = [];
122
+ while (more) {
123
+ const b = Number(val & SEVEN_BIT_MASK_BIG_INT);
124
+ val = val >> 7n;
125
+ more = val !== 0n;
126
+ if (more) {
127
+ r.push(b | CONTINUATION_BIT);
128
+ } else {
129
+ r.push(b);
130
+ }
131
+ }
132
+ return r;
133
+ }
134
+ var MIN_U32 = 0;
135
+ var MAX_U32 = 2 ** 32 - 1;
136
+ function u32(v) {
137
+ if (v < MIN_U32 || v > MAX_U32) {
138
+ throw Error(`Value out of range for u32: ${v}`);
139
+ }
140
+ return leb128(v);
141
+ }
142
+ function sleb128(v) {
143
+ let val = BigInt(v);
144
+ let more = true;
145
+ const r = [];
146
+ while (more) {
147
+ const b = Number(val & SEVEN_BIT_MASK_BIG_INT);
148
+ const signBitSet = !!(b & 64);
149
+ val = val >> 7n;
150
+ if (val === 0n && !signBitSet || val === -1n && signBitSet) {
151
+ more = false;
152
+ r.push(b);
153
+ } else {
154
+ r.push(b | CONTINUATION_BIT);
155
+ }
156
+ }
157
+ return r;
158
+ }
159
+ var MIN_I32 = -(2 ** 32 / 2);
160
+ var MAX_I32 = 2 ** 32 / 2 - 1;
161
+ var I32_NEG_OFFSET = 2 ** 32;
162
+ function i32(v) {
163
+ if (v < MIN_I32 || v > MAX_U32) {
164
+ throw Error(`Value out of range for i32: ${v}`);
165
+ }
166
+ if (v > MAX_I32) {
167
+ return sleb128(v - I32_NEG_OFFSET);
168
+ }
169
+ return sleb128(v);
170
+ }
171
+ function section(id, contents) {
172
+ const sizeInBytes = contents.flat(Infinity).length;
173
+ return [id, u32(sizeInBytes), contents];
174
+ }
175
+ function vec(elements) {
176
+ return [u32(elements.length), elements];
177
+ }
178
+ var SECTION_ID_TYPE = 1;
179
+ function functype(paramTypes, resultTypes) {
180
+ return [96, vec(paramTypes), vec(resultTypes)];
181
+ }
182
+ function typesec(functypes) {
183
+ return section(SECTION_ID_TYPE, vec(functypes));
184
+ }
185
+ var SECTION_ID_FUNCTION = 3;
186
+ var typeidx = (x) => u32(x);
187
+ function funcsec(typeidxs) {
188
+ return section(SECTION_ID_FUNCTION, vec(typeidxs));
189
+ }
190
+ var SECTION_ID_CODE = 10;
191
+ function code(func2) {
192
+ const sizeInBytes = func2.flat(Infinity).length;
193
+ return [u32(sizeInBytes), func2];
194
+ }
195
+ function func(locals2, body) {
196
+ return [vec(locals2), body];
197
+ }
198
+ function codesec(codes) {
199
+ return section(SECTION_ID_CODE, vec(codes));
200
+ }
201
+ var instr = {
202
+ end: 11
203
+ };
204
+ var SECTION_ID_EXPORT = 7;
205
+ function name(s) {
206
+ return vec(stringToBytes(s));
207
+ }
208
+ function export_(nm, exportdesc2) {
209
+ return [name(nm), exportdesc2];
210
+ }
211
+ function exportsec(exports) {
212
+ return section(SECTION_ID_EXPORT, vec(exports));
213
+ }
214
+ var funcidx = (x) => u32(x);
215
+ var exportdesc = {
216
+ func(idx) {
217
+ return [0, funcidx(idx)];
218
+ }
219
+ };
220
+ function module(sections) {
221
+ return [magic(), version(), sections];
222
+ }
223
+ var valtype = {
224
+ i32: 127,
225
+ i64: 126,
226
+ f32: 125,
227
+ f64: 124
228
+ };
229
+ instr.i32 = { const: 65 };
230
+ instr.i64 = { const: 66 };
231
+ instr.f32 = { const: 67 };
232
+ instr.f64 = { const: 68 };
233
+ instr.i32.add = 106;
234
+ instr.i32.sub = 107;
235
+ instr.i32.mul = 108;
236
+ instr.i32.div_s = 109;
237
+ instr.local = {};
238
+ instr.local.get = 32;
239
+ instr.local.set = 33;
240
+ instr.local.tee = 34;
241
+ function locals(n, type) {
242
+ return [u32(n), type];
243
+ }
244
+ var localidx = (x) => u32(x);
245
+ instr.drop = 26;
246
+ instr.call = 16;
247
+ instr.if = 4;
248
+ instr.else = 5;
249
+ var blocktype = { empty: 64, ...valtype };
250
+ instr.i32.eq = 70;
251
+ instr.i32.ne = 71;
252
+ instr.i32.lt_s = 72;
253
+ instr.i32.lt_u = 73;
254
+ instr.i32.gt_s = 74;
255
+ instr.i32.gt_u = 75;
256
+ instr.i32.le_s = 76;
257
+ instr.i32.le_u = 77;
258
+ instr.i32.ge_s = 78;
259
+ instr.i32.ge_u = 79;
260
+ instr.i32.eqz = 69;
261
+ instr.i32.and = 113;
262
+ instr.i32.or = 114;
263
+ var labelidx = u32;
264
+ instr.block = 2;
265
+ instr.loop = 3;
266
+ instr.br = 12;
267
+ instr.br_if = 13;
268
+ var SECTION_ID_IMPORT = 2;
269
+ function import_(mod, nm, d) {
270
+ return [name(mod), name(nm), d];
271
+ }
272
+ function importsec(ims) {
273
+ return section(SECTION_ID_IMPORT, vec(ims));
274
+ }
275
+ var importdesc = {
276
+ // x:typeidx
277
+ func(x) {
278
+ return [0, typeidx(x)];
279
+ }
280
+ };
281
+ var SECTION_ID_MEMORY = 5;
282
+ function memsec(mems) {
283
+ return section(SECTION_ID_MEMORY, vec(mems));
284
+ }
285
+ function mem(memtype2) {
286
+ return memtype2;
287
+ }
288
+ function memtype(limits2) {
289
+ return limits2;
290
+ }
291
+ var limits = {
292
+ // n:u32
293
+ min(n) {
294
+ return [0, u32(n)];
295
+ },
296
+ // n:u32, m:u32
297
+ minmax(n, m) {
298
+ return [1, u32(n), u32(m)];
299
+ }
300
+ };
301
+ var memidx = u32;
302
+ exportdesc.mem = (idx) => [2, memidx(idx)];
303
+ instr.memory = {
304
+ size: 63,
305
+ // [] -> [i32]
306
+ grow: 64
307
+ // [i32] -> [i32]
308
+ };
309
+ instr.i32.load = 40;
310
+ instr.i32.store = 54;
311
+ function memarg(align, offset) {
312
+ return [u32(align), u32(offset)];
313
+ }
314
+ function int32ToBytes(v) {
315
+ return [v & 255, v >> 8 & 255, v >> 16 & 255, v >> 24 & 255];
316
+ }
317
+ instr.unreachable = 0;
318
+ var SECTION_ID_DATA = 11;
319
+ function data(x, e, bs) {
320
+ return [x, e, vec(bs)];
321
+ }
322
+ function datasec(segs) {
323
+ return section(SECTION_ID_DATA, vec(segs));
324
+ }
325
+ var SECTION_ID_CUSTOM = 0;
326
+ function custom(name2, bytes) {
327
+ return [name2, bytes];
328
+ }
329
+ function customsec(custom2) {
330
+ return section(SECTION_ID_CUSTOM, custom2);
331
+ }
332
+ function namesec(namedata2) {
333
+ return customsec(custom(name("name"), namedata2));
334
+ }
335
+ function namedata(modulenamesubsec2, funcnamesubsec2, localnamesubsec2) {
336
+ return [modulenamesubsec2, funcnamesubsec2, localnamesubsec2];
337
+ }
338
+ var CUSTOM_NAME_SUB_SEC_MODULE = 0;
339
+ function modulenamesubsec(n) {
340
+ return namesubsection(CUSTOM_NAME_SUB_SEC_MODULE, name(n));
341
+ }
342
+ var CUSTOM_NAME_SUB_SEC_FUNC = 1;
343
+ function funcnamesubsec(namemap2) {
344
+ return namesubsection(CUSTOM_NAME_SUB_SEC_FUNC, namemap2);
345
+ }
346
+ function namesubsection(N, B) {
347
+ const flatB = B.flat(Infinity);
348
+ const size = u32(flatB.length);
349
+ return [N, size, flatB];
350
+ }
351
+ function namemap(nameassocs) {
352
+ return vec(nameassocs);
353
+ }
354
+ function nameassoc(idx, n) {
355
+ return [idx, name(n)];
356
+ }
357
+ var CUSTOM_NAME_SUB_SEC_LOCAL = 2;
358
+ function localnamesubsec(indirectnamemap2) {
359
+ return namesubsection(CUSTOM_NAME_SUB_SEC_LOCAL, indirectnamemap2);
360
+ }
361
+ function indirectnamemap(indirectnameassocs) {
362
+ return vec(indirectnameassocs);
363
+ }
364
+ function indirectnameassoc(idx, namemap2) {
365
+ return [idx, namemap2];
366
+ }
367
+ var SECTION_ID_START = 8;
368
+ var start = (x) => funcidx(x);
369
+ function startsec(st) {
370
+ return section(SECTION_ID_START, st);
371
+ }
372
+ instr.global = {};
373
+ instr.global.get = 35;
374
+ instr.global.set = 36;
375
+ var globalidx = (x) => u32(x);
376
+ var SECTION_ID_GLOBAL = 6;
377
+ var mut = {
378
+ const: 0,
379
+ var: 1
380
+ };
381
+ function globaltype(t, m) {
382
+ return [t, m];
383
+ }
384
+ function global(gt, e) {
385
+ return [gt, e];
386
+ }
387
+ function globalsec(globs) {
388
+ return section(SECTION_ID_GLOBAL, vec(globs));
389
+ }
390
+ var SECTION_ID_TABLE = 4;
391
+ var elemtype = { funcref: 112 };
392
+ function tabletype(et, lim) {
393
+ return [et, lim];
394
+ }
395
+ function table(tt) {
396
+ return tt;
397
+ }
398
+ function tablesec(tables) {
399
+ return section(SECTION_ID_TABLE, vec(tables));
400
+ }
401
+ var tableidx = (x) => u32(x);
402
+ instr.call_indirect = 17;
403
+ var SECTION_ID_ELEMENT = 9;
404
+ function elem(x, e, ys) {
405
+ return [x, e, vec(ys)];
406
+ }
407
+ function elemsec(segs) {
408
+ return section(SECTION_ID_ELEMENT, vec(segs));
409
+ }
410
+ instr.nop = 1;
411
+ instr.br_table = 14;
412
+ instr.return = 15;
413
+ instr.select = 27;
414
+ instr.i64.load = 41;
415
+ instr.f32.load = 42;
416
+ instr.f64.load = 43;
417
+ instr.i32.load8_s = 44;
418
+ instr.i32.load8_u = 45;
419
+ instr.i32.load16_s = 46;
420
+ instr.i32.load16_u = 47;
421
+ instr.i64.load8_s = 48;
422
+ instr.i64.load8_u = 49;
423
+ instr.i64.load16_s = 50;
424
+ instr.i64.load16_u = 51;
425
+ instr.i64.load32_s = 52;
426
+ instr.i64.load32_u = 53;
427
+ instr.i64.store = 55;
428
+ instr.f32.store = 56;
429
+ instr.f64.store = 57;
430
+ instr.i32.store8 = 58;
431
+ instr.i32.store16 = 59;
432
+ instr.i64.store8 = 60;
433
+ instr.i64.store16 = 61;
434
+ instr.i64.store32 = 62;
435
+ instr.i64.eqz = 80;
436
+ instr.i64.eq = 81;
437
+ instr.i64.ne = 82;
438
+ instr.i64.lt_s = 83;
439
+ instr.i64.lt_u = 84;
440
+ instr.i64.gt_s = 85;
441
+ instr.i64.gt_u = 86;
442
+ instr.i64.le_s = 87;
443
+ instr.i64.le_u = 88;
444
+ instr.i64.ge_s = 89;
445
+ instr.i64.ge_u = 90;
446
+ instr.f32.eq = 91;
447
+ instr.f32.ne = 92;
448
+ instr.f32.lt = 93;
449
+ instr.f32.gt = 94;
450
+ instr.f32.le = 95;
451
+ instr.f32.ge = 96;
452
+ instr.f64.eq = 97;
453
+ instr.f64.ne = 98;
454
+ instr.f64.lt = 99;
455
+ instr.f64.gt = 100;
456
+ instr.f64.le = 101;
457
+ instr.f64.ge = 102;
458
+ instr.i32.clz = 103;
459
+ instr.i32.ctz = 104;
460
+ instr.i32.popcnt = 105;
461
+ instr.i32.div_u = 110;
462
+ instr.i32.rem_s = 111;
463
+ instr.i32.rem_u = 112;
464
+ instr.i32.xor = 115;
465
+ instr.i32.shl = 116;
466
+ instr.i32.shr_s = 117;
467
+ instr.i32.shr_u = 118;
468
+ instr.i32.rotl = 119;
469
+ instr.i32.rotr = 120;
470
+ instr.i64.clz = 121;
471
+ instr.i64.ctz = 122;
472
+ instr.i64.popcnt = 123;
473
+ instr.i64.add = 124;
474
+ instr.i64.sub = 125;
475
+ instr.i64.mul = 126;
476
+ instr.i64.div_s = 127;
477
+ instr.i64.div_u = 128;
478
+ instr.i64.rem_s = 129;
479
+ instr.i64.rem_u = 130;
480
+ instr.i64.and = 131;
481
+ instr.i64.or = 132;
482
+ instr.i64.xor = 133;
483
+ instr.i64.shl = 134;
484
+ instr.i64.shr_s = 135;
485
+ instr.i64.shr_u = 136;
486
+ instr.i64.rotl = 137;
487
+ instr.i64.rotr = 138;
488
+ instr.f32.abs = 139;
489
+ instr.f32.neg = 140;
490
+ instr.f32.ceil = 141;
491
+ instr.f32.floor = 142;
492
+ instr.f32.trunc = 143;
493
+ instr.f32.nearest = 144;
494
+ instr.f32.sqrt = 145;
495
+ instr.f32.add = 146;
496
+ instr.f32.sub = 147;
497
+ instr.f32.mul = 148;
498
+ instr.f32.div = 149;
499
+ instr.f32.min = 150;
500
+ instr.f32.max = 151;
501
+ instr.f32.copysign = 152;
502
+ instr.f64.abs = 153;
503
+ instr.f64.neg = 154;
504
+ instr.f64.ceil = 155;
505
+ instr.f64.floor = 156;
506
+ instr.f64.trunc = 157;
507
+ instr.f64.nearest = 158;
508
+ instr.f64.sqrt = 159;
509
+ instr.f64.add = 160;
510
+ instr.f64.sub = 161;
511
+ instr.f64.mul = 162;
512
+ instr.f64.div = 163;
513
+ instr.f64.min = 164;
514
+ instr.f64.max = 165;
515
+ instr.f64.copysign = 166;
516
+ instr.i32.wrap_i64 = 167;
517
+ instr.i32.trunc_f32_s = 168;
518
+ instr.i32.trunc_f32_u = 169;
519
+ instr.i32.trunc_f64_s = 170;
520
+ instr.i32.trunc_f64_u = 171;
521
+ instr.i64.extend_i32_s = 172;
522
+ instr.i64.extend_i32_u = 173;
523
+ instr.i64.trunc_f32_s = 174;
524
+ instr.i64.trunc_f32_u = 175;
525
+ instr.i64.trunc_f64_s = 176;
526
+ instr.i64.trunc_f64_u = 177;
527
+ instr.f32.convert_i32_s = 178;
528
+ instr.f32.convert_i32_u = 179;
529
+ instr.f32.convert_i64_s = 180;
530
+ instr.f32.convert_i64_u = 181;
531
+ instr.f32.demote_f64 = 182;
532
+ instr.f64.convert_i32_s = 183;
533
+ instr.f64.convert_i32_u = 184;
534
+ instr.f64.convert_i64_s = 185;
535
+ instr.f64.convert_i64_u = 186;
536
+ instr.f64.promote_f32 = 187;
537
+ instr.i32.reinterpret_f32 = 188;
538
+ instr.i64.reinterpret_f64 = 189;
539
+ instr.f32.reinterpret_i32 = 190;
540
+ instr.f64.reinterpret_i64 = 191;
541
+
542
+ // src/Compiler.js
543
+ import * as ohm from "ohm-js";
544
+
545
+ // src/ir.ts
546
+ var alt = (children) => ({
547
+ type: "Alt",
548
+ children,
549
+ outArity: outArity(children[0])
550
+ });
551
+ var any = () => ({ type: "Any" });
552
+ var apply = (ruleName, children = []) => ({
553
+ type: "Apply",
554
+ ruleName,
555
+ children
556
+ });
557
+ var applyGeneralized = (ruleName, caseIdx) => ({
558
+ type: "ApplyGeneralized",
559
+ ruleName,
560
+ caseIdx
561
+ });
562
+ var caseInsensitive = (value) => ({
563
+ type: "CaseInsensitive",
564
+ value
565
+ });
566
+ var dispatch = (child, patterns) => ({
567
+ type: "Dispatch",
568
+ child,
569
+ patterns
570
+ });
571
+ var end = () => ({ type: "End" });
572
+ var lex = (child) => ({
573
+ type: "Lex",
574
+ child,
575
+ outArity: outArity(child)
576
+ });
577
+ var lookahead = (child) => ({
578
+ type: "Lookahead",
579
+ child,
580
+ outArity: outArity(child)
581
+ });
582
+ var opt = (child) => ({ type: "Opt", child });
583
+ var not = (child) => ({ type: "Not", child });
584
+ var param = (index) => ({ type: "Param", index });
585
+ var plus = (child) => ({ type: "Plus", child });
586
+ var range = (lo, hi) => ({ type: "Range", lo, hi });
587
+ var seq = (children) => ({
588
+ type: "Seq",
589
+ children,
590
+ outArity: children.reduce((acc, child) => acc + outArity(child), 0)
591
+ });
592
+ var star = (child) => ({ type: "Star", child });
593
+ var terminal = (value, caseInsensitive2 = false) => ({
594
+ type: "Terminal",
595
+ value
596
+ });
597
+ var unicodeChar = (categoryOrProp) => ({
598
+ type: "UnicodeChar",
599
+ categoryOrProp
600
+ });
601
+ var liftedTerminal = (terminalId) => ({
602
+ type: "LiftedTerminal",
603
+ terminalId
604
+ });
605
+ function unreachable(x, msg) {
606
+ throw new Error(msg);
607
+ }
608
+ function checkNotNull(x, msg = "unexpected null value") {
609
+ if (x == null) throw new Error(msg);
610
+ return x;
611
+ }
612
+ function checkApplyLike(exp) {
613
+ return checkExprType(exp, "Apply", "LiftedTerminal", "Param");
614
+ }
615
+ function checkExprType(exp, ...types) {
616
+ if (!types.includes(exp.type)) {
617
+ throw new Error(`Expected one of [${types.join(", ")}], but got '${exp.type}'`);
618
+ }
619
+ return exp;
620
+ }
621
+ function substituteParams(exp, actuals) {
622
+ switch (exp.type) {
623
+ case "Param":
624
+ return checkNotNull(actuals[exp.index]);
625
+ case "Apply":
626
+ if (exp.children.length === 0) return exp;
627
+ return apply(
628
+ exp.ruleName,
629
+ exp.children.map((c) => {
630
+ const ans = substituteParams(c, actuals);
631
+ return checkApplyLike(ans);
632
+ })
633
+ );
634
+ case "Dispatch": {
635
+ const newChild = substituteParams(exp.child, actuals);
636
+ return dispatch(checkExprType(newChild, "Apply"), exp.patterns);
637
+ }
638
+ case "Alt":
639
+ case "Seq":
640
+ return {
641
+ type: exp.type,
642
+ children: exp.children.map((c) => substituteParams(c, actuals)),
643
+ outArity: exp.outArity
644
+ };
645
+ case "Lex":
646
+ case "Lookahead":
647
+ return {
648
+ type: exp.type,
649
+ child: substituteParams(exp.child, actuals),
650
+ outArity: exp.outArity
651
+ };
652
+ case "Not":
653
+ case "Opt":
654
+ case "Plus":
655
+ case "Star":
656
+ return {
657
+ type: exp.type,
658
+ child: substituteParams(exp.child, actuals)
659
+ };
660
+ case "Any":
661
+ case "ApplyGeneralized":
662
+ case "CaseInsensitive":
663
+ case "End":
664
+ case "LiftedTerminal":
665
+ case "Range":
666
+ case "Terminal":
667
+ case "UnicodeChar":
668
+ return exp;
669
+ default:
670
+ unreachable(exp, `not handled: ${exp}`);
671
+ }
672
+ }
673
+ function specializedName(app) {
674
+ if (app.type === "LiftedTerminal") {
675
+ return `$term$${app.terminalId}`;
676
+ }
677
+ const argsNames = app.children.map((c) => {
678
+ if (c.type === "Param") throw new Error(`unexpected Param`);
679
+ return specializedName(c);
680
+ }).join(",");
681
+ return app.ruleName + (argsNames.length > 0 ? `<${argsNames}>` : "");
682
+ }
683
+ function rewrite(exp, actions) {
684
+ const action = actions[exp.type];
685
+ if (action) {
686
+ return action(exp);
687
+ }
688
+ switch (exp.type) {
689
+ case "Alt":
690
+ return alt(exp.children.map((e) => rewrite(e, actions)));
691
+ case "Seq":
692
+ return seq(exp.children.map((e) => rewrite(e, actions)));
693
+ case "Any":
694
+ case "Apply":
695
+ case "ApplyGeneralized":
696
+ case "CaseInsensitive":
697
+ case "End":
698
+ case "LiftedTerminal":
699
+ case "Param":
700
+ case "Range":
701
+ case "Terminal":
702
+ case "UnicodeChar":
703
+ return exp;
704
+ case "Dispatch":
705
+ return { type: exp.type, child: rewrite(exp.child, actions), patterns: exp.patterns };
706
+ case "Lex":
707
+ return lex(rewrite(exp.child, actions));
708
+ case "Lookahead":
709
+ return lookahead(rewrite(exp.child, actions));
710
+ case "Not":
711
+ return not(rewrite(exp.child, actions));
712
+ case "Opt":
713
+ return opt(rewrite(exp.child, actions));
714
+ case "Plus":
715
+ return plus(rewrite(exp.child, actions));
716
+ case "Star":
717
+ return star(rewrite(exp.child, actions));
718
+ default:
719
+ unreachable(exp, `not handled: ${exp}`);
720
+ }
721
+ }
722
+ function toString(exp) {
723
+ switch (exp.type) {
724
+ case "Alt":
725
+ return `(${exp.children.map(toString).join(" | ")})`;
726
+ case "Seq":
727
+ return `(${exp.children.map(toString).join(" ")})`;
728
+ case "Any":
729
+ return "$any";
730
+ case "Apply":
731
+ return exp.children.length > 0 ? `${exp.ruleName}<${exp.children.map(toString).join(",")}>` : exp.ruleName;
732
+ case "ApplyGeneralized":
733
+ return `${exp.ruleName}<#${exp.caseIdx}>`;
734
+ case "CaseInsensitive":
735
+ return `$caseInsensitive<${JSON.stringify(exp.value)}>`;
736
+ case "End":
737
+ return "$end";
738
+ case "LiftedTerminal":
739
+ return `$term$${exp.terminalId}`;
740
+ case "Param":
741
+ return `$${exp.index}`;
742
+ case "Range":
743
+ return `${JSON.stringify(exp.lo)}..${JSON.stringify(exp.hi)}`;
744
+ case "Terminal":
745
+ return JSON.stringify(exp.value);
746
+ case "UnicodeChar":
747
+ return `$unicodeChar<${JSON.stringify(exp.categoryOrProp)}>`;
748
+ case "Dispatch":
749
+ return `$dispatch`;
750
+ // TODO: Improve this.
751
+ case "Lex":
752
+ return `#${toString(exp.child)}`;
753
+ case "Lookahead":
754
+ return `&${toString(exp.child)}`;
755
+ case "Not":
756
+ return `~${toString(exp.child)}`;
757
+ case "Opt":
758
+ return `${toString(exp.child)}?`;
759
+ case "Plus":
760
+ return `${toString(exp.child)}+`;
761
+ case "Star":
762
+ return `${toString(exp.child)}*`;
763
+ default:
764
+ unreachable(exp, `not handled: ${exp}`);
765
+ }
766
+ }
767
+ function outArity(exp) {
768
+ switch (exp.type) {
769
+ case "Alt":
770
+ case "Seq":
771
+ case "Lex":
772
+ case "Lookahead":
773
+ return exp.outArity;
774
+ case "Any":
775
+ case "Apply":
776
+ case "ApplyGeneralized":
777
+ case "CaseInsensitive":
778
+ case "End":
779
+ case "LiftedTerminal":
780
+ case "Param":
781
+ case "Range":
782
+ case "Terminal":
783
+ case "UnicodeChar":
784
+ case "Dispatch":
785
+ return 1;
786
+ case "Not":
787
+ return 0;
788
+ case "Opt":
789
+ case "Plus":
790
+ case "Star":
791
+ return 1;
792
+ default:
793
+ unreachable(exp, `not handled: ${exp}`);
794
+ }
795
+ }
796
+
797
+ // build/ohmRuntime.wasm_sections.ts
798
+ function decodeBase64(str) {
799
+ const bytes = atob(str);
800
+ const result = [];
801
+ for (let i = 0; i < bytes.length; i++) {
802
+ result[i] = bytes.charCodeAt(i);
803
+ }
804
+ return result;
805
+ }
806
+ var destImportCount = 5;
807
+ var startFuncidx = 51;
808
+ var funcidxByName = {
809
+ dummy: 20,
810
+ match: 42,
811
+ evalApplyGeneralized: 43,
812
+ evalApplyNoMemo0: 44,
813
+ evalApply0: 41,
814
+ handleLeftRecursion: 40,
815
+ newTerminalNode: 45,
816
+ newNonterminalNode: 38,
817
+ newIterationNode: 46,
818
+ getBindingsLength: 47,
819
+ setBindingsLength: 48,
820
+ getCstRoot: 49,
821
+ doMatchUnicodeChar: 50
822
+ };
823
+ var typesec2 = {
824
+ entryCount: 10,
825
+ contents: decodeBase64(
826
+ "YAF/AX9gAn9/AGACf38Bf2AAAGAAAX9gAX8AYAR/f39/AGADf39/AGAFf39/f38Bf2AEf39/fwF/"
827
+ )
828
+ };
829
+ var importsec2 = {
830
+ entryCount: 5,
831
+ contents: decodeBase64(
832
+ "A2VudgVhYm9ydAAGCm9obVJ1bnRpbWUIcHJpbnRJMzIABQpvaG1SdW50aW1lD2ZpbGxJbnB1dEJ1ZmZlcgACCm9obVJ1bnRpbWUPaXNSdWxlU3ludGFjdGljAAAKb2htUnVudGltZRBtYXRjaFVuaWNvZGVDaGFyAAA="
833
+ )
834
+ };
835
+ var funcsec2 = {
836
+ entryCount: 47,
837
+ contents: decodeBase64("BQEAAQEBAQIHAQEBAQIDBQMDAwAAAAAAAgIGAAICAAIBCAcJAAACAAIIBAUEAAM=")
838
+ };
839
+ var globalsec2 = {
840
+ entryCount: 11,
841
+ contents: decodeBase64(
842
+ "fwFBAAt/AUEAC38BQQALfwBBAAt/AEEBC38AQQILfwFBAAt/AUEAC38AQQALfwFBAAt/AEGsgoggCw=="
843
+ )
844
+ };
845
+ var codesec2 = {
846
+ entryCount: 47,
847
+ contents: decodeBase64(
848
+ "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"
849
+ )
850
+ };
851
+
852
+ // src/Compiler.js
853
+ var WASM_PAGE_SIZE = 64 * 1024;
854
+ var DEBUG = process.env.OHM_DEBUG === "1";
855
+ var FAST_SAVE_BINDINGS = true;
856
+ var FAST_RESTORE_BINDINGS = true;
857
+ var IMPLICIT_SPACE_SKIPPING = true;
858
+ var EMIT_GENERALIZED_RULES = false;
859
+ var { instr: instr2 } = emit_exports;
860
+ var { pexprs } = ohm;
861
+ var isNonNull = (x) => x != null;
862
+ function assert(cond, msg) {
863
+ if (!cond) {
864
+ throw new Error(msg ?? "assertion failed");
865
+ }
866
+ }
867
+ function checkNotNull2(x, msg = "unexpected null value") {
868
+ assert(x != null, msg);
869
+ return x;
870
+ }
871
+ function checkNoUndefined(arr) {
872
+ assert(arr.indexOf(void 0) === -1, `found undefined @ ${arr.indexOf(void 0)}`);
873
+ return arr;
874
+ }
875
+ function setdefault(map, key, makeDefaultVal) {
876
+ if (!map.has(key)) map.set(key, makeDefaultVal());
877
+ return map.get(key);
878
+ }
879
+ var getNotNull = (map, k) => checkNotNull2(map.get(k), `not found: '${k}'`);
880
+ var isApplyLike = (exp) => exp instanceof pexprs.Apply || exp instanceof pexprs.Param;
881
+ function uniqueName(names, str) {
882
+ let name2 = str;
883
+ outer: if (names.has(str)) {
884
+ for (let i = 0; i < 1e3; i++) {
885
+ name2 = `${str}_${i}`;
886
+ if (!names.has(name2)) break outer;
887
+ }
888
+ throw new Error(`Unique name generation failed for ${str}`);
889
+ }
890
+ names.add(name2);
891
+ return name2;
892
+ }
893
+ function isSyntacticRule(ruleName) {
894
+ assert(ruleName[0] !== "$", ruleName);
895
+ return ruleName[0] === ruleName[0].toUpperCase();
896
+ }
897
+ var asciiChars = Array.from({ length: 128 }).map((_, i) => String.fromCharCode(i));
898
+ var IndexedSet = class {
899
+ constructor() {
900
+ this._map = /* @__PURE__ */ new Map();
901
+ }
902
+ add(item) {
903
+ if (this._map.has(item)) {
904
+ return this._map.get(item);
905
+ }
906
+ const idx = this._map.size;
907
+ this._map.set(checkNotNull2(item), idx);
908
+ return idx;
909
+ }
910
+ getIndex(item) {
911
+ return this._map.get(item);
912
+ }
913
+ has(item) {
914
+ return this._map.has(item);
915
+ }
916
+ get size() {
917
+ return this._map.size;
918
+ }
919
+ keys() {
920
+ return [...this._map.keys()];
921
+ }
922
+ values() {
923
+ return [...this._map.keys()];
924
+ }
925
+ [Symbol.iterator]() {
926
+ return this._map[Symbol.iterator]();
927
+ }
928
+ };
929
+ function collectParams(exp, seen = /* @__PURE__ */ new Set()) {
930
+ switch (exp.constructor) {
931
+ case pexprs.Param:
932
+ if (!seen.has(exp.index)) {
933
+ seen.add(exp.index);
934
+ return [exp];
935
+ }
936
+ return [];
937
+ case pexprs.Alt:
938
+ return exp.terms.flatMap((e) => collectParams(e, seen));
939
+ case pexprs.Apply:
940
+ return exp.args.flatMap((e) => collectParams(e, seen));
941
+ case pexprs.Lookahead:
942
+ case pexprs.Not:
943
+ case pexprs.Opt:
944
+ case pexprs.Plus:
945
+ case pexprs.Seq:
946
+ return exp.factors.flatMap((e) => collectParams(e, seen));
947
+ case pexprs.Star:
948
+ return collectParams(exp.expr, seen);
949
+ case pexprs.Range:
950
+ case pexprs.Terminal:
951
+ case pexprs.UnicodeChar:
952
+ return [];
953
+ default:
954
+ throw new Error(`not handled: ${exp.constructor.name}`);
955
+ }
956
+ }
957
+ var prebuiltFuncidx = (nm) => checkNotNull2(funcidxByName[nm]);
958
+ function mergeSections(sectionId, prebuiltSec, els) {
959
+ const count = prebuiltSec.entryCount + els.length;
960
+ return section(sectionId, [u32(count), prebuiltSec.contents, els]);
961
+ }
962
+ function functypeToString(paramTypes, resultTypes) {
963
+ const toStr = (t) => checkNotNull2(["f64", "f32", "i64", "i32"][t - valtype.f64]);
964
+ const params = paramTypes.map(toStr).join(",");
965
+ const results = resultTypes.map(toStr).join(",");
966
+ return "[" + params + "][" + results + "]";
967
+ }
968
+ var TypeMap = class {
969
+ constructor(startIdx = 0) {
970
+ this._map = /* @__PURE__ */ new Map();
971
+ this._startIdx = startIdx;
972
+ }
973
+ add(paramTypes, resultTypes) {
974
+ const key = functypeToString(paramTypes, resultTypes);
975
+ if (this._map.has(key)) {
976
+ return this._map.get(key)[0];
977
+ }
978
+ const idx = this._startIdx + this._map.size;
979
+ this._map.set(key, [idx, functype(paramTypes, resultTypes)]);
980
+ return idx;
981
+ }
982
+ addDecls(decls) {
983
+ for (const { paramTypes, resultTypes } of decls) {
984
+ this.add(paramTypes, resultTypes);
985
+ }
986
+ }
987
+ getIdx(paramTypes, resultTypes) {
988
+ const key = functypeToString(paramTypes, resultTypes);
989
+ return checkNotNull2(this._map.get(key))[0];
990
+ }
991
+ getIdxForDecl(decl) {
992
+ return this.getIdx(decl.paramTypes, decl.resultTypes);
993
+ }
994
+ getTypes() {
995
+ return [...this._map.values()].map(([_, t]) => t);
996
+ }
997
+ };
998
+ var Assembler = class _Assembler {
999
+ constructor(typeMap) {
1000
+ this._globals = /* @__PURE__ */ new Map();
1001
+ this._functionDecls = [];
1002
+ this._blockStack = [];
1003
+ this._code = [];
1004
+ this._locals = void 0;
1005
+ this._typeMap = typeMap;
1006
+ }
1007
+ addBlocktype(paramTypes, resultTypes) {
1008
+ this._typeMap.add(paramTypes, resultTypes);
1009
+ }
1010
+ blocktype(paramTypes, resultTypes) {
1011
+ const idx = this._typeMap.getIdx(paramTypes, resultTypes);
1012
+ assert(idx !== -1, `Unknown blocktype: '${functypeToString(paramTypes, resultTypes)}'`);
1013
+ return i32(idx);
1014
+ }
1015
+ doEmit(thunk) {
1016
+ const oldCode = this._code;
1017
+ this._code = [];
1018
+ thunk();
1019
+ const body = [...this._code, instr2.end];
1020
+ this._code = oldCode;
1021
+ return body;
1022
+ }
1023
+ addGlobal(name2, type, mut2, initThunk) {
1024
+ assert(!this._globals.has(name2), `Global '${name2}' already exists`);
1025
+ const idx = this._globals.size;
1026
+ const initExpr = this.doEmit(initThunk);
1027
+ this._globals.set(name2, { idx, type, mut: mut2, initExpr });
1028
+ return idx;
1029
+ }
1030
+ addLocal(name2, type) {
1031
+ assert(!this._locals.has(name2), `Local '${name2}' already exists`);
1032
+ assert(type === valtype.i32, `invalid local type: ${type}`);
1033
+ const idx = this._locals.size;
1034
+ this._locals.set(name2, idx);
1035
+ return idx;
1036
+ }
1037
+ addFunction(name2, paramTypes, resultTypes, bodyFn) {
1038
+ this._locals = /* @__PURE__ */ new Map();
1039
+ paramTypes.forEach((t, i) => {
1040
+ this.addLocal(`__arg${i}`, t);
1041
+ });
1042
+ bodyFn(this);
1043
+ this._functionDecls.push({
1044
+ name: name2,
1045
+ paramTypes,
1046
+ resultTypes,
1047
+ locals: [locals(this._locals.size, valtype.i32)],
1048
+ // TODO: Support other types?
1049
+ body: [...this._code, instr2.end]
1050
+ });
1051
+ this._code = [];
1052
+ this._locals = void 0;
1053
+ }
1054
+ // Pure codegen helpers (used to generate the function bodies).
1055
+ globalidx(name2) {
1056
+ const { idx } = checkNotNull2(this._globals.get(name2), `Unknown global: ${name2}`);
1057
+ return idx;
1058
+ }
1059
+ localidx(name2) {
1060
+ return checkNotNull2(this._locals.get(name2), `Unknown local: ${name2}`);
1061
+ }
1062
+ emit(...bytes) {
1063
+ this._code.push(...checkNoUndefined(bytes.flat(Infinity)));
1064
+ }
1065
+ block(bt, bodyThunk, label = "") {
1066
+ this._blockOnly(bt, label);
1067
+ bodyThunk();
1068
+ this._endBlock();
1069
+ }
1070
+ // Prefer to use `block`, but for some cases it's more convenient to emit
1071
+ // the block and the end separately.
1072
+ // Note: `label` (if specified) is not unique (e.g., 'pexprEnd').
1073
+ _blockOnly(bt, label) {
1074
+ this.emit(instr2.block, bt);
1075
+ this._blockStack.push(label ? `block:${label}` : "block");
1076
+ }
1077
+ // This should always be paired with `blockOnly`.
1078
+ _endBlock() {
1079
+ const what = this._blockStack.pop().split(":")[0];
1080
+ assert(what === "block", "Invalid endBlock");
1081
+ this.emit(instr2.end);
1082
+ }
1083
+ loop(bt, bodyThunk) {
1084
+ this.emit(instr2.loop, bt);
1085
+ this._blockStack.push("loop");
1086
+ bodyThunk();
1087
+ this._blockStack.pop();
1088
+ this.emit(instr2.end);
1089
+ }
1090
+ if(bt, bodyThunk) {
1091
+ this.ifElse(bt, bodyThunk);
1092
+ }
1093
+ ifElse(bt, thenThunk, elseThunk = void 0) {
1094
+ this.emit(instr2.if, bt);
1095
+ this._blockStack.push("if");
1096
+ thenThunk();
1097
+ if (elseThunk) {
1098
+ this.emit(instr2.else);
1099
+ elseThunk();
1100
+ }
1101
+ this._blockStack.pop();
1102
+ this.emit(instr2.end);
1103
+ }
1104
+ ifFalse(bt, bodyThunk) {
1105
+ this.emit(instr2.i32.eqz);
1106
+ this.if(bt, bodyThunk);
1107
+ }
1108
+ br(depth) {
1109
+ this.emit(instr2.br, labelidx(depth));
1110
+ }
1111
+ i32Add() {
1112
+ this.emit(instr2.i32.add);
1113
+ }
1114
+ i32Const(value) {
1115
+ this.emit(instr2.i32.const, i32(value));
1116
+ }
1117
+ i32Load(offset = 0) {
1118
+ this.emit(instr2.i32.load, memarg(_Assembler.ALIGN_4_BYTES, offset));
1119
+ }
1120
+ i32Load8u(offset = 0) {
1121
+ this.emit(instr2.i32.load8_u, memarg(_Assembler.ALIGN_1_BYTE, offset));
1122
+ }
1123
+ i32Mul() {
1124
+ this.emit(instr2.i32.mul);
1125
+ }
1126
+ i32Eq() {
1127
+ this.emit(instr2.i32.eq);
1128
+ }
1129
+ i32Ne() {
1130
+ this.emit(instr2.i32.ne);
1131
+ }
1132
+ // Store [addr:i32, val:i32] -> []
1133
+ i32Store(offset = 0) {
1134
+ this.emit(instr2.i32.store, memarg(_Assembler.ALIGN_4_BYTES, offset));
1135
+ }
1136
+ i32Sub() {
1137
+ this.emit(instr2.i32.sub);
1138
+ }
1139
+ globalGet(name2) {
1140
+ this.emit(instr2.global.get, this.globalidx(name2));
1141
+ }
1142
+ globalSet(name2) {
1143
+ this.emit(instr2.global.set, this.globalidx(name2));
1144
+ }
1145
+ localGet(name2) {
1146
+ this.emit(instr2.local.get, this.localidx(name2));
1147
+ }
1148
+ localSet(name2) {
1149
+ this.emit(instr2.local.set, this.localidx(name2));
1150
+ }
1151
+ localTee(name2) {
1152
+ this.emit(instr2.local.tee, this.localidx(name2));
1153
+ }
1154
+ break(depth) {
1155
+ const what = this._blockStack.at(-(depth + 1)).split(":")[0];
1156
+ assert(what === "block" || what === "if", "Invalid break");
1157
+ this.emit(instr2.br, labelidx(depth));
1158
+ }
1159
+ // Conditional break -- emits a `br_if` for the given depth.
1160
+ condBreak(depth) {
1161
+ const what = this._blockStack.at(-(depth + 1)).split(":")[0];
1162
+ assert(what === "block" || what === "if", "Invalid condBreak");
1163
+ this.emit(instr2.br_if, labelidx(depth));
1164
+ }
1165
+ continue(depth) {
1166
+ const what = this._blockStack.at(-(depth + 1)).split(":")[0];
1167
+ assert(what === "loop", "Invalid continue");
1168
+ this.emit(instr2.br, labelidx(depth));
1169
+ }
1170
+ brTable(labels, defaultLabelidx) {
1171
+ this.emit(instr2.br_table, vec(labels), defaultLabelidx);
1172
+ }
1173
+ return() {
1174
+ this.emit(instr2.return);
1175
+ }
1176
+ // Emit a dense jump table (switch-like) using br_table.
1177
+ switch(bt, discrimThunk, numCases, caseCb, defaultThunk) {
1178
+ const startStackHeight = this._blockStack.length;
1179
+ const labels = [];
1180
+ for (let i = 0; i < numCases; i++) {
1181
+ this._blockOnly(bt);
1182
+ labels.push(labelidx(i));
1183
+ }
1184
+ this.block(blocktype.empty, () => {
1185
+ discrimThunk();
1186
+ this.brTable(labels, labelidx(labels.length));
1187
+ });
1188
+ for (let i = 0; i < numCases; i++) {
1189
+ const depth = labels.length - (i + 1);
1190
+ caseCb(i, depth);
1191
+ this.break(depth);
1192
+ this._endBlock();
1193
+ }
1194
+ assert(this._blockStack.length === startStackHeight);
1195
+ }
1196
+ // "Macros" -- codegen helpers specific to Ohm.
1197
+ i32Inc() {
1198
+ this.i32Const(1);
1199
+ this.i32Add();
1200
+ }
1201
+ i32Dec() {
1202
+ this.i32Const(1);
1203
+ this.i32Sub();
1204
+ }
1205
+ dup() {
1206
+ this.localTee("tmp");
1207
+ this.localGet("tmp");
1208
+ }
1209
+ currCharCode() {
1210
+ this.globalGet("pos");
1211
+ this.i32Load8u(Compiler.INPUT_BUFFER_OFFSET);
1212
+ }
1213
+ nextCharCode() {
1214
+ this.currCharCode();
1215
+ this.incPos();
1216
+ }
1217
+ setRet(val) {
1218
+ this.i32Const(val);
1219
+ this.localSet("ret");
1220
+ }
1221
+ pushStackFrame(saveThunk) {
1222
+ this.globalGet("sp");
1223
+ this.i32Const(_Assembler.STACK_FRAME_SIZE_BYTES);
1224
+ this.i32Sub();
1225
+ this.globalSet("sp");
1226
+ if (saveThunk) {
1227
+ saveThunk();
1228
+ } else {
1229
+ this.savePos();
1230
+ this.saveNumBindings();
1231
+ }
1232
+ }
1233
+ popStackFrame() {
1234
+ this.i32Const(_Assembler.STACK_FRAME_SIZE_BYTES);
1235
+ this.globalGet("sp");
1236
+ this.i32Add();
1237
+ this.globalSet("sp");
1238
+ }
1239
+ // Save the current input position.
1240
+ savePos() {
1241
+ this.globalGet("sp");
1242
+ this.globalGet("pos");
1243
+ this.i32Store();
1244
+ }
1245
+ // Load the saved input position onto the stack.
1246
+ getSavedPos() {
1247
+ this.globalGet("sp");
1248
+ this.i32Load();
1249
+ }
1250
+ restorePos() {
1251
+ this.getSavedPos();
1252
+ this.globalSet("pos");
1253
+ }
1254
+ saveNumBindings() {
1255
+ this.globalGet("sp");
1256
+ if (FAST_SAVE_BINDINGS) {
1257
+ this.globalGet("bindings");
1258
+ this.i32Load(12);
1259
+ } else {
1260
+ this.callPrebuiltFunc("getBindingsLength");
1261
+ }
1262
+ this.i32Store(4);
1263
+ }
1264
+ getSavedNumBindings() {
1265
+ this.globalGet("sp");
1266
+ this.i32Load(4);
1267
+ }
1268
+ restoreBindingsLength() {
1269
+ if (FAST_RESTORE_BINDINGS) {
1270
+ this.globalGet("bindings");
1271
+ this.getSavedNumBindings();
1272
+ this.i32Store(12);
1273
+ } else {
1274
+ this.getSavedNumBindings();
1275
+ this.callPrebuiltFunc("setBindingsLength");
1276
+ }
1277
+ }
1278
+ saveFailurePos() {
1279
+ this.globalGet("sp");
1280
+ this.localGet("failurePos");
1281
+ this.i32Store();
1282
+ }
1283
+ restoreFailurePos() {
1284
+ this.globalGet("sp");
1285
+ this.i32Load();
1286
+ this.localSet("failurePos");
1287
+ }
1288
+ saveGlobalFailurePos() {
1289
+ this.globalGet("sp");
1290
+ this.globalGet("rightmostFailurePos");
1291
+ this.i32Store(4);
1292
+ }
1293
+ restoreGlobalFailurePos() {
1294
+ this.globalGet("sp");
1295
+ this.i32Load(4);
1296
+ this.globalSet("rightmostFailurePos");
1297
+ }
1298
+ updateGlobalFailurePos() {
1299
+ this.i32Max(
1300
+ () => this.globalGet("rightmostFailurePos"),
1301
+ () => this.localGet("failurePos")
1302
+ );
1303
+ this.globalSet("rightmostFailurePos");
1304
+ }
1305
+ updateLocalFailurePos(origPosThunk) {
1306
+ this.i32Max(() => this.localGet("failurePos"), origPosThunk);
1307
+ this.localSet("failurePos");
1308
+ }
1309
+ // Increment the current input position by 1.
1310
+ // [i32, i32] -> [i32]
1311
+ incPos() {
1312
+ this.globalGet("pos");
1313
+ this.i32Inc();
1314
+ this.globalSet("pos");
1315
+ }
1316
+ callPrebuiltFunc(name2) {
1317
+ this.emit(instr2.call, funcidx(prebuiltFuncidx(name2)));
1318
+ }
1319
+ newIterNodeWithSavedPosAndBindings(arity, isOpt = false) {
1320
+ this.getSavedPos();
1321
+ this.globalGet("pos");
1322
+ this.getSavedNumBindings();
1323
+ this.i32Const(arity);
1324
+ this.i32Const(isOpt ? 1 : 0);
1325
+ this.callPrebuiltFunc("newIterationNode");
1326
+ }
1327
+ newCaseInsensitiveNode(ruleId) {
1328
+ this.getSavedPos();
1329
+ this.globalGet("pos");
1330
+ this.i32Const(ruleId);
1331
+ this.globalGet("bindings");
1332
+ this.i32Load(12);
1333
+ this.i32Const(1);
1334
+ this.i32Sub();
1335
+ this.i32Const(-1);
1336
+ this.callPrebuiltFunc("newNonterminalNode");
1337
+ }
1338
+ // [startIdx: i32] -> [ptr: i32]
1339
+ newTerminalNode() {
1340
+ this.localGet("postSpacesPos");
1341
+ this.globalGet("pos");
1342
+ this.callPrebuiltFunc("newTerminalNode");
1343
+ }
1344
+ i32Max(aThunk, bThunk) {
1345
+ aThunk();
1346
+ bThunk();
1347
+ aThunk();
1348
+ bThunk();
1349
+ this.emit(instr2.i32.gt_s, instr2.select);
1350
+ }
1351
+ // Return the depth of the block with the given label.
1352
+ depthOf(label) {
1353
+ const i = this._blockStack.findLastIndex((what) => what === `block:${label}`);
1354
+ assert(i !== -1, `Unknown label: ${label}`);
1355
+ return this._blockStack.length - i - 1;
1356
+ }
1357
+ ruleEvalReturn() {
1358
+ this.localGet("ret");
1359
+ this.emit(instr2.i32.eqz, instr2.i32.eqz);
1360
+ this.localGet("failurePos");
1361
+ this.i32Const(1);
1362
+ this.emit(instr2.i32.shl);
1363
+ this.emit(instr2.i32.or);
1364
+ }
1365
+ };
1366
+ Assembler.ALIGN_1_BYTE = 0;
1367
+ Assembler.ALIGN_4_BYTES = 2;
1368
+ Assembler.CST_NODE_HEADER_SIZE_BYTES = 8;
1369
+ Assembler.MEMO_COL_SIZE_BYTES = 4 * 256;
1370
+ Assembler.STACK_FRAME_SIZE_BYTES = 8;
1371
+ var Compiler = class {
1372
+ constructor(grammar2) {
1373
+ assert(grammar2 && "superGrammar" in grammar2, "Not a valid grammar: " + grammar2);
1374
+ if (!(grammar2 instanceof ohm.ohmGrammar.constructor)) {
1375
+ assert(
1376
+ !!grammar2.source,
1377
+ "Grammar smells fishy. Do you have multiple instances of ohm-js?"
1378
+ );
1379
+ grammar2 = ohm.grammar(grammar2.source.contents);
1380
+ }
1381
+ this.grammar = grammar2;
1382
+ this.importDecls = [];
1383
+ this.ruleIdByName = new IndexedSet();
1384
+ this._ensureRuleId(grammar2.defaultStartRule);
1385
+ this._ensureRuleId("$term");
1386
+ this._ensureRuleId("$spaces");
1387
+ this.rules = void 0;
1388
+ this._nextLiftedId = 0;
1389
+ this._lexContextStack = [];
1390
+ this._applySpacesImplicit = apply("$spaces");
1391
+ }
1392
+ importCount() {
1393
+ return importsec2.entryCount + this.importDecls.length;
1394
+ }
1395
+ ruleId(name2) {
1396
+ return checkNotNull2(this.ruleIdByName.getIndex(name2), `Unknown rule: ${name2}`);
1397
+ }
1398
+ // This should be the only place where we assign rule IDs!
1399
+ _ensureRuleId(name2, { notMemoized } = {}) {
1400
+ const idx = this.ruleIdByName.add(name2);
1401
+ assert(notMemoized || idx < 256, `too many rules: ${idx}`);
1402
+ return idx;
1403
+ }
1404
+ inLexicalContext() {
1405
+ return checkNotNull2(this._lexContextStack.at(-1));
1406
+ }
1407
+ liftPExpr(exp, isSyntactic) {
1408
+ assert(!(exp instanceof pexprs.Terminal));
1409
+ const name2 = `$lifted${this._nextLiftedId++}`;
1410
+ const freeVars = collectParams(exp);
1411
+ let body = exp;
1412
+ let formals = [];
1413
+ const maxIndex = freeVars.reduce((acc, param2) => Math.max(acc, param2.index), -1);
1414
+ if (freeVars.length > 0) {
1415
+ const newParams = new Array(maxIndex + 1);
1416
+ freeVars.forEach((p, i) => {
1417
+ newParams[p.index] = new pexprs.Param(i);
1418
+ });
1419
+ body = exp.substituteParams(newParams);
1420
+ formals = newParams.filter(isNonNull).map((p) => `__${p.index}`);
1421
+ }
1422
+ const actuals = freeVars.filter(isNonNull);
1423
+ const ruleInfo = { body, formals, isSyntactic, source: exp.source };
1424
+ return [name2, ruleInfo, actuals];
1425
+ }
1426
+ // Return a funcidx corresponding to the eval function for the given rule.
1427
+ ruleEvalFuncIdx(name2) {
1428
+ const offset = this.importCount() + funcsec2.entryCount;
1429
+ return funcidx(this.ruleId(name2) + offset);
1430
+ }
1431
+ // Return an object implementing all of the debug imports.
1432
+ getDebugImports(log) {
1433
+ const ans = {};
1434
+ for (const decl of this.importDecls.filter((d) => d.module === "debug")) {
1435
+ const { name: name2 } = decl;
1436
+ ans[name2] = (arg) => {
1437
+ log(name2, arg);
1438
+ };
1439
+ }
1440
+ return ans;
1441
+ }
1442
+ normalize() {
1443
+ assert(!this.rules, "already normalized");
1444
+ this.simplifyApplications();
1445
+ this.specializeApplications();
1446
+ }
1447
+ compile() {
1448
+ this.normalize();
1449
+ const typeMap = this.typeMap = new TypeMap(typesec2.entryCount);
1450
+ const asm = this.asm = new Assembler(typeMap);
1451
+ asm.addBlocktype([valtype.i32], []);
1452
+ asm.addBlocktype([valtype.i32], [valtype.i32]);
1453
+ asm.addBlocktype([], [valtype.i32]);
1454
+ asm.addGlobal("pos", valtype.i32, mut.var, () => asm.i32Const(0));
1455
+ asm.addGlobal("rightmostFailurePos", valtype.i32, mut.var, () => asm.i32Const(-1));
1456
+ asm.addGlobal("sp", valtype.i32, mut.var, () => asm.i32Const(0));
1457
+ asm.addGlobal("__Runtime.Stub", valtype.i32, mut.const, () => asm.i32Const(0));
1458
+ asm.addGlobal("__Runtime.Minimal", valtype.i32, mut.const, () => asm.i32Const(1));
1459
+ asm.addGlobal("__Runtime.Incremental", valtype.i32, mut.const, () => asm.i32Const(2));
1460
+ asm.addGlobal("__startOffset", valtype.i32, mut.var, () => asm.i32Const(0));
1461
+ asm.addGlobal("__offset", valtype.i32, mut.var, () => asm.i32Const(0));
1462
+ asm.addGlobal("__ASC_RUNTIME", valtype.i32, mut.const, () => asm.i32Const(0));
1463
+ asm.addGlobal("bindings", valtype.i32, mut.var, () => asm.i32Const(0));
1464
+ asm.addGlobal("__heap_base", valtype.i32, mut.var, () => asm.i32Const(67240172));
1465
+ if (DEBUG) {
1466
+ for (let i = 0; i < 5e3; i++) {
1467
+ this.importDecls.push({
1468
+ module: "debug",
1469
+ name: `debug${i}`,
1470
+ paramTypes: [],
1471
+ resultTypes: []
1472
+ });
1473
+ }
1474
+ }
1475
+ const functionDecls = this.functionDecls();
1476
+ this.rewriteDebugLabels(functionDecls);
1477
+ return this.buildModule(typeMap, functionDecls);
1478
+ }
1479
+ simplifyApplications() {
1480
+ const { grammar: grammar2 } = this;
1481
+ const lookUpRule = (name2) => ({
1482
+ ...checkNotNull2(grammar2.rules[name2]),
1483
+ isSyntactic: isSyntacticRule(name2)
1484
+ });
1485
+ const ownRuleNames = Object.keys(grammar2.rules).filter(
1486
+ (name2) => Object.hasOwn(grammar2.rules, name2)
1487
+ );
1488
+ const rules = ownRuleNames.map((name2) => [name2, lookUpRule(name2)]);
1489
+ rules.push(["spaces", lookUpRule("spaces")]);
1490
+ const liftedTerminals = new IndexedSet();
1491
+ const liftTerminal = ({ obj }) => {
1492
+ const id = liftedTerminals.add(obj);
1493
+ assert(id >= 0 && id < 65535, "too many terminals!");
1494
+ return liftedTerminal(id);
1495
+ };
1496
+ const simplifyArg = (exp, isSyntactic) => {
1497
+ if (isApplyLike(exp)) {
1498
+ return simplify(exp, isSyntactic);
1499
+ }
1500
+ if (exp instanceof pexprs.Terminal) {
1501
+ return liftTerminal(exp);
1502
+ }
1503
+ const [name2, info, env] = this.liftPExpr(exp, isSyntactic);
1504
+ const args = env.map((p) => {
1505
+ assert(p instanceof pexprs.Param, "Expected Param");
1506
+ return param(p.index);
1507
+ });
1508
+ rules.push([name2, info]);
1509
+ return apply(name2, args);
1510
+ };
1511
+ const simplify = (exp, isSyntactic) => {
1512
+ if (exp instanceof pexprs.Alt) {
1513
+ return alt(exp.terms.map((e) => simplify(e, isSyntactic)));
1514
+ }
1515
+ if (exp === pexprs.any) return any();
1516
+ if (exp === pexprs.end) return end();
1517
+ switch (exp.constructor) {
1518
+ case pexprs.Apply: {
1519
+ const ruleInfo = lookUpRule(exp.ruleName);
1520
+ if (ruleInfo.body instanceof pexprs.CaseInsensitiveTerminal) {
1521
+ assert(exp.args.length === 1 && exp.args[0] instanceof pexprs.Terminal);
1522
+ return caseInsensitive(exp.args[0].obj);
1523
+ }
1524
+ rules.push([exp.ruleName, ruleInfo]);
1525
+ return apply(
1526
+ exp.ruleName,
1527
+ exp.args.map((arg) => simplifyArg(arg, isSyntactic))
1528
+ );
1529
+ }
1530
+ case pexprs.Lex:
1531
+ return lex(simplify(exp.expr, true));
1532
+ case pexprs.Lookahead:
1533
+ return lookahead(simplify(exp.expr, isSyntactic));
1534
+ case pexprs.Not:
1535
+ return not(simplify(exp.expr, isSyntactic));
1536
+ case pexprs.Opt:
1537
+ return opt(simplify(exp.expr, isSyntactic));
1538
+ case pexprs.Plus:
1539
+ return plus(simplify(exp.expr, isSyntactic));
1540
+ case pexprs.Seq:
1541
+ return seq(exp.factors.map((e) => simplify(e, isSyntactic)));
1542
+ case pexprs.Star:
1543
+ return star(simplify(exp.expr, isSyntactic));
1544
+ case pexprs.Param:
1545
+ return param(exp.index);
1546
+ case pexprs.Range:
1547
+ return range(exp.from, exp.to);
1548
+ case pexprs.Terminal:
1549
+ return terminal(exp.obj);
1550
+ case pexprs.UnicodeChar:
1551
+ return unicodeChar(exp.categoryOrProp ?? exp["category"]);
1552
+ default:
1553
+ throw new Error(`not handled: ${exp.constructor.name}`);
1554
+ }
1555
+ };
1556
+ const newRules = /* @__PURE__ */ new Map();
1557
+ for (let i = 0; i < rules.length; i++) {
1558
+ const [name2, info] = rules[i];
1559
+ if (!newRules.has(name2)) {
1560
+ newRules.set(name2, {
1561
+ ...info,
1562
+ body: simplify(info.body, info.isSyntactic)
1563
+ });
1564
+ }
1565
+ }
1566
+ this.rules = newRules;
1567
+ this.liftedTerminals = liftedTerminals;
1568
+ }
1569
+ compileTerminalRule(name2) {
1570
+ const { asm } = this;
1571
+ this.beginLexContext(true);
1572
+ asm.addFunction(`$${name2}`, [valtype.i32], [valtype.i32], () => {
1573
+ asm.addLocal("ret", valtype.i32);
1574
+ asm.addLocal("tmp", valtype.i32);
1575
+ asm.addLocal("postSpacesPos", valtype.i32);
1576
+ asm.addLocal("failurePos", valtype.i32);
1577
+ asm.i32Const(-1);
1578
+ asm.localSet("failurePos");
1579
+ const values = this.liftedTerminals.values();
1580
+ asm.switch(
1581
+ blocktype.empty,
1582
+ () => asm.localGet("__arg0"),
1583
+ values.length,
1584
+ (i) => this.emitTerminal(terminal(values[i])),
1585
+ () => asm.emit(instr2.unreachable)
1586
+ );
1587
+ asm.localGet("ret");
1588
+ });
1589
+ this.endLexContext();
1590
+ return this.asm._functionDecls.at(-1);
1591
+ }
1592
+ beginLexContext(initialVal) {
1593
+ assert(this._lexContextStack.length === 0);
1594
+ this._lexContextStack.push(initialVal);
1595
+ }
1596
+ endLexContext() {
1597
+ this._lexContextStack.pop();
1598
+ assert(this._lexContextStack.length === 0);
1599
+ }
1600
+ compileRule(name2) {
1601
+ const { asm } = this;
1602
+ const ruleInfo = getNotNull(this.rules, name2);
1603
+ let paramTypes = [];
1604
+ if (ruleInfo.patterns) {
1605
+ paramTypes = [valtype.i32];
1606
+ }
1607
+ const restoreFailurePos = name2 === this._applySpacesImplicit.ruleName;
1608
+ this.beginLexContext(!ruleInfo.isSyntactic);
1609
+ asm.addFunction(`$${name2}`, paramTypes, [valtype.i32], () => {
1610
+ asm.addLocal("ret", valtype.i32);
1611
+ asm.addLocal("tmp", valtype.i32);
1612
+ asm.addLocal("postSpacesPos", valtype.i32);
1613
+ asm.addLocal("failurePos", valtype.i32);
1614
+ asm.globalGet("rightmostFailurePos");
1615
+ asm.localSet("failurePos");
1616
+ if (restoreFailurePos) {
1617
+ asm.addLocal("origFailurePos", valtype.i32);
1618
+ asm.globalGet("rightmostFailurePos");
1619
+ asm.localSet("origFailurePos");
1620
+ }
1621
+ asm.emit(`BEGIN eval:${name2}`);
1622
+ this.emitPExpr(ruleInfo.body);
1623
+ if (restoreFailurePos) {
1624
+ asm.localGet("origFailurePos");
1625
+ asm.dup();
1626
+ asm.globalSet("rightmostFailurePos");
1627
+ asm.localSet("failurePos");
1628
+ }
1629
+ asm.ruleEvalReturn();
1630
+ asm.emit(`END eval:${name2}`);
1631
+ });
1632
+ this.endLexContext();
1633
+ return this.asm._functionDecls.at(-1);
1634
+ }
1635
+ // Beginning with the default start rule, recursively visit all reachable
1636
+ // parsing expressions. For all parameterized rules, create a specialized
1637
+ // version of that rule for every possible set of actual parameters.
1638
+ // At the end, there are no more applications with arguments.
1639
+ specializeApplications() {
1640
+ const newRules = /* @__PURE__ */ new Map();
1641
+ const { rules } = this;
1642
+ const patternsByRule = /* @__PURE__ */ new Map();
1643
+ let hasCaseInsensitiveTerminals = false;
1644
+ const specialize = (exp) => rewrite(exp, {
1645
+ Apply: (app) => {
1646
+ const { ruleName, children } = app;
1647
+ const ruleInfo = getNotNull(rules, ruleName);
1648
+ if (["liquidRawTagImpl", "liquidTagRule"].includes(ruleName)) {
1649
+ return specialize(substituteParams(ruleInfo.body, children));
1650
+ }
1651
+ const specializedName2 = specializedName(app);
1652
+ this._ensureRuleId(specializedName2);
1653
+ if (!newRules.has(specializedName2)) {
1654
+ newRules.set(specializedName2, {});
1655
+ let body = specialize(substituteParams(ruleInfo.body, children));
1656
+ if (children.length > 0) {
1657
+ const rulePatterns = setdefault(patternsByRule, ruleName, () => /* @__PURE__ */ new Map());
1658
+ rulePatterns.set(specializedName2, children);
1659
+ if (EMIT_GENERALIZED_RULES) {
1660
+ const caseIdx = rulePatterns.size - 1;
1661
+ body = applyGeneralized(ruleName, caseIdx);
1662
+ }
1663
+ }
1664
+ newRules.set(specializedName2, { ...ruleInfo, body, formals: [] });
1665
+ }
1666
+ return apply(specializedName2);
1667
+ },
1668
+ CaseInsensitive: (exp2) => {
1669
+ hasCaseInsensitiveTerminals = true;
1670
+ return exp2;
1671
+ }
1672
+ });
1673
+ specialize(apply(this.grammar.defaultStartRule));
1674
+ const spacesInfo = getNotNull(rules, "spaces");
1675
+ newRules.set("$spaces", {
1676
+ ...spacesInfo,
1677
+ body: specialize(spacesInfo.body)
1678
+ });
1679
+ if (hasCaseInsensitiveTerminals) {
1680
+ assert(!newRules.has("caseInsensitive"));
1681
+ this._ensureRuleId("caseInsensitive", { notMemoized: true });
1682
+ newRules.set("caseInsensitive", {
1683
+ name: "caseInsensitive",
1684
+ body: seq([not(end()), end()]),
1685
+ // ~end end
1686
+ formals: [],
1687
+ description: ""
1688
+ });
1689
+ }
1690
+ this.rules = newRules;
1691
+ if (EMIT_GENERALIZED_RULES) {
1692
+ const insertDispatches = (exp, patterns) => rewrite(exp, {
1693
+ Apply: (app) => app.children.length === 0 ? app : dispatch(app, patterns),
1694
+ Param: (p) => dispatch(p, patterns)
1695
+ });
1696
+ for (const [name2, patterns] of patternsByRule.entries()) {
1697
+ this._ensureRuleId(name2, { notMemoized: true });
1698
+ const ruleInfo = getNotNull(rules, name2);
1699
+ const patternsArr = [...patterns.values()];
1700
+ newRules.set(name2, {
1701
+ ...ruleInfo,
1702
+ body: insertDispatches(ruleInfo.body, patternsArr),
1703
+ patterns: patternsArr
1704
+ });
1705
+ }
1706
+ }
1707
+ }
1708
+ buildRuleNamesSection(ruleNames) {
1709
+ return custom(name("ruleNames"), vec(ruleNames.map((n, i) => name(n))));
1710
+ }
1711
+ buildModule(typeMap, functionDecls) {
1712
+ const ruleNames = this.ruleIdByName.values();
1713
+ assert(destImportCount === this.importCount(), "import count mismatch");
1714
+ ruleNames.forEach(
1715
+ (n, i) => assert(i === this.ruleIdByName.getIndex(n), `out of order: ${n}`)
1716
+ );
1717
+ typeMap.addDecls(this.importDecls);
1718
+ typeMap.addDecls(functionDecls);
1719
+ const globals = [];
1720
+ const imports = this.importDecls.map(
1721
+ (f, i) => import_(f.module, f.name, importdesc.func(typeMap.getIdxForDecl(f)))
1722
+ );
1723
+ const funcs = functionDecls.map((f, i) => typeidx(typeMap.getIdxForDecl(f)));
1724
+ const codes = functionDecls.map((f) => code(func(f.locals, f.body)));
1725
+ const exportOffset = this.importCount() + funcsec2.entryCount;
1726
+ const exports = functionDecls.map(
1727
+ (f, i) => export_(f.name, exportdesc.func(i + exportOffset))
1728
+ );
1729
+ exports.push(export_("memory", exportdesc.mem(0)));
1730
+ exports.push(export_("match", exportdesc.func(prebuiltFuncidx("match"))));
1731
+ exports.push(export_("getCstRoot", exportdesc.func(prebuiltFuncidx("getCstRoot"))));
1732
+ for (const [name2, { type, mut: mut2, initExpr }] of this.asm._globals.entries()) {
1733
+ globals.push(global(globaltype(type, mut2), initExpr));
1734
+ exports.push(export_(name2, [3, this.asm.globalidx(name2)]));
1735
+ }
1736
+ const numRules = this.ruleIdByName.size;
1737
+ const table2 = table(
1738
+ tabletype(elemtype.funcref, limits.minmax(numRules, numRules))
1739
+ );
1740
+ const tableData = ruleNames.map((name2) => this.ruleEvalFuncIdx(name2));
1741
+ assert(numRules === tableData.length, "Invalid rule count");
1742
+ const indexOfStart = functionDecls.findIndex((f) => f.name === "start");
1743
+ assert(indexOfStart !== -1, "No start function found");
1744
+ const startFuncidx2 = this.importCount() + funcsec2.entryCount + indexOfStart;
1745
+ const mod = module([
1746
+ mergeSections(SECTION_ID_TYPE, typesec2, typeMap.getTypes()),
1747
+ mergeSections(SECTION_ID_IMPORT, importsec2, imports),
1748
+ mergeSections(SECTION_ID_FUNCTION, funcsec2, funcs),
1749
+ tablesec([table2]),
1750
+ memsec([mem(memtype(limits.min(1024 + 24)))]),
1751
+ globalsec(globals),
1752
+ exportsec(exports),
1753
+ startsec(start(startFuncidx2)),
1754
+ elemsec([elem(tableidx(0), [instr2.i32.const, i32(0), instr2.end], tableData)]),
1755
+ mergeSections(SECTION_ID_CODE, codesec2, codes),
1756
+ customsec(this.buildRuleNamesSection(ruleNames)),
1757
+ namesec(namedata(modulenamesubsec(this.grammar.name)))
1758
+ ]);
1759
+ const bytes = Uint8Array.from(mod.flat(Infinity));
1760
+ return bytes;
1761
+ }
1762
+ // A *brilliant* way to add arbitrary labels to the generated code.
1763
+ // Goes through the body of all functions in `decls`, and replaces any
1764
+ // strings with a call to a dummy function with the same name.
1765
+ // Ensures that there are no duplicate dummy function names, but does not
1766
+ // guarantee that there are no collisions with other functions.
1767
+ // Returns the list of dummy functions that need to be added to the module.
1768
+ rewriteDebugLabels(decls) {
1769
+ let nextIdx = 0;
1770
+ const intoFuncidx = (i) => funcidx(importsec2.entryCount + i);
1771
+ const names = /* @__PURE__ */ new Set();
1772
+ for (let i = 0; i < decls.length; i++) {
1773
+ const entry = decls[i];
1774
+ entry.body = entry.body.flatMap((x) => {
1775
+ if (typeof x !== "string") return x;
1776
+ if (!DEBUG) return [];
1777
+ const idx = nextIdx++;
1778
+ const decl = checkNotNull2(this.importDecls[idx], "Too few debug functions!");
1779
+ assert(decl.module === "debug");
1780
+ decl.name = uniqueName(names, x);
1781
+ let pushArg = [];
1782
+ if (x.startsWith("END")) {
1783
+ decl.paramTypes = [valtype.i32];
1784
+ const retIdx = entry.paramTypes.length;
1785
+ pushArg = [instr2.local.get, localidx(retIdx)];
1786
+ }
1787
+ return [...pushArg, instr2.call, intoFuncidx(idx)].flat(Infinity);
1788
+ });
1789
+ }
1790
+ }
1791
+ functionDecls() {
1792
+ const ruleDecls = [];
1793
+ for (const name2 of this.ruleIdByName.keys()) {
1794
+ if (name2 === "$term") {
1795
+ ruleDecls.push(this.compileTerminalRule(name2));
1796
+ } else {
1797
+ assert(!name2.startsWith("$term"));
1798
+ ruleDecls.push(this.compileRule(name2));
1799
+ }
1800
+ }
1801
+ const { asm } = this;
1802
+ asm.addFunction("start", [], [], () => {
1803
+ asm.emit(instr2.call, funcidx(startFuncidx));
1804
+ });
1805
+ ruleDecls.push(asm._functionDecls.at(-1));
1806
+ return ruleDecls;
1807
+ }
1808
+ // Handle an application-like expression (i.e. an actual Apply, or a Param)
1809
+ // in the *body* of the generalized version of a parameterized rule.
1810
+ // Generalized rules can behave like a specific specialized version of the
1811
+ // rule; they take an i32 `caseIdx` argument that selects the behaviour.
1812
+ // Then, for any Param -- or Apply that involves a Param -- we dynamically
1813
+ // dispatch to the correct specialized version of the rule.
1814
+ emitDispatch({ child: exp, patterns }) {
1815
+ const { asm } = this;
1816
+ const handleCase = (i) => {
1817
+ let newExp = substituteParams(exp, patterns[i]);
1818
+ if (newExp.type === "Apply") {
1819
+ newExp = apply(specializedName(newExp));
1820
+ }
1821
+ this.emitPExpr(newExp);
1822
+ };
1823
+ if (patterns.length === 1) {
1824
+ handleCase(0);
1825
+ return;
1826
+ }
1827
+ assert(patterns.length > 1);
1828
+ asm.switch(
1829
+ blocktype.empty,
1830
+ () => asm.localGet("__arg0"),
1831
+ patterns.length,
1832
+ handleCase,
1833
+ () => {
1834
+ asm.emit(instr2.unreachable);
1835
+ }
1836
+ );
1837
+ }
1838
+ // Contract: emitPExpr always means we're going deeper in the PExpr tree.
1839
+ emitPExpr(exp, { preHook, postHook } = {}) {
1840
+ const { asm } = this;
1841
+ const allowFastApply = !preHook && !postHook;
1842
+ assert(!(exp.type === "Apply" && exp.children.length > 0));
1843
+ if (exp.type === "Apply" && allowFastApply) {
1844
+ asm.emit(`BEGIN apply:${exp.ruleName}`);
1845
+ this.emitApply(exp);
1846
+ asm.emit(`END apply:${exp.ruleName}`);
1847
+ return;
1848
+ }
1849
+ if (exp.type === "ApplyGeneralized") {
1850
+ assert(EMIT_GENERALIZED_RULES && allowFastApply);
1851
+ asm.emit(`BEGIN applyGeneralized:${exp.ruleName}`);
1852
+ this.emitApplyGeneralized(exp);
1853
+ asm.emit(`END applyGeneralized:${exp.ruleName}`);
1854
+ return;
1855
+ }
1856
+ const debugLabel = toString(exp);
1857
+ asm.emit(`BEGIN ${debugLabel}`);
1858
+ asm.pushStackFrame();
1859
+ asm.block(
1860
+ blocktype.empty,
1861
+ () => {
1862
+ if (preHook) preHook();
1863
+ switch (exp.type) {
1864
+ case "Alt":
1865
+ this.emitAlt(exp);
1866
+ break;
1867
+ case "Any":
1868
+ this.emitAny();
1869
+ break;
1870
+ case "CaseInsensitive":
1871
+ this.emitCaseInsensitive(exp);
1872
+ break;
1873
+ case "Dispatch":
1874
+ this.emitDispatch(exp);
1875
+ break;
1876
+ case "End":
1877
+ this.emitEnd();
1878
+ break;
1879
+ case "Lex":
1880
+ this.emitLex(exp);
1881
+ break;
1882
+ case "LiftedTerminal":
1883
+ this.emitApplyTerm(exp);
1884
+ break;
1885
+ case "Lookahead":
1886
+ this.emitLookahead(exp);
1887
+ break;
1888
+ case "Not":
1889
+ this.emitNot(exp);
1890
+ break;
1891
+ case "Seq":
1892
+ this.emitSeq(exp);
1893
+ break;
1894
+ case "Star":
1895
+ this.emitStar(exp);
1896
+ break;
1897
+ case "Opt":
1898
+ this.emitOpt(exp);
1899
+ break;
1900
+ case "Range":
1901
+ this.emitRange(exp);
1902
+ break;
1903
+ case "Plus":
1904
+ this.emitPlus(exp);
1905
+ break;
1906
+ case "Terminal":
1907
+ this.emitTerminal(exp);
1908
+ break;
1909
+ case "UnicodeChar":
1910
+ this.emitUnicodeChar(exp);
1911
+ break;
1912
+ case "Param":
1913
+ // Fall through (Params should not exist at codegen time).
1914
+ default:
1915
+ throw new Error(`not handled: ${exp.type}`);
1916
+ }
1917
+ },
1918
+ "pexprEnd"
1919
+ );
1920
+ if (postHook) postHook();
1921
+ asm.popStackFrame();
1922
+ asm.emit(`END ${debugLabel}`);
1923
+ }
1924
+ emitAlt(exp) {
1925
+ const { asm } = this;
1926
+ asm.block(blocktype.empty, () => {
1927
+ for (const term of exp.children) {
1928
+ this.emitPExpr(term);
1929
+ asm.localGet("ret");
1930
+ asm.condBreak(asm.depthOf("pexprEnd"));
1931
+ asm.restorePos();
1932
+ asm.restoreBindingsLength();
1933
+ }
1934
+ });
1935
+ }
1936
+ emitAny() {
1937
+ const { asm } = this;
1938
+ this.wrapTerminalLike(() => {
1939
+ asm.i32Const(255);
1940
+ asm.nextCharCode();
1941
+ asm.i32Eq();
1942
+ asm.condBreak(asm.depthOf("failure"));
1943
+ });
1944
+ }
1945
+ emitApplyTerm({ terminalId }) {
1946
+ const { asm } = this;
1947
+ this.maybeEmitSpaceSkipping();
1948
+ asm.globalGet("pos");
1949
+ asm.localSet("tmp");
1950
+ asm.i32Const(terminalId);
1951
+ asm.emit(instr2.call, this.ruleEvalFuncIdx("$term"));
1952
+ asm.localTee("ret");
1953
+ asm.ifFalse(blocktype.empty, () => {
1954
+ asm.updateLocalFailurePos(() => asm.localGet("tmp"));
1955
+ });
1956
+ }
1957
+ // Emit an application of the generalized version of a parameterized rule.
1958
+ // Need to know which case we're applying!
1959
+ emitApplyGeneralized(exp) {
1960
+ const { asm } = this;
1961
+ asm.i32Const(this.ruleId(exp.ruleName));
1962
+ asm.i32Const(exp.caseIdx);
1963
+ asm.callPrebuiltFunc("evalApplyGeneralized");
1964
+ asm.localSet("ret");
1965
+ }
1966
+ emitApply(exp) {
1967
+ assert(exp.children.length === 0);
1968
+ if (exp !== this._applySpacesImplicit) {
1969
+ this.maybeEmitSpaceSkipping();
1970
+ }
1971
+ const { asm } = this;
1972
+ asm.i32Const(this.ruleId(exp.ruleName));
1973
+ if (exp.ruleName.includes("_")) {
1974
+ asm.callPrebuiltFunc("evalApplyNoMemo0");
1975
+ } else {
1976
+ asm.callPrebuiltFunc("evalApply0");
1977
+ }
1978
+ asm.updateLocalFailurePos(() => asm.globalGet("rightmostFailurePos"));
1979
+ asm.localSet("ret");
1980
+ }
1981
+ emitEnd() {
1982
+ const { asm } = this;
1983
+ this.wrapTerminalLike(() => {
1984
+ asm.i32Const(255);
1985
+ asm.currCharCode();
1986
+ asm.i32Ne();
1987
+ asm.condBreak(asm.depthOf("failure"));
1988
+ });
1989
+ }
1990
+ emitFail() {
1991
+ const { asm } = this;
1992
+ asm.i32Const(0);
1993
+ asm.localSet("ret");
1994
+ }
1995
+ emitLex({ child }) {
1996
+ this._lexContextStack.push(true);
1997
+ this.emitPExpr(child);
1998
+ this._lexContextStack.pop();
1999
+ }
2000
+ emitLookahead({ child }) {
2001
+ const { asm } = this;
2002
+ this.emitPExpr(child);
2003
+ asm.restoreBindingsLength();
2004
+ asm.restorePos();
2005
+ }
2006
+ emitNot({ child }) {
2007
+ const { asm } = this;
2008
+ asm.pushStackFrame(() => {
2009
+ asm.saveFailurePos();
2010
+ asm.saveGlobalFailurePos();
2011
+ });
2012
+ this.emitPExpr(child);
2013
+ asm.localGet("ret");
2014
+ asm.emit(instr2.i32.eqz);
2015
+ asm.localSet("ret");
2016
+ asm.restoreGlobalFailurePos();
2017
+ asm.restoreFailurePos();
2018
+ asm.popStackFrame();
2019
+ asm.restoreBindingsLength();
2020
+ asm.restorePos();
2021
+ }
2022
+ emitOpt({ child }) {
2023
+ const { asm } = this;
2024
+ this.emitPExpr(child);
2025
+ asm.localGet("ret");
2026
+ asm.ifFalse(blocktype.empty, () => {
2027
+ asm.restorePos();
2028
+ asm.restoreBindingsLength();
2029
+ });
2030
+ asm.newIterNodeWithSavedPosAndBindings(outArity(child), true);
2031
+ asm.localSet("ret");
2032
+ }
2033
+ emitPlus(plusExp) {
2034
+ const { asm } = this;
2035
+ this.emitPExpr(plusExp.child);
2036
+ asm.localGet("ret");
2037
+ asm.if(blocktype.empty, () => {
2038
+ this.emitStar(plusExp);
2039
+ });
2040
+ }
2041
+ emitRange(exp) {
2042
+ assert(exp.lo.length === 1 && exp.hi.length === 1);
2043
+ const lo = exp.lo.charCodeAt(0);
2044
+ const hi = exp.hi.charCodeAt(0);
2045
+ const { asm } = this;
2046
+ this.wrapTerminalLike(() => {
2047
+ asm.nextCharCode();
2048
+ asm.dup();
2049
+ asm.i32Const(hi);
2050
+ asm.emit(instr2.i32.gt_u);
2051
+ asm.condBreak(asm.depthOf("failure"));
2052
+ asm.i32Const(lo);
2053
+ asm.emit(instr2.i32.lt_u);
2054
+ asm.condBreak(asm.depthOf("failure"));
2055
+ });
2056
+ }
2057
+ emitSeq({ children }) {
2058
+ const { asm } = this;
2059
+ if (children.length === 0) {
2060
+ asm.setRet(1);
2061
+ return;
2062
+ }
2063
+ for (const c of children) {
2064
+ this.emitPExpr(c);
2065
+ asm.localGet("ret");
2066
+ asm.emit(instr2.i32.eqz);
2067
+ asm.condBreak(asm.depthOf("pexprEnd"));
2068
+ }
2069
+ }
2070
+ maybeEmitSpaceSkipping() {
2071
+ if (IMPLICIT_SPACE_SKIPPING && !this.inLexicalContext()) {
2072
+ this.asm.emit("BEGIN space skipping");
2073
+ this.emitApply(this._applySpacesImplicit);
2074
+ this.asm.emit("END space skipping");
2075
+ }
2076
+ }
2077
+ emitStar({ child }, { reuseStackFrame } = {}) {
2078
+ const { asm } = this;
2079
+ asm.pushStackFrame();
2080
+ asm.block(
2081
+ blocktype.empty,
2082
+ () => {
2083
+ asm.loop(blocktype.empty, () => {
2084
+ asm.savePos();
2085
+ asm.saveNumBindings();
2086
+ this.emitPExpr(child);
2087
+ asm.localGet("ret");
2088
+ asm.emit(instr2.i32.eqz);
2089
+ asm.condBreak(asm.depthOf("done"));
2090
+ asm.continue(0);
2091
+ });
2092
+ },
2093
+ "done"
2094
+ );
2095
+ asm.restorePos();
2096
+ asm.restoreBindingsLength();
2097
+ asm.popStackFrame();
2098
+ asm.newIterNodeWithSavedPosAndBindings(outArity(child));
2099
+ asm.localSet("ret");
2100
+ }
2101
+ wrapTerminalLike(thunk) {
2102
+ const { asm } = this;
2103
+ this.maybeEmitSpaceSkipping();
2104
+ asm.globalGet("pos");
2105
+ asm.localSet("postSpacesPos");
2106
+ asm.block(
2107
+ blocktype.empty,
2108
+ () => {
2109
+ asm.block(
2110
+ blocktype.empty,
2111
+ () => {
2112
+ thunk();
2113
+ asm.newTerminalNode();
2114
+ asm.localSet("ret");
2115
+ asm.break(asm.depthOf("_done"));
2116
+ },
2117
+ "failure"
2118
+ );
2119
+ asm.updateLocalFailurePos(() => asm.localGet("postSpacesPos"));
2120
+ asm.setRet(0);
2121
+ },
2122
+ "_done"
2123
+ );
2124
+ }
2125
+ emitCaseInsensitive({ value }) {
2126
+ const { asm } = this;
2127
+ assert(
2128
+ [...value].every((c) => c <= "\x7F"),
2129
+ "not supported: case-insensitive Unicode"
2130
+ );
2131
+ const str = value.toLowerCase();
2132
+ asm.emit(JSON.stringify(`caseInsensitive:${value}`));
2133
+ this.wrapTerminalLike(() => {
2134
+ for (const c of [...str]) {
2135
+ asm.i32Const(c.charCodeAt(0));
2136
+ asm.currCharCode();
2137
+ if ("a" <= c && c <= "z" || "A" <= c && c <= "Z") {
2138
+ asm.i32Const(32);
2139
+ asm.emit(instr2.i32.or);
2140
+ }
2141
+ asm.emit(instr2.i32.ne);
2142
+ asm.condBreak(asm.depthOf("failure"));
2143
+ asm.incPos();
2144
+ }
2145
+ });
2146
+ asm.localGet("ret");
2147
+ asm.if(blocktype.empty, () => {
2148
+ asm.newCaseInsensitiveNode(this.ruleId("caseInsensitive"));
2149
+ asm.localSet("ret");
2150
+ });
2151
+ }
2152
+ emitTerminal(exp) {
2153
+ const { asm } = this;
2154
+ asm.emit(JSON.stringify(exp.value));
2155
+ this.wrapTerminalLike(() => {
2156
+ for (const c of [...exp.value]) {
2157
+ asm.i32Const(c.charCodeAt(0));
2158
+ asm.currCharCode();
2159
+ asm.emit(instr2.i32.ne);
2160
+ asm.condBreak(asm.depthOf("failure"));
2161
+ asm.incPos();
2162
+ }
2163
+ });
2164
+ }
2165
+ emitUnicodeChar(exp) {
2166
+ const { asm } = this;
2167
+ assert(["Ll", "Lu", "Ltmo"].includes(exp.categoryOrProp));
2168
+ const makeLabels = () => asciiChars.map((c) => {
2169
+ const isLowercase = "a" <= c && c <= "z";
2170
+ const isUppercase = "A" <= c && c <= "Z";
2171
+ if (exp.categoryOrProp === "Lu" && isUppercase || exp.categoryOrProp === "Ll" && isLowercase) {
2172
+ return labelidx(asm.depthOf("fastSuccess"));
2173
+ }
2174
+ return labelidx(asm.depthOf("failure"));
2175
+ });
2176
+ this.wrapTerminalLike(() => {
2177
+ asm.block(
2178
+ blocktype.empty,
2179
+ () => {
2180
+ asm.block(
2181
+ blocktype.empty,
2182
+ () => {
2183
+ asm.block(
2184
+ blocktype.empty,
2185
+ () => {
2186
+ asm.currCharCode();
2187
+ asm.brTable(makeLabels(), labelidx(asm.depthOf("default")));
2188
+ },
2189
+ "default"
2190
+ );
2191
+ switch (exp.categoryOrProp) {
2192
+ case "Lu":
2193
+ asm.i32Const(1 << 1);
2194
+ break;
2195
+ case "Ll":
2196
+ asm.i32Const(1 << 2);
2197
+ break;
2198
+ case "Ltmo":
2199
+ asm.i32Const(1 << 3 | 1 << 4 | 1 << 5);
2200
+ break;
2201
+ default:
2202
+ assert(false, "not handled");
2203
+ }
2204
+ asm.callPrebuiltFunc("doMatchUnicodeChar");
2205
+ asm.ifElse(
2206
+ blocktype.empty,
2207
+ () => asm.break(asm.depthOf("slowSuccess")),
2208
+ () => asm.break(asm.depthOf("failure"))
2209
+ );
2210
+ },
2211
+ "fastSuccess"
2212
+ );
2213
+ asm.incPos();
2214
+ },
2215
+ "slowSuccess"
2216
+ );
2217
+ });
2218
+ }
2219
+ };
2220
+ Compiler.STACK_START_OFFSET = WASM_PAGE_SIZE;
2221
+ Compiler.INPUT_BUFFER_OFFSET = WASM_PAGE_SIZE;
2222
+ Compiler.MEMO_START_OFFSET = 2 * WASM_PAGE_SIZE;
2223
+ Compiler.CST_START_OFFSET = (1024 + 2) * WASM_PAGE_SIZE;
2224
+ var ConstantsForTesting = {
2225
+ CST_NODE_SIZE_BYTES: checkNotNull2(Assembler.CST_NODE_HEADER_SIZE_BYTES),
2226
+ CST_START_OFFSET: checkNotNull2(Compiler.CST_START_OFFSET),
2227
+ MEMO_COL_SIZE_BYTES: checkNotNull2(Assembler.MEMO_COL_SIZE_BYTES),
2228
+ MEMO_START_OFFSET: checkNotNull2(Compiler.MEMO_START_OFFSET)
2229
+ };
2230
+
2231
+ // src/cli.js
9
2232
  function main() {
10
2233
  const argsConfig = {
11
2234
  options: {
@@ -27,7 +2250,7 @@ function main() {
27
2250
  process.exit(1);
28
2251
  }
29
2252
  const filename = args.positionals[0];
30
- const ns = ohm.grammars(fs.readFileSync(filename, "utf8"));
2253
+ const ns = ohm2.grammars(fs.readFileSync(filename, "utf8"));
31
2254
  let g = Object.values(ns).at(-1);
32
2255
  const { grammarName } = args.values;
33
2256
  if (grammarName) {