@lexd/core 0.1.0

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.
Files changed (54) hide show
  1. package/LICENSE +21 -0
  2. package/dist/ast.d.ts +121 -0
  3. package/dist/ast.d.ts.map +1 -0
  4. package/dist/ast.js +26 -0
  5. package/dist/ast.js.map +1 -0
  6. package/dist/codegen.d.ts +25 -0
  7. package/dist/codegen.d.ts.map +1 -0
  8. package/dist/codegen.js +30 -0
  9. package/dist/codegen.js.map +1 -0
  10. package/dist/decompile.d.ts +11 -0
  11. package/dist/decompile.d.ts.map +1 -0
  12. package/dist/decompile.js +524 -0
  13. package/dist/decompile.js.map +1 -0
  14. package/dist/emit.d.ts +6 -0
  15. package/dist/emit.d.ts.map +1 -0
  16. package/dist/emit.js +16 -0
  17. package/dist/emit.js.map +1 -0
  18. package/dist/errors.d.ts +6 -0
  19. package/dist/errors.d.ts.map +1 -0
  20. package/dist/errors.js +9 -0
  21. package/dist/errors.js.map +1 -0
  22. package/dist/index.d.ts +49 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +145 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/lexer.d.ts +38 -0
  27. package/dist/lexer.d.ts.map +1 -0
  28. package/dist/lexer.js +97 -0
  29. package/dist/lexer.js.map +1 -0
  30. package/dist/lexicon.d.ts +138 -0
  31. package/dist/lexicon.d.ts.map +1 -0
  32. package/dist/lexicon.js +3 -0
  33. package/dist/lexicon.js.map +1 -0
  34. package/dist/lower.d.ts +6 -0
  35. package/dist/lower.d.ts.map +1 -0
  36. package/dist/lower.js +447 -0
  37. package/dist/lower.js.map +1 -0
  38. package/dist/parser.d.ts +7 -0
  39. package/dist/parser.d.ts.map +1 -0
  40. package/dist/parser.js +684 -0
  41. package/dist/parser.js.map +1 -0
  42. package/dist/registry.d.ts +31 -0
  43. package/dist/registry.d.ts.map +1 -0
  44. package/dist/registry.js +99 -0
  45. package/dist/registry.js.map +1 -0
  46. package/dist/stdlib-imports.d.ts +8 -0
  47. package/dist/stdlib-imports.d.ts.map +1 -0
  48. package/dist/stdlib-imports.js +20 -0
  49. package/dist/stdlib-imports.js.map +1 -0
  50. package/dist/validate.d.ts +5 -0
  51. package/dist/validate.d.ts.map +1 -0
  52. package/dist/validate.js +52 -0
  53. package/dist/validate.js.map +1 -0
  54. package/package.json +41 -0
