zuzu-js 0.1.1 → 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/runtime.js +7 -0
- package/lib/transpiler-new/codegen.js +72 -26
- package/lib/transpiler-new/parser.js +5 -9
- package/modules/std/io.js +16 -0
- package/modules/std/proc.js +19 -3
- package/package.json +1 -1
- package/stdlib/modules/test/parser.zzm +13 -2
|
@@ -985,14 +985,17 @@
|
|
|
985
985
|
return 1;
|
|
986
986
|
}
|
|
987
987
|
slice(start, end) {
|
|
988
|
-
return new
|
|
988
|
+
return new this.constructor(this.bytes.slice(start, end));
|
|
989
989
|
}
|
|
990
990
|
at(index) {
|
|
991
|
-
|
|
991
|
+
let idx = Number(index);
|
|
992
|
+
if (idx < 0) {
|
|
993
|
+
idx = this.bytes.length + idx;
|
|
994
|
+
}
|
|
992
995
|
if (idx < 0 || idx >= this.bytes.length) {
|
|
993
996
|
return null;
|
|
994
997
|
}
|
|
995
|
-
return new
|
|
998
|
+
return new this.constructor([this.bytes[idx]]);
|
|
996
999
|
}
|
|
997
1000
|
to_String() {
|
|
998
1001
|
let out = "";
|
|
@@ -1164,6 +1167,8 @@
|
|
|
1164
1167
|
let inSingle = false;
|
|
1165
1168
|
let inDouble = false;
|
|
1166
1169
|
let inBacktick = false;
|
|
1170
|
+
let inRegex = false;
|
|
1171
|
+
let inRegexClass = false;
|
|
1167
1172
|
let inLineComment = false;
|
|
1168
1173
|
let inBlockComment = false;
|
|
1169
1174
|
let escape = false;
|
|
@@ -1190,6 +1195,35 @@
|
|
|
1190
1195
|
masked.push(ch === "\n" ? "\n" : " ");
|
|
1191
1196
|
continue;
|
|
1192
1197
|
}
|
|
1198
|
+
if (inRegex) {
|
|
1199
|
+
if (escape) {
|
|
1200
|
+
escape = false;
|
|
1201
|
+
masked.push(" ");
|
|
1202
|
+
continue;
|
|
1203
|
+
}
|
|
1204
|
+
if (ch === "\\") {
|
|
1205
|
+
escape = true;
|
|
1206
|
+
masked.push(" ");
|
|
1207
|
+
continue;
|
|
1208
|
+
}
|
|
1209
|
+
if (ch === "[") {
|
|
1210
|
+
inRegexClass = true;
|
|
1211
|
+
masked.push(" ");
|
|
1212
|
+
continue;
|
|
1213
|
+
}
|
|
1214
|
+
if (ch === "]") {
|
|
1215
|
+
inRegexClass = false;
|
|
1216
|
+
masked.push(" ");
|
|
1217
|
+
continue;
|
|
1218
|
+
}
|
|
1219
|
+
if (ch === "/" && !inRegexClass) {
|
|
1220
|
+
inRegex = false;
|
|
1221
|
+
masked.push(" ");
|
|
1222
|
+
continue;
|
|
1223
|
+
}
|
|
1224
|
+
masked.push(ch === "\n" ? "\n" : " ");
|
|
1225
|
+
continue;
|
|
1226
|
+
}
|
|
1193
1227
|
if (inSingle || inDouble || inBacktick) {
|
|
1194
1228
|
if (escape) {
|
|
1195
1229
|
escape = false;
|
|
@@ -1225,6 +1259,12 @@
|
|
|
1225
1259
|
masked.push(" ");
|
|
1226
1260
|
continue;
|
|
1227
1261
|
}
|
|
1262
|
+
if (ch === "/" && looksLikeRegexLiteralStart(stripped, i)) {
|
|
1263
|
+
inRegex = true;
|
|
1264
|
+
inRegexClass = false;
|
|
1265
|
+
masked.push(" ");
|
|
1266
|
+
continue;
|
|
1267
|
+
}
|
|
1228
1268
|
if (ch === "'") {
|
|
1229
1269
|
inSingle = true;
|
|
1230
1270
|
masked.push(" ");
|
|
@@ -1295,6 +1335,17 @@
|
|
|
1295
1335
|
}
|
|
1296
1336
|
return [...names];
|
|
1297
1337
|
}
|
|
1338
|
+
function looksLikeRegexLiteralStart(source, index) {
|
|
1339
|
+
let pos = index - 1;
|
|
1340
|
+
while (pos >= 0 && /\s/u.test(source[pos])) {
|
|
1341
|
+
pos--;
|
|
1342
|
+
}
|
|
1343
|
+
if (pos < 0) {
|
|
1344
|
+
return true;
|
|
1345
|
+
}
|
|
1346
|
+
const previous = source[pos];
|
|
1347
|
+
return /[({[=,:;!~?&|+\-*%^<>]/u.test(previous);
|
|
1348
|
+
}
|
|
1298
1349
|
function collectTopLevelUnpackDeclarationNames(source, topLevelMask) {
|
|
1299
1350
|
const names = [];
|
|
1300
1351
|
const rx = /(?:^|[;\n])\s*(?:export\s+)?(?:let|const)\b/gm;
|
|
@@ -5240,25 +5291,21 @@
|
|
|
5240
5291
|
function previous() {
|
|
5241
5292
|
return tokens[index - 1];
|
|
5242
5293
|
}
|
|
5243
|
-
function
|
|
5294
|
+
function canTerminateSimpleStatement() {
|
|
5244
5295
|
const token = current();
|
|
5245
|
-
const prev = previous();
|
|
5246
|
-
if (!prev) {
|
|
5247
|
-
return false;
|
|
5248
|
-
}
|
|
5249
5296
|
if (token.type === "punctuation" && token.value === "}") {
|
|
5250
5297
|
return true;
|
|
5251
5298
|
}
|
|
5252
5299
|
if (token.type === "eof") {
|
|
5253
5300
|
return true;
|
|
5254
5301
|
}
|
|
5255
|
-
return
|
|
5302
|
+
return false;
|
|
5256
5303
|
}
|
|
5257
5304
|
function consumeStatementTerminator(message) {
|
|
5258
5305
|
if (match("punctuation", ";")) {
|
|
5259
5306
|
return;
|
|
5260
5307
|
}
|
|
5261
|
-
if (
|
|
5308
|
+
if (canTerminateSimpleStatement()) {
|
|
5262
5309
|
return;
|
|
5263
5310
|
}
|
|
5264
5311
|
throw new TranspilerSyntaxError(message || "Expected statement terminator", current());
|
|
@@ -6389,7 +6436,7 @@
|
|
|
6389
6436
|
prefix: true
|
|
6390
6437
|
}, keyword, endLocFromNode(test));
|
|
6391
6438
|
}
|
|
6392
|
-
|
|
6439
|
+
consumeStatementTerminator(semicolonMessage);
|
|
6393
6440
|
const consequent = withLoc({
|
|
6394
6441
|
type: "BlockStatement",
|
|
6395
6442
|
body: [stmt]
|
|
@@ -6406,7 +6453,7 @@
|
|
|
6406
6453
|
const keyword = current();
|
|
6407
6454
|
index++;
|
|
6408
6455
|
const iterable = parseExpression();
|
|
6409
|
-
|
|
6456
|
+
consumeStatementTerminator(semicolonMessage);
|
|
6410
6457
|
const body = withLoc({
|
|
6411
6458
|
type: "BlockStatement",
|
|
6412
6459
|
body: [stmt]
|
|
@@ -7338,6 +7385,7 @@
|
|
|
7338
7385
|
...options,
|
|
7339
7386
|
asyncContext: needsAsyncWrapper && !syncEval,
|
|
7340
7387
|
asyncNames: new Set(collectAsyncFunctionNames(ast.body)),
|
|
7388
|
+
evalNames: /* @__PURE__ */ new Set(["eval", ...collectEvalImportNames(ast.body)]),
|
|
7341
7389
|
weakStorageNames: new Set(collectWeakDeclaredNames(ast.body)),
|
|
7342
7390
|
scopeNames: /* @__PURE__ */ new Set([
|
|
7343
7391
|
...expressionDeclaredNames
|
|
@@ -7390,7 +7438,8 @@ ${source}
|
|
|
7390
7438
|
"__argc__",
|
|
7391
7439
|
"__file__",
|
|
7392
7440
|
"__global__",
|
|
7393
|
-
"__system__"
|
|
7441
|
+
"__system__",
|
|
7442
|
+
...options.evalNames || []
|
|
7394
7443
|
].filter(Boolean));
|
|
7395
7444
|
const localKinds = /* @__PURE__ */ new Set([
|
|
7396
7445
|
"FunctionDeclaration",
|
|
@@ -7417,6 +7466,21 @@ ${source}
|
|
|
7417
7466
|
}
|
|
7418
7467
|
return;
|
|
7419
7468
|
}
|
|
7469
|
+
if (value.type === "TryStatement") {
|
|
7470
|
+
visit(value.block, value);
|
|
7471
|
+
for (const handler of value.handlers || []) {
|
|
7472
|
+
const paramName = handler.paramName;
|
|
7473
|
+
const hadParam = paramName ? declared.has(paramName) : false;
|
|
7474
|
+
if (paramName) {
|
|
7475
|
+
declared.add(paramName);
|
|
7476
|
+
}
|
|
7477
|
+
visit(handler.body, handler);
|
|
7478
|
+
if (paramName && !hadParam) {
|
|
7479
|
+
declared.delete(paramName);
|
|
7480
|
+
}
|
|
7481
|
+
}
|
|
7482
|
+
return;
|
|
7483
|
+
}
|
|
7420
7484
|
if (value.type === "VariableUnpackDeclaration") {
|
|
7421
7485
|
visit(value.init, value);
|
|
7422
7486
|
for (const entry of bindingEntriesForPattern(value.pattern)) {
|
|
@@ -7490,6 +7554,7 @@ ${source}
|
|
|
7490
7554
|
syncEval: options.syncEval,
|
|
7491
7555
|
asyncContext: options.asyncContext,
|
|
7492
7556
|
asyncNames: options.asyncNames,
|
|
7557
|
+
evalNames: options.evalNames,
|
|
7493
7558
|
weakStorageNames: options.weakStorageNames,
|
|
7494
7559
|
scopeNames: options.scopeNames,
|
|
7495
7560
|
bodylessFunctionNames: options.bodylessFunctionNames,
|
|
@@ -7908,7 +7973,7 @@ globalThis[${JSON.stringify(node.id.name)}] = ${name2};` : declaration;
|
|
|
7908
7973
|
for (const param of params) {
|
|
7909
7974
|
if (param.type === "SpecialParameter") {
|
|
7910
7975
|
if (param.special === "lead_rest") {
|
|
7911
|
-
lines.push(`
|
|
7976
|
+
lines.push(`const ${param.leadName} = arguments[${argIndex}];`);
|
|
7912
7977
|
argIndex++;
|
|
7913
7978
|
lines.push(`const ${param.name} = Array.prototype.slice.call( arguments, ${argIndex} );`);
|
|
7914
7979
|
continue;
|
|
@@ -7935,11 +8000,11 @@ globalThis[${JSON.stringify(node.id.name)}] = ${name2};` : declaration;
|
|
|
7935
8000
|
continue;
|
|
7936
8001
|
}
|
|
7937
8002
|
if (param.defaultValue) {
|
|
7938
|
-
lines.push(`
|
|
8003
|
+
lines.push(`const ${paramName} = __argc__ > ${argIndex} ? arguments[${argIndex}] : ${emitExpression(param.defaultValue)};`);
|
|
7939
8004
|
} else if (param.optional) {
|
|
7940
|
-
lines.push(`
|
|
8005
|
+
lines.push(`const ${paramName} = __argc__ > ${argIndex} ? arguments[${argIndex}] : null;`);
|
|
7941
8006
|
} else {
|
|
7942
|
-
lines.push(`
|
|
8007
|
+
lines.push(`const ${paramName} = arguments[${argIndex}];`);
|
|
7943
8008
|
}
|
|
7944
8009
|
if (param.typeName) {
|
|
7945
8010
|
lines.push(
|
|
@@ -7955,62 +8020,71 @@ globalThis[${JSON.stringify(node.id.name)}] = ${name2};` : declaration;
|
|
|
7955
8020
|
case "pairlist_only":
|
|
7956
8021
|
return [
|
|
7957
8022
|
`const __zuzu_call_args = Array.prototype.slice.call( arguments );`,
|
|
7958
|
-
|
|
8023
|
+
"let __zuzu_named_args = __zuzu_pairlist_literal( [] );",
|
|
7959
8024
|
"for ( const __a of __zuzu_call_args ) {",
|
|
7960
|
-
|
|
7961
|
-
"}"
|
|
8025
|
+
'if ( __zuzu_is_pairlist( __a ) ) { __zuzu_named_args = __a; } else { throw new Exception( "named PairList parameter only accepts named arguments" ); }',
|
|
8026
|
+
"}",
|
|
8027
|
+
`const ${signature.namedName} = __zuzu_named_args;`
|
|
7962
8028
|
].join("\n");
|
|
7963
8029
|
case "pairlist_rest_array":
|
|
7964
8030
|
case "rest_array_pairlist":
|
|
7965
8031
|
return [
|
|
7966
8032
|
`const __zuzu_call_args = Array.prototype.slice.call( arguments );`,
|
|
7967
|
-
|
|
7968
|
-
|
|
8033
|
+
"let __zuzu_named_args = __zuzu_pairlist_literal( [] );",
|
|
8034
|
+
"const __zuzu_rest_args = [];",
|
|
7969
8035
|
"for ( const __a of __zuzu_call_args ) {",
|
|
7970
|
-
|
|
7971
|
-
"}"
|
|
8036
|
+
"if ( __zuzu_is_pairlist( __a ) ) { __zuzu_named_args = __a; } else { __zuzu_rest_args.push( __a ); }",
|
|
8037
|
+
"}",
|
|
8038
|
+
`const ${signature.namedName} = __zuzu_named_args;`,
|
|
8039
|
+
`const ${signature.restName} = __zuzu_rest_args;`
|
|
7972
8040
|
].join("\n");
|
|
7973
8041
|
case "lead_pairlist":
|
|
7974
8042
|
return [
|
|
7975
8043
|
"const __zuzu_call_args = Array.prototype.slice.call( arguments );",
|
|
7976
|
-
`
|
|
7977
|
-
|
|
7978
|
-
|
|
8044
|
+
`const ${signature.headName} = __zuzu_call_args[0];`,
|
|
8045
|
+
"let __zuzu_named_args = __zuzu_pairlist_literal( [] );",
|
|
8046
|
+
"const __zuzu_rest_args = [];",
|
|
7979
8047
|
"for ( let __i = 1; __i < __zuzu_call_args.length; __i++ ) {",
|
|
7980
8048
|
"const __a = __zuzu_call_args[__i];",
|
|
7981
|
-
|
|
7982
|
-
"}"
|
|
8049
|
+
"if ( __zuzu_is_pairlist( __a ) ) { __zuzu_named_args = __a; } else { __zuzu_rest_args.push( __a ); }",
|
|
8050
|
+
"}",
|
|
8051
|
+
`const ${signature.namedName} = __zuzu_named_args;`,
|
|
8052
|
+
`const ${signature.restName} = __zuzu_rest_args;`
|
|
7983
8053
|
].join("\n");
|
|
7984
8054
|
case "trail_pairlist":
|
|
7985
8055
|
return [
|
|
7986
8056
|
"const __zuzu_call_args = Array.prototype.slice.call( arguments );",
|
|
7987
|
-
`
|
|
7988
|
-
|
|
7989
|
-
|
|
8057
|
+
`const ${signature.headName} = __zuzu_call_args[0];`,
|
|
8058
|
+
"const __zuzu_rest_args = [];",
|
|
8059
|
+
"let __zuzu_named_args = __zuzu_pairlist_literal( [] );",
|
|
7990
8060
|
"for ( let __i = 1; __i < __zuzu_call_args.length; __i++ ) {",
|
|
7991
8061
|
"const __a = __zuzu_call_args[__i];",
|
|
7992
|
-
|
|
7993
|
-
"}"
|
|
8062
|
+
"if ( __zuzu_is_pairlist( __a ) ) { __zuzu_named_args = __a; } else { __zuzu_rest_args.push( __a ); }",
|
|
8063
|
+
"}",
|
|
8064
|
+
`const ${signature.restName} = __zuzu_rest_args;`,
|
|
8065
|
+
`const ${signature.namedName} = __zuzu_named_args;`
|
|
7994
8066
|
].join("\n");
|
|
7995
8067
|
case "scalar_pairlist":
|
|
7996
8068
|
return [
|
|
7997
8069
|
"const __zuzu_call_args = Array.prototype.slice.call( arguments );",
|
|
7998
|
-
`
|
|
7999
|
-
|
|
8070
|
+
`const ${signature.headName} = __zuzu_call_args[0];`,
|
|
8071
|
+
"let __zuzu_named_args = __zuzu_pairlist_literal( [] );",
|
|
8000
8072
|
"for ( let __i = 1; __i < __zuzu_call_args.length; __i++ ) {",
|
|
8001
8073
|
"const __a = __zuzu_call_args[__i];",
|
|
8002
|
-
|
|
8003
|
-
"}"
|
|
8074
|
+
'if ( __zuzu_is_pairlist( __a ) ) { __zuzu_named_args = __a; } else { throw new Exception( "named arguments not allowed for this function" ); }',
|
|
8075
|
+
"}",
|
|
8076
|
+
`const ${signature.namedName} = __zuzu_named_args;`
|
|
8004
8077
|
].join("\n");
|
|
8005
8078
|
case "variadic":
|
|
8006
8079
|
return [
|
|
8007
8080
|
"const __zuzu_call_args = Array.prototype.slice.call( arguments );",
|
|
8008
|
-
`
|
|
8009
|
-
|
|
8081
|
+
`const ${signature.headName} = __zuzu_call_args[0];`,
|
|
8082
|
+
"const __zuzu_rest_args = [];",
|
|
8010
8083
|
"for ( let __i = 1; __i < __zuzu_call_args.length; __i++ ) {",
|
|
8011
8084
|
"const __a = __zuzu_call_args[__i];",
|
|
8012
|
-
|
|
8013
|
-
"}"
|
|
8085
|
+
'if ( __zuzu_is_pairlist( __a ) ) { throw new Exception( "named arguments not allowed for this function" ); } __zuzu_rest_args.push( __a );',
|
|
8086
|
+
"}",
|
|
8087
|
+
`const ${signature.restName} = __zuzu_rest_args;`
|
|
8014
8088
|
].join("\n");
|
|
8015
8089
|
default:
|
|
8016
8090
|
return "";
|
|
@@ -8077,7 +8151,7 @@ globalThis[${JSON.stringify(node.id.name)}] = ${name2};` : declaration;
|
|
|
8077
8151
|
const moduleName = `__zuzu_imported_${Math.abs(hashString(node.source))}_${node.specifiers.length}_${options.syncEval ? loopCounter++ : 0}`;
|
|
8078
8152
|
const defineImports = node.specifiers.map((specifier) => {
|
|
8079
8153
|
const importedName = normalizeImportedName(node.source, specifier.imported);
|
|
8080
|
-
if (node.source === "std/eval" && importedName === "eval"
|
|
8154
|
+
if (node.source === "std/eval" && importedName === "eval") {
|
|
8081
8155
|
return "";
|
|
8082
8156
|
}
|
|
8083
8157
|
return defineLiveImport(specifier.local, moduleName, importedName, options);
|
|
@@ -8263,6 +8337,21 @@ ${cleanup}
|
|
|
8263
8337
|
}
|
|
8264
8338
|
return names;
|
|
8265
8339
|
}
|
|
8340
|
+
function collectEvalImportNames(statements = []) {
|
|
8341
|
+
const names = [];
|
|
8342
|
+
for (const stmt of statements) {
|
|
8343
|
+
if (stmt.type !== "ImportDeclaration" || stmt.source !== "std/eval") {
|
|
8344
|
+
continue;
|
|
8345
|
+
}
|
|
8346
|
+
for (const specifier of stmt.specifiers || []) {
|
|
8347
|
+
const importedName = normalizeImportedName(stmt.source, specifier.imported);
|
|
8348
|
+
if (importedName === "eval" && specifier.local) {
|
|
8349
|
+
names.push(specifier.local);
|
|
8350
|
+
}
|
|
8351
|
+
}
|
|
8352
|
+
}
|
|
8353
|
+
return names;
|
|
8354
|
+
}
|
|
8266
8355
|
function collectDeclaredNames(statements) {
|
|
8267
8356
|
const names = [];
|
|
8268
8357
|
for (const stmt of statements || []) {
|
|
@@ -8741,7 +8830,7 @@ ${cleanup}
|
|
|
8741
8830
|
if (node.callee.type === "Super") {
|
|
8742
8831
|
const argArray = emitCallArgumentArray(node.arguments);
|
|
8743
8832
|
source = `__zuzu_super_dispatch( __zuzu_super_static__, self, __zuzu_super_class__, __zuzu_super_method__, ${argArray} )`;
|
|
8744
|
-
} else if (node.callee.type === "Identifier" &&
|
|
8833
|
+
} else if (node.callee.type === "Identifier" && (options.evalNames || /* @__PURE__ */ new Set(["eval"])).has(node.callee.name) && node.arguments.length > 0) {
|
|
8745
8834
|
source = emitEvalCall(node.arguments);
|
|
8746
8835
|
} else if (node.callee.type === "MemberExpression" && !node.callee.computed && node.callee.property.type === "Identifier" && node.callee.property.name === "length" && node.arguments.length === 0) {
|
|
8747
8836
|
source = `__zuzu_length( ${emitExpression(node.callee.object)} )`;
|
|
@@ -8972,7 +9061,7 @@ ${cleanup}
|
|
|
8972
9061
|
return `__zuzu_ne( ${left}, ${right} )`;
|
|
8973
9062
|
case "!=":
|
|
8974
9063
|
case "\u2260":
|
|
8975
|
-
return `
|
|
9064
|
+
return `__zuzu_ne( ${left}, ${right} )`;
|
|
8976
9065
|
case "~":
|
|
8977
9066
|
return `__zuzu_match( ${left}, ${right} )`;
|
|
8978
9067
|
case "_":
|
|
@@ -9150,12 +9239,8 @@ ${cleanup}
|
|
|
9150
9239
|
function emitSliceExpression(node) {
|
|
9151
9240
|
const object = emitExpression(node.object);
|
|
9152
9241
|
const start = node.start ? emitExpression(node.start) : "0";
|
|
9153
|
-
|
|
9154
|
-
|
|
9155
|
-
}
|
|
9156
|
-
const length = emitExpression(node.length);
|
|
9157
|
-
const end = isNegativeNumericLiteral(node.length) ? length : `__zuzu_add( ${start}, ${length} )`;
|
|
9158
|
-
return `${object}.slice( ${start}, ${end} )`;
|
|
9242
|
+
const length = node.length == null ? "null" : emitExpression(node.length);
|
|
9243
|
+
return `__zuzu_get_slice( ${object}, ${start}, ${length} )`;
|
|
9159
9244
|
}
|
|
9160
9245
|
function unwrapGroupedExpression(node) {
|
|
9161
9246
|
let current = node;
|
|
@@ -9164,9 +9249,6 @@ ${cleanup}
|
|
|
9164
9249
|
}
|
|
9165
9250
|
return current;
|
|
9166
9251
|
}
|
|
9167
|
-
function isNegativeNumericLiteral(node) {
|
|
9168
|
-
return !!(node && node.type === "UnaryExpression" && node.operator === "-" && node.argument && node.argument.type === "NumericLiteral");
|
|
9169
|
-
}
|
|
9170
9252
|
function emitRegexReplaceExpression(node) {
|
|
9171
9253
|
const leftTarget = unwrapGroupedExpression(node.left);
|
|
9172
9254
|
if (leftTarget && leftTarget.type === "BinaryExpression" && ["@", "@@", "@?"].includes(leftTarget.operator)) {
|
|
@@ -10973,6 +11055,14 @@ ${cleanup}
|
|
|
10973
11055
|
slurp_utf8_async() {
|
|
10974
11056
|
return new Task(async () => fs.promises.readFile(this.value, "utf8"));
|
|
10975
11057
|
}
|
|
11058
|
+
append(value) {
|
|
11059
|
+
traceBlockingOperation("std/io Path.append");
|
|
11060
|
+
if (!(value && value.bytes instanceof Uint8Array)) {
|
|
11061
|
+
throw new Error(`TypeException: Path.append expects BinaryString, got ${typeName2(value)}`);
|
|
11062
|
+
}
|
|
11063
|
+
fs.appendFileSync(this.value, Buffer.from(value.bytes));
|
|
11064
|
+
return this;
|
|
11065
|
+
}
|
|
10976
11066
|
append_async(value) {
|
|
10977
11067
|
return new Task(async () => {
|
|
10978
11068
|
if (!(value && value.bytes instanceof Uint8Array)) {
|
|
@@ -10982,6 +11072,14 @@ ${cleanup}
|
|
|
10982
11072
|
return this;
|
|
10983
11073
|
});
|
|
10984
11074
|
}
|
|
11075
|
+
append_utf8(text) {
|
|
11076
|
+
traceBlockingOperation("std/io Path.append_utf8");
|
|
11077
|
+
if (typeof text !== "string") {
|
|
11078
|
+
throw new Error(`TypeException: Path.append_utf8 expects String, got ${typeName2(text)}`);
|
|
11079
|
+
}
|
|
11080
|
+
fs.appendFileSync(this.value, text, "utf8");
|
|
11081
|
+
return this;
|
|
11082
|
+
}
|
|
10985
11083
|
append_utf8_async(text) {
|
|
10986
11084
|
return new Task(async () => {
|
|
10987
11085
|
if (typeof text !== "string") {
|
|
@@ -12492,10 +12590,11 @@ ${cleanup}
|
|
|
12492
12590
|
if (typeof target === "string" || Array.isArray(target)) {
|
|
12493
12591
|
let resolved = Number(index);
|
|
12494
12592
|
if (Number.isFinite(resolved)) {
|
|
12593
|
+
const indexed = typeof target === "string" ? [...target] : target;
|
|
12495
12594
|
if (resolved < 0) {
|
|
12496
|
-
resolved =
|
|
12595
|
+
resolved = indexed.length + resolved;
|
|
12497
12596
|
}
|
|
12498
|
-
return resolveWeakValue(
|
|
12597
|
+
return resolveWeakValue(indexed[resolved] ?? null);
|
|
12499
12598
|
}
|
|
12500
12599
|
}
|
|
12501
12600
|
if (target && typeof target === "object" && target.constructor && typeof target.constructor.__zuzu_class_name === "string" && !Object.prototype.hasOwnProperty.call(target, key) && typeof target[key] === "function") {
|
|
@@ -12503,22 +12602,58 @@ ${cleanup}
|
|
|
12503
12602
|
}
|
|
12504
12603
|
return resolveWeakValue(target[index]);
|
|
12505
12604
|
}
|
|
12605
|
+
function zuzuSliceBounds(size, from, length) {
|
|
12606
|
+
let start = Number(from ?? 0);
|
|
12607
|
+
if (!Number.isFinite(start)) {
|
|
12608
|
+
start = 0;
|
|
12609
|
+
}
|
|
12610
|
+
if (start < 0) {
|
|
12611
|
+
start = size + start;
|
|
12612
|
+
}
|
|
12613
|
+
start = Math.max(0, Math.min(size, start));
|
|
12614
|
+
if (length == null) {
|
|
12615
|
+
return [start, size];
|
|
12616
|
+
}
|
|
12617
|
+
const span = Number(length);
|
|
12618
|
+
if (!Number.isFinite(span)) {
|
|
12619
|
+
return [start, start];
|
|
12620
|
+
}
|
|
12621
|
+
const end = span < 0 ? Math.max(0, Math.min(size, size + span)) : Math.max(0, Math.min(size, start + span));
|
|
12622
|
+
return [Math.min(start, end), Math.max(start, end)];
|
|
12623
|
+
}
|
|
12624
|
+
function zuzuGetSlice(target, from, length) {
|
|
12625
|
+
target = resolveWeakValue(target);
|
|
12626
|
+
if (target == null) {
|
|
12627
|
+
return null;
|
|
12628
|
+
}
|
|
12629
|
+
if (typeof target === "string") {
|
|
12630
|
+
const chars = [...target];
|
|
12631
|
+
const [start, end] = zuzuSliceBounds(chars.length, from, length);
|
|
12632
|
+
return chars.slice(start, end).join("");
|
|
12633
|
+
}
|
|
12634
|
+
if (target instanceof ZuzuBinary) {
|
|
12635
|
+
const [start, end] = zuzuSliceBounds(target.length, from, length);
|
|
12636
|
+
return target.slice(start, end);
|
|
12637
|
+
}
|
|
12638
|
+
if (Array.isArray(target)) {
|
|
12639
|
+
const [start, end] = zuzuSliceBounds(target.length, from, length);
|
|
12640
|
+
return target.slice(start, end);
|
|
12641
|
+
}
|
|
12642
|
+
return target.slice(from, length == null ? void 0 : Number(from) + Number(length));
|
|
12643
|
+
}
|
|
12506
12644
|
function zuzuAssignSlice(target, from, length, value) {
|
|
12507
12645
|
const hasLength = length != null;
|
|
12508
|
-
const span = hasLength ? Number(length) : null;
|
|
12509
12646
|
const replacement = value == null ? "" : value;
|
|
12510
12647
|
if (typeof target === "string") {
|
|
12511
|
-
|
|
12512
|
-
|
|
12513
|
-
|
|
12514
|
-
|
|
12515
|
-
start2 = Math.max(0, Math.min(target.length, start2));
|
|
12516
|
-
const end = hasLength ? Math.max(0, Math.min(target.length, span >= 0 ? start2 + span : target.length + span)) : target.length;
|
|
12517
|
-
return target.slice(0, start2) + String(replacement) + target.slice(end);
|
|
12648
|
+
const chars = [...target];
|
|
12649
|
+
const [start2, end] = zuzuSliceBounds(chars.length, from, length);
|
|
12650
|
+
chars.splice(start2, end - start2, ...[...String(replacement)]);
|
|
12651
|
+
return chars.join("");
|
|
12518
12652
|
}
|
|
12519
12653
|
const start = Number(from);
|
|
12520
12654
|
if (Array.isArray(target)) {
|
|
12521
12655
|
const items = Array.isArray(replacement) ? replacement : [replacement];
|
|
12656
|
+
const span = hasLength ? Number(length) : null;
|
|
12522
12657
|
if (hasLength) {
|
|
12523
12658
|
target.splice(start, span, ...items);
|
|
12524
12659
|
} else {
|
|
@@ -12527,7 +12662,16 @@ ${cleanup}
|
|
|
12527
12662
|
return target;
|
|
12528
12663
|
}
|
|
12529
12664
|
if (target instanceof ZuzuBinary) {
|
|
12530
|
-
|
|
12665
|
+
if (!(value instanceof ZuzuBinary)) {
|
|
12666
|
+
throw new Error(`TypeException: BinaryString slice assignment expects BinaryString, got ${zuzuTypeof(value)}`);
|
|
12667
|
+
}
|
|
12668
|
+
const [byteStart, byteEnd] = zuzuSliceBounds(target.length, from, length);
|
|
12669
|
+
const next = new Uint8Array(target.length - (byteEnd - byteStart) + value.bytes.length);
|
|
12670
|
+
next.set(target.bytes.slice(0, byteStart), 0);
|
|
12671
|
+
next.set(value.bytes, byteStart);
|
|
12672
|
+
next.set(target.bytes.slice(byteEnd), byteStart + value.bytes.length);
|
|
12673
|
+
target.bytes = next;
|
|
12674
|
+
return target;
|
|
12531
12675
|
}
|
|
12532
12676
|
throw new Error(`TypeException: slice assignment expects String or Array, got ${zuzuTypeof(target)}`);
|
|
12533
12677
|
}
|
|
@@ -12547,18 +12691,27 @@ ${cleanup}
|
|
|
12547
12691
|
throw new Error("TypeException: cannot assign to null");
|
|
12548
12692
|
}
|
|
12549
12693
|
if (target instanceof ZuzuBinary) {
|
|
12550
|
-
|
|
12694
|
+
if (!(value instanceof ZuzuBinary)) {
|
|
12695
|
+
throw new Error(`TypeException: BinaryString index assignment expects BinaryString, got ${zuzuTypeof(value)}`);
|
|
12696
|
+
}
|
|
12697
|
+
zuzuAssignSlice(target, index, 1, value);
|
|
12698
|
+
if (typeof assignTarget === "function") {
|
|
12699
|
+
assignTarget(target);
|
|
12700
|
+
}
|
|
12701
|
+
return target;
|
|
12551
12702
|
}
|
|
12552
12703
|
if (typeof target === "string") {
|
|
12553
12704
|
let resolved = Number(index);
|
|
12554
12705
|
if (!Number.isFinite(resolved)) {
|
|
12555
12706
|
throw new Error("TypeException: String index assignment expects numeric index");
|
|
12556
12707
|
}
|
|
12708
|
+
const chars = [...target];
|
|
12557
12709
|
if (resolved < 0) {
|
|
12558
|
-
resolved =
|
|
12710
|
+
resolved = chars.length + resolved;
|
|
12559
12711
|
}
|
|
12560
|
-
resolved = Math.max(0, Math.min(
|
|
12561
|
-
|
|
12712
|
+
resolved = Math.max(0, Math.min(chars.length, resolved));
|
|
12713
|
+
chars.splice(resolved, resolved < chars.length ? 1 : 0, ...[...String(value ?? "")]);
|
|
12714
|
+
const updated = chars.join("");
|
|
12562
12715
|
return typeof assignTarget === "function" ? assignTarget(updated) : updated;
|
|
12563
12716
|
}
|
|
12564
12717
|
if (isPairListLike(target)) {
|
|
@@ -12578,14 +12731,10 @@ ${cleanup}
|
|
|
12578
12731
|
const hasLength = length != null;
|
|
12579
12732
|
const span = hasLength ? Number(length) : null;
|
|
12580
12733
|
if (arguments.length === 0) {
|
|
12581
|
-
|
|
12582
|
-
if (target instanceof ZuzuBinary) {
|
|
12583
|
-
return target.slice(start, end);
|
|
12584
|
-
}
|
|
12585
|
-
return target.slice(start, end);
|
|
12734
|
+
return zuzuGetSlice(target, start, hasLength ? span : null);
|
|
12586
12735
|
}
|
|
12587
|
-
if (target instanceof ZuzuBinary) {
|
|
12588
|
-
|
|
12736
|
+
if (target instanceof ZuzuBinary || typeof target === "string") {
|
|
12737
|
+
return zuzuAssignSlice(target, start, hasLength ? span : null, maybeValue);
|
|
12589
12738
|
}
|
|
12590
12739
|
if (!hasLength) {
|
|
12591
12740
|
target.splice(start, target.length - start, ...maybeValue);
|
|
@@ -12714,6 +12863,13 @@ ${cleanup}
|
|
|
12714
12863
|
if (typeName2 === "PairList") {
|
|
12715
12864
|
return isPairListLike(value) ? 1 : 0;
|
|
12716
12865
|
}
|
|
12866
|
+
if (typeName2 === "Exception") {
|
|
12867
|
+
const globalType2 = globalThis.Exception;
|
|
12868
|
+
if (globalType2 != null && zuzuInstanceof(value, globalType2)) {
|
|
12869
|
+
return 1;
|
|
12870
|
+
}
|
|
12871
|
+
return value instanceof Error ? 1 : 0;
|
|
12872
|
+
}
|
|
12717
12873
|
return zuzuTypeof(value) === typeName2 ? 1 : 0;
|
|
12718
12874
|
}
|
|
12719
12875
|
if (typeName2 === "BinaryString") {
|
|
@@ -13948,6 +14104,9 @@ ${cleanup}
|
|
|
13948
14104
|
__zuzu_ref_key(target, key) {
|
|
13949
14105
|
return refKey(target, key);
|
|
13950
14106
|
},
|
|
14107
|
+
__zuzu_get_slice(target, from, length) {
|
|
14108
|
+
return zuzuGetSlice(target, from, length);
|
|
14109
|
+
},
|
|
13951
14110
|
__zuzu_ref_slice(target, from, length) {
|
|
13952
14111
|
return refSlice(target, from, length);
|
|
13953
14112
|
},
|
|
@@ -39328,9 +39487,9 @@ ${lines.join("\n")}
|
|
|
39328
39487
|
}
|
|
39329
39488
|
});
|
|
39330
39489
|
|
|
39331
|
-
// ../../../../../tmp/zuzu-browser-build.
|
|
39490
|
+
// ../../../../../tmp/zuzu-browser-build.WePoiO/browser-stdlib.generated.js
|
|
39332
39491
|
var require_browser_stdlib_generated = __commonJS({
|
|
39333
|
-
"../../../../../tmp/zuzu-browser-build.
|
|
39492
|
+
"../../../../../tmp/zuzu-browser-build.WePoiO/browser-stdlib.generated.js"(exports2, module2) {
|
|
39334
39493
|
"use strict";
|
|
39335
39494
|
function createBrowserStdlib2() {
|
|
39336
39495
|
const jsModules = /* @__PURE__ */ Object.create(null);
|
|
@@ -45188,9 +45347,10 @@ class ZZTemplate extends ZTemplate {
|
|
|
45188
45347
|
}
|
|
45189
45348
|
}
|
|
45190
45349
|
`;
|
|
45350
|
+
virtualFiles["/modules/test/more.zzm"] = '=encoding utf8\n\n=head1 NAME\n\ntest/more - Write unit tests and integration tests in ZuzuScript.\n\n=head1 SYNOPSIS\n\n from test/more import *;\n from my/project import frobnicate;\n\n is(frobnicate(21), 42, "frobinated 21 correctly");\n is(frobnicate(null), null, "frobinate on null input");\n\n done_testing();\n\n=cut\n\n\nlet Number _COUNT := 0;\nlet Number _PASSED := 0;\nlet Number _FAILED := 0;\nlet Number _LEVEL := 0;\nlet Number _PLAN := -1;\nlet Number _TODO_FAILED := 0;\nlet Number _TODO_PASSED := 0;\n\nlet TODO;\n\nfunction _directive () {\n if ( TODO ) {\n if ( TODO instanceof String ) {\n return ` # TODO ${TODO}`;\n }\n else {\n return " # TODO";\n }\n }\n return "";\n}\n\nfunction _indent () {\n let i := _LEVEL;\n let str := "";\n while ( i > 0 ) {\n str _= " ";\n i--;\n }\n\n return str;\n}\n\nclass BailOutException extends Exception;\nclass SkipAllException extends Exception;\n\nfunction _module_name_is_valid ( String module ) {\n return module ~ /^[A-Za-z_][A-Za-z0-9_]*(\\/[A-Za-z_][A-Za-z0-9_]*)*$/;\n}\n\nfunction _module_is_available ( String module ) {\n from std/eval import eval;\n\n try {\n eval( `do { from ${module} import *; }; true;` );\n return true;\n }\n catch {\n return false;\n }\n}\n\nfunction _capability_is_available ( String capability ) {\n if ( not( capability ~ /^[A-Za-z_][A-Za-z0-9_]*$/ ) ) {\n die `Invalid capability name: ${capability}`;\n }\n\n let deny_key := `deny_${capability}`;\n if ( deny_key in __system__ ) {\n return not __system__.get(deny_key);\n }\n\n return false;\n}\n\n=head1 IMPLEMENTATION SUPPORT\n\nThis module is supported by all implementations of ZuzuScript.\n\n=head1 DESCRIPTION\n\nC<< test/more >> is a module for test-driven development. It can be used\nfor writing unit tests and integration tests. It generates output in TAP\nL<https://testanything.org/>.\n\nThis module should feel familiar to anybody who has used C<< Test::More >>\nfor Perl, though there are some minor differences.\n\n=head2 Functions\n\n=over\n\n=item C<< pass(String name?) >>\n\nIndicates the named test has passed.\n\n=cut\n\nfunction pass ( String name? ) {\n ++_PASSED;\n ++_COUNT;\n ++_TODO_PASSED if TODO;\n if ( name \u2261 null ) {\n say `${_indent()}ok ${_COUNT}${_directive()}`;\n }\n else {\n say `${_indent()}ok ${_COUNT} - ${name}${_directive()}`;\n }\n\n return true;\n}\n\n=item C<< fail(String name?) >>\n\nIndicates the named test has failed.\n\n=cut\n\nfunction fail ( String name ) {\n ++_FAILED;\n ++_COUNT;\n ++_TODO_FAILED if TODO;\n if ( name \u2261 null ) {\n say `${_indent()}not ok ${_COUNT}${_directive()}`;\n }\n else {\n say `${_indent()}not ok ${_COUNT} - ${name}${_directive()}`;\n }\n\n return false;\n}\n\n=item C<< ok(expr, String name?) >>\n\nPasses the named test only if C<expr> is truthy.\n\n=cut\n\nfunction ok ( expr, String name? ) {\n if (expr) {\n return pass(name);\n }\n else {\n return fail(name);\n }\n}\n\nfunction _coerced_equal ( got, expected ) {\n if ( got \u2261 expected ) {\n return true;\n }\n\n if ( got instanceof Boolean and expected instanceof Number ) {\n return ( got ? 1: 0 ) = expected;\n }\n if ( got instanceof Number and expected instanceof Boolean ) {\n return got = ( expected ? 1: 0 );\n }\n\n return false;\n}\n\n=item C<< is(got, expected, String name?) >>\n\nPasses the named test only if C<< got \u2261 expected >>.\n\n=cut\n\nfunction is ( got, expected, String name? ) {\n\n if ( not ok( _coerced_equal( got, expected ), name ) ) {\n from std/dump import Dumper;\n say `${_indent()}# expected: ${Dumper.dump(expected)}`;\n say `${_indent()}# got: ${Dumper.dump(got)}`;\n return false;\n }\n\n return true;\n}\n\n=item C<< isnt(got, unexpected, String name?) >>\n\nPasses the named test only if C<< got \u2262 expected >>.\n\n=cut\n\nfunction isnt ( got, unexpected, String name? ) {\n return ok( not _coerced_equal( got, unexpected ), name );\n}\n\n=item C<< like(got, expected_re, String name?) >>\n\nPasses the named test only if C<< got ~ expected >>.\n\n=cut\n\nfunction like ( got, Regexp expected_re, String name? ) {\n\n if ( not ok( got ~ expected_re, name ) ) {\n say `${_indent()}# expected (regexp): ${expected_re}`;\n say `${_indent()}# got: ${got}`;\n return false;\n }\n\n return true;\n}\n\n=item C<< unlike(got, unexpected_re, String name?) >>\n\nFails the named test only if C<< got ~ expected >>.\n\n=cut\n\nfunction unlike ( got, Regexp unexpected_re, String name? ) {\n\n if ( not ok( not( got ~ unexpected_re ), name ) ) {\n say `${_indent()}# unexpected (regexp): ${unexpected_re}`;\n say `${_indent()}# got: ${got}`;\n return false;\n }\n\n return true;\n}\n\n=item C<< diag(diagnostic) >>\n\nOutputs the diagnostic.\n\n=cut\n\nfunction diag (diagnostic) {\n say `${_indent()}# ${diagnostic}`;\n return true;\n}\n\n=item C<< explain(value) >>\n\nCombines diag with Dumper.dump();\n\n=cut\n\nfunction explain (value) {\n from std/dump import Dumper;\n return diag( Dumper.dump(value) );\n}\n\n=item C<< bail_out(String message?) >>\n\nBail out of running further tests.\n\n=cut\n\nfunction bail_out ( String message? ) {\n let e;\n if ( message \u2261 null ) {\n e := new BailOutException( message: "Bail out!" );\n }\n else {\n e := new BailOutException( message: `Bail out! ${message}` );\n }\n throw e;\n}\n\n=item C<< skip_all(String reason) >>\n\nSkips the whole test file by emitting a TAP skip-all plan and exiting\nsuccessfully when the runtime provides C<std/proc>.\n\nThis is intended for guards at the beginning of a test script, before\nany tests have run. Browser-like hosts without C<std/proc> use a\nspecial exception fallback that the browser ztest runner treats as a\nskip.\n\n=cut\n\nfunction skip_all ( String reason ) {\n die "Cannot skip all tests after tests have already run" if _COUNT > 0;\n die "Cannot skip all tests in a subtest" if _LEVEL > 0;\n _PLAN := 0;\n say `1..${_PLAN} # SKIP: ${reason}`;\n\n from std/proc try import Proc;\n Proc.exit(0) if Proc \u2262 null;\n throw new SkipAllException( message: reason );\n}\n\n=item C<< requires_module(String module) >>\n\nSkips the whole test file if the named module cannot be loaded.\n\n=cut\n\nfunction requires_module ( String module ) {\n if ( not _module_name_is_valid(module) ) {\n die `Invalid module name: ${module}`;\n }\n\n if ( not _module_is_available(module) ) {\n skip_all( `module ${module} is unavailable` );\n }\n\n return true;\n}\n\n=item C<< requires_capability(String capability) >>\n\nSkips the whole test file if the named runtime capability is not\navailable.\n\n=cut\n\nfunction requires_capability ( String capability ) {\n if ( not _capability_is_available(capability) ) {\n skip_all( `capability ${capability} is unavailable` );\n }\n\n return true;\n}\n\n=item C<< author_testing() >>\n\nSkips the whole test file unless the C<AUTHOR_TESTING> environment\nvariable is set to a true value.\n\n=cut\n\nfunction author_testing () {\n requires_capability( "proc" );\n from std/proc try import Env;\n if ( Env and Env.get( "AUTHOR_TESTING", false ) ) {\n return true;\n }\n skip_all( "requires AUTHOR_TESTING=1" );\n}\n\n=item C<< extended_testing() >>\n\nSkips the whole test file unless the C<EXTENDED_TESTING> environment\nvariable is set to a true value.\n\n=cut\n\nfunction extended_testing () {\n requires_capability( "proc" );\n from std/proc try import Env;\n if ( Env and Env.get( "EXTENDED_TESTING", false ) ) {\n return true;\n }\n skip_all( "requires EXTENDED_TESTING=1" );\n}\n\n=item C<< plan(Number n) >>\n\nIndicate the number of tests you intend on running, before running any\ntests.\n\ndone_testing() can later check the number.\n\n=cut\n\nfunction plan ( Number n ) {\n die "Must plan() before running any tests" if _COUNT > 0;\n die "Cannot plan() in a subtest" if _LEVEL > 0;\n die "Must plan() at least one test" if n < 1;\n _PLAN := n;\n say `1..${_PLAN}`;\n}\n\n=item C<< done_testing(Number n?) >>\n\nIndicates that testing is finished.\n\nYou may optionally provide the expected total number of tests, and the\nfunction will throw an exception if that doesn\'t match the number of\ntests which were actually run.\n\nWill also throw an error if you called plan() earlier and the actual\nnumber of tests run differs from your plan.\n\n=cut\n\nfunction done_testing ( Number n? ) {\n die "Unexpected done_testing() in subtest" if _LEVEL > 0;\n die `Expected ${n} tests, but ran ${_COUNT}` if n \u2262 null and n \u2260 _COUNT;\n\n function maybe_fail_count ( should_die ) {\n if ( _TODO_PASSED > 0 ) {\n warn `Passed ${_TODO_PASSED} TODO tests!`;\n }\n if ( _FAILED > 0 ) {\n let msg := `Failed ${_FAILED} tests`;\n msg _= ` (${_TODO_FAILED} todo, ${_FAILED - _TODO_FAILED} true fails)` if _TODO_FAILED > 0;\n die msg if should_die and ( _FAILED > _TODO_FAILED );\n warn msg;\n }\n }\n\n if ( _PLAN < 0 ) {\n say `1..${_COUNT}`;\n }\n else if ( _PLAN \u2260 _COUNT ) {\n maybe_fail_count(false);\n die `Planned ${_PLAN} tests, but ran ${_COUNT}`;\n }\n\n maybe_fail_count(true);\n return true;\n}\n\n=item C<< subtest(String name, Function f) >>\n\nCalls f() as a subtest.\n\nDon\'t use done_testing() within the function.\n\n=cut\n\nfunction subtest ( String name, Function f ) {\n let orig_context := {\n count: _COUNT,\n passed: _PASSED,\n failed: _FAILED,\n level: _LEVEL,\n todo_passed: _TODO_PASSED,\n todo_failed: _TODO_FAILED,\n };\n\n function restore_context () {\n _COUNT := orig_context{count};\n _PASSED := orig_context{passed};\n _FAILED := orig_context{failed};\n _LEVEL := orig_context{level};\n _TODO_PASSED := orig_context{todo_passed};\n _TODO_FAILED := orig_context{todo_failed};\n }\n\n _COUNT := 0;\n _PASSED := 0;\n _FAILED := 0;\n _TODO_PASSED := 0;\n _TODO_FAILED := 0;\n _LEVEL++;\n let is_ok := true;\n\n try {\n diag( `Subtest: ${name}` );\n f();\n say `${_indent()}1..${_COUNT}`;\n is_ok := false if _FAILED > _TODO_FAILED;\n restore_context();\n }\n catch ( BailOutException e ) {\n throw e;\n }\n catch ( Exception e ) {\n is_ok := false;\n restore_context();\n }\n\n return ok( is_ok, name );\n}\n\n=back\n\n=item C<< todo(Boolean c, String reason, Function f) >>\n\nRuns the tests in the given function, but if condition c is true then\nfirst sets TODO to true.\n\nYou can manually set and unset the TODO variable instead.\n\n=cut\n\nfunction todo ( Boolean c, String reason, Function f ) {\n let orig := TODO;\n TODO := reason if c;\n try {\n f();\n }\n catch {\n }\n TODO := orig;\n return not c;\n}\n\n=back\n\n=item C<< exception(Function f) >>\n\nCalls f() and returns any exception thrown.\n\nReturns null if no exception was thrown.\n\n=cut\n\nfunction exception ( Function f ) {\n try {\n f();\n return null;\n }\n catch ( BailOutException e ) {\n throw e;\n }\n catch ( Exception e ) {\n return e;\n }\n}\n\n=back\n\n=head1 COPYRIGHT AND LICENCE\n\nB<< test/more >> is copyright Toby Inkster.\n\nIt is free software; you may redistribute it and/or modify it under\nthe terms of either the Artistic License 1.0 or the GNU General Public\nLicense version 2.\n\n=cut\n';
|
|
45191
45351
|
return {
|
|
45192
45352
|
repoRoot: "/",
|
|
45193
|
-
includePaths: [],
|
|
45353
|
+
includePaths: ["/__zuzu_browser_modules__/0"],
|
|
45194
45354
|
jsModules,
|
|
45195
45355
|
virtualFiles
|
|
45196
45356
|
};
|
|
@@ -45566,7 +45726,7 @@ class ZZTemplate extends ZTemplate {
|
|
|
45566
45726
|
}
|
|
45567
45727
|
});
|
|
45568
45728
|
|
|
45569
|
-
// ../../../../../tmp/zuzu-browser-build.
|
|
45729
|
+
// ../../../../../tmp/zuzu-browser-build.WePoiO/browser-worker-entry.generated.js
|
|
45570
45730
|
var { createBrowserStdlib } = require_browser_stdlib_generated();
|
|
45571
45731
|
globalThis.__ZUZU_BROWSER_DEFAULT_RUNTIME_OPTIONS__ = createBrowserStdlib();
|
|
45572
45732
|
var { installBrowserWorker } = require_browser_worker_entry();
|