@weborigami/language 0.6.1 → 0.6.3
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/package.json +2 -2
- package/src/compiler/origami.pegjs +2 -0
- package/src/compiler/parse.js +113 -91
- package/src/compiler/parserHelpers.js +2 -0
- package/src/handlers/yaml_handler.js +115 -31
- package/src/project/jsGlobals.js +2 -62
- package/src/protocols/constructHref.js +3 -0
- package/src/protocols/explorehttp.js +13 -0
- package/src/protocols/protocolGlobals.js +1 -0
- package/src/protocols/protocols.js +1 -0
- package/src/runtime/errors.js +18 -5
- package/src/runtime/ops.js +10 -0
- package/test/handlers/yaml_handler.test.js +2 -5
- package/test/project/jsGlobals.test.js +14 -8
- package/test/runtime/ops.test.js +18 -0
- package/test/runtime/jsGlobals.test.js +0 -21
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weborigami/language",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.3",
|
|
4
4
|
"description": "Web Origami expression language compiler and runtime",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./main.js",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"typescript": "5.9.3"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@weborigami/async-tree": "0.6.
|
|
14
|
+
"@weborigami/async-tree": "0.6.3",
|
|
15
15
|
"exif-parser": "0.1.12",
|
|
16
16
|
"watcher": "2.3.1",
|
|
17
17
|
"yaml": "2.8.1"
|
package/src/compiler/parse.js
CHANGED
|
@@ -396,17 +396,19 @@ function peg$parse(input, options) {
|
|
|
396
396
|
const peg$c55 = "?.";
|
|
397
397
|
const peg$c56 = "<=";
|
|
398
398
|
const peg$c57 = ">=";
|
|
399
|
-
const peg$c58 = "
|
|
400
|
-
const peg$c59 = "
|
|
401
|
-
const peg$c60 = "
|
|
402
|
-
const peg$c61 = "
|
|
403
|
-
const peg$c62 = "
|
|
404
|
-
const peg$c63 = "
|
|
405
|
-
const peg$c64 = "
|
|
406
|
-
const peg$c65 = "
|
|
407
|
-
const peg$c66 = "
|
|
408
|
-
const peg$c67 = "
|
|
409
|
-
const peg$c68 = "
|
|
399
|
+
const peg$c58 = "instanceof";
|
|
400
|
+
const peg$c59 = "in";
|
|
401
|
+
const peg$c60 = "#!";
|
|
402
|
+
const peg$c61 = "<<";
|
|
403
|
+
const peg$c62 = ">>>";
|
|
404
|
+
const peg$c63 = ">>";
|
|
405
|
+
const peg$c64 = "\u2192";
|
|
406
|
+
const peg$c65 = "->";
|
|
407
|
+
const peg$c66 = "${";
|
|
408
|
+
const peg$c67 = "~";
|
|
409
|
+
const peg$c68 = "await";
|
|
410
|
+
const peg$c69 = "typeof";
|
|
411
|
+
const peg$c70 = "void";
|
|
410
412
|
|
|
411
413
|
const peg$r0 = /^[^\/>\t\n\r]/;
|
|
412
414
|
const peg$r1 = /^[0-9]/;
|
|
@@ -515,31 +517,33 @@ function peg$parse(input, options) {
|
|
|
515
517
|
const peg$e88 = peg$classExpectation(["/", "\n", "\r"], true, false, false);
|
|
516
518
|
const peg$e89 = peg$literalExpectation("<=", false);
|
|
517
519
|
const peg$e90 = peg$literalExpectation(">=", false);
|
|
518
|
-
const peg$e91 = peg$literalExpectation("
|
|
519
|
-
const peg$e92 = peg$
|
|
520
|
-
const peg$e93 = peg$literalExpectation("
|
|
521
|
-
const peg$e94 = peg$
|
|
522
|
-
const peg$e95 = peg$literalExpectation("
|
|
523
|
-
const peg$e96 = peg$
|
|
524
|
-
const peg$e97 = peg$literalExpectation("
|
|
525
|
-
const peg$e98 = peg$
|
|
526
|
-
const peg$e99 = peg$
|
|
527
|
-
const peg$e100 = peg$
|
|
528
|
-
const peg$e101 = peg$
|
|
529
|
-
const peg$e102 = peg$otherExpectation("
|
|
530
|
-
const peg$e103 = peg$
|
|
531
|
-
const peg$e104 = peg$otherExpectation("template
|
|
532
|
-
const peg$e105 = peg$
|
|
533
|
-
const peg$e106 = peg$
|
|
534
|
-
const peg$e107 = peg$classExpectation(["
|
|
535
|
-
const peg$e108 = peg$literalExpectation("
|
|
536
|
-
const peg$e109 = peg$
|
|
537
|
-
const peg$e110 = peg$literalExpectation("
|
|
538
|
-
const peg$e111 = peg$
|
|
539
|
-
const peg$e112 = peg$
|
|
540
|
-
const peg$e113 = peg$classExpectation([
|
|
541
|
-
const peg$e114 = peg$
|
|
542
|
-
const peg$e115 = peg$classExpectation(["
|
|
520
|
+
const peg$e91 = peg$literalExpectation("instanceof", false);
|
|
521
|
+
const peg$e92 = peg$literalExpectation("in", false);
|
|
522
|
+
const peg$e93 = peg$literalExpectation("#!", false);
|
|
523
|
+
const peg$e94 = peg$classExpectation(["\n", "\r"], true, false, false);
|
|
524
|
+
const peg$e95 = peg$literalExpectation("<<", false);
|
|
525
|
+
const peg$e96 = peg$literalExpectation(">>>", false);
|
|
526
|
+
const peg$e97 = peg$literalExpectation(">>", false);
|
|
527
|
+
const peg$e98 = peg$otherExpectation("lambda function");
|
|
528
|
+
const peg$e99 = peg$literalExpectation("\u2192", false);
|
|
529
|
+
const peg$e100 = peg$literalExpectation("->", false);
|
|
530
|
+
const peg$e101 = peg$otherExpectation("single quote string");
|
|
531
|
+
const peg$e102 = peg$otherExpectation("string");
|
|
532
|
+
const peg$e103 = peg$literalExpectation("${", false);
|
|
533
|
+
const peg$e104 = peg$otherExpectation("template document");
|
|
534
|
+
const peg$e105 = peg$otherExpectation("template literal");
|
|
535
|
+
const peg$e106 = peg$otherExpectation("template substitution");
|
|
536
|
+
const peg$e107 = peg$classExpectation(["!", "+"], false, false, false);
|
|
537
|
+
const peg$e108 = peg$literalExpectation("~", false);
|
|
538
|
+
const peg$e109 = peg$classExpectation(["/", ")", "]", "}"], false, false, false);
|
|
539
|
+
const peg$e110 = peg$literalExpectation("await", false);
|
|
540
|
+
const peg$e111 = peg$literalExpectation("typeof", false);
|
|
541
|
+
const peg$e112 = peg$literalExpectation("void", false);
|
|
542
|
+
const peg$e113 = peg$classExpectation(["/", ",", ")", "]", "}"], true, false, false);
|
|
543
|
+
const peg$e114 = peg$otherExpectation("slash-separated path");
|
|
544
|
+
const peg$e115 = peg$classExpectation([["a", "z"]], false, false, false);
|
|
545
|
+
const peg$e116 = peg$classExpectation([["a", "z"], ["0", "9"], ["+", "."]], false, false, false);
|
|
546
|
+
const peg$e117 = peg$classExpectation([":"], false, false, false);
|
|
543
547
|
|
|
544
548
|
function peg$f0() {
|
|
545
549
|
return null;
|
|
@@ -5209,6 +5213,24 @@ function peg$parse(input, options) {
|
|
|
5209
5213
|
s0 = peg$FAILED;
|
|
5210
5214
|
if (peg$silentFails === 0) { peg$fail(peg$e3); }
|
|
5211
5215
|
}
|
|
5216
|
+
if (s0 === peg$FAILED) {
|
|
5217
|
+
if (input.substr(peg$currPos, 10) === peg$c58) {
|
|
5218
|
+
s0 = peg$c58;
|
|
5219
|
+
peg$currPos += 10;
|
|
5220
|
+
} else {
|
|
5221
|
+
s0 = peg$FAILED;
|
|
5222
|
+
if (peg$silentFails === 0) { peg$fail(peg$e91); }
|
|
5223
|
+
}
|
|
5224
|
+
if (s0 === peg$FAILED) {
|
|
5225
|
+
if (input.substr(peg$currPos, 2) === peg$c59) {
|
|
5226
|
+
s0 = peg$c59;
|
|
5227
|
+
peg$currPos += 2;
|
|
5228
|
+
} else {
|
|
5229
|
+
s0 = peg$FAILED;
|
|
5230
|
+
if (peg$silentFails === 0) { peg$fail(peg$e92); }
|
|
5231
|
+
}
|
|
5232
|
+
}
|
|
5233
|
+
}
|
|
5212
5234
|
}
|
|
5213
5235
|
}
|
|
5214
5236
|
}
|
|
@@ -5254,12 +5276,12 @@ function peg$parse(input, options) {
|
|
|
5254
5276
|
let s0, s1, s2, s3;
|
|
5255
5277
|
|
|
5256
5278
|
s0 = peg$currPos;
|
|
5257
|
-
if (input.substr(peg$currPos, 2) === peg$
|
|
5258
|
-
s1 = peg$
|
|
5279
|
+
if (input.substr(peg$currPos, 2) === peg$c60) {
|
|
5280
|
+
s1 = peg$c60;
|
|
5259
5281
|
peg$currPos += 2;
|
|
5260
5282
|
} else {
|
|
5261
5283
|
s1 = peg$FAILED;
|
|
5262
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
5284
|
+
if (peg$silentFails === 0) { peg$fail(peg$e93); }
|
|
5263
5285
|
}
|
|
5264
5286
|
if (s1 !== peg$FAILED) {
|
|
5265
5287
|
s2 = [];
|
|
@@ -5268,7 +5290,7 @@ function peg$parse(input, options) {
|
|
|
5268
5290
|
peg$currPos++;
|
|
5269
5291
|
} else {
|
|
5270
5292
|
s3 = peg$FAILED;
|
|
5271
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
5293
|
+
if (peg$silentFails === 0) { peg$fail(peg$e94); }
|
|
5272
5294
|
}
|
|
5273
5295
|
while (s3 !== peg$FAILED) {
|
|
5274
5296
|
s2.push(s3);
|
|
@@ -5277,7 +5299,7 @@ function peg$parse(input, options) {
|
|
|
5277
5299
|
peg$currPos++;
|
|
5278
5300
|
} else {
|
|
5279
5301
|
s3 = peg$FAILED;
|
|
5280
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
5302
|
+
if (peg$silentFails === 0) { peg$fail(peg$e94); }
|
|
5281
5303
|
}
|
|
5282
5304
|
}
|
|
5283
5305
|
peg$savedPos = s0;
|
|
@@ -5359,28 +5381,28 @@ function peg$parse(input, options) {
|
|
|
5359
5381
|
function peg$parseshiftOperator() {
|
|
5360
5382
|
let s0;
|
|
5361
5383
|
|
|
5362
|
-
if (input.substr(peg$currPos, 2) === peg$
|
|
5363
|
-
s0 = peg$
|
|
5384
|
+
if (input.substr(peg$currPos, 2) === peg$c61) {
|
|
5385
|
+
s0 = peg$c61;
|
|
5364
5386
|
peg$currPos += 2;
|
|
5365
5387
|
} else {
|
|
5366
5388
|
s0 = peg$FAILED;
|
|
5367
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
5389
|
+
if (peg$silentFails === 0) { peg$fail(peg$e95); }
|
|
5368
5390
|
}
|
|
5369
5391
|
if (s0 === peg$FAILED) {
|
|
5370
|
-
if (input.substr(peg$currPos, 3) === peg$
|
|
5371
|
-
s0 = peg$
|
|
5392
|
+
if (input.substr(peg$currPos, 3) === peg$c62) {
|
|
5393
|
+
s0 = peg$c62;
|
|
5372
5394
|
peg$currPos += 3;
|
|
5373
5395
|
} else {
|
|
5374
5396
|
s0 = peg$FAILED;
|
|
5375
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
5397
|
+
if (peg$silentFails === 0) { peg$fail(peg$e96); }
|
|
5376
5398
|
}
|
|
5377
5399
|
if (s0 === peg$FAILED) {
|
|
5378
|
-
if (input.substr(peg$currPos, 2) === peg$
|
|
5379
|
-
s0 = peg$
|
|
5400
|
+
if (input.substr(peg$currPos, 2) === peg$c63) {
|
|
5401
|
+
s0 = peg$c63;
|
|
5380
5402
|
peg$currPos += 2;
|
|
5381
5403
|
} else {
|
|
5382
5404
|
s0 = peg$FAILED;
|
|
5383
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
5405
|
+
if (peg$silentFails === 0) { peg$fail(peg$e97); }
|
|
5384
5406
|
}
|
|
5385
5407
|
}
|
|
5386
5408
|
}
|
|
@@ -5450,7 +5472,7 @@ function peg$parse(input, options) {
|
|
|
5450
5472
|
peg$silentFails--;
|
|
5451
5473
|
if (s0 === peg$FAILED) {
|
|
5452
5474
|
s1 = peg$FAILED;
|
|
5453
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
5475
|
+
if (peg$silentFails === 0) { peg$fail(peg$e98); }
|
|
5454
5476
|
}
|
|
5455
5477
|
|
|
5456
5478
|
return s0;
|
|
@@ -5460,19 +5482,19 @@ function peg$parse(input, options) {
|
|
|
5460
5482
|
let s0;
|
|
5461
5483
|
|
|
5462
5484
|
if (input.charCodeAt(peg$currPos) === 8594) {
|
|
5463
|
-
s0 = peg$
|
|
5485
|
+
s0 = peg$c64;
|
|
5464
5486
|
peg$currPos++;
|
|
5465
5487
|
} else {
|
|
5466
5488
|
s0 = peg$FAILED;
|
|
5467
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
5489
|
+
if (peg$silentFails === 0) { peg$fail(peg$e99); }
|
|
5468
5490
|
}
|
|
5469
5491
|
if (s0 === peg$FAILED) {
|
|
5470
|
-
if (input.substr(peg$currPos, 2) === peg$
|
|
5471
|
-
s0 = peg$
|
|
5492
|
+
if (input.substr(peg$currPos, 2) === peg$c65) {
|
|
5493
|
+
s0 = peg$c65;
|
|
5472
5494
|
peg$currPos += 2;
|
|
5473
5495
|
} else {
|
|
5474
5496
|
s0 = peg$FAILED;
|
|
5475
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
5497
|
+
if (peg$silentFails === 0) { peg$fail(peg$e100); }
|
|
5476
5498
|
}
|
|
5477
5499
|
}
|
|
5478
5500
|
|
|
@@ -5497,7 +5519,7 @@ function peg$parse(input, options) {
|
|
|
5497
5519
|
peg$currPos++;
|
|
5498
5520
|
} else {
|
|
5499
5521
|
s3 = peg$FAILED;
|
|
5500
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
5522
|
+
if (peg$silentFails === 0) { peg$fail(peg$e94); }
|
|
5501
5523
|
}
|
|
5502
5524
|
while (s3 !== peg$FAILED) {
|
|
5503
5525
|
s2.push(s3);
|
|
@@ -5506,7 +5528,7 @@ function peg$parse(input, options) {
|
|
|
5506
5528
|
peg$currPos++;
|
|
5507
5529
|
} else {
|
|
5508
5530
|
s3 = peg$FAILED;
|
|
5509
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
5531
|
+
if (peg$silentFails === 0) { peg$fail(peg$e94); }
|
|
5510
5532
|
}
|
|
5511
5533
|
}
|
|
5512
5534
|
peg$savedPos = s0;
|
|
@@ -5553,7 +5575,7 @@ function peg$parse(input, options) {
|
|
|
5553
5575
|
peg$silentFails--;
|
|
5554
5576
|
if (s0 === peg$FAILED) {
|
|
5555
5577
|
s1 = peg$FAILED;
|
|
5556
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
5578
|
+
if (peg$silentFails === 0) { peg$fail(peg$e101); }
|
|
5557
5579
|
}
|
|
5558
5580
|
|
|
5559
5581
|
return s0;
|
|
@@ -5726,7 +5748,7 @@ function peg$parse(input, options) {
|
|
|
5726
5748
|
peg$silentFails--;
|
|
5727
5749
|
if (s0 === peg$FAILED) {
|
|
5728
5750
|
s1 = peg$FAILED;
|
|
5729
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
5751
|
+
if (peg$silentFails === 0) { peg$fail(peg$e102); }
|
|
5730
5752
|
}
|
|
5731
5753
|
|
|
5732
5754
|
return s0;
|
|
@@ -5775,12 +5797,12 @@ function peg$parse(input, options) {
|
|
|
5775
5797
|
s0 = peg$currPos;
|
|
5776
5798
|
s1 = peg$currPos;
|
|
5777
5799
|
peg$silentFails++;
|
|
5778
|
-
if (input.substr(peg$currPos, 2) === peg$
|
|
5779
|
-
s2 = peg$
|
|
5800
|
+
if (input.substr(peg$currPos, 2) === peg$c66) {
|
|
5801
|
+
s2 = peg$c66;
|
|
5780
5802
|
peg$currPos += 2;
|
|
5781
5803
|
} else {
|
|
5782
5804
|
s2 = peg$FAILED;
|
|
5783
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
5805
|
+
if (peg$silentFails === 0) { peg$fail(peg$e103); }
|
|
5784
5806
|
}
|
|
5785
5807
|
peg$silentFails--;
|
|
5786
5808
|
if (s2 === peg$FAILED) {
|
|
@@ -5861,7 +5883,7 @@ function peg$parse(input, options) {
|
|
|
5861
5883
|
peg$silentFails--;
|
|
5862
5884
|
if (s0 === peg$FAILED) {
|
|
5863
5885
|
s1 = peg$FAILED;
|
|
5864
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
5886
|
+
if (peg$silentFails === 0) { peg$fail(peg$e104); }
|
|
5865
5887
|
}
|
|
5866
5888
|
|
|
5867
5889
|
return s0;
|
|
@@ -5920,7 +5942,7 @@ function peg$parse(input, options) {
|
|
|
5920
5942
|
peg$silentFails--;
|
|
5921
5943
|
if (s0 === peg$FAILED) {
|
|
5922
5944
|
s1 = peg$FAILED;
|
|
5923
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
5945
|
+
if (peg$silentFails === 0) { peg$fail(peg$e105); }
|
|
5924
5946
|
}
|
|
5925
5947
|
|
|
5926
5948
|
return s0;
|
|
@@ -5940,12 +5962,12 @@ function peg$parse(input, options) {
|
|
|
5940
5962
|
if (peg$silentFails === 0) { peg$fail(peg$e42); }
|
|
5941
5963
|
}
|
|
5942
5964
|
if (s2 === peg$FAILED) {
|
|
5943
|
-
if (input.substr(peg$currPos, 2) === peg$
|
|
5944
|
-
s2 = peg$
|
|
5965
|
+
if (input.substr(peg$currPos, 2) === peg$c66) {
|
|
5966
|
+
s2 = peg$c66;
|
|
5945
5967
|
peg$currPos += 2;
|
|
5946
5968
|
} else {
|
|
5947
5969
|
s2 = peg$FAILED;
|
|
5948
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
5970
|
+
if (peg$silentFails === 0) { peg$fail(peg$e103); }
|
|
5949
5971
|
}
|
|
5950
5972
|
}
|
|
5951
5973
|
peg$silentFails--;
|
|
@@ -5993,12 +6015,12 @@ function peg$parse(input, options) {
|
|
|
5993
6015
|
|
|
5994
6016
|
peg$silentFails++;
|
|
5995
6017
|
s0 = peg$currPos;
|
|
5996
|
-
if (input.substr(peg$currPos, 2) === peg$
|
|
5997
|
-
s1 = peg$
|
|
6018
|
+
if (input.substr(peg$currPos, 2) === peg$c66) {
|
|
6019
|
+
s1 = peg$c66;
|
|
5998
6020
|
peg$currPos += 2;
|
|
5999
6021
|
} else {
|
|
6000
6022
|
s1 = peg$FAILED;
|
|
6001
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
6023
|
+
if (peg$silentFails === 0) { peg$fail(peg$e103); }
|
|
6002
6024
|
}
|
|
6003
6025
|
if (s1 !== peg$FAILED) {
|
|
6004
6026
|
s2 = peg$parseexpectExpression();
|
|
@@ -6028,7 +6050,7 @@ function peg$parse(input, options) {
|
|
|
6028
6050
|
peg$silentFails--;
|
|
6029
6051
|
if (s0 === peg$FAILED) {
|
|
6030
6052
|
s1 = peg$FAILED;
|
|
6031
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
6053
|
+
if (peg$silentFails === 0) { peg$fail(peg$e106); }
|
|
6032
6054
|
}
|
|
6033
6055
|
|
|
6034
6056
|
return s0;
|
|
@@ -6085,16 +6107,16 @@ function peg$parse(input, options) {
|
|
|
6085
6107
|
peg$currPos++;
|
|
6086
6108
|
} else {
|
|
6087
6109
|
s0 = peg$FAILED;
|
|
6088
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
6110
|
+
if (peg$silentFails === 0) { peg$fail(peg$e107); }
|
|
6089
6111
|
}
|
|
6090
6112
|
if (s0 === peg$FAILED) {
|
|
6091
6113
|
s0 = peg$currPos;
|
|
6092
6114
|
if (input.charCodeAt(peg$currPos) === 126) {
|
|
6093
|
-
s1 = peg$
|
|
6115
|
+
s1 = peg$c67;
|
|
6094
6116
|
peg$currPos++;
|
|
6095
6117
|
} else {
|
|
6096
6118
|
s1 = peg$FAILED;
|
|
6097
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
6119
|
+
if (peg$silentFails === 0) { peg$fail(peg$e108); }
|
|
6098
6120
|
}
|
|
6099
6121
|
if (s1 !== peg$FAILED) {
|
|
6100
6122
|
s2 = peg$currPos;
|
|
@@ -6104,7 +6126,7 @@ function peg$parse(input, options) {
|
|
|
6104
6126
|
peg$currPos++;
|
|
6105
6127
|
} else {
|
|
6106
6128
|
s3 = peg$FAILED;
|
|
6107
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
6129
|
+
if (peg$silentFails === 0) { peg$fail(peg$e109); }
|
|
6108
6130
|
}
|
|
6109
6131
|
peg$silentFails--;
|
|
6110
6132
|
if (s3 === peg$FAILED) {
|
|
@@ -6127,12 +6149,12 @@ function peg$parse(input, options) {
|
|
|
6127
6149
|
s0 = peg$parseminus();
|
|
6128
6150
|
if (s0 === peg$FAILED) {
|
|
6129
6151
|
s0 = peg$currPos;
|
|
6130
|
-
if (input.substr(peg$currPos, 5) === peg$
|
|
6131
|
-
s1 = peg$
|
|
6152
|
+
if (input.substr(peg$currPos, 5) === peg$c68) {
|
|
6153
|
+
s1 = peg$c68;
|
|
6132
6154
|
peg$currPos += 5;
|
|
6133
6155
|
} else {
|
|
6134
6156
|
s1 = peg$FAILED;
|
|
6135
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
6157
|
+
if (peg$silentFails === 0) { peg$fail(peg$e110); }
|
|
6136
6158
|
}
|
|
6137
6159
|
if (s1 !== peg$FAILED) {
|
|
6138
6160
|
s2 = peg$currPos;
|
|
@@ -6157,12 +6179,12 @@ function peg$parse(input, options) {
|
|
|
6157
6179
|
}
|
|
6158
6180
|
if (s0 === peg$FAILED) {
|
|
6159
6181
|
s0 = peg$currPos;
|
|
6160
|
-
if (input.substr(peg$currPos, 6) === peg$
|
|
6161
|
-
s1 = peg$
|
|
6182
|
+
if (input.substr(peg$currPos, 6) === peg$c69) {
|
|
6183
|
+
s1 = peg$c69;
|
|
6162
6184
|
peg$currPos += 6;
|
|
6163
6185
|
} else {
|
|
6164
6186
|
s1 = peg$FAILED;
|
|
6165
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
6187
|
+
if (peg$silentFails === 0) { peg$fail(peg$e111); }
|
|
6166
6188
|
}
|
|
6167
6189
|
if (s1 !== peg$FAILED) {
|
|
6168
6190
|
s2 = peg$currPos;
|
|
@@ -6187,12 +6209,12 @@ function peg$parse(input, options) {
|
|
|
6187
6209
|
}
|
|
6188
6210
|
if (s0 === peg$FAILED) {
|
|
6189
6211
|
s0 = peg$currPos;
|
|
6190
|
-
if (input.substr(peg$currPos, 4) === peg$
|
|
6191
|
-
s1 = peg$
|
|
6212
|
+
if (input.substr(peg$currPos, 4) === peg$c70) {
|
|
6213
|
+
s1 = peg$c70;
|
|
6192
6214
|
peg$currPos += 4;
|
|
6193
6215
|
} else {
|
|
6194
6216
|
s1 = peg$FAILED;
|
|
6195
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
6217
|
+
if (peg$silentFails === 0) { peg$fail(peg$e112); }
|
|
6196
6218
|
}
|
|
6197
6219
|
if (s1 !== peg$FAILED) {
|
|
6198
6220
|
s2 = peg$currPos;
|
|
@@ -6372,7 +6394,7 @@ function peg$parse(input, options) {
|
|
|
6372
6394
|
peg$currPos++;
|
|
6373
6395
|
} else {
|
|
6374
6396
|
s1 = peg$FAILED;
|
|
6375
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
6397
|
+
if (peg$silentFails === 0) { peg$fail(peg$e113); }
|
|
6376
6398
|
}
|
|
6377
6399
|
if (s1 !== peg$FAILED) {
|
|
6378
6400
|
s2 = peg$currPos;
|
|
@@ -6435,7 +6457,7 @@ function peg$parse(input, options) {
|
|
|
6435
6457
|
peg$silentFails--;
|
|
6436
6458
|
if (s0 === peg$FAILED) {
|
|
6437
6459
|
s1 = peg$FAILED;
|
|
6438
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
6460
|
+
if (peg$silentFails === 0) { peg$fail(peg$e114); }
|
|
6439
6461
|
}
|
|
6440
6462
|
|
|
6441
6463
|
return s0;
|
|
@@ -6450,7 +6472,7 @@ function peg$parse(input, options) {
|
|
|
6450
6472
|
peg$currPos++;
|
|
6451
6473
|
} else {
|
|
6452
6474
|
s1 = peg$FAILED;
|
|
6453
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
6475
|
+
if (peg$silentFails === 0) { peg$fail(peg$e115); }
|
|
6454
6476
|
}
|
|
6455
6477
|
if (s1 !== peg$FAILED) {
|
|
6456
6478
|
s2 = [];
|
|
@@ -6459,7 +6481,7 @@ function peg$parse(input, options) {
|
|
|
6459
6481
|
peg$currPos++;
|
|
6460
6482
|
} else {
|
|
6461
6483
|
s3 = peg$FAILED;
|
|
6462
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
6484
|
+
if (peg$silentFails === 0) { peg$fail(peg$e116); }
|
|
6463
6485
|
}
|
|
6464
6486
|
while (s3 !== peg$FAILED) {
|
|
6465
6487
|
s2.push(s3);
|
|
@@ -6468,7 +6490,7 @@ function peg$parse(input, options) {
|
|
|
6468
6490
|
peg$currPos++;
|
|
6469
6491
|
} else {
|
|
6470
6492
|
s3 = peg$FAILED;
|
|
6471
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
6493
|
+
if (peg$silentFails === 0) { peg$fail(peg$e116); }
|
|
6472
6494
|
}
|
|
6473
6495
|
}
|
|
6474
6496
|
s3 = input.charAt(peg$currPos);
|
|
@@ -6476,7 +6498,7 @@ function peg$parse(input, options) {
|
|
|
6476
6498
|
peg$currPos++;
|
|
6477
6499
|
} else {
|
|
6478
6500
|
s3 = peg$FAILED;
|
|
6479
|
-
if (peg$silentFails === 0) { peg$fail(peg$
|
|
6501
|
+
if (peg$silentFails === 0) { peg$fail(peg$e117); }
|
|
6480
6502
|
}
|
|
6481
6503
|
if (s3 !== peg$FAILED) {
|
|
6482
6504
|
peg$savedPos = s0;
|
|
@@ -142,6 +142,8 @@ export function makeBinaryOperation(left, [operatorToken, right]) {
|
|
|
142
142
|
">>>": ops.shiftRightUnsigned,
|
|
143
143
|
"^": ops.bitwiseXor,
|
|
144
144
|
"|": ops.bitwiseOr,
|
|
145
|
+
instanceof: ops.instanceOf,
|
|
146
|
+
in: ops.inOperator,
|
|
145
147
|
};
|
|
146
148
|
const op = operators[operatorToken];
|
|
147
149
|
|
|
@@ -3,11 +3,11 @@ import {
|
|
|
3
3
|
isUnpackable,
|
|
4
4
|
symbols,
|
|
5
5
|
toString,
|
|
6
|
+
Tree,
|
|
6
7
|
} from "@weborigami/async-tree";
|
|
7
8
|
import * as YAMLModule from "yaml";
|
|
8
9
|
import * as compile from "../compiler/compile.js";
|
|
9
10
|
import projectGlobals from "../project/projectGlobals.js";
|
|
10
|
-
import * as expressionFunction from "../runtime/expressionFunction.js";
|
|
11
11
|
import getSource from "./getSource.js";
|
|
12
12
|
|
|
13
13
|
// The "yaml" package doesn't seem to provide a default export that the browser can
|
|
@@ -15,6 +15,17 @@ import getSource from "./getSource.js";
|
|
|
15
15
|
// @ts-ignore
|
|
16
16
|
const YAML = YAMLModule.default ?? YAMLModule.YAML;
|
|
17
17
|
|
|
18
|
+
// True if we encountered !ori or !ori.call tags while parsing
|
|
19
|
+
let hasOriTags = false;
|
|
20
|
+
|
|
21
|
+
// When processing the !ori tag, the YAML parser will convert our compiler
|
|
22
|
+
// errors into YAML syntax errors. We track the last compiler error so we can
|
|
23
|
+
// re-throw it.
|
|
24
|
+
let lastCompilerError = null;
|
|
25
|
+
|
|
26
|
+
// The source of the last Origami line parsed in a YAML file, used for errors
|
|
27
|
+
let source;
|
|
28
|
+
|
|
18
29
|
/**
|
|
19
30
|
* A YAML file
|
|
20
31
|
*
|
|
@@ -31,72 +42,145 @@ export default {
|
|
|
31
42
|
throw new Error("Tried to parse something as YAML but it wasn't text.");
|
|
32
43
|
}
|
|
33
44
|
const parent = getParent(packed, options);
|
|
34
|
-
const oriCallTag = await oriCallTagForParent(parent, options);
|
|
35
|
-
const oriTag = await oriTagForParent(parent, options);
|
|
45
|
+
const oriCallTag = await oriCallTagForParent(parent, options, yaml);
|
|
46
|
+
const oriTag = await oriTagForParent(parent, options, yaml);
|
|
47
|
+
hasOriTags = false; // Haven't seen any yet
|
|
48
|
+
|
|
49
|
+
let data;
|
|
36
50
|
// YAML parser is sync, but top-level !ori or !ori.call tags will return a
|
|
37
51
|
// promise.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
52
|
+
try {
|
|
53
|
+
// @ts-ignore TypeScript complains customTags isn't valid here but it is.
|
|
54
|
+
data = YAML.parse(yaml, {
|
|
55
|
+
customTags: [oriCallTag, oriTag],
|
|
56
|
+
});
|
|
57
|
+
} catch (/** @type {any} */ error) {
|
|
58
|
+
if (error.name === "SyntaxError") {
|
|
59
|
+
// One of our compiler errors, probably thrown by !ori.call tag
|
|
60
|
+
throw error;
|
|
61
|
+
}
|
|
62
|
+
const errorText = yaml.slice(error.pos[0], error.pos[1]);
|
|
63
|
+
const isOriError = errorText === "!ori" || errorText === "!ori.call";
|
|
64
|
+
if (isOriError && lastCompilerError) {
|
|
65
|
+
// Error is in an Origami tag, probably throw by !ori tag. Find the
|
|
66
|
+
// position of the Origami source in the YAML text.
|
|
67
|
+
let offset = error.pos[0] + errorText.length;
|
|
68
|
+
while (/\s/.test(yaml[offset])) {
|
|
69
|
+
offset++;
|
|
70
|
+
}
|
|
71
|
+
lastCompilerError.location.source.offset = offset;
|
|
72
|
+
throw lastCompilerError;
|
|
73
|
+
} else {
|
|
74
|
+
// Some other YAML parsing error
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (data instanceof Promise) {
|
|
80
|
+
// Top-level !ori or !ori.call tag returned a promise
|
|
81
|
+
data = await data;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (hasOriTags) {
|
|
85
|
+
// Resolve any promises in the data.
|
|
86
|
+
data = await Tree.plain(data);
|
|
87
|
+
}
|
|
88
|
+
|
|
42
89
|
if (data && typeof data === "object" && Object.isExtensible(data)) {
|
|
43
90
|
Object.defineProperty(data, symbols.deep, {
|
|
44
91
|
enumerable: false,
|
|
45
92
|
value: true,
|
|
46
93
|
});
|
|
47
94
|
}
|
|
95
|
+
|
|
48
96
|
return data;
|
|
49
97
|
},
|
|
50
98
|
};
|
|
51
99
|
|
|
52
|
-
async function oriCallTagForParent(parent, options) {
|
|
100
|
+
async function oriCallTagForParent(parent, options, yaml) {
|
|
53
101
|
const globals = await projectGlobals();
|
|
54
102
|
return {
|
|
55
103
|
collection: "seq",
|
|
56
104
|
|
|
57
105
|
tag: "!ori.call",
|
|
58
106
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
async resolve(value) {
|
|
107
|
+
resolve(value) {
|
|
108
|
+
hasOriTags = true;
|
|
62
109
|
/** @type {any[]} */
|
|
63
110
|
const args = typeof value?.toJSON === "function" ? value.toJSON() : value;
|
|
64
111
|
|
|
65
112
|
// First arg is Origami source
|
|
66
113
|
const text = args.shift();
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
const codeFn = compile.expression(source, {
|
|
70
|
-
globals,
|
|
71
|
-
parent,
|
|
72
|
-
});
|
|
114
|
+
source = getSource(text, options);
|
|
73
115
|
|
|
74
|
-
//
|
|
75
|
-
|
|
116
|
+
// Offset the source position to account for its location in YAML text
|
|
117
|
+
source.context = yaml;
|
|
118
|
+
const firstItem = value.items[0];
|
|
119
|
+
source.offset = firstItem.range[0];
|
|
120
|
+
if (
|
|
121
|
+
firstItem.type === "QUOTE_DOUBLE" ||
|
|
122
|
+
firstItem.type === "QUOTE_SINGLE"
|
|
123
|
+
) {
|
|
124
|
+
// Account for opening quote
|
|
125
|
+
source.offset += 1;
|
|
126
|
+
}
|
|
76
127
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
128
|
+
lastCompilerError = null;
|
|
129
|
+
let codeFn;
|
|
130
|
+
try {
|
|
131
|
+
codeFn = compile.expression(source, {
|
|
132
|
+
globals,
|
|
133
|
+
parent,
|
|
134
|
+
});
|
|
135
|
+
} catch (error) {
|
|
136
|
+
lastCompilerError = error;
|
|
137
|
+
throw error;
|
|
80
138
|
}
|
|
81
139
|
|
|
82
|
-
|
|
140
|
+
// Return a promise for the code's evaluation. If we instead define
|
|
141
|
+
// resolve() as async, the catch block in unpack() won't catch Origami
|
|
142
|
+
// parse errors.
|
|
143
|
+
return new Promise(async (resolve) => {
|
|
144
|
+
// Evaluate the code to get a function
|
|
145
|
+
let fn = await codeFn.call(parent);
|
|
146
|
+
|
|
147
|
+
// Call the function with the rest of the args
|
|
148
|
+
if (isUnpackable(fn)) {
|
|
149
|
+
fn = await fn.unpack();
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Resolve any promise args
|
|
153
|
+
const resolvedArgs = await Promise.all(args);
|
|
154
|
+
|
|
155
|
+
const result = await fn.call(null, ...resolvedArgs);
|
|
156
|
+
resolve(result);
|
|
157
|
+
});
|
|
83
158
|
},
|
|
84
159
|
};
|
|
85
160
|
}
|
|
86
161
|
|
|
87
162
|
// Define the !ori tag for YAML parsing. This will run in the context of the
|
|
88
163
|
// supplied parent.
|
|
89
|
-
async function oriTagForParent(parent, options) {
|
|
164
|
+
async function oriTagForParent(parent, options, yaml) {
|
|
90
165
|
const globals = await projectGlobals();
|
|
91
166
|
return {
|
|
92
|
-
identify: expressionFunction.isExpressionFunction,
|
|
93
|
-
|
|
94
167
|
resolve(text) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
168
|
+
hasOriTags = true;
|
|
169
|
+
source = getSource(text, options);
|
|
170
|
+
source.context = yaml;
|
|
171
|
+
|
|
172
|
+
lastCompilerError = null;
|
|
173
|
+
let fn;
|
|
174
|
+
try {
|
|
175
|
+
fn = compile.expression(source, {
|
|
176
|
+
globals,
|
|
177
|
+
parent,
|
|
178
|
+
});
|
|
179
|
+
} catch (error) {
|
|
180
|
+
lastCompilerError = error;
|
|
181
|
+
throw error;
|
|
182
|
+
}
|
|
183
|
+
|
|
100
184
|
return fn.call(parent);
|
|
101
185
|
},
|
|
102
186
|
|
package/src/project/jsGlobals.js
CHANGED
|
@@ -12,7 +12,7 @@ import path from "node:path";
|
|
|
12
12
|
* Fetch API
|
|
13
13
|
* URL API
|
|
14
14
|
*/
|
|
15
|
-
const globals =
|
|
15
|
+
const globals = {
|
|
16
16
|
AbortController,
|
|
17
17
|
AbortSignal,
|
|
18
18
|
AggregateError,
|
|
@@ -152,7 +152,7 @@ const globals = bindStaticMethodsForGlobals({
|
|
|
152
152
|
// Special cases
|
|
153
153
|
fetch: fetchWrapper,
|
|
154
154
|
import: importWrapper,
|
|
155
|
-
}
|
|
155
|
+
};
|
|
156
156
|
|
|
157
157
|
// Give access to our own custom globals as `globalThis`
|
|
158
158
|
Object.defineProperty(globals, "globalThis", {
|
|
@@ -190,64 +190,4 @@ async function importWrapper(modulePath) {
|
|
|
190
190
|
}
|
|
191
191
|
importWrapper.containerAsTarget = true;
|
|
192
192
|
|
|
193
|
-
/**
|
|
194
|
-
* Some JavaScript globals like Promise have static methods like Promise.all
|
|
195
|
-
* verify that the call target is the class. This creates an issue because the
|
|
196
|
-
* Origami evaluate() function calls all functions with the evaluation context
|
|
197
|
-
* -- the tree in which the code is running -- as the call target.
|
|
198
|
-
*
|
|
199
|
-
* This function works around the problem. If the indicated object has no static
|
|
200
|
-
* methods, it's returned as is. If it does have static methods, this returns an
|
|
201
|
-
* extension of the object that overrides the static methods with ones that are
|
|
202
|
-
* bound to the object.
|
|
203
|
-
*/
|
|
204
|
-
function bindStaticMethods(obj) {
|
|
205
|
-
if (typeof obj !== "function" && (typeof obj !== "object" || obj === null)) {
|
|
206
|
-
// Something like `NaN` or `null`
|
|
207
|
-
return obj;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
const staticMethodDescriptors = Object.entries(
|
|
211
|
-
Object.getOwnPropertyDescriptors(obj)
|
|
212
|
-
)
|
|
213
|
-
.filter(([key, descriptor]) => descriptor.value instanceof Function)
|
|
214
|
-
.map(([key, descriptor]) => [
|
|
215
|
-
key,
|
|
216
|
-
{
|
|
217
|
-
...descriptor,
|
|
218
|
-
value: descriptor.value.bind(obj),
|
|
219
|
-
},
|
|
220
|
-
]);
|
|
221
|
-
if (staticMethodDescriptors.length === 0) {
|
|
222
|
-
// No static methods
|
|
223
|
-
return obj;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
let extended;
|
|
227
|
-
if (typeof obj === "object" || !obj.prototype) {
|
|
228
|
-
// A regular object or an oddball like Proxy with no prototype
|
|
229
|
-
extended = Object.create(obj);
|
|
230
|
-
} else {
|
|
231
|
-
// A function, possibly a constructor called with or without `new`
|
|
232
|
-
/** @this {any} */
|
|
233
|
-
extended = function (...args) {
|
|
234
|
-
const calledWithNew = this instanceof extended;
|
|
235
|
-
return calledWithNew ? new obj(...args) : obj(...args);
|
|
236
|
-
};
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
Object.defineProperties(
|
|
240
|
-
extended,
|
|
241
|
-
Object.fromEntries(staticMethodDescriptors)
|
|
242
|
-
);
|
|
243
|
-
|
|
244
|
-
return extended;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
function bindStaticMethodsForGlobals(objects) {
|
|
248
|
-
const entries = Object.entries(objects);
|
|
249
|
-
const bound = entries.map(([key, value]) => [key, bindStaticMethods(value)]);
|
|
250
|
-
return Object.fromEntries(bound);
|
|
251
|
-
}
|
|
252
|
-
|
|
253
193
|
export default globals;
|
|
@@ -9,6 +9,9 @@ import { pathFromKeys } from "@weborigami/async-tree";
|
|
|
9
9
|
*/
|
|
10
10
|
export default function constructHref(protocol, host, ...keys) {
|
|
11
11
|
const path = pathFromKeys(keys);
|
|
12
|
+
if (host.endsWith("/")) {
|
|
13
|
+
host = host.slice(0, -1);
|
|
14
|
+
}
|
|
12
15
|
let href = [host, path].join("/");
|
|
13
16
|
if (!href.startsWith(protocol)) {
|
|
14
17
|
if (!href.startsWith("//")) {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ExplorableSiteMap } from "@weborigami/async-tree";
|
|
2
|
+
import constructSiteTree from "./constructSiteTree.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A site tree with JSON Keys via HTTP.
|
|
6
|
+
*
|
|
7
|
+
*
|
|
8
|
+
* @param {string} host
|
|
9
|
+
* @param {...string} keys
|
|
10
|
+
*/
|
|
11
|
+
export default function explorehttp(host, ...keys) {
|
|
12
|
+
return constructSiteTree("http:", ExplorableSiteMap, host, ...keys);
|
|
13
|
+
}
|
package/src/runtime/errors.js
CHANGED
|
@@ -144,9 +144,22 @@ export function maybeOrigamiSourceCode(text) {
|
|
|
144
144
|
// Return user-friendly line information for the error location
|
|
145
145
|
function lineInfo(location) {
|
|
146
146
|
let { source, start } = location;
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
let
|
|
147
|
+
|
|
148
|
+
let line;
|
|
149
|
+
let column;
|
|
150
|
+
if (source.offset && source.context) {
|
|
151
|
+
// Account for source code that was offset within a larger document
|
|
152
|
+
const offset = source.offset + start.offset;
|
|
153
|
+
// Calculate line and column from offset
|
|
154
|
+
const textUpToOffset = source.context.slice(0, offset);
|
|
155
|
+
const lines = textUpToOffset.split("\n");
|
|
156
|
+
line = lines.length;
|
|
157
|
+
column = lines[lines.length - 1].length + 1;
|
|
158
|
+
} else {
|
|
159
|
+
// Use indicated start location as is
|
|
160
|
+
line = start.line;
|
|
161
|
+
column = start.column;
|
|
162
|
+
}
|
|
150
163
|
|
|
151
164
|
if (typeof source === "object" && source.url) {
|
|
152
165
|
const { url } = source;
|
|
@@ -162,10 +175,10 @@ function lineInfo(location) {
|
|
|
162
175
|
// Not a file: URL, use as is
|
|
163
176
|
fileRef = url.href;
|
|
164
177
|
}
|
|
165
|
-
return `\n at ${fileRef}:${line}:${
|
|
178
|
+
return `\n at ${fileRef}:${line}:${column}`;
|
|
166
179
|
} else if (source.text.includes("\n")) {
|
|
167
180
|
// Don't know the URL, but has multiple lines so add line number
|
|
168
|
-
return `\n at line ${line}, column ${
|
|
181
|
+
return `\n at line ${line}, column ${column}`;
|
|
169
182
|
} else {
|
|
170
183
|
return "";
|
|
171
184
|
}
|
package/src/runtime/ops.js
CHANGED
|
@@ -181,6 +181,11 @@ export async function homeDirectory(...keys) {
|
|
|
181
181
|
}
|
|
182
182
|
addOpLabel(homeDirectory, "«ops.homeDirectory»");
|
|
183
183
|
|
|
184
|
+
export function inOperator(a, b) {
|
|
185
|
+
return a in b;
|
|
186
|
+
}
|
|
187
|
+
addOpLabel(inOperator, "«ops.inOperator»");
|
|
188
|
+
|
|
184
189
|
/**
|
|
185
190
|
* Given the tree currently be using as the context for the runtime, walk up the
|
|
186
191
|
* parent chain `depth` levels and return that tree.
|
|
@@ -203,6 +208,11 @@ export async function inherited(depth, state) {
|
|
|
203
208
|
addOpLabel(inherited, "«ops.inherited»");
|
|
204
209
|
inherited.needsState = true;
|
|
205
210
|
|
|
211
|
+
export function instanceOf(a, b) {
|
|
212
|
+
return a instanceof b;
|
|
213
|
+
}
|
|
214
|
+
addOpLabel(instanceOf, "«ops.instanceOf»");
|
|
215
|
+
|
|
206
216
|
/**
|
|
207
217
|
* Return a function that will invoke the given code.
|
|
208
218
|
*
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Tree } from "@weborigami/async-tree";
|
|
2
1
|
import assert from "node:assert";
|
|
3
2
|
import { describe, test } from "node:test";
|
|
4
3
|
import yaml_handler from "../../src/handlers/yaml_handler.js";
|
|
@@ -22,8 +21,7 @@ message: Hello
|
|
|
22
21
|
answer: !ori 1 + 1
|
|
23
22
|
`;
|
|
24
23
|
const data = await yaml_handler.unpack(text);
|
|
25
|
-
|
|
26
|
-
assert.deepEqual(plain, {
|
|
24
|
+
assert.deepEqual(data, {
|
|
27
25
|
message: "Hello",
|
|
28
26
|
answer: 2,
|
|
29
27
|
});
|
|
@@ -38,8 +36,7 @@ answer: !ori.call
|
|
|
38
36
|
- 3
|
|
39
37
|
`;
|
|
40
38
|
const data = await yaml_handler.unpack(text);
|
|
41
|
-
|
|
42
|
-
assert.deepEqual(plain, {
|
|
39
|
+
assert.deepEqual(data, {
|
|
43
40
|
message: "Hello",
|
|
44
41
|
answer: 5,
|
|
45
42
|
});
|
|
@@ -3,19 +3,25 @@ import { describe, test } from "node:test";
|
|
|
3
3
|
import jsGlobals from "../../src/project/jsGlobals.js";
|
|
4
4
|
|
|
5
5
|
describe("jsGlobals", () => {
|
|
6
|
-
test("can invoke
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
const result = (
|
|
10
|
-
await all(["fruit", "computer", "park"].map((item) => `Apple ${item}`))
|
|
11
|
-
).join(", ");
|
|
12
|
-
assert.equal(result, "Apple fruit, Apple computer, Apple park");
|
|
6
|
+
test("can invoke finicky methods like Promise.all that check their receiver", async () => {
|
|
7
|
+
const value = await jsGlobals.Promise.all([Promise.resolve("hi")]);
|
|
8
|
+
assert.equal(value, "hi");
|
|
13
9
|
});
|
|
14
10
|
|
|
15
|
-
test("can invoke a method on a
|
|
11
|
+
test("can invoke a static method on a global", () => {
|
|
16
12
|
const { Math } = jsGlobals;
|
|
17
13
|
const a = [1, 3, 2];
|
|
18
14
|
const b = Math.max.apply(null, a);
|
|
19
15
|
assert.equal(b, 3);
|
|
20
16
|
});
|
|
17
|
+
|
|
18
|
+
test("can invoke a global constructor", async () => {
|
|
19
|
+
const { Number: fixture } = jsGlobals;
|
|
20
|
+
// Without `new`
|
|
21
|
+
const instance1 = fixture(5);
|
|
22
|
+
assert.equal(instance1, 5);
|
|
23
|
+
// With `new`
|
|
24
|
+
const instance = new fixture();
|
|
25
|
+
assert(instance instanceof Number);
|
|
26
|
+
});
|
|
21
27
|
});
|
package/test/runtime/ops.test.js
CHANGED
|
@@ -155,6 +155,14 @@ describe("ops", () => {
|
|
|
155
155
|
assert(ops.greaterThanOrEqual("ab", "aa"));
|
|
156
156
|
});
|
|
157
157
|
|
|
158
|
+
test("ops.inOperator returns true if a is in object b", () => {
|
|
159
|
+
assert.strictEqual(ops.inOperator("a", { a: 1, b: 2 }), true);
|
|
160
|
+
assert.strictEqual(ops.inOperator("c", { a: 1, b: 2 }), false);
|
|
161
|
+
const arr = [0, 0, 0];
|
|
162
|
+
assert.strictEqual(ops.inOperator(1, arr), true);
|
|
163
|
+
assert.strictEqual(ops.inOperator(3, arr), false);
|
|
164
|
+
});
|
|
165
|
+
|
|
158
166
|
test("ops.inherited walks up the object parent chain", async () => {
|
|
159
167
|
const tree = new ObjectMap(
|
|
160
168
|
{
|
|
@@ -168,6 +176,16 @@ describe("ops", () => {
|
|
|
168
176
|
assert.equal(await ops.inherited(2, { object: b }), tree);
|
|
169
177
|
});
|
|
170
178
|
|
|
179
|
+
test("ops.instanceOf checks prototype chain", () => {
|
|
180
|
+
class Parent {}
|
|
181
|
+
class Child extends Parent {}
|
|
182
|
+
const child = new Child();
|
|
183
|
+
assert.strictEqual(ops.instanceOf(child, Child), true);
|
|
184
|
+
assert.strictEqual(ops.instanceOf(child, Parent), true);
|
|
185
|
+
assert.strictEqual(ops.instanceOf(child, Object), true);
|
|
186
|
+
assert.strictEqual(ops.instanceOf(child, Array), false);
|
|
187
|
+
});
|
|
188
|
+
|
|
171
189
|
test("ops.lambda defines a function with no inputs", async () => {
|
|
172
190
|
const code = createCode([ops.lambda, [], [ops.literal, "result"]]);
|
|
173
191
|
const fn = await evaluate(code);
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert";
|
|
2
|
-
import { describe, test } from "node:test";
|
|
3
|
-
import jsGlobals from "../../src/project/jsGlobals.js";
|
|
4
|
-
|
|
5
|
-
describe("jsGlobals", () => {
|
|
6
|
-
test("wraps static methods to bind them to defining object", async () => {
|
|
7
|
-
const all = jsGlobals.Promise.all;
|
|
8
|
-
const value = await all([Promise.resolve("hi")]);
|
|
9
|
-
assert.equal(value, "hi");
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
test("can invoke a global constructor", async () => {
|
|
13
|
-
const { Number: fixture } = jsGlobals;
|
|
14
|
-
// Without `new`
|
|
15
|
-
const instance1 = fixture(5);
|
|
16
|
-
assert.equal(instance1, 5);
|
|
17
|
-
// With `new`
|
|
18
|
-
const instance = new fixture();
|
|
19
|
-
assert(instance instanceof Number);
|
|
20
|
-
});
|
|
21
|
-
});
|