Skip to content

Commit 3f3346f

Browse files
tommieguybedford
authored andcommitted
Changes exports to ExportSpecifier.
Adds information about the local name for "export { a as b }" and whether it's an ambient export or not. Breaking change for the parse() API since exports is no longer an array of strings.
1 parent 3f441e4 commit 3f3346f

File tree

8 files changed

+337
-181
lines changed

8 files changed

+337
-181
lines changed

chompfile.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ deps = ['src/lexer.h', 'src/lexer.c']
7373
run = """
7474
${{ WASI_PATH }}/bin/clang src/lexer.c --sysroot=${{ WASI_PATH }}/share/wasi-sysroot -o lib/lexer.wasm -nostartfiles \
7575
"-Wl,-z,stack-size=13312,--no-entry,--compress-relocations,--strip-all,\
76-
--export=parse,--export=sa,--export=e,--export=ri,--export=re,--export=is,--export=ie,--export=ss,--export=ip,--export=se,--export=ai,--export=id,--export=es,--export=ee,--export=f,--export=__heap_base" \
76+
--export=parse,--export=sa,--export=e,--export=ri,--export=re,--export=is,--export=ie,--export=ss,--export=ip,--export=se,--export=ai,--export=id,--export=es,--export=ee,--export=els,--export=ele,--export=ea,--export=f,--export=__heap_base" \
7777
-Wno-logical-op-parentheses -Wno-parentheses \
7878
-Oz
7979
"""
@@ -87,7 +87,7 @@ run = """
8787
${{ EMSDK_PATH }}/emsdk activate 1.40.1-fastcomp
8888
8989
${{ EMSDK_PATH }}/fastcomp/emscripten/emcc ./src/lexer.c -o lib/lexer.emcc.js -s WASM=0 -Oz --closure 1 \
90-
-s EXPORTED_FUNCTIONS="['_parse','_sa','_e','_ri','_re','_is','_ie','_ss','_ip','_se','_ai','_id','_es','_ee','_f','_setSource']" \
90+
-s EXPORTED_FUNCTIONS="['_parse','_sa','_e','_ri','_re','_is','_ie','_ss','_ip','_se','_ai','_id','_es','_ee','_els','_ele','_ea','_f','_setSource']" \
9191
-s ERROR_ON_UNDEFINED_SYMBOLS=0 -s SINGLE_FILE=1 -s TOTAL_STACK=4997968 -s --separate-asm -Wno-logical-op-parentheses -Wno-parentheses
9292
9393
# rm lib/lexer.emcc.js

lexer.js

+19-7
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ function addImport (ss, s, e, d) {
2020
return impt;
2121
}
2222

23+
function addExport (s, e, ls, le, a) {
24+
exports.push({ s, e, ls, le, a, n: undefined, ln: undefined });
25+
}
26+
2327
function readName (impt) {
2428
let { d, s } = impt;
2529
if (d !== -1)
@@ -43,7 +47,7 @@ export function parse (_source, _name) {
4347
name = _name || '@';
4448

4549
imports = [];
46-
exports = new Set();
50+
exports = [];
4751

4852
source = _source;
4953
pos = -1;
@@ -202,7 +206,7 @@ export function parse (_source, _name) {
202206
if (templateDepth !== -1 || openTokenDepth)
203207
syntaxError();
204208

205-
return [imports, [...exports], facade];
209+
return [imports, exports, facade];
206210
}
207211

208212
function tryParseImportStatement () {
@@ -287,6 +291,7 @@ function tryParseImportStatement () {
287291

288292
function tryParseExportStatement () {
289293
const sStartPos = pos;
294+
const prevExport = exports.length;
290295

291296
pos += 6;
292297

@@ -300,7 +305,7 @@ function tryParseExportStatement () {
300305
switch (ch) {
301306
// export default ...
302307
case 100/*d*/:
303-
exports.add(source.slice(pos, pos + 7));
308+
addExport(pos, pos + 7, -1, -1, true);
304309
return;
305310

306311
// export async? function*? name () {
@@ -317,17 +322,18 @@ function tryParseExportStatement () {
317322
}
318323
const startPos = pos;
319324
ch = readToWsOrPunctuator(ch);
320-
exports.add(source.slice(startPos, pos));
325+
addExport(startPos, pos, -1, -1, true);
321326
pos--;
322327
return;
323328

329+
// export class name ...
324330
case 99/*c*/:
325331
if (source.startsWith('lass', pos + 1) && isBrOrWsOrPunctuatorNotDot(source.charCodeAt(pos + 5))) {
326332
pos += 5;
327333
ch = commentWhitespace(true);
328334
const startPos = pos;
329335
ch = readToWsOrPunctuator(ch);
330-
exports.add(source.slice(startPos, pos));
336+
addExport(startPos, pos, -1, -1, true);
331337
pos--;
332338
return;
333339
}
@@ -353,7 +359,7 @@ function tryParseExportStatement () {
353359
}
354360
if (pos === startPos)
355361
return;
356-
exports.add(source.slice(startPos, pos));
362+
addExport(startPos, pos, -1, -1, false);
357363
ch = commentWhitespace(true);
358364
if (ch === 61/*=*/) {
359365
pos--;
@@ -404,6 +410,11 @@ function tryParseExportStatement () {
404410
if (ch === 102/*f*/ && source.startsWith('rom', pos + 1)) {
405411
pos += 4;
406412
readImportString(sStartPos, commentWhitespace(true));
413+
414+
// There were no local names.
415+
for (let i = prevExport; i < exports.length; ++i) {
416+
exports[i].ls = exports[i].le = -1;
417+
}
407418
}
408419
else {
409420
pos--;
@@ -556,6 +567,7 @@ function readCodePointToString () {
556567

557568
function readExportAs (startPos, endPos) {
558569
let ch = source.charCodeAt(pos);
570+
let ls = startPos, le = endPos;
559571
if (ch === 97 /*a*/) {
560572
pos += 2;
561573
ch = commentWhitespace(true);
@@ -565,7 +577,7 @@ function readExportAs (startPos, endPos) {
565577
ch = commentWhitespace(true);
566578
}
567579
if (pos !== startPos)
568-
exports.add(source.slice(startPos, endPos));
580+
addExport(startPos, endPos, ls, le, true);
569581
return ch;
570582
}
571583

src/lexer.asm.js

+9-2
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,15 @@ export function parse (_source, _name = '@') {
5151
imports.push({ n, s, e, ss, se, d, a });
5252
}
5353
while (asm.re()) {
54-
const start = asm.es(), ch = source.charCodeAt(start);
55-
exports.push((ch === 34 || ch === 39) ? readString(start + 1, ch) : source.slice(asm.es(), asm.ee()));
54+
const s = asm.es(), e = asm.ee(), ls = asm.els(), le = asm.ele();
55+
const ch = source.charCodeAt(s);
56+
const lch = ls >= 0 ? source.charCodeAt(ls) : -1;
57+
exports.push({
58+
s, e, ls, le,
59+
a: Boolean(asm.ea()),
60+
n: (ch === 34 || ch === 39) ? readString(s + 1, ch) : source.slice(s, e),
61+
ln: ls < 0 ? undefined : (lch === 34 || lch === 39) ? readString(ls + 1, lch) : source.slice(ls, le),
62+
});
5663
}
5764

5865
return [imports, exports, !!asm.f()];

src/lexer.c

+14-5
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,7 @@ void tryParseImportStatement () {
346346

347347
void tryParseExportStatement () {
348348
char16_t* sStartPos = pos;
349+
Export* prev_export_write_head = export_write_head;
349350

350351
pos += 6;
351352

@@ -359,7 +360,7 @@ void tryParseExportStatement () {
359360
switch (ch) {
360361
// export default ...
361362
case 'd':
362-
addExport(pos, pos + 7);
363+
addExport(pos, pos + 7, NULL, NULL, false);
363364
return;
364365

365366
// export async? function*? name () {
@@ -376,17 +377,18 @@ void tryParseExportStatement () {
376377
}
377378
const char16_t* startPos = pos;
378379
ch = readToWsOrPunctuator(ch);
379-
addExport(startPos, pos);
380+
addExport(startPos, pos, startPos, pos, true);
380381
pos--;
381382
return;
382383

384+
// export class name ...
383385
case 'c':
384386
if (memcmp(pos + 1, &LASS[0], 4 * 2) == 0 && isBrOrWsOrPunctuatorNotDot(*(pos + 5))) {
385387
pos += 5;
386388
ch = commentWhitespace(true);
387389
const char16_t* startPos = pos;
388390
ch = readToWsOrPunctuator(ch);
389-
addExport(startPos, pos);
391+
addExport(startPos, pos, startPos, pos, true);
390392
pos--;
391393
return;
392394
}
@@ -412,7 +414,7 @@ void tryParseExportStatement () {
412414
}
413415
if (pos == startPos)
414416
return;
415-
addExport(startPos, pos);
417+
addExport(startPos, pos, startPos, pos, false);
416418
ch = commentWhitespace(true);
417419
if (ch == '=') {
418420
pos--;
@@ -480,6 +482,11 @@ void tryParseExportStatement () {
480482
if (ch == 'f' && memcmp(pos + 1, &FROM[1], 3 * 2) == 0) {
481483
pos += 4;
482484
readImportString(sStartPos, commentWhitespace(true));
485+
486+
// There were no local names.
487+
for (Export* exprt = prev_export_write_head == NULL ? first_export : prev_export_write_head->next; exprt != NULL; exprt = exprt->next) {
488+
exprt->local_start = exprt->local_end = NULL;
489+
}
483490
}
484491
else {
485492
pos--;
@@ -488,6 +495,8 @@ void tryParseExportStatement () {
488495

489496
char16_t readExportAs (char16_t* startPos, char16_t* endPos) {
490497
char16_t ch = *pos;
498+
char16_t* localStartPos = startPos == endPos ? NULL : startPos;
499+
char16_t* localEndPos = startPos == endPos ? NULL : endPos;
491500

492501
if (ch == 'a') {
493502
pos += 2;
@@ -515,7 +524,7 @@ char16_t readExportAs (char16_t* startPos, char16_t* endPos) {
515524
}
516525

517526
if (pos != startPos)
518-
addExport(startPos, endPos);
527+
addExport(startPos, endPos, localStartPos, localEndPos, true);
519528
return ch;
520529
}
521530

src/lexer.h

+19-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ typedef struct Import Import;
3030
struct Export {
3131
const char16_t* start;
3232
const char16_t* end;
33+
const char16_t* local_start;
34+
const char16_t* local_end;
35+
bool ambient;
3336
struct Export* next;
3437
};
3538
typedef struct Export Export;
@@ -109,7 +112,7 @@ void addImport (const char16_t* statement_start, const char16_t* start, const ch
109112
import->next = NULL;
110113
}
111114

112-
void addExport (const char16_t* start, const char16_t* end) {
115+
void addExport (const char16_t* start, const char16_t* end, const char16_t* local_start, const char16_t* local_end, bool ambient) {
113116
Export* export = (Export*)(analysis_head);
114117
analysis_head = analysis_head + sizeof(Export);
115118
if (export_write_head == NULL)
@@ -119,6 +122,9 @@ void addExport (const char16_t* start, const char16_t* end) {
119122
export_write_head = export;
120123
export->start = start;
121124
export->end = end;
125+
export->local_start = local_start;
126+
export->local_end = local_end;
127+
export->ambient = ambient;
122128
export->next = NULL;
123129
}
124130

@@ -168,6 +174,18 @@ uint32_t es () {
168174
uint32_t ee () {
169175
return export_read_head->end - source;
170176
}
177+
// getExportLocalStart
178+
int32_t els () {
179+
return export_read_head->local_start ? export_read_head->local_start - source : -1;
180+
}
181+
// getExportLocalEnd
182+
int32_t ele () {
183+
return export_read_head->local_end ? export_read_head->local_end - source : -1;
184+
}
185+
// getExportIsAmbient
186+
bool ea () {
187+
return export_read_head->ambient;
188+
}
171189
// readImport
172190
bool ri () {
173191
if (import_read_head == NULL)

src/lexer.js

+9-2
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,15 @@ export function parse (source, name = '@') {
2626
imports.push({ n, s, e, ss, se, d, a });
2727
}
2828
while (wasm.re()) {
29-
const expt = source.slice(wasm.es(), wasm.ee()), ch = expt[0];
30-
exports.push((ch === '"' || ch === "'") ? decode(expt) : expt);
29+
const s = wasm.es(), e = wasm.ee(), ls = wasm.els(), le = wasm.ele();
30+
const n = source.slice(s, e), ch = n[0];
31+
const ln = ls < 0 ? undefined : source.slice(ls, le), lch = ln ? ln[0] : '';
32+
exports.push({
33+
s, e, ls, le,
34+
a: Boolean(wasm.ea()),
35+
n: (ch === '"' || ch === "'") ? decode(n) : n,
36+
ln: (lch === '"' || lch === "'") ? decode(ln) : ln,
37+
});
3138
}
3239

3340
function decode (str) {

0 commit comments

Comments
 (0)