funcity 0.3.0 → 0.4.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/index.cjs +92 -32
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.mjs +92 -32
- package/dist/index.mjs.map +1 -1
- package/dist/parser.d.ts +9 -2
- package/dist/parser.d.ts.map +1 -1
- package/dist/reducer.d.ts +2 -2
- package/dist/scripting.d.ts +2 -2
- package/dist/standards.d.ts +2 -2
- package/dist/tokenizer.d.ts +9 -2
- package/dist/tokenizer.d.ts.map +1 -1
- package/dist/types.d.ts +2 -2
- package/dist/utils.d.ts +2 -2
- package/images/funcity.120.png +0 -0
- package/package.json +13 -12
package/dist/index.cjs
CHANGED
|
@@ -302,16 +302,8 @@ const tokenizeIdentity = (context) => {
|
|
|
302
302
|
range: { start, end: context.cursor.location("end") }
|
|
303
303
|
};
|
|
304
304
|
};
|
|
305
|
-
const
|
|
306
|
-
const
|
|
307
|
-
context.cursor.skip(2);
|
|
308
|
-
const tokens = [
|
|
309
|
-
{
|
|
310
|
-
kind: "open",
|
|
311
|
-
symbol: "{{",
|
|
312
|
-
range: { start: openStart, end: context.cursor.location("end") }
|
|
313
|
-
}
|
|
314
|
-
];
|
|
305
|
+
const tokenizeCodeTokens = (context, stopOnClose, finalizeUnknownOnEot) => {
|
|
306
|
+
const tokens = [];
|
|
315
307
|
let unknownStartLocation;
|
|
316
308
|
const finalizeUnknown = () => {
|
|
317
309
|
if (unknownStartLocation) {
|
|
@@ -327,20 +319,21 @@ const tokenizeCodeBlock = (context) => {
|
|
|
327
319
|
}
|
|
328
320
|
};
|
|
329
321
|
while (!context.cursor.eot()) {
|
|
330
|
-
if (context.cursor.assert("}}")) {
|
|
322
|
+
if (stopOnClose && context.cursor.assert("}}")) {
|
|
331
323
|
finalizeUnknown();
|
|
332
|
-
|
|
333
|
-
context.cursor.skip(2);
|
|
334
|
-
tokens.push({
|
|
335
|
-
kind: "close",
|
|
336
|
-
symbol: "}}",
|
|
337
|
-
range: { start: location, end: context.cursor.location("end") }
|
|
338
|
-
});
|
|
339
|
-
return tokens;
|
|
324
|
+
return { tokens, closed: true };
|
|
340
325
|
}
|
|
341
326
|
const ch = context.cursor.getChar();
|
|
342
327
|
if (ch === "\\") {
|
|
343
328
|
const next = context.cursor.getChar(1);
|
|
329
|
+
if (next === "\n") {
|
|
330
|
+
context.cursor.skip(2);
|
|
331
|
+
continue;
|
|
332
|
+
}
|
|
333
|
+
if (next === "\r" && context.cursor.getChar(2) === "\n") {
|
|
334
|
+
context.cursor.skip(3);
|
|
335
|
+
continue;
|
|
336
|
+
}
|
|
344
337
|
if (next === "{" || next === "}") {
|
|
345
338
|
context.cursor.skip(2);
|
|
346
339
|
continue;
|
|
@@ -405,12 +398,41 @@ const tokenizeCodeBlock = (context) => {
|
|
|
405
398
|
} else if (ch === " ") {
|
|
406
399
|
finalizeUnknown();
|
|
407
400
|
context.cursor.skip(1);
|
|
408
|
-
} else
|
|
409
|
-
|
|
401
|
+
} else {
|
|
402
|
+
if (!unknownStartLocation) {
|
|
403
|
+
unknownStartLocation = context.cursor.location("start");
|
|
404
|
+
}
|
|
410
405
|
context.cursor.skip(1);
|
|
411
406
|
}
|
|
412
407
|
context.cursor.skipChars(" ");
|
|
413
408
|
}
|
|
409
|
+
if (finalizeUnknownOnEot) {
|
|
410
|
+
finalizeUnknown();
|
|
411
|
+
}
|
|
412
|
+
return { tokens, closed: false };
|
|
413
|
+
};
|
|
414
|
+
const tokenizeCodeBlock = (context) => {
|
|
415
|
+
const openStart = context.cursor.location("start");
|
|
416
|
+
context.cursor.skip(2);
|
|
417
|
+
const tokens = [
|
|
418
|
+
{
|
|
419
|
+
kind: "open",
|
|
420
|
+
symbol: "{{",
|
|
421
|
+
range: { start: openStart, end: context.cursor.location("end") }
|
|
422
|
+
}
|
|
423
|
+
];
|
|
424
|
+
const result = tokenizeCodeTokens(context, true, false);
|
|
425
|
+
tokens.push(...result.tokens);
|
|
426
|
+
if (result.closed) {
|
|
427
|
+
const location = context.cursor.location("start");
|
|
428
|
+
context.cursor.skip(2);
|
|
429
|
+
tokens.push({
|
|
430
|
+
kind: "close",
|
|
431
|
+
symbol: "}}",
|
|
432
|
+
range: { start: location, end: context.cursor.location("end") }
|
|
433
|
+
});
|
|
434
|
+
return tokens;
|
|
435
|
+
}
|
|
414
436
|
const causeLocation = context.cursor.location("start");
|
|
415
437
|
context.errors.push({
|
|
416
438
|
type: "error",
|
|
@@ -435,9 +457,12 @@ const createTokenizerCursor = (script) => {
|
|
|
435
457
|
const ch = script[currentIndex];
|
|
436
458
|
if (ch === "\r") {
|
|
437
459
|
rawColumn = 0;
|
|
438
|
-
} else if (ch === "\n" && lastch !== "\r") {
|
|
439
|
-
rawColumn = 0;
|
|
440
460
|
rawLine++;
|
|
461
|
+
} else if (ch === "\n") {
|
|
462
|
+
rawColumn = 0;
|
|
463
|
+
if (lastch !== "\r") {
|
|
464
|
+
rawLine++;
|
|
465
|
+
}
|
|
441
466
|
} else {
|
|
442
467
|
rawColumn++;
|
|
443
468
|
}
|
|
@@ -514,6 +539,14 @@ const createTokenizerCursor = (script) => {
|
|
|
514
539
|
location
|
|
515
540
|
};
|
|
516
541
|
};
|
|
542
|
+
const runCodeTokenizer = (script, errors) => {
|
|
543
|
+
const context = {
|
|
544
|
+
cursor: createTokenizerCursor(script),
|
|
545
|
+
errors
|
|
546
|
+
};
|
|
547
|
+
const result = tokenizeCodeTokens(context, false, true);
|
|
548
|
+
return result.tokens;
|
|
549
|
+
};
|
|
517
550
|
const runTokenizer = (script, errors) => {
|
|
518
551
|
const context = {
|
|
519
552
|
cursor: createTokenizerCursor(script),
|
|
@@ -645,6 +678,9 @@ const parseLambdaExpression = (cursor, errors) => {
|
|
|
645
678
|
};
|
|
646
679
|
const parsePartialExpression = (cursor, errors) => {
|
|
647
680
|
const token = cursor.peekToken();
|
|
681
|
+
if (!token) {
|
|
682
|
+
return void 0;
|
|
683
|
+
}
|
|
648
684
|
switch (token.kind) {
|
|
649
685
|
case "number": {
|
|
650
686
|
const node = parseNumber(cursor);
|
|
@@ -1029,14 +1065,15 @@ const extractParameterArguments = (namesNode, errors) => {
|
|
|
1029
1065
|
}
|
|
1030
1066
|
}
|
|
1031
1067
|
};
|
|
1032
|
-
const
|
|
1068
|
+
const parseBlockCore = (cursor, errors, mode) => {
|
|
1033
1069
|
const rootState = {
|
|
1034
1070
|
kind: "root",
|
|
1035
1071
|
startRange: emptyRange,
|
|
1036
1072
|
branch: createBranchState()
|
|
1037
1073
|
};
|
|
1038
1074
|
const statementStates = [rootState];
|
|
1039
|
-
|
|
1075
|
+
const isCodeMode = mode === "code";
|
|
1076
|
+
let isInExpressionBlock = isCodeMode;
|
|
1040
1077
|
while (true) {
|
|
1041
1078
|
const token = drainEndOfLineAndPeek(cursor);
|
|
1042
1079
|
if (!token) {
|
|
@@ -1063,14 +1100,16 @@ const parseBlock = (cursor, errors) => {
|
|
|
1063
1100
|
case "open": {
|
|
1064
1101
|
if (token.symbol === "{{") {
|
|
1065
1102
|
cursor.skipToken();
|
|
1066
|
-
if (
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1103
|
+
if (!isCodeMode) {
|
|
1104
|
+
if (isInExpressionBlock) {
|
|
1105
|
+
errors.push({
|
|
1106
|
+
type: "error",
|
|
1107
|
+
description: `Already opened expression block`,
|
|
1108
|
+
range: token.range
|
|
1109
|
+
});
|
|
1110
|
+
}
|
|
1111
|
+
isInExpressionBlock = true;
|
|
1072
1112
|
}
|
|
1073
|
-
isInExpressionBlock = true;
|
|
1074
1113
|
} else {
|
|
1075
1114
|
const node = parseExpression(cursor, errors);
|
|
1076
1115
|
if (node) {
|
|
@@ -1081,6 +1120,10 @@ const parseBlock = (cursor, errors) => {
|
|
|
1081
1120
|
}
|
|
1082
1121
|
case "close": {
|
|
1083
1122
|
cursor.skipToken();
|
|
1123
|
+
if (token.symbol === "}}" && isCodeMode) {
|
|
1124
|
+
flushCurrentBranch(statementStates);
|
|
1125
|
+
break;
|
|
1126
|
+
}
|
|
1084
1127
|
if (!isInExpressionBlock) {
|
|
1085
1128
|
errors.push({
|
|
1086
1129
|
type: "error",
|
|
@@ -1089,6 +1132,14 @@ const parseBlock = (cursor, errors) => {
|
|
|
1089
1132
|
});
|
|
1090
1133
|
break;
|
|
1091
1134
|
}
|
|
1135
|
+
if (isCodeMode) {
|
|
1136
|
+
errors.push({
|
|
1137
|
+
type: "error",
|
|
1138
|
+
description: `Mismatched close bracket`,
|
|
1139
|
+
range: token.range
|
|
1140
|
+
});
|
|
1141
|
+
break;
|
|
1142
|
+
}
|
|
1092
1143
|
flushCurrentBranch(statementStates);
|
|
1093
1144
|
isInExpressionBlock = false;
|
|
1094
1145
|
break;
|
|
@@ -1335,6 +1386,9 @@ const parseBlock = (cursor, errors) => {
|
|
|
1335
1386
|
}
|
|
1336
1387
|
return rootState.branch.blocks;
|
|
1337
1388
|
};
|
|
1389
|
+
const parseBlock = (cursor, errors) => {
|
|
1390
|
+
return parseBlockCore(cursor, errors, "script");
|
|
1391
|
+
};
|
|
1338
1392
|
const createParserCursor = (tokens) => {
|
|
1339
1393
|
let index = 0;
|
|
1340
1394
|
const peekToken = () => {
|
|
@@ -1360,6 +1414,10 @@ const createParserCursor = (tokens) => {
|
|
|
1360
1414
|
skipToken
|
|
1361
1415
|
};
|
|
1362
1416
|
};
|
|
1417
|
+
const parseExpressions = (tokens, errors) => {
|
|
1418
|
+
const cursor = createParserCursor(tokens);
|
|
1419
|
+
return parseBlockCore(cursor, errors, "code");
|
|
1420
|
+
};
|
|
1363
1421
|
const runParser = (tokens, errors) => {
|
|
1364
1422
|
const cursor = createParserCursor(tokens);
|
|
1365
1423
|
const blockNodes = parseBlock(cursor, errors);
|
|
@@ -2137,8 +2195,10 @@ exports.makeFunCityFunction = makeFunCityFunction;
|
|
|
2137
2195
|
exports.outputErrors = outputErrors;
|
|
2138
2196
|
exports.parseBlock = parseBlock;
|
|
2139
2197
|
exports.parseExpression = parseExpression;
|
|
2198
|
+
exports.parseExpressions = parseExpressions;
|
|
2140
2199
|
exports.reduceExpressionNode = reduceExpressionNode;
|
|
2141
2200
|
exports.reduceNode = reduceNode;
|
|
2201
|
+
exports.runCodeTokenizer = runCodeTokenizer;
|
|
2142
2202
|
exports.runParser = runParser;
|
|
2143
2203
|
exports.runReducer = runReducer;
|
|
2144
2204
|
exports.runScriptOnce = runScriptOnce;
|