@naanlang/naan 1.0.13 → 1.0.15
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/LICENSE.md +1 -1
- package/README.md +1 -1
- package/bin/index.js +2 -2
- package/dist/naan.min.js +5 -5
- package/frameworks/browser/https_request.nlg +9 -1
- package/frameworks/browser/sworker.js +23 -23
- package/frameworks/browser/terminals.nlg +4 -1
- package/frameworks/node/https_request.nlg +28 -6
- package/frameworks/project/build.nlg +18 -17
- package/frameworks/project/projects.nlg +1 -1
- package/lib/browser/env_web.js +6 -6
- package/lib/browser/env_webworker.js +9 -0
- package/lib/core/naanlib.js +5 -5
- package/lib/env_node.js +13 -4
- package/package.json +1 -1
- package/plugins/openSearch/openSearch.nlg +16 -14
- package/plugins/serviceAws/aws_dynamo.nlg +48 -13
- package/test/test_01_core.nlg +36 -8
- package/test/test_03_jsinterop.nlg +11 -2
- package/test/test_05_strings.nlg +1 -1
- package/test/test_06_lingoparse.nlg +43 -4
- package/test/test_07_lingo.nlg +33 -2
package/lib/env_node.js
CHANGED
|
@@ -37,6 +37,7 @@ exports.NaanNodeREPL = function NaanNodeREPL(options) {
|
|
|
37
37
|
if (typeof(options) != 'object')
|
|
38
38
|
options = { };
|
|
39
39
|
var repl = require('repl');
|
|
40
|
+
var replServer;
|
|
40
41
|
var process = require('process');
|
|
41
42
|
var Naan = require('./core/naanlib');
|
|
42
43
|
var naanlib = new Naan.Naanlib();
|
|
@@ -69,6 +70,14 @@ exports.NaanNodeREPL = function NaanNodeREPL(options) {
|
|
|
69
70
|
outEnable = true;
|
|
70
71
|
naanlib.textLine(cmd);
|
|
71
72
|
};
|
|
73
|
+
|
|
74
|
+
this.setPrompt = function setPrompt(prompt) {
|
|
75
|
+
if (replServer) {
|
|
76
|
+
replServer.setPrompt(prompt);
|
|
77
|
+
return (prompt);
|
|
78
|
+
}
|
|
79
|
+
return (false);
|
|
80
|
+
};
|
|
72
81
|
|
|
73
82
|
|
|
74
83
|
//==========================================================================
|
|
@@ -85,9 +94,9 @@ exports.NaanNodeREPL = function NaanNodeREPL(options) {
|
|
|
85
94
|
|
|
86
95
|
if (!options.replDisable)
|
|
87
96
|
{
|
|
88
|
-
|
|
97
|
+
replServer = repl.start({ prompt: 'Naan> ', eval: myEval});
|
|
89
98
|
|
|
90
|
-
|
|
99
|
+
replServer.on('line', function(cmd) { // process raw command line
|
|
91
100
|
if (cmd.charAt(0) != ".") {
|
|
92
101
|
textToRemoteTerm(cmd);
|
|
93
102
|
naanlib.textLine(cmd + "\n");
|
|
@@ -98,7 +107,7 @@ exports.NaanNodeREPL = function NaanNodeREPL(options) {
|
|
|
98
107
|
// Hook the ^C interrupt
|
|
99
108
|
//
|
|
100
109
|
|
|
101
|
-
|
|
110
|
+
replServer._events.SIGINT = function () {
|
|
102
111
|
naanlib.escape();
|
|
103
112
|
};
|
|
104
113
|
|
|
@@ -106,7 +115,7 @@ exports.NaanNodeREPL = function NaanNodeREPL(options) {
|
|
|
106
115
|
// Hook an exit command
|
|
107
116
|
//
|
|
108
117
|
|
|
109
|
-
|
|
118
|
+
replServer.on('exit', function() {
|
|
110
119
|
process.exit();
|
|
111
120
|
});
|
|
112
121
|
}
|
package/package.json
CHANGED
|
@@ -32,6 +32,10 @@
|
|
|
32
32
|
* `number -- float or integer
|
|
33
33
|
* `url -- URL
|
|
34
34
|
*
|
|
35
|
+
* Although the currency type is only treated as a text field for now, the intent is that these will
|
|
36
|
+
* match the RegEx /([A-Z]{3})(-?[0-9]+(?:[,.][0-9]+)?)/ so that the currency type and amount can be
|
|
37
|
+
* differentiated. Please see ISO 4217 for valid currency types.
|
|
38
|
+
*
|
|
35
39
|
* Current options are:
|
|
36
40
|
* {
|
|
37
41
|
* languages: [
|
|
@@ -183,15 +187,15 @@ closure openSearchIndex(prosc, indexName, ioptions, local osin) {
|
|
|
183
187
|
//
|
|
184
188
|
// date
|
|
185
189
|
//
|
|
186
|
-
date: quote(
|
|
187
|
-
|
|
188
|
-
)
|
|
190
|
+
date: quote({
|
|
191
|
+
type: "date"
|
|
192
|
+
})
|
|
189
193
|
//
|
|
190
194
|
// boolean
|
|
191
195
|
//
|
|
192
|
-
boolean: quote(
|
|
193
|
-
|
|
194
|
-
)
|
|
196
|
+
boolean: quote({
|
|
197
|
+
type: "boolean"
|
|
198
|
+
})
|
|
195
199
|
//
|
|
196
200
|
// currency
|
|
197
201
|
//
|
|
@@ -213,15 +217,15 @@ closure openSearchIndex(prosc, indexName, ioptions, local osin) {
|
|
|
213
217
|
//
|
|
214
218
|
// integer
|
|
215
219
|
//
|
|
216
|
-
integer: quote(
|
|
217
|
-
|
|
218
|
-
)
|
|
220
|
+
integer: quote({
|
|
221
|
+
type: "long"
|
|
222
|
+
})
|
|
219
223
|
//
|
|
220
224
|
// number
|
|
221
225
|
//
|
|
222
|
-
number: quote(
|
|
223
|
-
|
|
224
|
-
)
|
|
226
|
+
number: quote({
|
|
227
|
+
type: "float"
|
|
228
|
+
})
|
|
225
229
|
//
|
|
226
230
|
// url
|
|
227
231
|
//
|
|
@@ -303,7 +307,6 @@ closure openSearchIndex(prosc, indexName, ioptions, local osin) {
|
|
|
303
307
|
properties: makeMapping(fields)
|
|
304
308
|
}
|
|
305
309
|
})
|
|
306
|
-
// printline("OpenSearchClient.create:\n${Dialect.print(params)}")
|
|
307
310
|
prosc.request(indexName, {
|
|
308
311
|
method: "PUT"
|
|
309
312
|
putdata: params
|
|
@@ -500,7 +503,6 @@ closure OpenSearchClient(goptions, local oscl, prosc) {
|
|
|
500
503
|
query.multi_match.fields = ["*"].concat(soptions.boost.fields.map(function (item) {
|
|
501
504
|
item.concat("^${soptions.boost.level}")
|
|
502
505
|
}))
|
|
503
|
-
printline(Dialect.print(soptions.boost))
|
|
504
506
|
if dictionary(soptions.qopts)
|
|
505
507
|
query.multi_match = merge(query.multi_match, soptions.qopts)
|
|
506
508
|
if dictionary(soptions.filter) {
|
|
@@ -357,7 +357,7 @@ closure DynaConverter(local conv) {
|
|
|
357
357
|
//
|
|
358
358
|
// condition dictionary:
|
|
359
359
|
// {
|
|
360
|
-
// key: <keyname, e.g. partition key name>
|
|
360
|
+
// key: <keyname, e.g. partition key name or path tuple> // required
|
|
361
361
|
// "=": <expression> // exclusive of other comparisons
|
|
362
362
|
// ">": <expression> // exclusive of other comparisons
|
|
363
363
|
// "<": <expression> // exclusive of other comparisons
|
|
@@ -365,11 +365,12 @@ closure DynaConverter(local conv) {
|
|
|
365
365
|
// beginsWith: <string-expression> // exclusive of other comparisons
|
|
366
366
|
// ">=": <expression> // with <= or alone
|
|
367
367
|
// "<=": <expression> // with >= or alone
|
|
368
|
+
// exists: <boolean> // keyname existence matches boolean
|
|
368
369
|
// }
|
|
369
370
|
//
|
|
370
371
|
|
|
371
372
|
conv.createKeyExpression = function createKeyExpression(params, conds
|
|
372
|
-
local attval, rangename, range, keyname, op, expr, rangex, arg1, arg2) {
|
|
373
|
+
local attval, attname, rangename, range, keyname, op, expr, rangex, arg1, arg2) {
|
|
373
374
|
|
|
374
375
|
// dupeop
|
|
375
376
|
//
|
|
@@ -382,14 +383,24 @@ closure DynaConverter(local conv) {
|
|
|
382
383
|
// build the expression
|
|
383
384
|
//
|
|
384
385
|
attval = genAttributeValueAdder(params)
|
|
386
|
+
attname = genAttributeNameAdder(params)
|
|
385
387
|
for `(rangename, ranges) in conds {
|
|
386
388
|
if !array(ranges)
|
|
387
389
|
ranges = [ranges]
|
|
388
390
|
for range in ranges {
|
|
389
391
|
rangex = false
|
|
390
|
-
|
|
392
|
+
if tuple(range.key) {
|
|
393
|
+
keyname = []
|
|
394
|
+
expr = range.key
|
|
395
|
+
while expr
|
|
396
|
+
keyname.push(attname(pop(expr)))
|
|
397
|
+
keyname = keyname.join(".")
|
|
398
|
+
}
|
|
399
|
+
else
|
|
400
|
+
keyname = tostring(range.key)
|
|
391
401
|
if !keyname
|
|
392
402
|
return (list(Error("key expression requires key name")))
|
|
403
|
+
keyname = attname(keyname)
|
|
393
404
|
for `(op, expr) in range {
|
|
394
405
|
if op == "key"
|
|
395
406
|
continue
|
|
@@ -417,10 +428,16 @@ closure DynaConverter(local conv) {
|
|
|
417
428
|
arg1 = rangex.1
|
|
418
429
|
if rangex.0 == "between" {
|
|
419
430
|
arg2 = rangex.2
|
|
420
|
-
expr = keyname
|
|
431
|
+
expr = "${keyname} between ${arg1} and ${arg2}"
|
|
421
432
|
}
|
|
422
433
|
else if rangex.0 == "beginsWith"
|
|
423
|
-
expr = "begins_with(
|
|
434
|
+
expr = "begins_with(${keyname}, ${arg1})"
|
|
435
|
+
else if rangex.0 == "exists" {
|
|
436
|
+
if arg1
|
|
437
|
+
expr = "attribute_exists(${keyname})"
|
|
438
|
+
else
|
|
439
|
+
expr = "attribute_not_exists(${keyname})"
|
|
440
|
+
}
|
|
424
441
|
else
|
|
425
442
|
expr = keyname.concat(space, rangex.0, space, arg1)
|
|
426
443
|
if params[rangename]
|
|
@@ -674,14 +691,26 @@ closure DynaTable(dyna, tablename, local table) {
|
|
|
674
691
|
|
|
675
692
|
// getRecord
|
|
676
693
|
//
|
|
677
|
-
// Get a record from the table with the specified hash value
|
|
694
|
+
// Get a record from the table with the specified hash value. The optional second argument can be
|
|
695
|
+
// the rangeValue of the item, or an options dictionary. Dictionary options include:
|
|
696
|
+
// {
|
|
697
|
+
// rangeValue: <range-key> // record's range key
|
|
698
|
+
// consistentRead: <boolean> // true to use consistent read
|
|
699
|
+
// }
|
|
700
|
+
// The result is a standard result tuple `(error, record).
|
|
701
|
+
|
|
678
702
|
//
|
|
679
|
-
table.getRecord = closure getRecord(hashValue,
|
|
703
|
+
table.getRecord = closure getRecord(hashValue, options, local params, rangeValue, pending) {
|
|
680
704
|
if preflightError(this)
|
|
681
705
|
return
|
|
682
706
|
params = {
|
|
683
707
|
TableName: tablename
|
|
684
708
|
}
|
|
709
|
+
if dictionary(options) {
|
|
710
|
+
rangeValue = options.rangeValue
|
|
711
|
+
params.ConsistentRead = options.consistentRead
|
|
712
|
+
} else
|
|
713
|
+
rangeValue = options
|
|
685
714
|
params.Key = makeDynKey(list(hashValue, rangeValue))
|
|
686
715
|
pending = new(nonce)
|
|
687
716
|
dyna.aws.getItem(params, function(error, data) {
|
|
@@ -856,6 +885,7 @@ closure DynaTable(dyna, tablename, local table) {
|
|
|
856
885
|
// reverse: <boolean> // reverse order
|
|
857
886
|
// project: <array> // project only specified attributes
|
|
858
887
|
// paging: <exclusive start key> // for paging; updated each call
|
|
888
|
+
// consistentRead: <boolean> // true to use consistent read
|
|
859
889
|
// limit: <number> // maximum count of results
|
|
860
890
|
// }
|
|
861
891
|
//
|
|
@@ -902,6 +932,8 @@ closure DynaTable(dyna, tablename, local table) {
|
|
|
902
932
|
params.ProjectionExpression = options.project.join(", ")
|
|
903
933
|
if options.paging
|
|
904
934
|
params.ExclusiveStartKey = options.paging
|
|
935
|
+
if options.consistentRead
|
|
936
|
+
params.ConsistentRead = options.consistentRead
|
|
905
937
|
output = []
|
|
906
938
|
`(error) = dynQueryPager(`query, params, options.limit, function(data) {
|
|
907
939
|
if data.Count > 0
|
|
@@ -921,12 +953,13 @@ closure DynaTable(dyna, tablename, local table) {
|
|
|
921
953
|
//
|
|
922
954
|
// Options:
|
|
923
955
|
// {
|
|
924
|
-
// index:
|
|
925
|
-
// filter:
|
|
926
|
-
// attmap:
|
|
927
|
-
// project:
|
|
928
|
-
// paging:
|
|
929
|
-
//
|
|
956
|
+
// index: <string> // index name in table
|
|
957
|
+
// filter: <key-expression> // conditions for items to return
|
|
958
|
+
// attmap: <dictionary> // map attribute names to #shortcuts
|
|
959
|
+
// project: <array> // project only specified attributes
|
|
960
|
+
// paging: <exclusive start key> // for paging; updated each call
|
|
961
|
+
// consistentRead: <boolean> // true to use consistent read
|
|
962
|
+
// limit: <number> // maximum count of results
|
|
930
963
|
// }
|
|
931
964
|
//
|
|
932
965
|
|
|
@@ -953,6 +986,8 @@ closure DynaTable(dyna, tablename, local table) {
|
|
|
953
986
|
params.ProjectionExpression = options.project.join(", ")
|
|
954
987
|
if options.paging
|
|
955
988
|
params.ExclusiveStartKey = options.paging
|
|
989
|
+
if options.consistentRead
|
|
990
|
+
params.ConsistentRead = options.consistentRead
|
|
956
991
|
output = []
|
|
957
992
|
`(error) = dynQueryPager(`scan, params, options.limit, function(data) {
|
|
958
993
|
if data.Count >= 0
|
package/test/test_01_core.nlg
CHANGED
|
@@ -319,10 +319,13 @@ RegisterTestCategory("core", [
|
|
|
319
319
|
[ "eval(`(+ 4 3));", "7" ],
|
|
320
320
|
|
|
321
321
|
[ "apply(`+, `(4 3));", "7" ],
|
|
322
|
-
|
|
322
|
+
[ "apply(getproc(`+), `(4, 3));", "7" ], // ensures that call takes a builtin as function
|
|
323
|
+
[ "apply(Number.parseInt, list('42'));", "42" ],
|
|
324
|
+
|
|
323
325
|
[ "call(car(`+), 4, 3);", "7" ],
|
|
324
326
|
[ "call(getproc(`+), 4, 3);", "7" ], // ensures that call takes a builtin as function
|
|
325
|
-
|
|
327
|
+
[ "call(Number.parseInt, '42');", "42" ],
|
|
328
|
+
|
|
326
329
|
[ "list();>", "false" ],
|
|
327
330
|
[ "list(3, 4, 5, `(6 7));>", "(3 4 5 (6 7))" ],
|
|
328
331
|
|
|
@@ -354,12 +357,16 @@ RegisterTestCategory("core", [
|
|
|
354
357
|
[ "print(testcore=`testcore);", "testcore|testcore" ],
|
|
355
358
|
[ "print(testcore=42);", "42|42" ],
|
|
356
359
|
|
|
357
|
-
[ "cond();",
|
|
360
|
+
[ "cond();", "false" ],
|
|
361
|
+
[ "cond(true);",
|
|
362
|
+
{ errors: "if expression required at (1, 6) found true" } ],
|
|
358
363
|
[ "quote(cond(if false 3 else if true 4));>", "(cond ((identity false) 3) ((identity true) 4))" ],
|
|
359
364
|
[ "cond(if false 3 else if true 4);", "4" ],
|
|
360
365
|
[ "cond (if 1 and\n 2, 3);", "3" ],
|
|
361
366
|
[ "cond(print(false),print(\"hi\"));",
|
|
362
|
-
{ errors: "
|
|
367
|
+
{ errors: "if expression required at (1, 6) found print" } ],
|
|
368
|
+
[ "cond(if 3 4, print(5));",
|
|
369
|
+
{ errors: "if expression required at (1, 14) found print" } ],
|
|
363
370
|
|
|
364
371
|
[ "body();", "false" ],
|
|
365
372
|
[ "quote(body(if false 3 else if true 4));>", "(body ((identity false) 3) ((identity true) 4))" ],
|
|
@@ -367,8 +374,10 @@ RegisterTestCategory("core", [
|
|
|
367
374
|
[ "body(print(\"hi\"), print(\" there\"),4+3);>", "hi there|7" ],
|
|
368
375
|
[ "body(print(false),print(\"hi\"));", "falsehi|\"hi\"" ],
|
|
369
376
|
|
|
370
|
-
[ "push();>",
|
|
371
|
-
|
|
377
|
+
[ "push();>",
|
|
378
|
+
{ errors: "attempt to modify constant false" } ],
|
|
379
|
+
[ "push(true);>",
|
|
380
|
+
{ errors: "attempt to modify constant false" } ],
|
|
372
381
|
[ "push(true, 3);>", "false" ],
|
|
373
382
|
[ "testcore=false;", "false" ],
|
|
374
383
|
[ "push(11, testcore);>", "(11)" ],
|
|
@@ -424,7 +433,9 @@ RegisterTestCategory("core", [
|
|
|
424
433
|
[ "temp(2, `(1 2 3));>", "(2 3)|(2 3)" ],
|
|
425
434
|
[ "function (ex1, lex1) { ex1+pop(lex1), print(lex1), lex1 }(2, `(1 2 3));>", "(2 3)|(2 3)" ],
|
|
426
435
|
[ "quote(function (a)\n { f(b)-\ng(c) * h(d)\n });>", "(function lambda (a) (- (f b) (* (g c) (h d))))" ],
|
|
427
|
-
[ "quote(function (a)\n { f(b)\n-g(c) * h(d)\n });>",
|
|
436
|
+
[ "quote(function (a)\n { f(b)\n-g(c) * h(d)\n });>",
|
|
437
|
+
{ errors: "ambiguous newline (use \\ or ,) at (3, 1) found -" }],
|
|
438
|
+
[ "quote(function (a)\n { f(b)\\\n-g(c) * h(d)\n });>", "(function lambda (a) (- (f b) (* (g c) (h d))))" ],
|
|
428
439
|
|
|
429
440
|
[ "tempo = temp.proc;>", "(function temp (ex1 lex1) (+ ex1 (pop lex1)) (print lex1) lex1)" ],
|
|
430
441
|
[ "function temp(ex1) { ex1 * 2 };", "==> redefined: temp|temp" ],
|
|
@@ -589,7 +600,21 @@ RegisterTestCategory("core", [
|
|
|
589
600
|
[ "bobby.sue(44);", "(44)(sue billy)/Dictionary{2}|(sam nevil bill)/(sue billy)|(\"sue\", \"billy\")" ],
|
|
590
601
|
[ "keys(bobby);>", "(\"sue\" \"billy\")" ],
|
|
591
602
|
|
|
592
|
-
|
|
603
|
+
["merge();", "{ }"],
|
|
604
|
+
["merge({a:3});", "{ a: 3 }"],
|
|
605
|
+
["merge({a:3,b:4});", "{ a: 3, b: 4 }"],
|
|
606
|
+
["merge({a:3,b:4,c:5});", "{ a: 3, b: 4, c: 5 }"],
|
|
607
|
+
["merge(`(a));", "{ }"],
|
|
608
|
+
["merge({a:3}, `(a));", "{ }"],
|
|
609
|
+
["merge({a:3,b:4}, `(a), {c:5});", "{ b: 4, c: 5 }"],
|
|
610
|
+
["merge({a:3,b:4}, `(c), {c:5});", "{ a: 3, b: 4, c: 5 }"],
|
|
611
|
+
["merge({a:3,b:4}, `(g), {c:5});", "{ a: 3, b: 4, c: 5 }"],
|
|
612
|
+
["merge({true:a,false:b});", "{ true: a, false: a }"],
|
|
613
|
+
["merge({true:a,false:b}, `(true));", "{ false: a }"],
|
|
614
|
+
["oo={true:a}; oo[1.0/3]=`b; oo;", "{ true: a }|b|{ true: a, 0.3333333333333333: b }"],
|
|
615
|
+
["merge(oo, list(1.0/3), {false:c});", "{ true: a, false: c }"],
|
|
616
|
+
["oo;", "{ true: a, 0.3333333333333333: b }"],
|
|
617
|
+
|
|
593
618
|
//
|
|
594
619
|
// object getters
|
|
595
620
|
//
|
|
@@ -796,6 +821,9 @@ RegisterTestCategory("core", [
|
|
|
796
821
|
[ "cons(`a);>", "(a)" ],
|
|
797
822
|
[ "cons(`a,`b);>", "(a . b)" ],
|
|
798
823
|
[ "cons(`a,`b,`c);>", "(a b . c)" ],
|
|
824
|
+
|
|
825
|
+
[ "unintern(true) === true", "false"],
|
|
826
|
+
|
|
799
827
|
[ "length(stacktrace());", "55" ],
|
|
800
828
|
|
|
801
829
|
//
|
|
@@ -35,11 +35,11 @@ RegisterTestCategory("JSinterop", [
|
|
|
35
35
|
|
|
36
36
|
[ "o(3);", {
|
|
37
37
|
"dev": { errors: "xcall \"[object Object]\": TypeError: object.apply is not a function" }
|
|
38
|
-
"prod": { errors: "xcall \"[object Object]\": TypeError:
|
|
38
|
+
"prod": { errors: "xcall \"[object Object]\": TypeError: r[3].apply is not a function" }
|
|
39
39
|
}[ "prod"]],
|
|
40
40
|
[ "o(Number);", {
|
|
41
41
|
"dev": { errors: "xcall \"[object Object]\": TypeError: object.apply is not a function" }
|
|
42
|
-
"prod": { errors: "xcall \"[object Object]\": TypeError:
|
|
42
|
+
"prod": { errors: "xcall \"[object Object]\": TypeError: r[3].apply is not a function" }
|
|
43
43
|
}[ "prod"]],
|
|
44
44
|
[ "Number(3);", "[Number 3]" ],
|
|
45
45
|
[ "Number(3).toString();", "\"3\"" ],
|
|
@@ -63,6 +63,15 @@ RegisterTestCategory("JSinterop", [
|
|
|
63
63
|
|
|
64
64
|
[ "xnew(js.g.Promise, function() {});", "[object Promise]" ],
|
|
65
65
|
|
|
66
|
+
//
|
|
67
|
+
// Arrays
|
|
68
|
+
//
|
|
69
|
+
|
|
70
|
+
["Array(3,4,5);", "[Array 3,4,5]"],
|
|
71
|
+
["Array([3]);", "[Array [3]]"],
|
|
72
|
+
["Array([3]).0;", "[Array 3]"],
|
|
73
|
+
["Array([3]).0.0;", "3"],
|
|
74
|
+
|
|
66
75
|
|
|
67
76
|
//
|
|
68
77
|
// child processes
|
package/test/test_05_strings.nlg
CHANGED
|
@@ -71,6 +71,6 @@ RegisterTestCategory("strings", [
|
|
|
71
71
|
[ "\"abc\".toString();", "\"abc\"" ],
|
|
72
72
|
[ "xapply(String, toString, list(\"abc\"));", "\"abc\"" ],
|
|
73
73
|
[ "xcall(String, toString, \"abc\");", "\"abc\"" ],
|
|
74
|
-
[ "function(local match) { \"abc\".match(RegExp(\"abc\")) }();",
|
|
74
|
+
[ "function(local match) { \"abc\".match(RegExp(\"abc\")) }();", '[Array "abc"]' ]
|
|
75
75
|
|
|
76
76
|
]);
|
|
@@ -438,15 +438,18 @@ RegisterTestCategory("Lingo parse", [
|
|
|
438
438
|
[ "try{nest()}finally{};",
|
|
439
439
|
{ exprs: "(catch ((nest)) false false)" } ],
|
|
440
440
|
[ "try{nest()}catch{}finally{};",
|
|
441
|
-
{ exprs: "(catch ((nest)) (((identity true))) false)" } ],
|
|
441
|
+
{ exprs: "(catch ((nest)) (((identity true) false)) false)" } ],
|
|
442
442
|
[ "function test1() { try { nest() } finally { } };",
|
|
443
443
|
{ exprs: "(defproc function test1 false (catch ((nest)) false false))",
|
|
444
444
|
text: "==> redefined: test1" } ],
|
|
445
445
|
[ "function(){try{nest()}catch{},if(1)2};",
|
|
446
|
-
{ exprs: "(function lambda false (catch ((nest)) (((identity true))) false) ((identity 1) 2))" } ],
|
|
446
|
+
{ exprs: "(function lambda false (catch ((nest)) (((identity true) false)) false) ((identity 1) 2))" } ],
|
|
447
447
|
[ "function(x) { try {} catch { if true { 4 } } };",
|
|
448
448
|
{ exprs: "(function lambda (x) (catch false (((identity true) 4)) false))" } ],
|
|
449
|
-
|
|
449
|
+
[ "try { throw(green) } catch { printline(4) };",
|
|
450
|
+
{ exprs: "(catch ((throw green)) (((identity true) (printline 4))) false)",
|
|
451
|
+
text: "4" } ],
|
|
452
|
+
|
|
450
453
|
//
|
|
451
454
|
// cond
|
|
452
455
|
//
|
|
@@ -468,7 +471,7 @@ RegisterTestCategory("Lingo parse", [
|
|
|
468
471
|
//
|
|
469
472
|
|
|
470
473
|
[ "function() {test()[3]};>", "(function lambda false (deref (test) 3))"],
|
|
471
|
-
[ "function() {test()
|
|
474
|
+
[ "function() {test()\\\n[3]};>", "(function lambda false (deref (test) 3))"],
|
|
472
475
|
[ "function() {test(),\n[3]};>", "(function lambda false (test) Array[1])"],
|
|
473
476
|
[ "function() {test(),\n[3]};", "function () {\n"
|
|
474
477
|
" test(),\n" // need comma before array
|
|
@@ -497,6 +500,42 @@ RegisterTestCategory("Lingo parse", [
|
|
|
497
500
|
" else {\n"
|
|
498
501
|
" { a: 3 } }\n" // need braces around dictionary
|
|
499
502
|
"}" ],
|
|
503
|
+
[ "function() {if 1, -2 };", "function () {\n"
|
|
504
|
+
" if 1\n"
|
|
505
|
+
" -2\n"
|
|
506
|
+
"}" ],
|
|
507
|
+
[ "function() {if 1,\n"
|
|
508
|
+
"-2 };", "function () {\n"
|
|
509
|
+
" if 1\n"
|
|
510
|
+
" -2\n"
|
|
511
|
+
"}" ],
|
|
512
|
+
[ "function() {if 1\n"
|
|
513
|
+
"-2 };",
|
|
514
|
+
{ errors: "ambiguous newline (use \\ or ,) at (2, 1) found -" } ],
|
|
515
|
+
[ "function() {if 1\\\n"
|
|
516
|
+
"-2 3 };", "function () {\n"
|
|
517
|
+
" if 1 - 2\n"
|
|
518
|
+
" 3\n"
|
|
519
|
+
"}" ],
|
|
520
|
+
[ "function(x) {if x\n[2]\n3 };",
|
|
521
|
+
{ errors: "ambiguous newline (use \\ or ,) at (2, 1) found [" } ],
|
|
522
|
+
[ "function(x) {if x,\n[2]\n3 };",
|
|
523
|
+
"function (x) {\n"
|
|
524
|
+
" if x\n"
|
|
525
|
+
" [2]\n"
|
|
526
|
+
" 3\n"
|
|
527
|
+
"}" ],
|
|
528
|
+
[ "function(x) {if x\\\n[2]\n3 };",
|
|
529
|
+
"function (x) {\n"
|
|
530
|
+
" if x[2]\n"
|
|
531
|
+
" 3\n"
|
|
532
|
+
"}" ],
|
|
533
|
+
[ "function(x) {if x\n(2)\n3 };",
|
|
534
|
+
{ errors: "ambiguous newline (use \\ or ,) at (2, 1) found (" } ],
|
|
535
|
+
[ "function() { else };",
|
|
536
|
+
{ errors: "stray keyword at (1, 14) found else" } ],
|
|
537
|
+
[ "function() { if 1 else 3 };",
|
|
538
|
+
{ errors: "stray keyword at (1, 19) found else" } ],
|
|
500
539
|
|
|
501
540
|
//
|
|
502
541
|
// semantic validity
|
package/test/test_07_lingo.nlg
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* column positioning: // // !
|
|
8
8
|
*
|
|
9
|
-
* Copyright (c) 2018-
|
|
9
|
+
* Copyright (c) 2018-2023 by Richard C. Zulch
|
|
10
10
|
*
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -159,15 +159,25 @@ RegisterTestCategory("Lingo", [
|
|
|
159
159
|
// " map : [(0, 23), 0, 9, 2, 7],\n" -- maps currently omitted
|
|
160
160
|
" comments : [] } }" ],
|
|
161
161
|
[ "testat@jim(true);", "\"you are annotated with true!\"" ],
|
|
162
|
+
[ "copyann(testat, a);", "testat" ],
|
|
163
|
+
[ "testat@*;", '("joe", "jim", ".sourcemap")' ],
|
|
164
|
+
[ "copyann(testat, a, true);", "testat" ],
|
|
165
|
+
[ "testat@*;", '("joe")' ],
|
|
166
|
+
[ "copyann(3, a);", { errors: "attempt to modify constant 3" } ],
|
|
167
|
+
[ "copyann(a, 3);", "false" ],
|
|
162
168
|
|
|
163
169
|
|
|
164
170
|
//
|
|
165
|
-
// lists, objects
|
|
171
|
+
// lists, dictionaries, objects, and arrays
|
|
166
172
|
//
|
|
167
173
|
|
|
168
174
|
[ "divide(71, 3);", "(23 . 2)" ],
|
|
169
175
|
[ "[3,4+5];", "[3, 9]" ],
|
|
170
176
|
[ "{a:3,b:4+5};", "{ a: 3, b: 9 }" ],
|
|
177
|
+
[ "function(g) { { a: 3+g } }(5);", "{ a: 8 }" ],
|
|
178
|
+
[ "function(g) { { a: false || undefined } }(6);", "{ }" ],
|
|
179
|
+
[ "function(g) { { a: false && g || undefined } }(7);", "{ }" ],
|
|
180
|
+
[ "function(g) { { a: true && g || undefined } }(8);", "{ a: 8 }" ],
|
|
171
181
|
|
|
172
182
|
[ "`(1, 2, {a:3,b:4}, 5);", "(1, 2, { a: 3, b: 4 }, 5)" ],
|
|
173
183
|
[ "`(1, 2, {a:3,b:4}, 5);>", "(1 2 Dictionary{2} 5)" ],
|
|
@@ -287,6 +297,27 @@ RegisterTestCategory("Lingo", [
|
|
|
287
297
|
[ "aa[1] /= 2;", "3" ],
|
|
288
298
|
|
|
289
299
|
|
|
300
|
+
//
|
|
301
|
+
// catch
|
|
302
|
+
//
|
|
303
|
+
|
|
304
|
+
[ "try { throw(green) } catch { printline(4) };", "4|4" ],
|
|
305
|
+
[ "try { throw(blue) } catch { false(),printline(5) };", "5|5" ],
|
|
306
|
+
[ "try { 1/0 } catch {};", "false"],
|
|
307
|
+
[ "try { 1/0 } catch { 0 };", "0"],
|
|
308
|
+
[ "try { 1/0 } catch { exception };", '(internal, "divide by zero")'],
|
|
309
|
+
[ "try { 1/0 } catch { if exception == 3 4, printline(5) };",
|
|
310
|
+
{ errors: "if expression required at (1, 42) found printline"} ],
|
|
311
|
+
[ "try { throw(blue) } catch { if exception == blue printline(blue) };", "blue|blue"],
|
|
312
|
+
[ "try { throw(green) } catch { if exception == blue printline(blue) };",
|
|
313
|
+
{ errors: "exception: green" } ],
|
|
314
|
+
[ "try { throw(green) } catch { if exception == blue printline(blue),"
|
|
315
|
+
"if exception == green printline(green) };", "green|green"],
|
|
316
|
+
[ "try { throw(red) } catch { if exception == blue printline(blue),"
|
|
317
|
+
"if exception == green printline(green) };",
|
|
318
|
+
{ errors: "exception: red" } ],
|
|
319
|
+
|
|
320
|
+
|
|
290
321
|
//
|
|
291
322
|
// if else
|
|
292
323
|
//
|