package/dist/parser.js ADDED
@@ -0,0 +1,684 @@
1
+ import { CstParser, } from 'chevrotain';
2
+ import { allTokens, NamespaceKw, ImportKw, FromKw, AsKw, TypeKw, UnionKw, ClosedKw, ParamsKw, InputKw, OutputKw, MessageKw, ErrorsKw, EncodingKw, SchemaKw, PermissionsKw, LCurly, RCurly, LParen, RParen, LBracket, RBracket, Colon, Comma, Question, At, Hash, Dot, Identifier, StringLiteral, NumberLiteral, BooleanLiteral, lexdLexer, } from './lexer.js';
3
+ import { PRIMITIVES, PRIMARY_ATTRS } from './ast.js';
4
+ class LexdParser extends CstParser {
5
+ constructor() {
6
+ super(allTokens, { recoveryEnabled: false });
7
+ this.performSelfAnalysis();
8
+ }
9
+ file = this.RULE('file', () => {
10
+ this.MANY(() => this.SUBRULE(this.importDecl));
11
+ this.MANY2(() => this.SUBRULE(this.namespaceDecl));
12
+ });
13
+ importDecl = this.RULE('importDecl', () => {
14
+ this.CONSUME(ImportKw);
15
+ this.OR([
16
+ {
17
+ ALT: () => {
18
+ this.CONSUME(LCurly);
19
+ this.SUBRULE(this.importBinding);
20
+ this.MANY(() => {
21
+ this.CONSUME(Comma);
22
+ this.SUBRULE2(this.importBinding);
23
+ });
24
+ this.CONSUME(RCurly);
25
+ this.CONSUME(FromKw);
26
+ this.CONSUME(StringLiteral);
27
+ },
28
+ },
29
+ {
30
+ ALT: () => {
31
+ this.SUBRULE(this.nsid);
32
+ this.OPTION(() => {
33
+ this.CONSUME(AsKw);
34
+ this.CONSUME(Identifier);
35
+ });
36
+ },
37
+ },
38
+ ]);
39
+ });
40
+ importBinding = this.RULE('importBinding', () => {
41
+ this.CONSUME(Identifier);
42
+ this.OPTION(() => {
43
+ this.CONSUME(AsKw);
44
+ this.CONSUME2(Identifier);
45
+ });
46
+ });
47
+ namespaceDecl = this.RULE('namespaceDecl', () => {
48
+ this.CONSUME(NamespaceKw);
49
+ this.SUBRULE(this.nsid);
50
+ this.CONSUME(LCurly);
51
+ this.MANY(() => this.SUBRULE(this.typeDecl));
52
+ this.CONSUME(RCurly);
53
+ });
54
+ nsid = this.RULE('nsid', () => {
55
+ this.CONSUME(Identifier);
56
+ this.MANY(() => {
57
+ this.CONSUME(Dot);
58
+ this.CONSUME2(Identifier);
59
+ });
60
+ });
61
+ typeDecl = this.RULE('typeDecl', () => {
62
+ this.MANY(() => this.SUBRULE(this.attribute));
63
+ this.CONSUME(TypeKw);
64
+ this.CONSUME(Identifier);
65
+ this.CONSUME(LCurly);
66
+ this.MANY2(() => this.SUBRULE(this.typeMember));
67
+ this.CONSUME(RCurly);
68
+ });
69
+ typeMember = this.RULE('typeMember', () => {
70
+ this.OR([
71
+ { ALT: () => this.SUBRULE(this.field) },
72
+ {
73
+ ALT: () => this.SUBRULE(this.paramsBlock),
74
+ GATE: () => this.laSectionBlock(ParamsKw),
75
+ },
76
+ {
77
+ ALT: () => this.SUBRULE(this.inputBlock),
78
+ GATE: () => this.laSectionBlock(InputKw),
79
+ },
80
+ {
81
+ ALT: () => this.SUBRULE(this.outputBlock),
82
+ GATE: () => this.laSectionBlock(OutputKw),
83
+ },
84
+ {
85
+ ALT: () => this.SUBRULE(this.messageBlock),
86
+ GATE: () => this.laSectionBlock(MessageKw),
87
+ },
88
+ {
89
+ ALT: () => this.SUBRULE(this.errorsBlock),
90
+ GATE: () => this.laSectionBlock(ErrorsKw),
91
+ },
92
+ {
93
+ ALT: () => this.SUBRULE(this.permissionsBlock),
94
+ GATE: () => this.laSectionBlock(PermissionsKw),
95
+ },
96
+ ]);
97
+ });
98
+ /** Section keywords are also valid field names; only treat them as blocks when followed by `{`. */
99
+ laSectionBlock = (kw) => {
100
+ return this.LA(1)?.tokenType === kw && this.LA(2)?.tokenType === LCurly;
101
+ };
102
+ paramsBlock = this.RULE('paramsBlock', () => {
103
+ this.CONSUME(ParamsKw);
104
+ this.CONSUME(LCurly);
105
+ this.MANY(() => this.SUBRULE(this.field));
106
+ this.CONSUME(RCurly);
107
+ });
108
+ inputBlock = this.RULE('inputBlock', () => {
109
+ this.CONSUME(InputKw);
110
+ this.CONSUME(LCurly);
111
+ this.MANY(() => this.SUBRULE(this.ioMember));
112
+ this.CONSUME(RCurly);
113
+ });
114
+ outputBlock = this.RULE('outputBlock', () => {
115
+ this.CONSUME(OutputKw);
116
+ this.CONSUME(LCurly);
117
+ this.MANY(() => this.SUBRULE(this.ioMember));
118
+ this.CONSUME(RCurly);
119
+ });
120
+ ioMember = this.RULE('ioMember', () => {
121
+ this.OR([
122
+ {
123
+ ALT: () => {
124
+ this.CONSUME(EncodingKw);
125
+ this.CONSUME(Colon);
126
+ this.CONSUME(StringLiteral);
127
+ },
128
+ },
129
+ {
130
+ ALT: () => {
131
+ this.CONSUME(SchemaKw);
132
+ this.OR2([
133
+ {
134
+ ALT: () => {
135
+ this.CONSUME2(Colon);
136
+ this.SUBRULE(this.typeExpr);
137
+ },
138
+ },
139
+ {
140
+ ALT: () => {
141
+ this.CONSUME(LCurly);
142
+ this.MANY(() => this.SUBRULE(this.field));
143
+ this.CONSUME(RCurly);
144
+ },
145
+ },
146
+ ]);
147
+ },
148
+ },
149
+ ]);
150
+ });
151
+ messageBlock = this.RULE('messageBlock', () => {
152
+ this.CONSUME(MessageKw);
153
+ this.CONSUME(LCurly);
154
+ this.CONSUME(SchemaKw);
155
+ this.CONSUME(Colon);
156
+ this.SUBRULE(this.typeExpr);
157
+ this.CONSUME(RCurly);
158
+ });
159
+ errorsBlock = this.RULE('errorsBlock', () => {
160
+ this.CONSUME(ErrorsKw);
161
+ this.CONSUME(LCurly);
162
+ this.OPTION(() => {
163
+ this.SUBRULE(this.errorItem);
164
+ this.MANY(() => {
165
+ this.OPTION2(() => this.CONSUME(Comma));
166
+ this.SUBRULE2(this.errorItem);
167
+ });
168
+ });
169
+ this.CONSUME(RCurly);
170
+ });
171
+ errorItem = this.RULE('errorItem', () => {
172
+ this.CONSUME(Identifier);
173
+ this.OPTION(() => {
174
+ this.CONSUME(Colon);
175
+ this.CONSUME(StringLiteral);
176
+ });
177
+ });
178
+ permissionsBlock = this.RULE('permissionsBlock', () => {
179
+ this.CONSUME(PermissionsKw);
180
+ this.CONSUME(LCurly);
181
+ this.MANY(() => this.SUBRULE(this.permissionEntry));
182
+ this.CONSUME(RCurly);
183
+ });
184
+ permissionEntry = this.RULE('permissionEntry', () => {
185
+ this.CONSUME(Identifier);
186
+ this.CONSUME(LCurly);
187
+ this.MANY(() => this.SUBRULE(this.permissionProp));
188
+ this.CONSUME(RCurly);
189
+ });
190
+ permissionProp = this.RULE('permissionProp', () => {
191
+ this.CONSUME(Identifier);
192
+ this.CONSUME(Colon);
193
+ this.OR([
194
+ { ALT: () => this.CONSUME(StringLiteral) },
195
+ { ALT: () => this.CONSUME(BooleanLiteral) },
196
+ {
197
+ ALT: () => {
198
+ this.CONSUME(LBracket);
199
+ this.OPTION(() => {
200
+ this.CONSUME2(StringLiteral);
201
+ this.MANY(() => {
202
+ this.CONSUME(Comma);
203
+ this.CONSUME3(StringLiteral);
204
+ });
205
+ });
206
+ this.CONSUME(RBracket);
207
+ },
208
+ },
209
+ ]);
210
+ });
211
+ attribute = this.RULE('attribute', () => {
212
+ this.CONSUME(At);
213
+ this.CONSUME(Identifier);
214
+ this.OPTION(() => {
215
+ this.CONSUME(LParen);
216
+ this.OPTION2(() => {
217
+ this.SUBRULE(this.attrArg);
218
+ this.MANY(() => {
219
+ this.CONSUME(Comma);
220
+ this.SUBRULE2(this.attrArg);
221
+ });
222
+ });
223
+ this.CONSUME(RParen);
224
+ });
225
+ });
226
+ attrArg = this.RULE('attrArg', () => {
227
+ this.OR([
228
+ { ALT: () => this.CONSUME(StringLiteral) },
229
+ { ALT: () => this.CONSUME(NumberLiteral) },
230
+ { ALT: () => this.CONSUME(BooleanLiteral) },
231
+ {
232
+ ALT: () => {
233
+ this.CONSUME(LBracket);
234
+ this.OPTION(() => {
235
+ this.SUBRULE(this.attrArg);
236
+ this.MANY(() => {
237
+ this.CONSUME(Comma);
238
+ this.SUBRULE2(this.attrArg);
239
+ });
240
+ });
241
+ this.CONSUME(RBracket);
242
+ },
243
+ },
244
+ ]);
245
+ });
246
+ fieldName = this.RULE('fieldName', () => {
247
+ this.OR([
248
+ { ALT: () => this.CONSUME(Identifier) },
249
+ { ALT: () => this.CONSUME(ParamsKw) },
250
+ { ALT: () => this.CONSUME(InputKw) },
251
+ { ALT: () => this.CONSUME(OutputKw) },
252
+ { ALT: () => this.CONSUME(MessageKw) },
253
+ { ALT: () => this.CONSUME(ErrorsKw) },
254
+ { ALT: () => this.CONSUME(PermissionsKw) },
255
+ ]);
256
+ });
257
+ field = this.RULE('field', () => {
258
+ this.MANY(() => this.SUBRULE(this.attribute));
259
+ this.SUBRULE(this.fieldName);
260
+ this.OPTION(() => this.CONSUME(Question));
261
+ this.CONSUME(Colon);
262
+ this.SUBRULE(this.typeExpr);
263
+ });
264
+ typeExpr = this.RULE('typeExpr', () => {
265
+ this.SUBRULE(this.typeExprInner);
266
+ this.OPTION(() => {
267
+ this.CONSUME(LBracket);
268
+ this.CONSUME(RBracket);
269
+ });
270
+ });
271
+ typeExprInner = this.RULE('typeExprInner', () => {
272
+ this.OR([
273
+ {
274
+ ALT: () => {
275
+ this.OPTION(() => this.CONSUME(ClosedKw));
276
+ this.CONSUME(UnionKw);
277
+ this.CONSUME(LParen);
278
+ this.SUBRULE(this.typeExpr);
279
+ this.MANY(() => {
280
+ this.CONSUME(Comma);
281
+ this.SUBRULE2(this.typeExpr);
282
+ });
283
+ this.CONSUME(RParen);
284
+ },
285
+ },
286
+ {
287
+ ALT: () => {
288
+ this.SUBRULE(this.typeAtom);
289
+ },
290
+ },
291
+ {
292
+ ALT: () => {
293
+ this.CONSUME(LCurly);
294
+ this.MANY3(() => this.SUBRULE(this.field));
295
+ this.CONSUME(RCurly);
296
+ },
297
+ },
298
+ ]);
299
+ });
300
+ typeAtom = this.RULE('typeAtom', () => {
301
+ this.OR([
302
+ {
303
+ ALT: () => {
304
+ this.CONSUME(Hash);
305
+ this.CONSUME(Identifier);
306
+ },
307
+ },
308
+ {
309
+ ALT: () => {
310
+ this.SUBRULE(this.nsid);
311
+ this.OPTION(() => {
312
+ this.CONSUME2(Hash);
313
+ this.CONSUME2(Identifier);
314
+ });
315
+ },
316
+ },
317
+ ]);
318
+ });
319
+ }
320
+ const parser = new LexdParser();
321
+ export class LexdSyntaxError extends Error {
322
+ span;
323
+ constructor(message, span) {
324
+ super(message);
325
+ this.span = span;
326
+ this.name = 'LexdSyntaxError';
327
+ }
328
+ }
329
+ function tokenSpan(token) {
330
+ return {
331
+ startOffset: token.startOffset,
332
+ endOffset: token.endOffset ?? token.startOffset,
333
+ startLine: token.startLine ?? 1,
334
+ startColumn: token.startColumn ?? 1,
335
+ endLine: token.endLine ?? token.startLine ?? 1,
336
+ endColumn: token.endColumn ?? token.startColumn ?? 1,
337
+ };
338
+ }
339
+ function mergeSpan(a, b) {
340
+ if (!a)
341
+ return b;
342
+ if (!b)
343
+ return a;
344
+ return {
345
+ startOffset: a.startOffset,
346
+ endOffset: b.endOffset,
347
+ startLine: a.startLine,
348
+ startColumn: a.startColumn,
349
+ endLine: b.endLine,
350
+ endColumn: b.endColumn,
351
+ };
352
+ }
353
+ function unquote(raw) {
354
+ const q = raw[0];
355
+ const body = raw.slice(1, -1);
356
+ if (q === '"') {
357
+ return body.replace(/\\(["\\nrt])/g, (_, c) => {
358
+ if (c === 'n')
359
+ return '\n';
360
+ if (c === 'r')
361
+ return '\r';
362
+ if (c === 't')
363
+ return '\t';
364
+ return c;
365
+ });
366
+ }
367
+ return body.replace(/\\(['\\nrt])/g, (_, c) => {
368
+ if (c === 'n')
369
+ return '\n';
370
+ if (c === 'r')
371
+ return '\r';
372
+ if (c === 't')
373
+ return '\t';
374
+ return c;
375
+ });
376
+ }
377
+ function parseAttrValue(cst) {
378
+ const children = cst.children;
379
+ if (children['StringLiteral']) {
380
+ return unquote(children['StringLiteral'][0].image);
381
+ }
382
+ if (children['NumberLiteral']) {
383
+ return Number(children['NumberLiteral'][0].image);
384
+ }
385
+ if (children['BooleanLiteral']) {
386
+ return children['BooleanLiteral'][0].image === 'true';
387
+ }
388
+ const nested = children['attrArg'];
389
+ if (nested) {
390
+ return nested.map(parseAttrValue);
391
+ }
392
+ return [];
393
+ }
394
+ function buildAttribute(cst) {
395
+ const nameTok = cst.children['Identifier'][0];
396
+ const args = cst.children['attrArg']?.map(parseAttrValue) ?? [];
397
+ return {
398
+ name: nameTok.image,
399
+ args,
400
+ span: tokenSpan(nameTok),
401
+ };
402
+ }
403
+ function buildNsid(cst) {
404
+ const ids = cst.children['Identifier'];
405
+ const name = ids.map((t) => t.image).join('.');
406
+ const first = ids[0];
407
+ const last = ids[ids.length - 1];
408
+ return {
409
+ name,
410
+ span: mergeSpan(tokenSpan(first), tokenSpan(last)),
411
+ };
412
+ }
413
+ function buildImportBinding(cst) {
414
+ const ids = cst.children['Identifier'];
415
+ const imported = ids[0].image;
416
+ const local = ids[1]?.image ?? imported;
417
+ return { imported, local };
418
+ }
419
+ function buildImportDecl(cst) {
420
+ if (cst.children['StringLiteral']) {
421
+ const module = unquote(cst.children['StringLiteral'][0].image);
422
+ const bindings = cst.children['importBinding'].map(buildImportBinding);
423
+ return {
424
+ kind: 'named',
425
+ module,
426
+ bindings: bindings.map((b) => ({
427
+ local: b.local,
428
+ imported: b.imported,
429
+ })),
430
+ };
431
+ }
432
+ const nsid = buildNsid(cst.children['nsid'][0]);
433
+ const aliasTok = cst.children['Identifier']?.[0];
434
+ const local = aliasTok?.image ?? nsid.name.split('.').pop();
435
+ return {
436
+ kind: 'whole',
437
+ module: nsid.name,
438
+ bindings: [{ local, imported: 'main' }],
439
+ span: nsid.span,
440
+ };
441
+ }
442
+ function buildTypeAtom(cst) {
443
+ if (!cst.children['nsid']) {
444
+ const id = cst.children['Identifier'][0];
445
+ return { kind: 'ref', name: `#${id.image}`, span: tokenSpan(id) };
446
+ }
447
+ const nsid = buildNsid(cst.children['nsid'][0]);
448
+ const fragTok = cst.children['Identifier']?.[0];
449
+ if (fragTok) {
450
+ return {
451
+ kind: 'ref',
452
+ name: `${nsid.name}#${fragTok.image}`,
453
+ span: mergeSpan(nsid.span, tokenSpan(fragTok)),
454
+ };
455
+ }
456
+ if (PRIMITIVES.has(nsid.name)) {
457
+ return {
458
+ kind: 'primitive',
459
+ name: nsid.name,
460
+ span: nsid.span,
461
+ };
462
+ }
463
+ return { kind: 'ref', name: nsid.name, span: nsid.span };
464
+ }
465
+ function buildTypeExpr(cst) {
466
+ const inner = buildTypeExprInner(cst.children['typeExprInner'][0]);
467
+ if (cst.children['LBracket']) {
468
+ return { kind: 'array', element: inner, span: inner.span };
469
+ }
470
+ return inner;
471
+ }
472
+ function buildTypeExprInner(cst) {
473
+ if (cst.children['UnionKw']) {
474
+ const parts = cst.children['typeExpr'];
475
+ return {
476
+ kind: 'union',
477
+ refs: parts.map(buildTypeExpr),
478
+ closed: Boolean(cst.children['ClosedKw']),
479
+ span: tokenSpan(cst.children['UnionKw'][0]),
480
+ };
481
+ }
482
+ if (cst.children['LCurly']) {
483
+ const fields = cst.children['field']?.map(buildField) ?? [];
484
+ const lcurly = cst.children['LCurly'][0];
485
+ const rcurly = cst.children['RCurly'][0];
486
+ return { kind: 'inline', fields, span: mergeSpan(tokenSpan(lcurly), tokenSpan(rcurly)) };
487
+ }
488
+ return buildTypeAtom(cst.children['typeAtom'][0]);
489
+ }
490
+ function fieldNameToken(cst) {
491
+ const nameNodes = cst.children['fieldName'];
492
+ if (!nameNodes?.length) {
493
+ throw new Error('Internal: field CST missing fieldName child');
494
+ }
495
+ for (const node of nameNodes) {
496
+ for (const key of [
497
+ 'Identifier',
498
+ 'ParamsKw',
499
+ 'InputKw',
500
+ 'OutputKw',
501
+ 'MessageKw',
502
+ 'ErrorsKw',
503
+ 'PermissionsKw',
504
+ ]) {
505
+ const tok = node.children[key]?.[0];
506
+ if (tok)
507
+ return tok;
508
+ }
509
+ }
510
+ throw new Error('field missing name');
511
+ }
512
+ function buildField(cst) {
513
+ const attrs = cst.children['attribute']?.map(buildAttribute) ?? [];
514
+ const nameTok = fieldNameToken(cst);
515
+ const optional = Boolean(cst.children['Question']);
516
+ const type = buildTypeExpr(cst.children['typeExpr'][0]);
517
+ return {
518
+ name: nameTok.image,
519
+ optional,
520
+ type,
521
+ attributes: attrs,
522
+ span: tokenSpan(nameTok),
523
+ };
524
+ }
525
+ function buildErrorItem(cst) {
526
+ const nameTok = cst.children['Identifier'][0];
527
+ const descTok = cst.children['StringLiteral']?.[0];
528
+ return {
529
+ name: nameTok.image,
530
+ description: descTok ? unquote(descTok.image) : undefined,
531
+ span: tokenSpan(nameTok),
532
+ };
533
+ }
534
+ function buildIoMembers(members) {
535
+ let encoding;
536
+ let schema;
537
+ for (const m of members ?? []) {
538
+ if (m.children['EncodingKw']) {
539
+ encoding = unquote(m.children['StringLiteral'][0].image);
540
+ }
541
+ else if (m.children['SchemaKw']) {
542
+ if (m.children['typeExpr']) {
543
+ schema = { kind: 'type', type: buildTypeExpr(m.children['typeExpr'][0]) };
544
+ }
545
+ else {
546
+ const fields = m.children['field']?.map(buildField) ?? [];
547
+ schema = { kind: 'inline', fields };
548
+ }
549
+ }
550
+ }
551
+ return { encoding, schema };
552
+ }
553
+ function buildPermissionEntry(cst) {
554
+ const resourceTok = cst.children['Identifier'][0];
555
+ const resourceName = resourceTok.image;
556
+ if (resourceName !== 'rpc' && resourceName !== 'repo') {
557
+ throw new LexdSyntaxError(`permission resource must be rpc or repo, got "${resourceName}"`, tokenSpan(resourceTok));
558
+ }
559
+ const props = {};
560
+ for (const p of cst.children['permissionProp'] ?? []) {
561
+ const key = p.children['Identifier'][0].image;
562
+ if (p.children['BooleanLiteral']) {
563
+ props[key] = p.children['BooleanLiteral'][0].image === 'true';
564
+ }
565
+ else if (p.children['LBracket']) {
566
+ const strs = p.children['StringLiteral'] ?? [];
567
+ props[key] = strs.map((t) => unquote(t.image));
568
+ }
569
+ else if (p.children['StringLiteral']) {
570
+ props[key] = unquote(p.children['StringLiteral'][0].image);
571
+ }
572
+ }
573
+ return { resource: resourceName, props };
574
+ }
575
+ function buildTypeMember(cst) {
576
+ if (cst.children['paramsBlock']) {
577
+ const b = cst.children['paramsBlock'][0];
578
+ return {
579
+ block: {
580
+ kind: 'params',
581
+ fields: b.children['field']?.map(buildField) ?? [],
582
+ },
583
+ };
584
+ }
585
+ if (cst.children['inputBlock']) {
586
+ const b = cst.children['inputBlock'][0];
587
+ const { encoding, schema } = buildIoMembers(b.children['ioMember']);
588
+ const block = { kind: 'input', encoding, schema };
589
+ return { block };
590
+ }
591
+ if (cst.children['outputBlock']) {
592
+ const b = cst.children['outputBlock'][0];
593
+ const { encoding, schema } = buildIoMembers(b.children['ioMember']);
594
+ const block = { kind: 'output', encoding, schema };
595
+ return { block };
596
+ }
597
+ if (cst.children['messageBlock']) {
598
+ const b = cst.children['messageBlock'][0];
599
+ const block = {
600
+ kind: 'message',
601
+ schema: buildTypeExpr(b.children['typeExpr'][0]),
602
+ };
603
+ return { block };
604
+ }
605
+ if (cst.children['errorsBlock']) {
606
+ const b = cst.children['errorsBlock'][0];
607
+ return {
608
+ block: {
609
+ kind: 'errors',
610
+ errors: b.children['errorItem']?.map(buildErrorItem) ?? [],
611
+ },
612
+ };
613
+ }
614
+ if (cst.children['permissionsBlock']) {
615
+ const b = cst.children['permissionsBlock'][0];
616
+ const block = {
617
+ kind: 'permissions',
618
+ entries: b.children['permissionEntry']?.map(buildPermissionEntry) ?? [],
619
+ };
620
+ return { block };
621
+ }
622
+ return { field: buildField(cst.children['field'][0]) };
623
+ }
624
+ function buildTypeDecl(cst) {
625
+ const attrs = cst.children['attribute']?.map(buildAttribute) ?? [];
626
+ const nameTok = cst.children['Identifier'][0];
627
+ const members = cst.children['typeMember'] ?? [];
628
+ const fields = [];
629
+ const blocks = [];
630
+ for (const m of members) {
631
+ const built = buildTypeMember(m);
632
+ if (built.field)
633
+ fields.push(built.field);
634
+ if (built.block)
635
+ blocks.push(built.block);
636
+ }
637
+ const primary = attrs.some((a) => PRIMARY_ATTRS.has(a.name));
638
+ const isToken = attrs.some((a) => a.name === 'token');
639
+ const isScalar = attrs.some((a) => a.name === 'scalar');
640
+ return {
641
+ name: nameTok.image,
642
+ attributes: attrs,
643
+ fields,
644
+ blocks,
645
+ primary,
646
+ isToken,
647
+ isScalar,
648
+ span: tokenSpan(nameTok),
649
+ };
650
+ }
651
+ function buildNamespace(cst) {
652
+ const nsid = buildNsid(cst.children['nsid'][0]);
653
+ const types = cst.children['typeDecl']?.map(buildTypeDecl) ?? [];
654
+ return {
655
+ name: nsid.name,
656
+ types,
657
+ span: nsid.span,
658
+ };
659
+ }
660
+ export function parseLexd(source, filename) {
661
+ const lexResult = lexdLexer.tokenize(source);
662
+ if (lexResult.errors.length > 0) {
663
+ const err = lexResult.errors[0];
664
+ throw new LexdSyntaxError(err.message, {
665
+ startOffset: err.offset,
666
+ endOffset: err.offset + (err.length ?? 0),
667
+ startLine: err.line ?? 1,
668
+ startColumn: err.column ?? 1,
669
+ endLine: err.line ?? 1,
670
+ endColumn: (err.column ?? 1) + (err.length ?? 0),
671
+ });
672
+ }
673
+ parser.input = lexResult.tokens;
674
+ const cst = parser.file();
675
+ if (parser.errors.length > 0) {
676
+ const err = parser.errors[0];
677
+ const tok = err.token;
678
+ throw new LexdSyntaxError(err.message, tok ? tokenSpan(tok) : undefined);
679
+ }
680
+ const imports = cst.children['importDecl']?.map(buildImportDecl) ?? [];
681
+ const namespaces = cst.children['namespaceDecl']?.map(buildNamespace) ?? [];
682
+ return { imports, namespaces, filename };
683
+ }
684
+ //# sourceMappingURL=parser.js.map