zuzu-js 0.1.2 → 0.2.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/dist/zuzu-browser-worker.js +240 -80
- package/dist/zuzu-browser.js +244 -84
- package/lib/cli.js +1 -1
- package/lib/runtime-helpers.js +49 -0
- package/lib/transpiler-new/codegen.js +32 -23
- package/lib/transpiler-new/parser.js +5 -9
- package/package.json +1 -1
- package/stdlib/modules/test/parser.zzm +13 -2
package/lib/cli.js
CHANGED
|
@@ -254,7 +254,7 @@ function stripShebang( source ) {
|
|
|
254
254
|
}
|
|
255
255
|
|
|
256
256
|
function printVersion( runtime, verbose ) {
|
|
257
|
-
process.stdout.write( 'zuzu-js version 0.
|
|
257
|
+
process.stdout.write( 'zuzu-js version 0.2.0\n' );
|
|
258
258
|
if ( verbose ) {
|
|
259
259
|
process.stdout.write( '\nlib search paths:\n' );
|
|
260
260
|
for ( const p of runtime.getModuleSearchRoots() ) {
|
package/lib/runtime-helpers.js
CHANGED
|
@@ -251,6 +251,8 @@ function collectTopLevelDeclarations( source, stripPod ) {
|
|
|
251
251
|
let inSingle = false;
|
|
252
252
|
let inDouble = false;
|
|
253
253
|
let inBacktick = false;
|
|
254
|
+
let inRegex = false;
|
|
255
|
+
let inRegexClass = false;
|
|
254
256
|
let inLineComment = false;
|
|
255
257
|
let inBlockComment = false;
|
|
256
258
|
let escape = false;
|
|
@@ -280,6 +282,35 @@ function collectTopLevelDeclarations( source, stripPod ) {
|
|
|
280
282
|
masked.push( ch === '\n' ? '\n' : ' ' );
|
|
281
283
|
continue;
|
|
282
284
|
}
|
|
285
|
+
if ( inRegex ) {
|
|
286
|
+
if ( escape ) {
|
|
287
|
+
escape = false;
|
|
288
|
+
masked.push( ' ' );
|
|
289
|
+
continue;
|
|
290
|
+
}
|
|
291
|
+
if ( ch === '\\' ) {
|
|
292
|
+
escape = true;
|
|
293
|
+
masked.push( ' ' );
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
296
|
+
if ( ch === '[' ) {
|
|
297
|
+
inRegexClass = true;
|
|
298
|
+
masked.push( ' ' );
|
|
299
|
+
continue;
|
|
300
|
+
}
|
|
301
|
+
if ( ch === ']' ) {
|
|
302
|
+
inRegexClass = false;
|
|
303
|
+
masked.push( ' ' );
|
|
304
|
+
continue;
|
|
305
|
+
}
|
|
306
|
+
if ( ch === '/' && !inRegexClass ) {
|
|
307
|
+
inRegex = false;
|
|
308
|
+
masked.push( ' ' );
|
|
309
|
+
continue;
|
|
310
|
+
}
|
|
311
|
+
masked.push( ch === '\n' ? '\n' : ' ' );
|
|
312
|
+
continue;
|
|
313
|
+
}
|
|
283
314
|
if ( inSingle || inDouble || inBacktick ) {
|
|
284
315
|
if ( escape ) {
|
|
285
316
|
escape = false;
|
|
@@ -318,6 +349,12 @@ function collectTopLevelDeclarations( source, stripPod ) {
|
|
|
318
349
|
masked.push( ' ' );
|
|
319
350
|
continue;
|
|
320
351
|
}
|
|
352
|
+
if ( ch === '/' && looksLikeRegexLiteralStart( stripped, i ) ) {
|
|
353
|
+
inRegex = true;
|
|
354
|
+
inRegexClass = false;
|
|
355
|
+
masked.push( ' ' );
|
|
356
|
+
continue;
|
|
357
|
+
}
|
|
321
358
|
if ( ch === '\'' ) {
|
|
322
359
|
inSingle = true;
|
|
323
360
|
masked.push( ' ' );
|
|
@@ -391,6 +428,18 @@ function collectTopLevelDeclarations( source, stripPod ) {
|
|
|
391
428
|
return [ ...names ];
|
|
392
429
|
}
|
|
393
430
|
|
|
431
|
+
function looksLikeRegexLiteralStart( source, index ) {
|
|
432
|
+
let pos = index - 1;
|
|
433
|
+
while ( pos >= 0 && /\s/u.test( source[pos] ) ) {
|
|
434
|
+
pos--;
|
|
435
|
+
}
|
|
436
|
+
if ( pos < 0 ) {
|
|
437
|
+
return true;
|
|
438
|
+
}
|
|
439
|
+
const previous = source[pos];
|
|
440
|
+
return /[({[=,:;!~?&|+\-*%^<>]/u.test( previous );
|
|
441
|
+
}
|
|
442
|
+
|
|
394
443
|
function collectTopLevelUnpackDeclarationNames( source, topLevelMask ) {
|
|
395
444
|
const names = [];
|
|
396
445
|
const rx = /(?:^|[;\n])\s*(?:export\s+)?(?:let|const)\b/gm;
|
|
@@ -729,7 +729,7 @@ function emitFunctionPreamble( params, signature = null ) {
|
|
|
729
729
|
for ( const param of params ) {
|
|
730
730
|
if ( param.type === 'SpecialParameter' ) {
|
|
731
731
|
if ( param.special === 'lead_rest' ) {
|
|
732
|
-
lines.push( `
|
|
732
|
+
lines.push( `const ${param.leadName} = arguments[${argIndex}];` );
|
|
733
733
|
argIndex++;
|
|
734
734
|
lines.push( `const ${param.name} = Array.prototype.slice.call( arguments, ${argIndex} );` );
|
|
735
735
|
continue;
|
|
@@ -757,13 +757,13 @@ function emitFunctionPreamble( params, signature = null ) {
|
|
|
757
757
|
continue;
|
|
758
758
|
}
|
|
759
759
|
if ( param.defaultValue ) {
|
|
760
|
-
lines.push( `
|
|
760
|
+
lines.push( `const ${paramName} = __argc__ > ${argIndex} ? arguments[${argIndex}] : ${emitExpression( param.defaultValue )};` );
|
|
761
761
|
}
|
|
762
762
|
else if ( param.optional ) {
|
|
763
|
-
lines.push( `
|
|
763
|
+
lines.push( `const ${paramName} = __argc__ > ${argIndex} ? arguments[${argIndex}] : null;` );
|
|
764
764
|
}
|
|
765
765
|
else {
|
|
766
|
-
lines.push( `
|
|
766
|
+
lines.push( `const ${paramName} = arguments[${argIndex}];` );
|
|
767
767
|
}
|
|
768
768
|
if ( param.typeName ) {
|
|
769
769
|
lines.push(
|
|
@@ -780,62 +780,71 @@ function emitSpecialFunctionPreamble( signature ) {
|
|
|
780
780
|
case 'pairlist_only':
|
|
781
781
|
return [
|
|
782
782
|
`const __zuzu_call_args = Array.prototype.slice.call( arguments );`,
|
|
783
|
-
|
|
783
|
+
'let __zuzu_named_args = __zuzu_pairlist_literal( [] );',
|
|
784
784
|
'for ( const __a of __zuzu_call_args ) {',
|
|
785
|
-
|
|
785
|
+
'if ( __zuzu_is_pairlist( __a ) ) { __zuzu_named_args = __a; } else { throw new Exception( "named PairList parameter only accepts named arguments" ); }',
|
|
786
786
|
'}',
|
|
787
|
+
`const ${signature.namedName} = __zuzu_named_args;`,
|
|
787
788
|
].join( '\n' );
|
|
788
789
|
case 'pairlist_rest_array':
|
|
789
790
|
case 'rest_array_pairlist':
|
|
790
791
|
return [
|
|
791
792
|
`const __zuzu_call_args = Array.prototype.slice.call( arguments );`,
|
|
792
|
-
|
|
793
|
-
|
|
793
|
+
'let __zuzu_named_args = __zuzu_pairlist_literal( [] );',
|
|
794
|
+
'const __zuzu_rest_args = [];',
|
|
794
795
|
'for ( const __a of __zuzu_call_args ) {',
|
|
795
|
-
|
|
796
|
+
'if ( __zuzu_is_pairlist( __a ) ) { __zuzu_named_args = __a; } else { __zuzu_rest_args.push( __a ); }',
|
|
796
797
|
'}',
|
|
798
|
+
`const ${signature.namedName} = __zuzu_named_args;`,
|
|
799
|
+
`const ${signature.restName} = __zuzu_rest_args;`,
|
|
797
800
|
].join( '\n' );
|
|
798
801
|
case 'lead_pairlist':
|
|
799
802
|
return [
|
|
800
803
|
'const __zuzu_call_args = Array.prototype.slice.call( arguments );',
|
|
801
|
-
`
|
|
802
|
-
|
|
803
|
-
|
|
804
|
+
`const ${signature.headName} = __zuzu_call_args[0];`,
|
|
805
|
+
'let __zuzu_named_args = __zuzu_pairlist_literal( [] );',
|
|
806
|
+
'const __zuzu_rest_args = [];',
|
|
804
807
|
'for ( let __i = 1; __i < __zuzu_call_args.length; __i++ ) {',
|
|
805
808
|
'const __a = __zuzu_call_args[__i];',
|
|
806
|
-
|
|
809
|
+
'if ( __zuzu_is_pairlist( __a ) ) { __zuzu_named_args = __a; } else { __zuzu_rest_args.push( __a ); }',
|
|
807
810
|
'}',
|
|
811
|
+
`const ${signature.namedName} = __zuzu_named_args;`,
|
|
812
|
+
`const ${signature.restName} = __zuzu_rest_args;`,
|
|
808
813
|
].join( '\n' );
|
|
809
814
|
case 'trail_pairlist':
|
|
810
815
|
return [
|
|
811
816
|
'const __zuzu_call_args = Array.prototype.slice.call( arguments );',
|
|
812
|
-
`
|
|
813
|
-
|
|
814
|
-
|
|
817
|
+
`const ${signature.headName} = __zuzu_call_args[0];`,
|
|
818
|
+
'const __zuzu_rest_args = [];',
|
|
819
|
+
'let __zuzu_named_args = __zuzu_pairlist_literal( [] );',
|
|
815
820
|
'for ( let __i = 1; __i < __zuzu_call_args.length; __i++ ) {',
|
|
816
821
|
'const __a = __zuzu_call_args[__i];',
|
|
817
|
-
|
|
822
|
+
'if ( __zuzu_is_pairlist( __a ) ) { __zuzu_named_args = __a; } else { __zuzu_rest_args.push( __a ); }',
|
|
818
823
|
'}',
|
|
824
|
+
`const ${signature.restName} = __zuzu_rest_args;`,
|
|
825
|
+
`const ${signature.namedName} = __zuzu_named_args;`,
|
|
819
826
|
].join( '\n' );
|
|
820
827
|
case 'scalar_pairlist':
|
|
821
828
|
return [
|
|
822
829
|
'const __zuzu_call_args = Array.prototype.slice.call( arguments );',
|
|
823
|
-
`
|
|
824
|
-
|
|
830
|
+
`const ${signature.headName} = __zuzu_call_args[0];`,
|
|
831
|
+
'let __zuzu_named_args = __zuzu_pairlist_literal( [] );',
|
|
825
832
|
'for ( let __i = 1; __i < __zuzu_call_args.length; __i++ ) {',
|
|
826
833
|
'const __a = __zuzu_call_args[__i];',
|
|
827
|
-
|
|
834
|
+
'if ( __zuzu_is_pairlist( __a ) ) { __zuzu_named_args = __a; } else { throw new Exception( "named arguments not allowed for this function" ); }',
|
|
828
835
|
'}',
|
|
836
|
+
`const ${signature.namedName} = __zuzu_named_args;`,
|
|
829
837
|
].join( '\n' );
|
|
830
838
|
case 'variadic':
|
|
831
839
|
return [
|
|
832
840
|
'const __zuzu_call_args = Array.prototype.slice.call( arguments );',
|
|
833
|
-
`
|
|
834
|
-
|
|
841
|
+
`const ${signature.headName} = __zuzu_call_args[0];`,
|
|
842
|
+
'const __zuzu_rest_args = [];',
|
|
835
843
|
'for ( let __i = 1; __i < __zuzu_call_args.length; __i++ ) {',
|
|
836
844
|
'const __a = __zuzu_call_args[__i];',
|
|
837
|
-
|
|
845
|
+
'if ( __zuzu_is_pairlist( __a ) ) { throw new Exception( "named arguments not allowed for this function" ); } __zuzu_rest_args.push( __a );',
|
|
838
846
|
'}',
|
|
847
|
+
`const ${signature.restName} = __zuzu_rest_args;`,
|
|
839
848
|
].join( '\n' );
|
|
840
849
|
default:
|
|
841
850
|
return '';
|
|
@@ -55,26 +55,22 @@ function parse( tokens, options = {} ) {
|
|
|
55
55
|
return tokens[index - 1];
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
function
|
|
58
|
+
function canTerminateSimpleStatement() {
|
|
59
59
|
const token = current();
|
|
60
|
-
const prev = previous();
|
|
61
|
-
if ( !prev ) {
|
|
62
|
-
return false;
|
|
63
|
-
}
|
|
64
60
|
if ( token.type === 'punctuation' && token.value === '}' ) {
|
|
65
61
|
return true;
|
|
66
62
|
}
|
|
67
63
|
if ( token.type === 'eof' ) {
|
|
68
64
|
return true;
|
|
69
65
|
}
|
|
70
|
-
return
|
|
66
|
+
return false;
|
|
71
67
|
}
|
|
72
68
|
|
|
73
69
|
function consumeStatementTerminator(message) {
|
|
74
70
|
if ( match( 'punctuation', ';' ) ) {
|
|
75
71
|
return;
|
|
76
72
|
}
|
|
77
|
-
if (
|
|
73
|
+
if ( canTerminateSimpleStatement() ) {
|
|
78
74
|
return;
|
|
79
75
|
}
|
|
80
76
|
throw new TranspilerSyntaxError( message || 'Expected statement terminator', current() );
|
|
@@ -1313,7 +1309,7 @@ function parse( tokens, options = {} ) {
|
|
|
1313
1309
|
prefix: true,
|
|
1314
1310
|
}, keyword, endLocFromNode( test ) );
|
|
1315
1311
|
}
|
|
1316
|
-
|
|
1312
|
+
consumeStatementTerminator( semicolonMessage );
|
|
1317
1313
|
const consequent = withLoc( {
|
|
1318
1314
|
type: 'BlockStatement',
|
|
1319
1315
|
body: [ stmt ],
|
|
@@ -1330,7 +1326,7 @@ function parse( tokens, options = {} ) {
|
|
|
1330
1326
|
const keyword = current();
|
|
1331
1327
|
index++;
|
|
1332
1328
|
const iterable = parseExpression();
|
|
1333
|
-
|
|
1329
|
+
consumeStatementTerminator( semicolonMessage );
|
|
1334
1330
|
const body = withLoc( {
|
|
1335
1331
|
type: 'BlockStatement',
|
|
1336
1332
|
body: [ stmt ],
|
package/package.json
CHANGED
|
@@ -158,6 +158,7 @@ function parse_lines ( Array lines ) {
|
|
|
158
158
|
let top_level := _new_counts();
|
|
159
159
|
let assertions := _new_counts();
|
|
160
160
|
let planned := null;
|
|
161
|
+
let plan_directive := "";
|
|
161
162
|
let tests := [];
|
|
162
163
|
|
|
163
164
|
for ( let line in lines ) {
|
|
@@ -170,8 +171,11 @@ function parse_lines ( Array lines ) {
|
|
|
170
171
|
|
|
171
172
|
if ( body ~ /^\d+\.\.\d+\b/ ) {
|
|
172
173
|
if ( is_top_level ) {
|
|
173
|
-
let
|
|
174
|
-
|
|
174
|
+
let plan_parts := split( body, "#", 2 );
|
|
175
|
+
let range_parts := split( trim( plan_parts[0] ), "..", 2 );
|
|
176
|
+
planned := trim( range_parts.get( 1, "" ) ) + 0;
|
|
177
|
+
plan_directive := trim( plan_parts.get( 1, "" ) )
|
|
178
|
+
if plan_parts.length() > 1;
|
|
175
179
|
}
|
|
176
180
|
next;
|
|
177
181
|
}
|
|
@@ -186,10 +190,17 @@ function parse_lines ( Array lines ) {
|
|
|
186
190
|
}
|
|
187
191
|
}
|
|
188
192
|
|
|
193
|
+
let skip_all_plan := false;
|
|
194
|
+
if ( planned ≡ 0 and plan_directive ~ /^skip\b/i ) {
|
|
195
|
+
skip_all_plan := true;
|
|
196
|
+
}
|
|
197
|
+
|
|
189
198
|
return {
|
|
190
199
|
top_level: top_level,
|
|
191
200
|
assertions: assertions,
|
|
192
201
|
planned: planned,
|
|
202
|
+
plan_directive: plan_directive,
|
|
203
|
+
skip_all: skip_all_plan,
|
|
193
204
|
tests: tests,
|
|
194
205
|
};
|
|
195
206
|
}
|