@ohm-js/wasm 0.4.3 → 0.6.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.
- package/README.md +11 -0
- package/dist/build/ohmRuntime.wasm_sections.d.ts +39 -0
- package/dist/build/ohmRuntime.wasm_sections.js +47 -0
- package/dist/index.d.ts +4 -8
- package/dist/index.js +4 -2243
- package/dist/src/AstBuilder.d.ts +17 -0
- package/dist/src/AstBuilder.js +143 -0
- package/dist/src/Compiler.d.ts +195 -0
- package/dist/src/Compiler.js +1559 -0
- package/dist/src/assert.d.ts +3 -0
- package/dist/src/assert.js +9 -0
- package/dist/src/cli.d.ts +2 -0
- package/dist/src/cli.js +56 -0
- package/dist/src/compat.d.ts +4 -0
- package/dist/src/compat.js +18 -0
- package/dist/src/ir.d.ts +121 -0
- package/dist/src/ir.js +297 -0
- package/dist/src/miniohm.d.ts +87 -0
- package/dist/src/miniohm.js +418 -0
- package/package.json +10 -5
- package/dist/cli.js +0 -2292
- package/dist/tsconfig.tsbuildinfo +0 -1
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
import { assert, checkNotNull } from "./assert.js";
|
|
2
|
+
const CST_NODE_TYPE_MASK = 0b11;
|
|
3
|
+
const CstNodeType = {
|
|
4
|
+
NONTERMINAL: 0,
|
|
5
|
+
TERMINAL: 1,
|
|
6
|
+
ITER_FLAG: 2,
|
|
7
|
+
OPTIONAL: 3,
|
|
8
|
+
};
|
|
9
|
+
const compileOptions = {
|
|
10
|
+
builtins: ['js-string'],
|
|
11
|
+
};
|
|
12
|
+
// Bit flags for Unicode categories, based on the order that they appear in
|
|
13
|
+
// https://www.unicode.org/Public/16.0.0/ucd/extracted/DerivedGeneralCategory.txt
|
|
14
|
+
const UnicodeCategoryNames = [
|
|
15
|
+
'Cn', // Unassigned
|
|
16
|
+
'Lu', // Uppercase_Letter
|
|
17
|
+
'Ll', // Lowercase_Letter
|
|
18
|
+
'Lt', // Titlecase_Letter
|
|
19
|
+
'Lm', // Modifier_Letter
|
|
20
|
+
'Lo', // Other_Letter
|
|
21
|
+
];
|
|
22
|
+
const utf8 = new TextDecoder('utf-8');
|
|
23
|
+
function regexFromCategoryBitmap(bitmap) {
|
|
24
|
+
const cats = [];
|
|
25
|
+
for (let i = 0; i < 32; i++) {
|
|
26
|
+
const mask = 1 << i;
|
|
27
|
+
if (bitmap & mask)
|
|
28
|
+
cats.push(UnicodeCategoryNames[i]);
|
|
29
|
+
}
|
|
30
|
+
return new RegExp(cats.map(cat => `\\p{${cat}}`).join('|'), 'uy' // u: unicode, y: sticky
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
export class WasmGrammar {
|
|
34
|
+
name = '';
|
|
35
|
+
_instance = undefined;
|
|
36
|
+
_imports = {
|
|
37
|
+
// System-level AssemblyScript imports.
|
|
38
|
+
env: {
|
|
39
|
+
abort( /* message: usize, fileName: usize, line: u32, column: u32 */) {
|
|
40
|
+
throw new Error('abort');
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
// For imports from ohmRuntime.ts.
|
|
44
|
+
ohmRuntime: {
|
|
45
|
+
printI32(val) {
|
|
46
|
+
// eslint-disable-next-line no-console
|
|
47
|
+
console.log(val);
|
|
48
|
+
},
|
|
49
|
+
isRuleSyntactic: (ruleId) => {
|
|
50
|
+
// TODO: Precompute this for all rules, and encode it in the module?
|
|
51
|
+
const name = this._ruleNames[ruleId];
|
|
52
|
+
assert(!!name);
|
|
53
|
+
return name[0] === name[0].toUpperCase();
|
|
54
|
+
},
|
|
55
|
+
fillInputBuffer: this._fillInputBuffer.bind(this),
|
|
56
|
+
matchUnicodeChar: (catBitmap) => {
|
|
57
|
+
const { input, pos } = this._instance.exports;
|
|
58
|
+
const re = regexFromCategoryBitmap(catBitmap);
|
|
59
|
+
re.lastIndex = pos;
|
|
60
|
+
const arr = re.exec(input.value);
|
|
61
|
+
if (arr) {
|
|
62
|
+
pos.value += arr[0].length;
|
|
63
|
+
}
|
|
64
|
+
return !!arr;
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
// Include a polyfill for js-string builtins for engines that don't
|
|
68
|
+
// support that feature (e.g., Safari).
|
|
69
|
+
'wasm:js-string': {
|
|
70
|
+
length(str) {
|
|
71
|
+
return str.length;
|
|
72
|
+
},
|
|
73
|
+
charCodeAt(str, idx) {
|
|
74
|
+
// NOTE: `index` is interpreted as a signed 32-bit integer when converted to
|
|
75
|
+
// a JS value using standard conversions. Reinterpret as unsigned here.
|
|
76
|
+
idx >>>= 0;
|
|
77
|
+
assert(idx < str.length, 'string index out of bounds');
|
|
78
|
+
return str.charCodeAt(idx);
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
_ruleIds = new Map();
|
|
83
|
+
_ruleNames = [];
|
|
84
|
+
_input = '';
|
|
85
|
+
_resultStack = [];
|
|
86
|
+
_managedResultCount = 0;
|
|
87
|
+
/**
|
|
88
|
+
* Create a new WasmGrammar object.
|
|
89
|
+
* If `bytes` is specified, the WebAssembly module will be synchronously
|
|
90
|
+
* compiled and instantiated. Use `instantiate` or `instantiateStreaming`
|
|
91
|
+
* to instantiate asynchronously.
|
|
92
|
+
*/
|
|
93
|
+
constructor(bytes) {
|
|
94
|
+
if (bytes) {
|
|
95
|
+
// @ts-expect-error: TS2554: Expected 1 arguments, but got 2.
|
|
96
|
+
const mod = new WebAssembly.Module(bytes, compileOptions);
|
|
97
|
+
this._init(mod, new WebAssembly.Instance(mod, this._imports));
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
_init(module, instance) {
|
|
101
|
+
this._instance = instance;
|
|
102
|
+
this._extractRuleIds(module);
|
|
103
|
+
this.name = this._getGrammarName(module);
|
|
104
|
+
return this;
|
|
105
|
+
}
|
|
106
|
+
_beginUse(result) {
|
|
107
|
+
assert(this._resultStack.at(-1) === result, `You can only use() the most recent MatchResult`);
|
|
108
|
+
result.detach = () => {
|
|
109
|
+
throw new Error("MatchResult shouldn't be detached inside use()");
|
|
110
|
+
};
|
|
111
|
+
this._managedResultCount++;
|
|
112
|
+
}
|
|
113
|
+
_endUse(result) {
|
|
114
|
+
const r = this._resultStack.pop();
|
|
115
|
+
assert(r === result, 'Mismatched _endUse');
|
|
116
|
+
this._managedResultCount--;
|
|
117
|
+
if (this._resultStack.length === 0) {
|
|
118
|
+
this._instance.exports.resetHeap();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
static async instantiate(source) {
|
|
122
|
+
return new WasmGrammar()._instantiate(source);
|
|
123
|
+
}
|
|
124
|
+
static async instantiateStreaming(source) {
|
|
125
|
+
return new WasmGrammar()._instantiateStreaming(source);
|
|
126
|
+
}
|
|
127
|
+
async _instantiate(source, debugImports = {}) {
|
|
128
|
+
const { module, instance } = await WebAssembly.instantiate(source, {
|
|
129
|
+
...this._imports,
|
|
130
|
+
debug: debugImports,
|
|
131
|
+
},
|
|
132
|
+
// @ts-expect-error: Expected 1-2 arguments, but got 3.
|
|
133
|
+
compileOptions);
|
|
134
|
+
return this._init(module, instance);
|
|
135
|
+
}
|
|
136
|
+
async _instantiateStreaming(source, debugImports = {}) {
|
|
137
|
+
const { module, instance } = await WebAssembly.instantiateStreaming(source, {
|
|
138
|
+
...this._imports,
|
|
139
|
+
debug: debugImports,
|
|
140
|
+
},
|
|
141
|
+
// @ts-expect-error: TS2554: Expected 1-2 arguments, but got 3.
|
|
142
|
+
compileOptions);
|
|
143
|
+
return this._init(module, instance);
|
|
144
|
+
}
|
|
145
|
+
_getGrammarName(module) {
|
|
146
|
+
const sections = WebAssembly.Module.customSections(module, 'name');
|
|
147
|
+
assert(sections.length === 1, `Expected one name section, found ${sections.length}`);
|
|
148
|
+
const data = new Uint8Array(sections[0]);
|
|
149
|
+
const decoder = new TextDecoder('utf-8');
|
|
150
|
+
return decoder.decode(data);
|
|
151
|
+
}
|
|
152
|
+
_extractRuleIds(module) {
|
|
153
|
+
const sections = WebAssembly.Module.customSections(module, 'ruleNames');
|
|
154
|
+
assert(sections.length === 1, `Expected one ruleNames section, found ${sections.length}`);
|
|
155
|
+
const data = new Uint8Array(sections[0]);
|
|
156
|
+
const dataView = new DataView(data.buffer);
|
|
157
|
+
let offset = 0;
|
|
158
|
+
const parseU32 = () => {
|
|
159
|
+
// Quick 'n dirty ULeb128 parsing, assuming no more than 2 bytes.
|
|
160
|
+
const b1 = dataView.getUint8(offset++);
|
|
161
|
+
let value = b1 & 0x7f;
|
|
162
|
+
if (b1 & 0x80) {
|
|
163
|
+
const b2 = dataView.getUint8(offset++);
|
|
164
|
+
assert((b2 & 0x80) === 0, 'Expected max two bytes');
|
|
165
|
+
value |= (b2 & 0x7f) << 7;
|
|
166
|
+
}
|
|
167
|
+
return value;
|
|
168
|
+
};
|
|
169
|
+
const decoder = new TextDecoder('utf-8');
|
|
170
|
+
const numEntries = parseU32();
|
|
171
|
+
for (let i = 0; i < numEntries; i++) {
|
|
172
|
+
const stringLen = parseU32();
|
|
173
|
+
const bytes = data.slice(offset, offset + stringLen);
|
|
174
|
+
offset += stringLen;
|
|
175
|
+
const name = decoder.decode(bytes);
|
|
176
|
+
this._ruleIds.set(name, i);
|
|
177
|
+
this._ruleNames.push(name);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
_detachMatchResult(result) {
|
|
181
|
+
assert(this._resultStack.at(-1) === result, `You can only detach() the most recent MatchResult`);
|
|
182
|
+
this._beginUse(result);
|
|
183
|
+
this._endUse(result);
|
|
184
|
+
}
|
|
185
|
+
match(input, ruleName) {
|
|
186
|
+
assert(this._resultStack.length === this._managedResultCount, 'Cannot match while there are unmanaged MatchResults');
|
|
187
|
+
this._input = input;
|
|
188
|
+
if (process.env.OHM_DEBUG === '1')
|
|
189
|
+
debugger; // eslint-disable-line no-debugger
|
|
190
|
+
const ruleId = checkNotNull(this._ruleIds.get(ruleName || this._ruleNames[0]), `unknown rule: '${ruleName}'`);
|
|
191
|
+
const succeeded = this._instance.exports.match(input, ruleId);
|
|
192
|
+
const result = new MatchResult(this, this._input, ruleName || this._ruleNames[0], succeeded ? this.getCstRoot() : null, this.getRightmostFailurePosition());
|
|
193
|
+
result.detach = this._detachMatchResult.bind(this, result);
|
|
194
|
+
this._resultStack.push(result);
|
|
195
|
+
return result;
|
|
196
|
+
}
|
|
197
|
+
getMemorySizeBytes() {
|
|
198
|
+
return this._instance.exports.memory.buffer.byteLength;
|
|
199
|
+
}
|
|
200
|
+
getCstRoot() {
|
|
201
|
+
const { exports } = this._instance;
|
|
202
|
+
const { buffer } = exports.memory;
|
|
203
|
+
const firstNode = new CstNode(this._ruleNames, new DataView(buffer), exports.bindingsAt(0), exports.input.value, 0);
|
|
204
|
+
if (firstNode.ctorName !== '$spaces') {
|
|
205
|
+
return firstNode;
|
|
206
|
+
}
|
|
207
|
+
assert(exports.getBindingsLength() > 1);
|
|
208
|
+
const nextAddr = exports.bindingsAt(1);
|
|
209
|
+
const root = new CstNode(this._ruleNames, new DataView(buffer), nextAddr, exports.input.value, firstNode.matchLength);
|
|
210
|
+
root.leadingSpaces = firstNode;
|
|
211
|
+
return root;
|
|
212
|
+
}
|
|
213
|
+
_fillInputBuffer(ptr, length) {
|
|
214
|
+
const encoder = new TextEncoder();
|
|
215
|
+
const { memory } = this._instance.exports;
|
|
216
|
+
const buf = new Uint8Array(memory.buffer, ptr, length);
|
|
217
|
+
const { read, written } = encoder.encodeInto(this._input, buf);
|
|
218
|
+
assert(read === this._input.length, 'Input was not fully read');
|
|
219
|
+
return written;
|
|
220
|
+
}
|
|
221
|
+
getRightmostFailurePosition() {
|
|
222
|
+
return this._instance.exports.rightmostFailurePos.value;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
export class CstNode {
|
|
226
|
+
_ruleNames;
|
|
227
|
+
_view;
|
|
228
|
+
_children;
|
|
229
|
+
_base;
|
|
230
|
+
_input;
|
|
231
|
+
startIdx;
|
|
232
|
+
leadingSpaces;
|
|
233
|
+
source;
|
|
234
|
+
constructor(ruleNames, dataView, ptr, input, startIdx) {
|
|
235
|
+
// Non-enumerable properties
|
|
236
|
+
Object.defineProperties(this, {
|
|
237
|
+
_ruleNames: { value: ruleNames },
|
|
238
|
+
_view: { value: dataView },
|
|
239
|
+
_children: { writable: true },
|
|
240
|
+
});
|
|
241
|
+
this._base = ptr;
|
|
242
|
+
this._input = input;
|
|
243
|
+
this.startIdx = startIdx;
|
|
244
|
+
this.leadingSpaces = undefined;
|
|
245
|
+
this.source = {
|
|
246
|
+
startIdx,
|
|
247
|
+
endIdx: startIdx + this.sourceString.length,
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
get type() {
|
|
251
|
+
return this._typeAndDetails & CST_NODE_TYPE_MASK;
|
|
252
|
+
}
|
|
253
|
+
isNonterminal() {
|
|
254
|
+
return this.type === CstNodeType.NONTERMINAL;
|
|
255
|
+
}
|
|
256
|
+
isTerminal() {
|
|
257
|
+
return this.type === CstNodeType.TERMINAL;
|
|
258
|
+
}
|
|
259
|
+
isIter() {
|
|
260
|
+
return (this._typeAndDetails & CstNodeType.ITER_FLAG) !== 0;
|
|
261
|
+
}
|
|
262
|
+
isOptional() {
|
|
263
|
+
return this.type === CstNodeType.OPTIONAL;
|
|
264
|
+
}
|
|
265
|
+
get ctorName() {
|
|
266
|
+
return this.isTerminal() ? '_terminal' : this.isIter() ? '_iter' : this.ruleName;
|
|
267
|
+
}
|
|
268
|
+
get ruleName() {
|
|
269
|
+
assert(this.isNonterminal(), 'Not a non-terminal');
|
|
270
|
+
const ruleId = this._view.getInt32(this._base + 8, true) >>> 2;
|
|
271
|
+
return this._ruleNames[ruleId].split('<')[0];
|
|
272
|
+
}
|
|
273
|
+
get count() {
|
|
274
|
+
return this._view.getUint32(this._base, true);
|
|
275
|
+
}
|
|
276
|
+
get matchLength() {
|
|
277
|
+
return this._view.getUint32(this._base + 4, true);
|
|
278
|
+
}
|
|
279
|
+
get _typeAndDetails() {
|
|
280
|
+
return this._view.getInt32(this._base + 8, true);
|
|
281
|
+
}
|
|
282
|
+
get arity() {
|
|
283
|
+
return this._typeAndDetails >>> 2;
|
|
284
|
+
}
|
|
285
|
+
get children() {
|
|
286
|
+
if (!this._children) {
|
|
287
|
+
this._children = this._computeChildren();
|
|
288
|
+
}
|
|
289
|
+
return this._children;
|
|
290
|
+
}
|
|
291
|
+
_computeChildren() {
|
|
292
|
+
const children = [];
|
|
293
|
+
let spaces;
|
|
294
|
+
let { startIdx } = this;
|
|
295
|
+
for (let i = 0; i < this.count; i++) {
|
|
296
|
+
const slotOffset = this._base + 16 + i * 4;
|
|
297
|
+
const ptr = this._view.getUint32(slotOffset, true);
|
|
298
|
+
// TODO: Avoid allocating $spaces nodes altogether?
|
|
299
|
+
const node = new CstNode(this._ruleNames, this._view, ptr, this._input, startIdx);
|
|
300
|
+
if (node.ctorName === '$spaces') {
|
|
301
|
+
assert(!spaces, 'Multiple $spaces nodes found');
|
|
302
|
+
spaces = node;
|
|
303
|
+
}
|
|
304
|
+
else {
|
|
305
|
+
if (spaces) {
|
|
306
|
+
node.leadingSpaces = spaces;
|
|
307
|
+
spaces = undefined;
|
|
308
|
+
}
|
|
309
|
+
children.push(node);
|
|
310
|
+
}
|
|
311
|
+
startIdx += node.matchLength;
|
|
312
|
+
}
|
|
313
|
+
assert(spaces === undefined, 'Unclaimed $spaces!');
|
|
314
|
+
return children;
|
|
315
|
+
}
|
|
316
|
+
get sourceString() {
|
|
317
|
+
return this._input.slice(this.startIdx, this.startIdx + this.matchLength);
|
|
318
|
+
}
|
|
319
|
+
isSyntactic(ruleName) {
|
|
320
|
+
const firstChar = this.ruleName[0];
|
|
321
|
+
return firstChar === firstChar.toUpperCase();
|
|
322
|
+
}
|
|
323
|
+
isLexical(ruleName) {
|
|
324
|
+
return !this.isSyntactic(ruleName);
|
|
325
|
+
}
|
|
326
|
+
toString() {
|
|
327
|
+
const ctorName = this.isTerminal() ? '_terminal' : this.isIter() ? '_iter' : this.ruleName;
|
|
328
|
+
const { sourceString, startIdx } = this;
|
|
329
|
+
return `CstNode {ctorName: ${ctorName}, sourceString: ${sourceString}, startIdx: ${startIdx} }`;
|
|
330
|
+
}
|
|
331
|
+
map(callbackFn) {
|
|
332
|
+
const { arity, children } = this;
|
|
333
|
+
assert(callbackFn.length === arity, 'bad arity');
|
|
334
|
+
const ans = [];
|
|
335
|
+
for (let i = 0; i < children.length; i += arity) {
|
|
336
|
+
ans.push(callbackFn(...children.slice(i, i + arity)));
|
|
337
|
+
}
|
|
338
|
+
return ans;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
export function dumpCstNode(node, depth = 0) {
|
|
342
|
+
const { _base, children, ctorName, matchLength, startIdx } = node;
|
|
343
|
+
const indent = Array.from({ length: depth }).join(' ');
|
|
344
|
+
const addr = _base.toString(16);
|
|
345
|
+
// eslint-disable-next-line no-console
|
|
346
|
+
console.log(`${indent}${addr} ${ctorName}@${startIdx}, matchLength ${matchLength}, children ${children.length}` // eslint-disable-line max-len
|
|
347
|
+
);
|
|
348
|
+
node.children.forEach(c => dumpCstNode(c, depth + 1));
|
|
349
|
+
}
|
|
350
|
+
export class MatchResult {
|
|
351
|
+
// Note: This is different from the JS implementation, which has:
|
|
352
|
+
// matcher: Matcher;
|
|
353
|
+
// …instead.
|
|
354
|
+
grammar;
|
|
355
|
+
input;
|
|
356
|
+
startExpr;
|
|
357
|
+
_cst;
|
|
358
|
+
_rightmostFailurePosition;
|
|
359
|
+
_rightmostFailures;
|
|
360
|
+
shortMessage;
|
|
361
|
+
message;
|
|
362
|
+
constructor(matcher, input, startExpr, cst, rightmostFailurePosition, optRecordedFailures) {
|
|
363
|
+
this.grammar = matcher;
|
|
364
|
+
this.input = input;
|
|
365
|
+
this.startExpr = startExpr;
|
|
366
|
+
this._cst = cst;
|
|
367
|
+
this._rightmostFailurePosition = rightmostFailurePosition;
|
|
368
|
+
this._rightmostFailures = optRecordedFailures;
|
|
369
|
+
// TODO: Define these as lazy properties, like in the JS implementation.
|
|
370
|
+
if (this.failed()) {
|
|
371
|
+
this.shortMessage = this.message = `Match failed at pos ${rightmostFailurePosition}`;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
[Symbol.dispose]() {
|
|
375
|
+
this.detach();
|
|
376
|
+
}
|
|
377
|
+
detach() {
|
|
378
|
+
throw new Error('MatchResult is not attached to any grammar');
|
|
379
|
+
}
|
|
380
|
+
succeeded() {
|
|
381
|
+
return !!this._cst;
|
|
382
|
+
}
|
|
383
|
+
failed() {
|
|
384
|
+
return !this.succeeded();
|
|
385
|
+
}
|
|
386
|
+
getRightmostFailurePosition() {
|
|
387
|
+
return this._rightmostFailurePosition;
|
|
388
|
+
}
|
|
389
|
+
getRightmostFailures() {
|
|
390
|
+
throw new Error('Not implemented yet: getRightmostFailures');
|
|
391
|
+
}
|
|
392
|
+
toString() {
|
|
393
|
+
return this.succeeded()
|
|
394
|
+
? '[match succeeded]'
|
|
395
|
+
: '[match failed at position ' + this.getRightmostFailurePosition() + ']';
|
|
396
|
+
}
|
|
397
|
+
// Return a string summarizing the expected contents of the input stream when
|
|
398
|
+
// the match failure occurred.
|
|
399
|
+
getExpectedText() {
|
|
400
|
+
if (this.succeeded()) {
|
|
401
|
+
throw new Error('cannot get expected text of a successful MatchResult');
|
|
402
|
+
}
|
|
403
|
+
throw new Error('Not implemented yet: getExpectedText');
|
|
404
|
+
}
|
|
405
|
+
getInterval() {
|
|
406
|
+
throw new Error('Not implemented yet: getInterval');
|
|
407
|
+
}
|
|
408
|
+
use(cb) {
|
|
409
|
+
try {
|
|
410
|
+
this.grammar._beginUse(this);
|
|
411
|
+
return cb(this);
|
|
412
|
+
}
|
|
413
|
+
finally {
|
|
414
|
+
this.grammar._endUse(this);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
//# sourceMappingURL=miniohm.js.map
|
package/package.json
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ohm-js/wasm",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Compile Ohm.js grammars to WebAsssembly",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": "./dist/index.js",
|
|
8
|
+
"./compat": "./dist/src/compat.js",
|
|
9
|
+
"./compiler": "./dist/src/Compiler.js"
|
|
10
|
+
},
|
|
6
11
|
"bin": {
|
|
7
|
-
"ohm2wasm": "dist/cli.js"
|
|
12
|
+
"ohm2wasm": "dist/src/cli.js"
|
|
8
13
|
},
|
|
9
14
|
"files": [
|
|
10
|
-
"dist"
|
|
15
|
+
"dist/**/*.js",
|
|
16
|
+
"dist/**/*.d.ts"
|
|
11
17
|
],
|
|
12
18
|
"type": "module",
|
|
13
19
|
"keywords": [],
|
|
@@ -22,8 +28,7 @@
|
|
|
22
28
|
"fast-check": "^4.2.0",
|
|
23
29
|
"fast-glob": "^3.3.3",
|
|
24
30
|
"mitata": "^1.0.34",
|
|
25
|
-
"wabt": "1.0.37-nightly.20250428"
|
|
26
|
-
"@ohm-js/miniohm-js": "^0.4.3"
|
|
31
|
+
"wabt": "1.0.37-nightly.20250428"
|
|
27
32
|
},
|
|
28
33
|
"peerDependencies": {
|
|
29
34
|
"ohm-js": "^17.1.0"
|