openalgo-script 0.1.0-alpha.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/LICENSE +201 -0
- package/NOTICE +12 -0
- package/README.md +255 -0
- package/dist/core/ast/annotations.d.ts +56 -0
- package/dist/core/ast/annotations.d.ts.map +1 -0
- package/dist/core/ast/annotations.js +27 -0
- package/dist/core/ast/annotations.js.map +1 -0
- package/dist/core/ast/build.d.ts +25 -0
- package/dist/core/ast/build.d.ts.map +1 -0
- package/dist/core/ast/build.js +26 -0
- package/dist/core/ast/build.js.map +1 -0
- package/dist/core/ast/children.d.ts +15 -0
- package/dist/core/ast/children.d.ts.map +1 -0
- package/dist/core/ast/children.js +103 -0
- package/dist/core/ast/children.js.map +1 -0
- package/dist/core/ast/expressions.d.ts +178 -0
- package/dist/core/ast/expressions.d.ts.map +1 -0
- package/dist/core/ast/expressions.js +50 -0
- package/dist/core/ast/expressions.js.map +1 -0
- package/dist/core/ast/header.d.ts +50 -0
- package/dist/core/ast/header.d.ts.map +1 -0
- package/dist/core/ast/header.js +2 -0
- package/dist/core/ast/header.js.map +1 -0
- package/dist/core/ast/index.d.ts +30 -0
- package/dist/core/ast/index.d.ts.map +1 -0
- package/dist/core/ast/index.js +21 -0
- package/dist/core/ast/index.js.map +1 -0
- package/dist/core/ast/name.d.ts +24 -0
- package/dist/core/ast/name.d.ts.map +1 -0
- package/dist/core/ast/name.js +2 -0
- package/dist/core/ast/name.js.map +1 -0
- package/dist/core/ast/node.d.ts +34 -0
- package/dist/core/ast/node.d.ts.map +1 -0
- package/dist/core/ast/node.js +70 -0
- package/dist/core/ast/node.js.map +1 -0
- package/dist/core/ast/script.d.ts +57 -0
- package/dist/core/ast/script.d.ts.map +1 -0
- package/dist/core/ast/script.js +2 -0
- package/dist/core/ast/script.js.map +1 -0
- package/dist/core/ast/statements.d.ts +161 -0
- package/dist/core/ast/statements.d.ts.map +1 -0
- package/dist/core/ast/statements.js +10 -0
- package/dist/core/ast/statements.js.map +1 -0
- package/dist/core/ast/walk.d.ts +39 -0
- package/dist/core/ast/walk.d.ts.map +1 -0
- package/dist/core/ast/walk.js +54 -0
- package/dist/core/ast/walk.js.map +1 -0
- package/dist/core/catalogue/catalogue.generated.d.ts +1590 -0
- package/dist/core/catalogue/catalogue.generated.d.ts.map +1 -0
- package/dist/core/catalogue/catalogue.generated.js +162 -0
- package/dist/core/catalogue/catalogue.generated.js.map +1 -0
- package/dist/core/catalogue/index.d.ts +15 -0
- package/dist/core/catalogue/index.d.ts.map +1 -0
- package/dist/core/catalogue/index.js +4 -0
- package/dist/core/catalogue/index.js.map +1 -0
- package/dist/core/catalogue/lookup.d.ts +14 -0
- package/dist/core/catalogue/lookup.d.ts.map +1 -0
- package/dist/core/catalogue/lookup.js +19 -0
- package/dist/core/catalogue/lookup.js.map +1 -0
- package/dist/core/catalogue/template.d.ts +15 -0
- package/dist/core/catalogue/template.d.ts.map +1 -0
- package/dist/core/catalogue/template.js +33 -0
- package/dist/core/catalogue/template.js.map +1 -0
- package/dist/core/catalogue/types.d.ts +34 -0
- package/dist/core/catalogue/types.d.ts.map +1 -0
- package/dist/core/catalogue/types.js +6 -0
- package/dist/core/catalogue/types.js.map +1 -0
- package/dist/core/catalogue/values.generated.d.ts +565 -0
- package/dist/core/catalogue/values.generated.d.ts.map +1 -0
- package/dist/core/catalogue/values.generated.js +6 -0
- package/dist/core/catalogue/values.generated.js.map +1 -0
- package/dist/core/diagnostics/collector.d.ts +46 -0
- package/dist/core/diagnostics/collector.d.ts.map +1 -0
- package/dist/core/diagnostics/collector.js +55 -0
- package/dist/core/diagnostics/collector.js.map +1 -0
- package/dist/core/diagnostics/diagnostic.d.ts +40 -0
- package/dist/core/diagnostics/diagnostic.d.ts.map +1 -0
- package/dist/core/diagnostics/diagnostic.js +29 -0
- package/dist/core/diagnostics/diagnostic.js.map +1 -0
- package/dist/core/diagnostics/index.d.ts +12 -0
- package/dist/core/diagnostics/index.d.ts.map +1 -0
- package/dist/core/diagnostics/index.js +3 -0
- package/dist/core/diagnostics/index.js.map +1 -0
- package/dist/core/index.d.ts +28 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +22 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/lex/blocks.d.ts +51 -0
- package/dist/core/lex/blocks.d.ts.map +1 -0
- package/dist/core/lex/blocks.js +56 -0
- package/dist/core/lex/blocks.js.map +1 -0
- package/dist/core/lex/characters.d.ts +38 -0
- package/dist/core/lex/characters.d.ts.map +1 -0
- package/dist/core/lex/characters.js +50 -0
- package/dist/core/lex/characters.js.map +1 -0
- package/dist/core/lex/comments.d.ts +50 -0
- package/dist/core/lex/comments.d.ts.map +1 -0
- package/dist/core/lex/comments.js +64 -0
- package/dist/core/lex/comments.js.map +1 -0
- package/dist/core/lex/index.d.ts +12 -0
- package/dist/core/lex/index.d.ts.map +1 -0
- package/dist/core/lex/index.js +12 -0
- package/dist/core/lex/index.js.map +1 -0
- package/dist/core/lex/layout.d.ts +40 -0
- package/dist/core/lex/layout.d.ts.map +1 -0
- package/dist/core/lex/layout.js +143 -0
- package/dist/core/lex/layout.js.map +1 -0
- package/dist/core/lex/lexer.d.ts +13 -0
- package/dist/core/lex/lexer.d.ts.map +1 -0
- package/dist/core/lex/lexer.js +419 -0
- package/dist/core/lex/lexer.js.map +1 -0
- package/dist/core/lex/numbers.d.ts +22 -0
- package/dist/core/lex/numbers.d.ts.map +1 -0
- package/dist/core/lex/numbers.js +58 -0
- package/dist/core/lex/numbers.js.map +1 -0
- package/dist/core/lex/statements.d.ts +24 -0
- package/dist/core/lex/statements.d.ts.map +1 -0
- package/dist/core/lex/statements.js +90 -0
- package/dist/core/lex/statements.js.map +1 -0
- package/dist/core/lex/strings.d.ts +27 -0
- package/dist/core/lex/strings.d.ts.map +1 -0
- package/dist/core/lex/strings.js +92 -0
- package/dist/core/lex/strings.js.map +1 -0
- package/dist/core/lex/unexpected.d.ts +31 -0
- package/dist/core/lex/unexpected.d.ts.map +1 -0
- package/dist/core/lex/unexpected.js +114 -0
- package/dist/core/lex/unexpected.js.map +1 -0
- package/dist/core/parse/annotations.d.ts +4 -0
- package/dist/core/parse/annotations.d.ts.map +1 -0
- package/dist/core/parse/annotations.js +49 -0
- package/dist/core/parse/annotations.js.map +1 -0
- package/dist/core/parse/blocks.d.ts +18 -0
- package/dist/core/parse/blocks.d.ts.map +1 -0
- package/dist/core/parse/blocks.js +47 -0
- package/dist/core/parse/blocks.js.map +1 -0
- package/dist/core/parse/branches.d.ts +17 -0
- package/dist/core/parse/branches.d.ts.map +1 -0
- package/dist/core/parse/branches.js +66 -0
- package/dist/core/parse/branches.js.map +1 -0
- package/dist/core/parse/cursor.d.ts +119 -0
- package/dist/core/parse/cursor.d.ts.map +1 -0
- package/dist/core/parse/cursor.js +305 -0
- package/dist/core/parse/cursor.js.map +1 -0
- package/dist/core/parse/expressions.d.ts +57 -0
- package/dist/core/parse/expressions.d.ts.map +1 -0
- package/dist/core/parse/expressions.js +373 -0
- package/dist/core/parse/expressions.js.map +1 -0
- package/dist/core/parse/functions.d.ts +16 -0
- package/dist/core/parse/functions.d.ts.map +1 -0
- package/dist/core/parse/functions.js +92 -0
- package/dist/core/parse/functions.js.map +1 -0
- package/dist/core/parse/index.d.ts +13 -0
- package/dist/core/parse/index.d.ts.map +1 -0
- package/dist/core/parse/index.js +13 -0
- package/dist/core/parse/index.js.map +1 -0
- package/dist/core/parse/loops.d.ts +13 -0
- package/dist/core/parse/loops.d.ts.map +1 -0
- package/dist/core/parse/loops.js +78 -0
- package/dist/core/parse/loops.js.map +1 -0
- package/dist/core/parse/names.d.ts +34 -0
- package/dist/core/parse/names.d.ts.map +1 -0
- package/dist/core/parse/names.js +122 -0
- package/dist/core/parse/names.js.map +1 -0
- package/dist/core/parse/script.d.ts +23 -0
- package/dist/core/parse/script.d.ts.map +1 -0
- package/dist/core/parse/script.js +55 -0
- package/dist/core/parse/script.js.map +1 -0
- package/dist/core/parse/statements.d.ts +14 -0
- package/dist/core/parse/statements.d.ts.map +1 -0
- package/dist/core/parse/statements.js +292 -0
- package/dist/core/parse/statements.js.map +1 -0
- package/dist/core/parse/switches.d.ts +16 -0
- package/dist/core/parse/switches.d.ts.map +1 -0
- package/dist/core/parse/switches.js +98 -0
- package/dist/core/parse/switches.js.map +1 -0
- package/dist/core/render/index.d.ts +10 -0
- package/dist/core/render/index.d.ts.map +1 -0
- package/dist/core/render/index.js +10 -0
- package/dist/core/render/index.js.map +1 -0
- package/dist/core/render/terminal.d.ts +11 -0
- package/dist/core/render/terminal.d.ts.map +1 -0
- package/dist/core/render/terminal.js +51 -0
- package/dist/core/render/terminal.js.map +1 -0
- package/dist/core/source/index.d.ts +7 -0
- package/dist/core/source/index.d.ts.map +1 -0
- package/dist/core/source/index.js +2 -0
- package/dist/core/source/index.js.map +1 -0
- package/dist/core/source/source.d.ts +41 -0
- package/dist/core/source/source.d.ts.map +1 -0
- package/dist/core/source/source.js +67 -0
- package/dist/core/source/source.js.map +1 -0
- package/dist/core/span/index.d.ts +3 -0
- package/dist/core/span/index.d.ts.map +1 -0
- package/dist/core/span/index.js +2 -0
- package/dist/core/span/index.js.map +1 -0
- package/dist/core/span/span.d.ts +67 -0
- package/dist/core/span/span.d.ts.map +1 -0
- package/dist/core/span/span.js +27 -0
- package/dist/core/span/span.js.map +1 -0
- package/dist/core/tokens/index.d.ts +8 -0
- package/dist/core/tokens/index.d.ts.map +1 -0
- package/dist/core/tokens/index.js +2 -0
- package/dist/core/tokens/index.js.map +1 -0
- package/dist/core/tokens/kind.d.ts +53 -0
- package/dist/core/tokens/kind.d.ts.map +1 -0
- package/dist/core/tokens/kind.js +94 -0
- package/dist/core/tokens/kind.js.map +1 -0
- package/dist/core/tokens/token.d.ts +36 -0
- package/dist/core/tokens/token.d.ts.map +1 -0
- package/dist/core/tokens/token.js +2 -0
- package/dist/core/tokens/token.js.map +1 -0
- package/package.json +52 -0
- package/spec/README.md +48 -0
- package/spec/errors.json +3204 -0
- package/src/core/ast/annotations.ts +68 -0
- package/src/core/ast/build.ts +35 -0
- package/src/core/ast/children.ts +110 -0
- package/src/core/ast/expressions.ts +254 -0
- package/src/core/ast/header.ts +53 -0
- package/src/core/ast/index.ts +102 -0
- package/src/core/ast/name.ts +24 -0
- package/src/core/ast/node.ts +120 -0
- package/src/core/ast/script.ts +60 -0
- package/src/core/ast/statements.ts +193 -0
- package/src/core/ast/walk.ts +67 -0
- package/src/core/catalogue/catalogue.generated.ts +171 -0
- package/src/core/catalogue/index.ts +20 -0
- package/src/core/catalogue/lookup.ts +23 -0
- package/src/core/catalogue/template.ts +38 -0
- package/src/core/catalogue/types.ts +37 -0
- package/src/core/catalogue/values.generated.ts +160 -0
- package/src/core/diagnostics/collector.ts +87 -0
- package/src/core/diagnostics/diagnostic.ts +72 -0
- package/src/core/diagnostics/index.ts +12 -0
- package/src/core/index.ts +146 -0
- package/src/core/lex/blocks.ts +92 -0
- package/src/core/lex/characters.ts +56 -0
- package/src/core/lex/comments.ts +75 -0
- package/src/core/lex/index.ts +11 -0
- package/src/core/lex/layout.ts +188 -0
- package/src/core/lex/lexer.ts +486 -0
- package/src/core/lex/numbers.ts +77 -0
- package/src/core/lex/statements.ts +94 -0
- package/src/core/lex/strings.ts +119 -0
- package/src/core/lex/unexpected.ts +125 -0
- package/src/core/parse/annotations.ts +60 -0
- package/src/core/parse/blocks.ts +52 -0
- package/src/core/parse/branches.ts +77 -0
- package/src/core/parse/cursor.ts +348 -0
- package/src/core/parse/expressions.ts +441 -0
- package/src/core/parse/functions.ts +109 -0
- package/src/core/parse/index.ts +12 -0
- package/src/core/parse/loops.ts +97 -0
- package/src/core/parse/names.ts +135 -0
- package/src/core/parse/script.ts +64 -0
- package/src/core/parse/statements.ts +329 -0
- package/src/core/parse/switches.ts +105 -0
- package/src/core/render/index.ts +9 -0
- package/src/core/render/terminal.ts +62 -0
- package/src/core/source/index.ts +6 -0
- package/src/core/source/source.ts +102 -0
- package/src/core/span/index.ts +2 -0
- package/src/core/span/span.ts +84 -0
- package/src/core/tokens/index.ts +15 -0
- package/src/core/tokens/kind.ts +123 -0
- package/src/core/tokens/token.ts +39 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A number literal, in every form of language.md 3.5: decimal with or without a
|
|
3
|
+
* fractional part, a fractional part with no leading digit, an exponent, digit
|
|
4
|
+
* group underscores and the hexadecimal form. There is no octal form, so `010`
|
|
5
|
+
* is ten, which falls out of reading the digits rather than being a special
|
|
6
|
+
* case.
|
|
7
|
+
*/
|
|
8
|
+
export interface NumberLiteral {
|
|
9
|
+
/** One past the last character of the literal. */
|
|
10
|
+
readonly end: number;
|
|
11
|
+
readonly value: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Reads the literal starting at `start`, which the caller has established
|
|
15
|
+
* begins a number: a digit, or a dot with a digit after it.
|
|
16
|
+
*
|
|
17
|
+
* The value is computed here and carried on the token so that no later stage
|
|
18
|
+
* re-reads the text and has to agree a second time about underscores and about
|
|
19
|
+
* the hexadecimal form.
|
|
20
|
+
*/
|
|
21
|
+
export declare function scanNumber(text: string, start: number): NumberLiteral;
|
|
22
|
+
//# sourceMappingURL=numbers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"numbers.d.ts","sourceRoot":"","sources":["../../../src/core/lex/numbers.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC5B,kDAAkD;IAClD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAwBD;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,aAAa,CA+BrE"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { DOT, isDigit, isHexDigit, UNDERSCORE } from './characters.js';
|
|
2
|
+
/**
|
|
3
|
+
* An underscore separates digit groups, so it only belongs to the literal when
|
|
4
|
+
* a digit follows it. `1_` and `1__0` therefore end the literal at the first
|
|
5
|
+
* underscore, and the caller reports what follows as a name that starts with a
|
|
6
|
+
* digit, which is what they are.
|
|
7
|
+
*/
|
|
8
|
+
function runOfDigits(text, from, digit) {
|
|
9
|
+
let i = from;
|
|
10
|
+
for (;;) {
|
|
11
|
+
const code = text.charCodeAt(i);
|
|
12
|
+
if (digit(code)) {
|
|
13
|
+
i++;
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
if (code === UNDERSCORE && digit(text.charCodeAt(i + 1))) {
|
|
17
|
+
i += 2;
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
return i;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Reads the literal starting at `start`, which the caller has established
|
|
25
|
+
* begins a number: a digit, or a dot with a digit after it.
|
|
26
|
+
*
|
|
27
|
+
* The value is computed here and carried on the token so that no later stage
|
|
28
|
+
* re-reads the text and has to agree a second time about underscores and about
|
|
29
|
+
* the hexadecimal form.
|
|
30
|
+
*/
|
|
31
|
+
export function scanNumber(text, start) {
|
|
32
|
+
const second = text.charCodeAt(start + 1);
|
|
33
|
+
const isHex = text.charCodeAt(start) === 0x30 &&
|
|
34
|
+
(second === 0x78 || second === 0x58) &&
|
|
35
|
+
isHexDigit(text.charCodeAt(start + 2));
|
|
36
|
+
if (isHex) {
|
|
37
|
+
const end = runOfDigits(text, start + 2, isHexDigit);
|
|
38
|
+
return { end, value: Number(text.slice(start, end).replace(/_/g, '')) };
|
|
39
|
+
}
|
|
40
|
+
let i = runOfDigits(text, start, isDigit);
|
|
41
|
+
// A dot only belongs to the literal when a digit follows it, so `x.y` reads as
|
|
42
|
+
// an element access and `1.` reads as a number and a dot.
|
|
43
|
+
if (text.charCodeAt(i) === DOT && isDigit(text.charCodeAt(i + 1))) {
|
|
44
|
+
i = runOfDigits(text, i + 1, isDigit);
|
|
45
|
+
}
|
|
46
|
+
const exponent = text.charCodeAt(i);
|
|
47
|
+
if (exponent === 0x65 || exponent === 0x45) {
|
|
48
|
+
const sign = text.charCodeAt(i + 1);
|
|
49
|
+
const digits = sign === 0x2b || sign === 0x2d ? i + 2 : i + 1;
|
|
50
|
+
// Without a digit the `e` is not an exponent, and the caller reports the
|
|
51
|
+
// letter sitting against a number rather than this reading a literal that
|
|
52
|
+
// is not there.
|
|
53
|
+
if (isDigit(text.charCodeAt(digits)))
|
|
54
|
+
i = runOfDigits(text, digits, isDigit);
|
|
55
|
+
}
|
|
56
|
+
return { end: i, value: Number(text.slice(start, i).replace(/_/g, '')) };
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=numbers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"numbers.js","sourceRoot":"","sources":["../../../src/core/lex/numbers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAevE;;;;;GAKG;AACH,SAAS,WAAW,CAAC,IAAY,EAAE,IAAY,EAAE,KAAgC;IAC/E,IAAI,CAAC,GAAG,IAAI,CAAC;IACb,SAAS,CAAC;QACR,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAChC,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAChB,CAAC,EAAE,CAAC;YACJ,SAAS;QACX,CAAC;QACD,IAAI,IAAI,KAAK,UAAU,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACzD,CAAC,IAAI,CAAC,CAAC;YACP,SAAS;QACX,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,KAAa;IACpD,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IAC1C,MAAM,KAAK,GACT,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,IAAI;QAC/B,CAAC,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,IAAI,CAAC;QACpC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;IAEzC,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,EAAE,UAAU,CAAC,CAAC;QACrD,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC;IAC1E,CAAC;IAED,IAAI,CAAC,GAAG,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IAE1C,+EAA+E;IAC/E,0DAA0D;IAC1D,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAClE,CAAC,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;IACxC,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IACpC,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACpC,MAAM,MAAM,GAAG,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAC9D,yEAAyE;QACzE,0EAA0E;QAC1E,gBAAgB;QAChB,IAAI,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;YAAE,CAAC,GAAG,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/E,CAAC;IAED,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC;AAC3E,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Token, TokenKind } from '../tokens/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Whether the last two tokens are the `=>` of a function declaration.
|
|
4
|
+
*
|
|
5
|
+
* Section 3.12 does not list `=>` among the punctuation, so it arrives as an
|
|
6
|
+
* `=` and a `>` that touch. Both readings need saying apart here: a line whose
|
|
7
|
+
* last token is `>` continues onto the next line, and a line that ends in `=>`
|
|
8
|
+
* is a function header whose body is the indented block below it, so it must
|
|
9
|
+
* not.
|
|
10
|
+
*/
|
|
11
|
+
export declare function endsWithArrow(tokens: readonly Token[]): boolean;
|
|
12
|
+
/** Whether the statement so far promises more, so the next line belongs to it. */
|
|
13
|
+
export declare function continuesLine(tokens: readonly Token[]): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Whether a statement that begins with this token and ends this way opens a
|
|
16
|
+
* block.
|
|
17
|
+
*
|
|
18
|
+
* `fn` is the one header with a form that fits on one line: with its body after
|
|
19
|
+
* the `=>` it opens nothing, and with nothing after the `=>` the block below it
|
|
20
|
+
* is the body (3.10, 11.1). Every other header opens a block always, because
|
|
21
|
+
* there is no statement separator to end a one-line body with.
|
|
22
|
+
*/
|
|
23
|
+
export declare function opensBlock(firstKind: TokenKind, arrowAtEnd: boolean): boolean;
|
|
24
|
+
//# sourceMappingURL=statements.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"statements.d.ts","sourceRoot":"","sources":["../../../src/core/lex/statements.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAqD3D;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,GAAG,OAAO,CAS/D;AAED,kFAAkF;AAClF,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,GAAG,OAAO,CAK/D;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,GAAG,OAAO,CAG7E"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a statement ends, and whether it opens a block. Both questions are
|
|
3
|
+
* asked of the tokens of a line, which is the whole of what language.md 3.10
|
|
4
|
+
* and 3.11 need to know about a statement before it is parsed.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* The tokens that promise a right-hand side, from 3.11: a binary operator, a
|
|
8
|
+
* comma, a `?`, a `:` or an `=`. A line ending in one of them continues onto
|
|
9
|
+
* the next line.
|
|
10
|
+
*
|
|
11
|
+
* The compound assignments are here on the same terms as `=`: each one promises
|
|
12
|
+
* a value just as plainly. `.` is deliberately absent, because 3.11 does not
|
|
13
|
+
* list it and a line that ends in a dot is a mistake rather than a wrap.
|
|
14
|
+
*/
|
|
15
|
+
const CONTINUING = new Set([
|
|
16
|
+
'+',
|
|
17
|
+
'-',
|
|
18
|
+
'*',
|
|
19
|
+
'/',
|
|
20
|
+
'%',
|
|
21
|
+
'==',
|
|
22
|
+
'!=',
|
|
23
|
+
'<',
|
|
24
|
+
'<=',
|
|
25
|
+
'>',
|
|
26
|
+
'>=',
|
|
27
|
+
'=',
|
|
28
|
+
'+=',
|
|
29
|
+
'-=',
|
|
30
|
+
'*=',
|
|
31
|
+
'/=',
|
|
32
|
+
'%=',
|
|
33
|
+
',',
|
|
34
|
+
'?',
|
|
35
|
+
':',
|
|
36
|
+
'and',
|
|
37
|
+
'or',
|
|
38
|
+
]);
|
|
39
|
+
/** The words that introduce a block, per 3.10 and the grammar of section 19. */
|
|
40
|
+
const HEADERS = new Set([
|
|
41
|
+
'if',
|
|
42
|
+
'else',
|
|
43
|
+
'for',
|
|
44
|
+
'while',
|
|
45
|
+
'switch',
|
|
46
|
+
'case',
|
|
47
|
+
'default',
|
|
48
|
+
]);
|
|
49
|
+
/**
|
|
50
|
+
* Whether the last two tokens are the `=>` of a function declaration.
|
|
51
|
+
*
|
|
52
|
+
* Section 3.12 does not list `=>` among the punctuation, so it arrives as an
|
|
53
|
+
* `=` and a `>` that touch. Both readings need saying apart here: a line whose
|
|
54
|
+
* last token is `>` continues onto the next line, and a line that ends in `=>`
|
|
55
|
+
* is a function header whose body is the indented block below it, so it must
|
|
56
|
+
* not.
|
|
57
|
+
*/
|
|
58
|
+
export function endsWithArrow(tokens) {
|
|
59
|
+
const last = tokens[tokens.length - 1];
|
|
60
|
+
const before = tokens[tokens.length - 2];
|
|
61
|
+
if (last === undefined || before === undefined)
|
|
62
|
+
return false;
|
|
63
|
+
return (last.kind === '>' &&
|
|
64
|
+
before.kind === '=' &&
|
|
65
|
+
before.span.offset + before.span.length === last.span.offset);
|
|
66
|
+
}
|
|
67
|
+
/** Whether the statement so far promises more, so the next line belongs to it. */
|
|
68
|
+
export function continuesLine(tokens) {
|
|
69
|
+
const last = tokens[tokens.length - 1];
|
|
70
|
+
if (last === undefined)
|
|
71
|
+
return false;
|
|
72
|
+
if (endsWithArrow(tokens))
|
|
73
|
+
return false;
|
|
74
|
+
return CONTINUING.has(last.kind);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Whether a statement that begins with this token and ends this way opens a
|
|
78
|
+
* block.
|
|
79
|
+
*
|
|
80
|
+
* `fn` is the one header with a form that fits on one line: with its body after
|
|
81
|
+
* the `=>` it opens nothing, and with nothing after the `=>` the block below it
|
|
82
|
+
* is the body (3.10, 11.1). Every other header opens a block always, because
|
|
83
|
+
* there is no statement separator to end a one-line body with.
|
|
84
|
+
*/
|
|
85
|
+
export function opensBlock(firstKind, arrowAtEnd) {
|
|
86
|
+
if (firstKind === 'fn')
|
|
87
|
+
return arrowAtEnd;
|
|
88
|
+
return HEADERS.has(firstKind);
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=statements.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"statements.js","sourceRoot":"","sources":["../../../src/core/lex/statements.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AAEH;;;;;;;;GAQG;AACH,MAAM,UAAU,GAA2B,IAAI,GAAG,CAAY;IAC5D,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IACH,IAAI;IACJ,IAAI;IACJ,GAAG;IACH,IAAI;IACJ,GAAG;IACH,IAAI;IACJ,GAAG;IACH,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,GAAG;IACH,GAAG;IACH,GAAG;IACH,KAAK;IACL,IAAI;CACL,CAAC,CAAC;AAEH,gFAAgF;AAChF,MAAM,OAAO,GAA2B,IAAI,GAAG,CAAY;IACzD,IAAI;IACJ,MAAM;IACN,KAAK;IACL,OAAO;IACP,QAAQ;IACR,MAAM;IACN,SAAS;CACV,CAAC,CAAC;AAEH;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAAC,MAAwB;IACpD,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACzC,IAAI,IAAI,KAAK,SAAS,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC7D,OAAO,CACL,IAAI,CAAC,IAAI,KAAK,GAAG;QACjB,MAAM,CAAC,IAAI,KAAK,GAAG;QACnB,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM,CAC7D,CAAC;AACJ,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,aAAa,CAAC,MAAwB;IACpD,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACvC,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACrC,IAAI,aAAa,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IACxC,OAAO,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACnC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU,CAAC,SAAoB,EAAE,UAAmB;IAClE,IAAI,SAAS,KAAK,IAAI;QAAE,OAAO,UAAU,CAAC;IAC1C,OAAO,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AAChC,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** A backslash sequence the language does not define, for OS1005. */
|
|
2
|
+
export interface BadEscape {
|
|
3
|
+
readonly offset: number;
|
|
4
|
+
readonly length: number;
|
|
5
|
+
/** The backslash and what followed it, which is the {sequence} of OS1005. */
|
|
6
|
+
readonly text: string;
|
|
7
|
+
}
|
|
8
|
+
export interface StringLiteral {
|
|
9
|
+
/** One past the closing quote, or the end of the line when there was none. */
|
|
10
|
+
readonly end: number;
|
|
11
|
+
/** The text the literal denotes, with its escapes already resolved. */
|
|
12
|
+
readonly value: string;
|
|
13
|
+
readonly unterminated: boolean;
|
|
14
|
+
readonly badEscapes: readonly BadEscape[];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Reads the literal opening at `start`, which is the quote character, in either
|
|
18
|
+
* delimiter of language.md 3.6.
|
|
19
|
+
*
|
|
20
|
+
* A literal may not span a line, so the scan stops at the newline and says so
|
|
21
|
+
* rather than swallowing the rest of the file. The caller reports OS1004 at the
|
|
22
|
+
* opening quote, which is where the mistake is, and keeps the text that was
|
|
23
|
+
* read so that the statement around it still parses and the reader is not shown
|
|
24
|
+
* a second error for the same missing character.
|
|
25
|
+
*/
|
|
26
|
+
export declare function scanString(text: string, start: number): StringLiteral;
|
|
27
|
+
//# sourceMappingURL=strings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strings.d.ts","sourceRoot":"","sources":["../../../src/core/lex/strings.ts"],"names":[],"mappings":"AAEA,qEAAqE;AACrE,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,6EAA6E;IAC7E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,8EAA8E;IAC9E,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,UAAU,EAAE,SAAS,SAAS,EAAE,CAAC;CAC3C;AAsBD;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,aAAa,CAqErE"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { BACKSLASH, isHexDigit, LINE_FEED } from './characters.js';
|
|
2
|
+
/** The escapes of language.md 3.6, apart from \uXXXX which carries its own digits. */
|
|
3
|
+
const SIMPLE = new Map([
|
|
4
|
+
[0x5c, '\\'],
|
|
5
|
+
[0x22, '"'],
|
|
6
|
+
[0x27, "'"],
|
|
7
|
+
[0x6e, '\n'],
|
|
8
|
+
[0x74, '\t'],
|
|
9
|
+
[0x72, '\r'],
|
|
10
|
+
[0x30, '\u0000'],
|
|
11
|
+
]);
|
|
12
|
+
const UNICODE_ESCAPE = 0x75;
|
|
13
|
+
/** How many hexadecimal digits follow, up to the four a \uXXXX escape needs. */
|
|
14
|
+
function hexDigitsAfter(text, from) {
|
|
15
|
+
let count = 0;
|
|
16
|
+
while (count < 4 && isHexDigit(text.charCodeAt(from + count)))
|
|
17
|
+
count++;
|
|
18
|
+
return count;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Reads the literal opening at `start`, which is the quote character, in either
|
|
22
|
+
* delimiter of language.md 3.6.
|
|
23
|
+
*
|
|
24
|
+
* A literal may not span a line, so the scan stops at the newline and says so
|
|
25
|
+
* rather than swallowing the rest of the file. The caller reports OS1004 at the
|
|
26
|
+
* opening quote, which is where the mistake is, and keeps the text that was
|
|
27
|
+
* read so that the statement around it still parses and the reader is not shown
|
|
28
|
+
* a second error for the same missing character.
|
|
29
|
+
*/
|
|
30
|
+
export function scanString(text, start) {
|
|
31
|
+
const quote = text.charCodeAt(start);
|
|
32
|
+
const badEscapes = [];
|
|
33
|
+
let value = '';
|
|
34
|
+
let plainFrom = start + 1;
|
|
35
|
+
let i = start + 1;
|
|
36
|
+
const takePlain = (upTo) => {
|
|
37
|
+
if (upTo > plainFrom)
|
|
38
|
+
value += text.slice(plainFrom, upTo);
|
|
39
|
+
};
|
|
40
|
+
while (i < text.length) {
|
|
41
|
+
const code = text.charCodeAt(i);
|
|
42
|
+
if (code === LINE_FEED)
|
|
43
|
+
break;
|
|
44
|
+
if (code === quote) {
|
|
45
|
+
takePlain(i);
|
|
46
|
+
return { end: i + 1, value, unterminated: false, badEscapes };
|
|
47
|
+
}
|
|
48
|
+
if (code !== BACKSLASH) {
|
|
49
|
+
i++;
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
const next = text.charCodeAt(i + 1);
|
|
53
|
+
// A backslash at the end of the line escapes nothing, because the line is
|
|
54
|
+
// where the literal has to end. That is one missing quote, not two errors.
|
|
55
|
+
if (Number.isNaN(next) || next === LINE_FEED)
|
|
56
|
+
break;
|
|
57
|
+
takePlain(i);
|
|
58
|
+
const simple = SIMPLE.get(next);
|
|
59
|
+
if (simple !== undefined) {
|
|
60
|
+
value += simple;
|
|
61
|
+
i += 2;
|
|
62
|
+
plainFrom = i;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (next === UNICODE_ESCAPE) {
|
|
66
|
+
const digits = hexDigitsAfter(text, i + 2);
|
|
67
|
+
if (digits === 4) {
|
|
68
|
+
value += String.fromCharCode(Number.parseInt(text.slice(i + 2, i + 6), 16));
|
|
69
|
+
i += 6;
|
|
70
|
+
plainFrom = i;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
const length = 2 + digits;
|
|
74
|
+
badEscapes.push({ offset: i, length, text: text.slice(i, i + length) });
|
|
75
|
+
value += text.slice(i + 1, i + length);
|
|
76
|
+
i += length;
|
|
77
|
+
plainFrom = i;
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
// The written character, whole: an astral character is two code units, and
|
|
81
|
+
// reporting half of one puts a broken surrogate in the message.
|
|
82
|
+
const written = String.fromCodePoint(text.codePointAt(i + 1) ?? next);
|
|
83
|
+
const length = 1 + written.length;
|
|
84
|
+
badEscapes.push({ offset: i, length, text: text.slice(i, i + length) });
|
|
85
|
+
value += written;
|
|
86
|
+
i += length;
|
|
87
|
+
plainFrom = i;
|
|
88
|
+
}
|
|
89
|
+
takePlain(i);
|
|
90
|
+
return { end: i, value, unterminated: true, badEscapes };
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=strings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strings.js","sourceRoot":"","sources":["../../../src/core/lex/strings.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OS1001: naming the character that was found, and the plain spelling to write
|
|
3
|
+
* instead.
|
|
4
|
+
*
|
|
5
|
+
* The replacement sentences are the substitution table of errors.md section 7,
|
|
6
|
+
* which is the one part of an OS1001 message that errors.json does not carry:
|
|
7
|
+
* the catalogue holds the message and the fix, and section 7 holds the third
|
|
8
|
+
* column that fills {suggestion}. The table is transcribed here rather than
|
|
9
|
+
* paraphrased, and the moment it moves into errors.json this file is generated
|
|
10
|
+
* away instead of being edited.
|
|
11
|
+
*
|
|
12
|
+
* A character the table does not name takes the generic sentence, which is what
|
|
13
|
+
* section 7 says to do with one.
|
|
14
|
+
*/
|
|
15
|
+
export interface Unexpected {
|
|
16
|
+
/** The {char} slot: what was found, quoted, and named when it cannot be seen. */
|
|
17
|
+
readonly char: string;
|
|
18
|
+
/** The {suggestion} slot: one sentence naming the plain spelling to use. */
|
|
19
|
+
readonly suggestion: string;
|
|
20
|
+
}
|
|
21
|
+
/** What OS1001 says about one rejected character, or one rejected operator. */
|
|
22
|
+
export declare function describeUnexpected(written: string): Unexpected;
|
|
23
|
+
/**
|
|
24
|
+
* Whether a code point is a letter the language does not allow in a name.
|
|
25
|
+
*
|
|
26
|
+
* It is asked once per word, at the character that ended the word, so that
|
|
27
|
+
* `l\u00e4ngd` is one name with one error on the one character 3.3 refuses,
|
|
28
|
+
* rather than two names with a stray character between them.
|
|
29
|
+
*/
|
|
30
|
+
export declare function isNonAsciiLetter(point: number): boolean;
|
|
31
|
+
//# sourceMappingURL=unexpected.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unexpected.d.ts","sourceRoot":"","sources":["../../../src/core/lex/unexpected.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,WAAW,UAAU;IACzB,iFAAiF;IACjF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,4EAA4E;IAC5E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AA0FD,+EAA+E;AAC/E,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,CAE9D;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEvD"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OS1001: naming the character that was found, and the plain spelling to write
|
|
3
|
+
* instead.
|
|
4
|
+
*
|
|
5
|
+
* The replacement sentences are the substitution table of errors.md section 7,
|
|
6
|
+
* which is the one part of an OS1001 message that errors.json does not carry:
|
|
7
|
+
* the catalogue holds the message and the fix, and section 7 holds the third
|
|
8
|
+
* column that fills {suggestion}. The table is transcribed here rather than
|
|
9
|
+
* paraphrased, and the moment it moves into errors.json this file is generated
|
|
10
|
+
* away instead of being edited.
|
|
11
|
+
*
|
|
12
|
+
* A character the table does not name takes the generic sentence, which is what
|
|
13
|
+
* section 7 says to do with one.
|
|
14
|
+
*/
|
|
15
|
+
const PLAIN_SPACE = 'Use a plain space instead.';
|
|
16
|
+
const STRAIGHT_QUOTE = 'Use a straight quote instead.';
|
|
17
|
+
const ASCII_NAME = 'Use the ASCII spelling of the name instead.';
|
|
18
|
+
const INDENTATION = 'Use indentation instead, which is how a block is written.';
|
|
19
|
+
const PUT_IN_A_STRING = 'Delete it, or put the text in a string.';
|
|
20
|
+
const GENERIC = 'Delete it, or move it inside a string literal.';
|
|
21
|
+
/** The rows of section 7 that name an exact spelling. */
|
|
22
|
+
const SPELLINGS = new Map([
|
|
23
|
+
['!', 'Write not instead.'],
|
|
24
|
+
['&&', 'Write and instead.'],
|
|
25
|
+
['||', 'Write or instead.'],
|
|
26
|
+
['^', 'Write pow(a, b) instead.'],
|
|
27
|
+
['**', 'Write pow(a, b) instead.'],
|
|
28
|
+
['++', 'Write a += 1 instead.'],
|
|
29
|
+
['{', INDENTATION],
|
|
30
|
+
['}', INDENTATION],
|
|
31
|
+
['#', PUT_IN_A_STRING],
|
|
32
|
+
['$', PUT_IN_A_STRING],
|
|
33
|
+
['@', PUT_IN_A_STRING],
|
|
34
|
+
]);
|
|
35
|
+
/**
|
|
36
|
+
* Names for the characters a reader cannot see on their screen.
|
|
37
|
+
*
|
|
38
|
+
* A message that quotes an invisible character quotes nothing, and the whole
|
|
39
|
+
* point of OS1001 is that an invisible character produces a baffling error
|
|
40
|
+
* three tokens later. The name and the code point are what makes the message
|
|
41
|
+
* act on: a reader can search their file for the one and read the other aloud.
|
|
42
|
+
*/
|
|
43
|
+
const NAMES = new Map([
|
|
44
|
+
[0x0009, 'a tab'],
|
|
45
|
+
[0x000d, 'a carriage return'],
|
|
46
|
+
[0x00a0, 'a no-break space'],
|
|
47
|
+
[0x2002, 'an en space'],
|
|
48
|
+
[0x2003, 'an em space'],
|
|
49
|
+
[0x2007, 'a figure space'],
|
|
50
|
+
[0x2009, 'a thin space'],
|
|
51
|
+
[0x200a, 'a hair space'],
|
|
52
|
+
[0x202f, 'a narrow no-break space'],
|
|
53
|
+
[0x3000, 'an ideographic space'],
|
|
54
|
+
[0x200b, 'a zero width space'],
|
|
55
|
+
[0x200c, 'a zero width non-joiner'],
|
|
56
|
+
[0x200d, 'a zero width joiner'],
|
|
57
|
+
[0xfeff, 'a byte order mark'],
|
|
58
|
+
[0x2018, 'a left single quotation mark'],
|
|
59
|
+
[0x2019, 'a right single quotation mark'],
|
|
60
|
+
[0x201c, 'a left double quotation mark'],
|
|
61
|
+
[0x201d, 'a right double quotation mark'],
|
|
62
|
+
[0x2013, 'an en dash'],
|
|
63
|
+
[0x2014, 'an em dash'],
|
|
64
|
+
[0x2026, 'a horizontal ellipsis'],
|
|
65
|
+
]);
|
|
66
|
+
const TYPOGRAPHIC_QUOTES = '\u2018\u2019\u201c\u201d\u201a\u201b\u201e\u201f';
|
|
67
|
+
const SPACE_SEPARATOR = /\p{Zs}/u;
|
|
68
|
+
const LETTER = /\p{L}/u;
|
|
69
|
+
const ASCII_GRAPHIC = /^[\x21-\x7e]+$/;
|
|
70
|
+
function codePointLabel(text) {
|
|
71
|
+
const point = text.codePointAt(0) ?? 0;
|
|
72
|
+
return `U+${point.toString(16).toUpperCase().padStart(4, '0')}`;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* The {char} slot. An ASCII graphic speaks for itself; everything else is
|
|
76
|
+
* quoted and then identified, because the quotes may well hold nothing a reader
|
|
77
|
+
* can see.
|
|
78
|
+
*/
|
|
79
|
+
function describe(written) {
|
|
80
|
+
if (ASCII_GRAPHIC.test(written))
|
|
81
|
+
return `"${written}"`;
|
|
82
|
+
const name = NAMES.get(written.codePointAt(0) ?? -1);
|
|
83
|
+
const label = codePointLabel(written);
|
|
84
|
+
return name === undefined ? `"${written}" (${label})` : `"${written}" (${name}, ${label})`;
|
|
85
|
+
}
|
|
86
|
+
function suggestionFor(written) {
|
|
87
|
+
const spelling = SPELLINGS.get(written);
|
|
88
|
+
if (spelling !== undefined)
|
|
89
|
+
return spelling;
|
|
90
|
+
// A tab is a space that happens to be a control character, and the table's
|
|
91
|
+
// answer to every other invisible space is the same plain space.
|
|
92
|
+
if (written === '\t' || SPACE_SEPARATOR.test(written))
|
|
93
|
+
return PLAIN_SPACE;
|
|
94
|
+
if (TYPOGRAPHIC_QUOTES.includes(written))
|
|
95
|
+
return STRAIGHT_QUOTE;
|
|
96
|
+
if (LETTER.test(written))
|
|
97
|
+
return ASCII_NAME;
|
|
98
|
+
return GENERIC;
|
|
99
|
+
}
|
|
100
|
+
/** What OS1001 says about one rejected character, or one rejected operator. */
|
|
101
|
+
export function describeUnexpected(written) {
|
|
102
|
+
return { char: describe(written), suggestion: suggestionFor(written) };
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Whether a code point is a letter the language does not allow in a name.
|
|
106
|
+
*
|
|
107
|
+
* It is asked once per word, at the character that ended the word, so that
|
|
108
|
+
* `l\u00e4ngd` is one name with one error on the one character 3.3 refuses,
|
|
109
|
+
* rather than two names with a stray character between them.
|
|
110
|
+
*/
|
|
111
|
+
export function isNonAsciiLetter(point) {
|
|
112
|
+
return point > 0x7f && LETTER.test(String.fromCodePoint(point));
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=unexpected.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unexpected.js","sourceRoot":"","sources":["../../../src/core/lex/unexpected.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"annotations.d.ts","sourceRoot":"","sources":["../../../src/core/parse/annotations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAKtD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AA6B1C,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAyBlE"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { makeNode } from '../ast/index.js';
|
|
2
|
+
import { spanning } from '../span/index.js';
|
|
3
|
+
import { RESERVED_WORDS } from '../tokens/index.js';
|
|
4
|
+
/**
|
|
5
|
+
* A type as a script writes it, on a parameter or a `var`.
|
|
6
|
+
*
|
|
7
|
+
* The grammar of section 19 admits only the real type names. The prose wins
|
|
8
|
+
* here, because OS2016 and OS2019 are check stage: this reads any word into a
|
|
9
|
+
* `namedType` and lets the checker be the one to say that `whole` is not a
|
|
10
|
+
* type, which is the difference between a caret with no sentence and a sentence
|
|
11
|
+
* naming the types that do exist.
|
|
12
|
+
*/
|
|
13
|
+
const RESERVED = new Set(RESERVED_WORDS);
|
|
14
|
+
/**
|
|
15
|
+
* What may stand as a type name.
|
|
16
|
+
*
|
|
17
|
+
* A literal is taken as well as a word, so `len: 5` reaches OS2016 with `5` in
|
|
18
|
+
* its message instead of failing here with a caret and nothing to act on.
|
|
19
|
+
*/
|
|
20
|
+
function isTypeWord(kind) {
|
|
21
|
+
return (kind === 'identifier' ||
|
|
22
|
+
kind === 'numberLiteral' ||
|
|
23
|
+
kind === 'stringLiteral' ||
|
|
24
|
+
RESERVED.has(kind));
|
|
25
|
+
}
|
|
26
|
+
export function parseTypeAnnotation(cursor) {
|
|
27
|
+
const token = cursor.token;
|
|
28
|
+
if (token.kind === 'series') {
|
|
29
|
+
cursor.advance();
|
|
30
|
+
const element = parseTypeAnnotation(cursor);
|
|
31
|
+
return makeNode('seriesType', spanning(token.span, element.span), { element });
|
|
32
|
+
}
|
|
33
|
+
if (token.kind === 'array' && cursor.peek().kind === '<') {
|
|
34
|
+
cursor.advance();
|
|
35
|
+
cursor.advance();
|
|
36
|
+
const element = parseTypeAnnotation(cursor);
|
|
37
|
+
const close = cursor.take('>');
|
|
38
|
+
if (close === undefined)
|
|
39
|
+
cursor.unexpected(cursor.token);
|
|
40
|
+
return makeNode('arrayType', spanning(token.span, close?.span ?? element.span), { element });
|
|
41
|
+
}
|
|
42
|
+
if (isTypeWord(token.kind)) {
|
|
43
|
+
cursor.advance();
|
|
44
|
+
return makeNode('namedType', token.span, { name: token.text });
|
|
45
|
+
}
|
|
46
|
+
cursor.unexpected(token);
|
|
47
|
+
return makeNode('namedType', cursor.holeSpan(), { name: '' });
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=annotations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"annotations.js","sourceRoot":"","sources":["../../../src/core/parse/annotations.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGpD;;;;;;;;GAQG;AAEH,MAAM,QAAQ,GAA2B,IAAI,GAAG,CAAY,cAAc,CAAC,CAAC;AAE5E;;;;;GAKG;AACH,SAAS,UAAU,CAAC,IAAe;IACjC,OAAO,CACL,IAAI,KAAK,YAAY;QACrB,IAAI,KAAK,eAAe;QACxB,IAAI,KAAK,eAAe;QACxB,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CACnB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAc;IAChD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;IAE3B,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC5B,MAAM,CAAC,OAAO,EAAE,CAAC;QACjB,MAAM,OAAO,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;QAC5C,OAAO,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;IACjF,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,IAAI,KAAK,GAAG,EAAE,CAAC;QACzD,MAAM,CAAC,OAAO,EAAE,CAAC;QACjB,MAAM,CAAC,OAAO,EAAE,CAAC;QACjB,MAAM,OAAO,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,KAAK,KAAK,SAAS;YAAE,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACzD,OAAO,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;IAC/F,CAAC;IAED,IAAI,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,MAAM,CAAC,OAAO,EAAE,CAAC;QACjB,OAAO,QAAQ,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IACjE,CAAC;IAED,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IACzB,OAAO,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;AAChE,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Block } from '../ast/index.js';
|
|
2
|
+
import type { Span } from '../span/index.js';
|
|
3
|
+
import type { Cursor } from './cursor.js';
|
|
4
|
+
/**
|
|
5
|
+
* The indented lines under a header, language.md 3.10.
|
|
6
|
+
*
|
|
7
|
+
* The lexer has already decided where a block begins and ends, so this reads an
|
|
8
|
+
* `indent`, statements, and a `dedent`, and the one rule it owns is what to do
|
|
9
|
+
* when the `indent` is not there: OS1010, reported against the header rather
|
|
10
|
+
* than against the line that failed to be a body, because the header is what
|
|
11
|
+
* the reader has to change.
|
|
12
|
+
*
|
|
13
|
+
* The statement loop insists on progress. A rule that reports without consuming
|
|
14
|
+
* anything would otherwise spin on the token it could not read, and a compiler
|
|
15
|
+
* that hangs on a malformed file is worse than one that gives up on it.
|
|
16
|
+
*/
|
|
17
|
+
export declare function parseBlock(cursor: Cursor, header: string, at: Span): Block;
|
|
18
|
+
//# sourceMappingURL=blocks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blocks.d.ts","sourceRoot":"","sources":["../../../src/core/parse/blocks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAkC,MAAM,iBAAiB,CAAC;AAE7E,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAE7C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAG1C;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,GAAG,KAAK,CA+B1E"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { makeNode } from '../ast/index.js';
|
|
2
|
+
import { spanning } from '../span/index.js';
|
|
3
|
+
import { parseStatement } from './statements.js';
|
|
4
|
+
/**
|
|
5
|
+
* The indented lines under a header, language.md 3.10.
|
|
6
|
+
*
|
|
7
|
+
* The lexer has already decided where a block begins and ends, so this reads an
|
|
8
|
+
* `indent`, statements, and a `dedent`, and the one rule it owns is what to do
|
|
9
|
+
* when the `indent` is not there: OS1010, reported against the header rather
|
|
10
|
+
* than against the line that failed to be a body, because the header is what
|
|
11
|
+
* the reader has to change.
|
|
12
|
+
*
|
|
13
|
+
* The statement loop insists on progress. A rule that reports without consuming
|
|
14
|
+
* anything would otherwise spin on the token it could not read, and a compiler
|
|
15
|
+
* that hangs on a malformed file is worse than one that gives up on it.
|
|
16
|
+
*/
|
|
17
|
+
export function parseBlock(cursor, header, at) {
|
|
18
|
+
if (!cursor.at('indent')) {
|
|
19
|
+
// A header that was already reported on has nothing to add by saying its
|
|
20
|
+
// body is missing too: the body is missing because of what it was told.
|
|
21
|
+
if (!cursor.reportedHere)
|
|
22
|
+
cursor.report('OS1010', at, { header });
|
|
23
|
+
const hole = cursor.holeSpan();
|
|
24
|
+
return makeNode('block', hole, { statements: [] });
|
|
25
|
+
}
|
|
26
|
+
if (!cursor.openBlock(cursor.token.span)) {
|
|
27
|
+
const span = cursor.token.span;
|
|
28
|
+
cursor.skipBlockBody();
|
|
29
|
+
return makeNode('block', span, { statements: [] });
|
|
30
|
+
}
|
|
31
|
+
const indent = cursor.advance();
|
|
32
|
+
const statements = [];
|
|
33
|
+
while (!cursor.at('dedent') && !cursor.at('endOfFile')) {
|
|
34
|
+
const before = cursor.position;
|
|
35
|
+
const statement = parseStatement(cursor);
|
|
36
|
+
if (statement !== undefined)
|
|
37
|
+
statements.push(statement);
|
|
38
|
+
if (cursor.position === before)
|
|
39
|
+
cursor.skipStatement();
|
|
40
|
+
}
|
|
41
|
+
cursor.closeBlock();
|
|
42
|
+
cursor.take('dedent');
|
|
43
|
+
const last = statements[statements.length - 1];
|
|
44
|
+
const span = last === undefined ? indent.span : spanning(indent.span, last.span);
|
|
45
|
+
return makeNode('block', span, { statements });
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=blocks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blocks.js","sourceRoot":"","sources":["../../../src/core/parse/blocks.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE3C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,UAAU,CAAC,MAAc,EAAE,MAAc,EAAE,EAAQ;IACjE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzB,yEAAyE;QACzE,wEAAwE;QACxE,IAAI,CAAC,MAAM,CAAC,YAAY;YAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QAClE,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;QAC/B,OAAO,QAAQ,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;IACrD,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACzC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;QAC/B,MAAM,CAAC,aAAa,EAAE,CAAC;QACvB,OAAO,QAAQ,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;IACrD,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;IAChC,MAAM,UAAU,GAAwC,EAAE,CAAC;IAE3D,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC;QACvD,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC;QAC/B,MAAM,SAAS,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;QACzC,IAAI,SAAS,KAAK,SAAS;YAAE,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACxD,IAAI,MAAM,CAAC,QAAQ,KAAK,MAAM;YAAE,MAAM,CAAC,aAAa,EAAE,CAAC;IACzD,CAAC;IAED,MAAM,CAAC,UAAU,EAAE,CAAC;IACpB,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAEtB,MAAM,IAAI,GAAG,UAAU,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC/C,MAAM,IAAI,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACjF,OAAO,QAAQ,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;AACjD,CAAC"}
|