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,40 @@
|
|
|
1
|
+
import type { DiagnosticSink } from '../diagnostics/index.js';
|
|
2
|
+
import type { SourceFile } from '../source/index.js';
|
|
3
|
+
import type { Token, TokenKind } from '../tokens/index.js';
|
|
4
|
+
/**
|
|
5
|
+
* What the shape of a file means: where a statement begins, where a block opens
|
|
6
|
+
* and closes, and what a line's leading whitespace is worth.
|
|
7
|
+
*
|
|
8
|
+
* It is a separate thing from the scanner because it works in lines and
|
|
9
|
+
* statements where the scanner works in characters, and because it is where the
|
|
10
|
+
* two rules that a naive lexer gets wrong live: a line that carries no token is
|
|
11
|
+
* never asked about its indentation, and a line indented past its siblings is
|
|
12
|
+
* one error rather than a new block.
|
|
13
|
+
*
|
|
14
|
+
* It writes the layout tokens straight into the list the scanner is filling, so
|
|
15
|
+
* an indent lands in front of the token that opened the block rather than being
|
|
16
|
+
* threaded back in afterwards.
|
|
17
|
+
*/
|
|
18
|
+
export declare class Layout {
|
|
19
|
+
#private;
|
|
20
|
+
constructor(file: SourceFile, sink: DiagnosticSink, tokens: Token[]);
|
|
21
|
+
/** Holds a line's leading whitespace, which may turn out to mean nothing at all. */
|
|
22
|
+
beginLine(line: number, offset: number, width: number, text: string, hasTab: boolean): void;
|
|
23
|
+
/** The line is over. Whatever it was holding was never wanted. */
|
|
24
|
+
endLine(): void;
|
|
25
|
+
/**
|
|
26
|
+
* Turns the leading whitespace into block structure, at the moment the line
|
|
27
|
+
* turns out to carry a token and not before. A line that produces no token
|
|
28
|
+
* never reaches here, which is the whole of the rule that a blank line and a
|
|
29
|
+
* comment-only line carry no indentation at all (3.10).
|
|
30
|
+
*/
|
|
31
|
+
admit(continuing: boolean): void;
|
|
32
|
+
/** The first token of a statement decides whether a block may open under it. */
|
|
33
|
+
observe(kind: TokenKind): void;
|
|
34
|
+
endStatement(): void;
|
|
35
|
+
/** A second statement beginning on a line that already held one, after a `;`. */
|
|
36
|
+
beginStatement(line: number, indent: number): void;
|
|
37
|
+
/** The end of the file closes every block still open. */
|
|
38
|
+
closeBlocks(at: number): void;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=layout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../src/core/lex/layout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AA2B3D;;;;;;;;;;;;;GAaG;AACH,qBAAa,MAAM;;gBAUL,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE;IAMnE,oFAAoF;IACpF,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI;IAI3F,kEAAkE;IAClE,OAAO,IAAI,IAAI;IAIf;;;;;OAKG;IACH,KAAK,CAAC,UAAU,EAAE,OAAO,GAAG,IAAI;IAsEhC,gFAAgF;IAChF,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;IAK9B,YAAY,IAAI,IAAI;IAWpB,iFAAiF;IACjF,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAIlD,yDAAyD;IACzD,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;CAkB9B"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { BlockStack } from './blocks.js';
|
|
2
|
+
import { endsWithArrow, opensBlock } from './statements.js';
|
|
3
|
+
/**
|
|
4
|
+
* What the shape of a file means: where a statement begins, where a block opens
|
|
5
|
+
* and closes, and what a line's leading whitespace is worth.
|
|
6
|
+
*
|
|
7
|
+
* It is a separate thing from the scanner because it works in lines and
|
|
8
|
+
* statements where the scanner works in characters, and because it is where the
|
|
9
|
+
* two rules that a naive lexer gets wrong live: a line that carries no token is
|
|
10
|
+
* never asked about its indentation, and a line indented past its siblings is
|
|
11
|
+
* one error rather than a new block.
|
|
12
|
+
*
|
|
13
|
+
* It writes the layout tokens straight into the list the scanner is filling, so
|
|
14
|
+
* an indent lands in front of the token that opened the block rather than being
|
|
15
|
+
* threaded back in afterwards.
|
|
16
|
+
*/
|
|
17
|
+
export class Layout {
|
|
18
|
+
#file;
|
|
19
|
+
#sink;
|
|
20
|
+
#tokens;
|
|
21
|
+
#blocks = new BlockStack();
|
|
22
|
+
#pending;
|
|
23
|
+
#statement;
|
|
24
|
+
#previous;
|
|
25
|
+
constructor(file, sink, tokens) {
|
|
26
|
+
this.#file = file;
|
|
27
|
+
this.#sink = sink;
|
|
28
|
+
this.#tokens = tokens;
|
|
29
|
+
}
|
|
30
|
+
/** Holds a line's leading whitespace, which may turn out to mean nothing at all. */
|
|
31
|
+
beginLine(line, offset, width, text, hasTab) {
|
|
32
|
+
this.#pending = { line, offset, width, text, hasTab };
|
|
33
|
+
}
|
|
34
|
+
/** The line is over. Whatever it was holding was never wanted. */
|
|
35
|
+
endLine() {
|
|
36
|
+
this.#pending = undefined;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Turns the leading whitespace into block structure, at the moment the line
|
|
40
|
+
* turns out to carry a token and not before. A line that produces no token
|
|
41
|
+
* never reaches here, which is the whole of the rule that a blank line and a
|
|
42
|
+
* comment-only line carry no indentation at all (3.10).
|
|
43
|
+
*/
|
|
44
|
+
admit(continuing) {
|
|
45
|
+
const pending = this.#pending;
|
|
46
|
+
if (pending === undefined)
|
|
47
|
+
return;
|
|
48
|
+
this.#pending = undefined;
|
|
49
|
+
if (pending.hasTab) {
|
|
50
|
+
this.#sink.report('OS1002', this.#span(pending.offset, pending.width), {});
|
|
51
|
+
}
|
|
52
|
+
if (continuing) {
|
|
53
|
+
this.#checkContinuation(pending);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
this.#enterBlock(pending);
|
|
57
|
+
this.#statement = { line: pending.line, indent: pending.width, firstKind: undefined };
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* A continuation line belongs to a statement that began above it, so it opens
|
|
61
|
+
* and closes nothing. It only has to sit further right than the line that
|
|
62
|
+
* began the statement, so that it can never be read as a new one (3.11).
|
|
63
|
+
*
|
|
64
|
+
* That is OS1028 rather than the block rule of OS1003, and the difference is
|
|
65
|
+
* not a formality: there is no block here, so OS1003's message would name an
|
|
66
|
+
* indentation no line carries and its fix would offer to end a block the file
|
|
67
|
+
* never opened.
|
|
68
|
+
*/
|
|
69
|
+
#checkContinuation(pending) {
|
|
70
|
+
const statement = this.#statement;
|
|
71
|
+
if (statement === undefined || pending.width > statement.indent)
|
|
72
|
+
return;
|
|
73
|
+
this.#sink.report('OS1028', this.#span(pending.offset, pending.width), {
|
|
74
|
+
found: pending.width,
|
|
75
|
+
statement: statement.indent,
|
|
76
|
+
line: statement.line,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
#enterBlock(pending) {
|
|
80
|
+
const firstToken = pending.offset + pending.width;
|
|
81
|
+
const event = this.#blocks.enter(pending.width, this.#afterHeader(), this.#previous?.line ?? pending.line);
|
|
82
|
+
switch (event.kind) {
|
|
83
|
+
case 'same':
|
|
84
|
+
break;
|
|
85
|
+
case 'open':
|
|
86
|
+
this.#tokens.push({
|
|
87
|
+
kind: 'indent',
|
|
88
|
+
span: this.#span(pending.offset, pending.width),
|
|
89
|
+
text: pending.text,
|
|
90
|
+
});
|
|
91
|
+
break;
|
|
92
|
+
case 'close':
|
|
93
|
+
this.#dedent(event.count, firstToken);
|
|
94
|
+
break;
|
|
95
|
+
case 'mismatch':
|
|
96
|
+
this.#dedent(event.count, firstToken);
|
|
97
|
+
this.#sink.report('OS1003', this.#span(pending.offset, pending.width), {
|
|
98
|
+
found: pending.width,
|
|
99
|
+
expected: event.expected,
|
|
100
|
+
line: event.openerLine,
|
|
101
|
+
});
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/** The first token of a statement decides whether a block may open under it. */
|
|
106
|
+
observe(kind) {
|
|
107
|
+
const statement = this.#statement;
|
|
108
|
+
if (statement !== undefined && statement.firstKind === undefined)
|
|
109
|
+
statement.firstKind = kind;
|
|
110
|
+
}
|
|
111
|
+
endStatement() {
|
|
112
|
+
const statement = this.#statement;
|
|
113
|
+
this.#statement = undefined;
|
|
114
|
+
if (statement === undefined || statement.firstKind === undefined)
|
|
115
|
+
return;
|
|
116
|
+
this.#previous = {
|
|
117
|
+
line: statement.line,
|
|
118
|
+
firstKind: statement.firstKind,
|
|
119
|
+
arrowAtEnd: endsWithArrow(this.#tokens),
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
/** A second statement beginning on a line that already held one, after a `;`. */
|
|
123
|
+
beginStatement(line, indent) {
|
|
124
|
+
this.#statement = { line, indent, firstKind: undefined };
|
|
125
|
+
}
|
|
126
|
+
/** The end of the file closes every block still open. */
|
|
127
|
+
closeBlocks(at) {
|
|
128
|
+
this.#dedent(this.#blocks.closeAll(), at);
|
|
129
|
+
}
|
|
130
|
+
#dedent(count, at) {
|
|
131
|
+
for (let i = 0; i < count; i++) {
|
|
132
|
+
this.#tokens.push({ kind: 'dedent', span: this.#span(at, 0), text: '' });
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
#afterHeader() {
|
|
136
|
+
const previous = this.#previous;
|
|
137
|
+
return previous !== undefined && opensBlock(previous.firstKind, previous.arrowAtEnd);
|
|
138
|
+
}
|
|
139
|
+
#span(offset, length) {
|
|
140
|
+
return this.#file.spanAt(offset, length);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.js","sourceRoot":"","sources":["../../../src/core/lex/layout.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAyB5D;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,MAAM;IACR,KAAK,CAAa;IAClB,KAAK,CAAiB;IACtB,OAAO,CAAU;IACjB,OAAO,GAAG,IAAI,UAAU,EAAE,CAAC;IAEpC,QAAQ,CAA0B;IAClC,UAAU,CAA4B;IACtC,SAAS,CAA8B;IAEvC,YAAY,IAAgB,EAAE,IAAoB,EAAE,MAAe;QACjE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IACxB,CAAC;IAED,oFAAoF;IACpF,SAAS,CAAC,IAAY,EAAE,MAAc,EAAE,KAAa,EAAE,IAAY,EAAE,MAAe;QAClF,IAAI,CAAC,QAAQ,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IACxD,CAAC;IAED,kEAAkE;IAClE,OAAO;QACL,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC;IAC5B,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,UAAmB;QACvB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC9B,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO;QAClC,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC;QAE1B,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;QAC7E,CAAC;QAED,IAAI,UAAU,EAAE,CAAC;YACf,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;YACjC,OAAO;QACT,CAAC;QAED,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAC1B,IAAI,CAAC,UAAU,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC;IACxF,CAAC;IAED;;;;;;;;;OASG;IACH,kBAAkB,CAAC,OAAoB;QACrC,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC;QAClC,IAAI,SAAS,KAAK,SAAS,IAAI,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC,MAAM;YAAE,OAAO;QACxE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE;YACrE,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,SAAS,EAAE,SAAS,CAAC,MAAM;YAC3B,IAAI,EAAE,SAAS,CAAC,IAAI;SACrB,CAAC,CAAC;IACL,CAAC;IAED,WAAW,CAAC,OAAoB;QAC9B,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;QAClD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAC9B,OAAO,CAAC,KAAK,EACb,IAAI,CAAC,YAAY,EAAE,EACnB,IAAI,CAAC,SAAS,EAAE,IAAI,IAAI,OAAO,CAAC,IAAI,CACrC,CAAC;QAEF,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,MAAM;gBACT,MAAM;YACR,KAAK,MAAM;gBACT,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;oBAChB,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC;oBAC/C,IAAI,EAAE,OAAO,CAAC,IAAI;iBACnB,CAAC,CAAC;gBACH,MAAM;YACR,KAAK,OAAO;gBACV,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;gBACtC,MAAM;YACR,KAAK,UAAU;gBACb,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;gBACtC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE;oBACrE,KAAK,EAAE,OAAO,CAAC,KAAK;oBACpB,QAAQ,EAAE,KAAK,CAAC,QAAQ;oBACxB,IAAI,EAAE,KAAK,CAAC,UAAU;iBACvB,CAAC,CAAC;gBACH,MAAM;QACV,CAAC;IACH,CAAC;IAED,gFAAgF;IAChF,OAAO,CAAC,IAAe;QACrB,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC;QAClC,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,CAAC,SAAS,KAAK,SAAS;YAAE,SAAS,CAAC,SAAS,GAAG,IAAI,CAAC;IAC/F,CAAC;IAED,YAAY;QACV,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC;QAClC,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAC5B,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,CAAC,SAAS,KAAK,SAAS;YAAE,OAAO;QACzE,IAAI,CAAC,SAAS,GAAG;YACf,IAAI,EAAE,SAAS,CAAC,IAAI;YACpB,SAAS,EAAE,SAAS,CAAC,SAAS;YAC9B,UAAU,EAAE,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC;SACxC,CAAC;IACJ,CAAC;IAED,iFAAiF;IACjF,cAAc,CAAC,IAAY,EAAE,MAAc;QACzC,IAAI,CAAC,UAAU,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC;IAC3D,CAAC;IAED,yDAAyD;IACzD,WAAW,CAAC,EAAU;QACpB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;IAC5C,CAAC;IAED,OAAO,CAAC,KAAa,EAAE,EAAU;QAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;YAC/B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC;IAED,YAAY;QACV,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC;QAChC,OAAO,QAAQ,KAAK,SAAS,IAAI,UAAU,CAAC,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;IACvF,CAAC;IAED,KAAK,CAAC,MAAc,EAAE,MAAc;QAClC,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3C,CAAC;CACF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { DiagnosticSink } from '../diagnostics/index.js';
|
|
2
|
+
import type { SourceFile } from '../source/index.js';
|
|
3
|
+
import type { Token } from '../tokens/index.js';
|
|
4
|
+
/**
|
|
5
|
+
* Reads a file into tokens, reporting what it cannot read and carrying on.
|
|
6
|
+
*
|
|
7
|
+
* Nothing here throws. One character the language does not have should cost the
|
|
8
|
+
* reader that character and not the rest of the file, so every lexical error is
|
|
9
|
+
* reported against its own span and the scan resumes at the next thing it can
|
|
10
|
+
* recognise.
|
|
11
|
+
*/
|
|
12
|
+
export declare function lex(file: SourceFile, diagnostics: DiagnosticSink): readonly Token[];
|
|
13
|
+
//# sourceMappingURL=lexer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lexer.d.ts","sourceRoot":"","sources":["../../../src/core/lex/lexer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,KAAK,EAA4B,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAwd1E;;;;;;;GAOG;AACH,wBAAgB,GAAG,CAAC,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,GAAG,SAAS,KAAK,EAAE,CAEnF"}
|
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
import { PUNCTUATORS, RESERVED_WORDS } from '../tokens/index.js';
|
|
2
|
+
import { APOSTROPHE, BACKSLASH, DOT, HASH, isBlank, isDigit, isNamePart, isNameStart, LINE_FEED, QUOTE, SEMICOLON, SLASH, SPACE, TAB, } from './characters.js';
|
|
3
|
+
import { closesComment, commentRegion, hasCloser, opensComment } from './comments.js';
|
|
4
|
+
import { Layout } from './layout.js';
|
|
5
|
+
import { scanNumber } from './numbers.js';
|
|
6
|
+
import { continuesLine } from './statements.js';
|
|
7
|
+
import { scanString } from './strings.js';
|
|
8
|
+
import { describeUnexpected, isNonAsciiLetter } from './unexpected.js';
|
|
9
|
+
const RESERVED = new Set(RESERVED_WORDS);
|
|
10
|
+
const ONE_CHARACTER = new Set(PUNCTUATORS.filter((mark) => mark.length === 1));
|
|
11
|
+
const TWO_CHARACTER = new Set(PUNCTUATORS.filter((mark) => mark.length === 2));
|
|
12
|
+
/**
|
|
13
|
+
* The two character operators of other languages, which this one does not have
|
|
14
|
+
* (3.12). They are matched as a pair so that the message names the operator the
|
|
15
|
+
* reader wrote and offers the one to write instead, rather than reporting one
|
|
16
|
+
* ampersand and leaving them to work out which half was wrong.
|
|
17
|
+
*/
|
|
18
|
+
const REJECTED_PAIRS = new Set(['&&', '||', '**', '++']);
|
|
19
|
+
const OPENING_BRACKETS = new Set(['(', '[']);
|
|
20
|
+
const CLOSING_BRACKETS = new Set([')', ']']);
|
|
21
|
+
const HEX_ONLY = /^[0-9a-fA-F]+$/;
|
|
22
|
+
class Lexer {
|
|
23
|
+
#file;
|
|
24
|
+
#text;
|
|
25
|
+
#sink;
|
|
26
|
+
#tokens = [];
|
|
27
|
+
#layout;
|
|
28
|
+
#offset = 0;
|
|
29
|
+
#line = 1;
|
|
30
|
+
#indent = 0;
|
|
31
|
+
#brackets = 0;
|
|
32
|
+
#continuing = false;
|
|
33
|
+
#lineHasToken = false;
|
|
34
|
+
#droppedAfterToken = false;
|
|
35
|
+
/** Whether a block comment marker opened a region that no closer has ended yet. */
|
|
36
|
+
#inComment = false;
|
|
37
|
+
constructor(file, sink) {
|
|
38
|
+
this.#file = file;
|
|
39
|
+
this.#text = file.text;
|
|
40
|
+
this.#sink = sink;
|
|
41
|
+
this.#layout = new Layout(file, sink, this.#tokens);
|
|
42
|
+
}
|
|
43
|
+
run() {
|
|
44
|
+
while (this.#offset < this.#text.length)
|
|
45
|
+
this.#readLine();
|
|
46
|
+
this.#finish();
|
|
47
|
+
return this.#tokens;
|
|
48
|
+
}
|
|
49
|
+
// -------------------------------------------------------------------------
|
|
50
|
+
// Lines
|
|
51
|
+
// -------------------------------------------------------------------------
|
|
52
|
+
#readLine() {
|
|
53
|
+
const start = this.#offset;
|
|
54
|
+
let i = start;
|
|
55
|
+
// A tab is one character of indentation here, and OS1002 as soon as the line
|
|
56
|
+
// turns out to carry a token. It is counted rather than expanded because the
|
|
57
|
+
// report is what matters and a width would be a guess at an editor setting.
|
|
58
|
+
let hasTab = false;
|
|
59
|
+
while (isBlank(this.#text.charCodeAt(i))) {
|
|
60
|
+
if (this.#text.charCodeAt(i) === TAB)
|
|
61
|
+
hasTab = true;
|
|
62
|
+
i++;
|
|
63
|
+
}
|
|
64
|
+
this.#indent = i - start;
|
|
65
|
+
this.#layout.beginLine(this.#line, start, this.#indent, this.#text.slice(start, i), hasTab);
|
|
66
|
+
this.#offset = i;
|
|
67
|
+
this.#lineHasToken = false;
|
|
68
|
+
this.#droppedAfterToken = false;
|
|
69
|
+
if (this.#inComment)
|
|
70
|
+
this.#skipComment(this.#offset);
|
|
71
|
+
let backslash = false;
|
|
72
|
+
while (this.#offset < this.#text.length) {
|
|
73
|
+
const code = this.#text.charCodeAt(this.#offset);
|
|
74
|
+
if (code === LINE_FEED)
|
|
75
|
+
break;
|
|
76
|
+
if (code === SPACE) {
|
|
77
|
+
this.#offset++;
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
if (code === SLASH && this.#text.charCodeAt(this.#offset + 1) === SLASH) {
|
|
81
|
+
// A comment produces no token, which is what lets a commented out line
|
|
82
|
+
// sit at column zero inside a block without closing it (3.10).
|
|
83
|
+
this.#offset = this.#endOfLine(this.#offset);
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
if (opensComment(this.#text, this.#offset)) {
|
|
87
|
+
this.#openComment();
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (closesComment(this.#text, this.#offset)) {
|
|
91
|
+
// A closer with nothing open. The region it was meant to end was never
|
|
92
|
+
// read as one, so the marker is reported where it sits and read as
|
|
93
|
+
// nothing at all.
|
|
94
|
+
this.#sink.report('OS1026', this.#span(this.#offset, 2), { marker: '*/' });
|
|
95
|
+
this.#offset += 2;
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
if (code === BACKSLASH && this.#isBlankTo(this.#offset + 1)) {
|
|
99
|
+
backslash = true;
|
|
100
|
+
this.#offset = this.#endOfLine(this.#offset);
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
this.#readToken();
|
|
104
|
+
}
|
|
105
|
+
this.#endLine(backslash);
|
|
106
|
+
}
|
|
107
|
+
#endLine(backslash) {
|
|
108
|
+
// A line carrying no token says nothing about the statement around it, so a
|
|
109
|
+
// blank line and a comment-only line inside a continuation leave it open
|
|
110
|
+
// (3.11) by never being asked.
|
|
111
|
+
if (this.#lineHasToken || backslash) {
|
|
112
|
+
// A trailing operator whose operand was rejected promised nothing: the
|
|
113
|
+
// operand was written, it was just not written in this language. Letting
|
|
114
|
+
// it continue would hand the next line to a broken statement, and one bad
|
|
115
|
+
// character would take a line that has nothing wrong with it.
|
|
116
|
+
const promised = !this.#droppedAfterToken && continuesLine(this.#tokens);
|
|
117
|
+
this.#continuing = this.#brackets > 0 || backslash || promised;
|
|
118
|
+
}
|
|
119
|
+
if (this.#lineHasToken && !this.#continuing) {
|
|
120
|
+
this.#layout.endStatement();
|
|
121
|
+
const atEnd = this.#offset >= this.#text.length;
|
|
122
|
+
this.#emitNewline(this.#span(this.#offset, atEnd ? 0 : 1));
|
|
123
|
+
}
|
|
124
|
+
if (this.#offset < this.#text.length) {
|
|
125
|
+
this.#offset++;
|
|
126
|
+
this.#line++;
|
|
127
|
+
}
|
|
128
|
+
this.#layout.endLine();
|
|
129
|
+
}
|
|
130
|
+
#finish() {
|
|
131
|
+
const last = this.#tokens[this.#tokens.length - 1];
|
|
132
|
+
if (last !== undefined && last.kind !== 'newline') {
|
|
133
|
+
// A bracket that is never closed reads the rest of the file as one
|
|
134
|
+
// statement (3.11), and that statement still has to end somewhere for the
|
|
135
|
+
// parser to report it against.
|
|
136
|
+
this.#layout.endStatement();
|
|
137
|
+
this.#emitNewline(this.#span(this.#text.length, 0));
|
|
138
|
+
}
|
|
139
|
+
this.#layout.closeBlocks(this.#text.length);
|
|
140
|
+
this.#tokens.push({ kind: 'endOfFile', span: this.#span(this.#text.length, 0), text: '' });
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* A region the writer meant as a comment, from its opener to its closer.
|
|
144
|
+
*
|
|
145
|
+
* It is reported once, at the opener, and then skipped. Reading the prose
|
|
146
|
+
* inside it as tokens would report the operators it happens to contain and
|
|
147
|
+
* the statements it appears to hold, which is several diagnostics about a
|
|
148
|
+
* program the writer did not write, and none of them would name the comment
|
|
149
|
+
* (3.2).
|
|
150
|
+
*/
|
|
151
|
+
#openComment() {
|
|
152
|
+
this.#sink.report('OS1026', this.#span(this.#offset, 2), { marker: '/*' });
|
|
153
|
+
this.#skipComment(this.#offset + 2);
|
|
154
|
+
// A closer written nowhere makes no region: the marker costs this line and
|
|
155
|
+
// the file is read on from the next one, rather than being swallowed whole
|
|
156
|
+
// by a form the language does not have (3.2).
|
|
157
|
+
this.#inComment = this.#inComment && hasCloser(this.#text, this.#offset);
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* The region, to its closer or to the end of the line, said once and then
|
|
161
|
+
* skipped: one region is one mistake however many lines it runs to, so a
|
|
162
|
+
* line below the opener is read as prose rather than reported again.
|
|
163
|
+
*/
|
|
164
|
+
#skipComment(from) {
|
|
165
|
+
const region = commentRegion(this.#text, from);
|
|
166
|
+
this.#inComment = region.open;
|
|
167
|
+
this.#offset = region.end;
|
|
168
|
+
}
|
|
169
|
+
#endOfLine(from) {
|
|
170
|
+
const at = this.#text.indexOf('\n', from);
|
|
171
|
+
return at === -1 ? this.#text.length : at;
|
|
172
|
+
}
|
|
173
|
+
#isBlankTo(from) {
|
|
174
|
+
for (let i = from; i < this.#text.length; i++) {
|
|
175
|
+
const code = this.#text.charCodeAt(i);
|
|
176
|
+
if (code === LINE_FEED)
|
|
177
|
+
return true;
|
|
178
|
+
if (!isBlank(code))
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
// -------------------------------------------------------------------------
|
|
184
|
+
// Tokens
|
|
185
|
+
// -------------------------------------------------------------------------
|
|
186
|
+
#readToken() {
|
|
187
|
+
const start = this.#offset;
|
|
188
|
+
const code = this.#text.charCodeAt(start);
|
|
189
|
+
if (isNameStart(code)) {
|
|
190
|
+
this.#readName(start);
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
if (isDigit(code) || (code === DOT && isDigit(this.#text.charCodeAt(start + 1)))) {
|
|
194
|
+
this.#readNumber(start);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
if (code === QUOTE || code === APOSTROPHE) {
|
|
198
|
+
this.#readString(start);
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
if (code === HASH) {
|
|
202
|
+
this.#readColour(start);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
if (code === SEMICOLON) {
|
|
206
|
+
this.#readSemicolon(start);
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
this.#readPunctuation(start);
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* A name, and with it every reserved word, which is spelled like one and told
|
|
213
|
+
* apart by the table rather than by the scanner.
|
|
214
|
+
*
|
|
215
|
+
* A reserved word keeps its own kind here even where the parser will accept it
|
|
216
|
+
* as a named argument label (3.4). The lexer cannot make that call: the same
|
|
217
|
+
* word before an `=` is a legal label inside a call and is OS1019 inside a
|
|
218
|
+
* parameter list, and only the parser knows which of the two it is reading.
|
|
219
|
+
*/
|
|
220
|
+
#readName(start) {
|
|
221
|
+
const word = this.#word(start);
|
|
222
|
+
if (word.foreign !== undefined) {
|
|
223
|
+
// Identifiers are ASCII (3.3). The whole word is taken as one name so that
|
|
224
|
+
// the statement around it still parses and one bad character reports once.
|
|
225
|
+
this.#sink.report('OS1001', this.#span(word.foreign.offset, word.foreign.written.length), describeUnexpected(word.foreign.written));
|
|
226
|
+
}
|
|
227
|
+
const text = this.#text.slice(start, word.end);
|
|
228
|
+
const kind = RESERVED.has(text) ? text : 'identifier';
|
|
229
|
+
this.#emit({ kind, span: this.#span(start, word.end - start), text });
|
|
230
|
+
this.#offset = word.end;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* A number literal, and the run that is not one: a base prefix the language
|
|
234
|
+
* does not have, a unit written against a quantity, a literal that ends in an
|
|
235
|
+
* underscore (3.5).
|
|
236
|
+
*
|
|
237
|
+
* Such a run is reported whole, as OS1029. Every character in it is one the
|
|
238
|
+
* language accepts, so naming the leading digit would name something legal,
|
|
239
|
+
* and deleting it, which is what OS1001 tells a reader to do with the
|
|
240
|
+
* character it names, leaves a valid name behind and a program that compiles
|
|
241
|
+
* and means something else.
|
|
242
|
+
*/
|
|
243
|
+
#readNumber(start) {
|
|
244
|
+
const literal = scanNumber(this.#text, start);
|
|
245
|
+
const after = this.#text.codePointAt(literal.end);
|
|
246
|
+
if (after !== undefined && (isNamePart(after) || isNonAsciiLetter(after))) {
|
|
247
|
+
// A name cannot begin with a digit (3.3), and a letter written against a
|
|
248
|
+
// number is that mistake rather than two tokens that happen to touch.
|
|
249
|
+
const word = this.#word(literal.end);
|
|
250
|
+
const written = this.#text.slice(start, word.end);
|
|
251
|
+
this.#sink.report('OS1029', this.#span(start, word.end - start), {
|
|
252
|
+
written,
|
|
253
|
+
number: this.#text.slice(start, literal.end),
|
|
254
|
+
});
|
|
255
|
+
this.#emit({
|
|
256
|
+
kind: 'identifier',
|
|
257
|
+
span: this.#span(start, word.end - start),
|
|
258
|
+
text: written,
|
|
259
|
+
});
|
|
260
|
+
this.#offset = word.end;
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
this.#emit({
|
|
264
|
+
kind: 'numberLiteral',
|
|
265
|
+
span: this.#span(start, literal.end - start),
|
|
266
|
+
text: this.#text.slice(start, literal.end),
|
|
267
|
+
value: literal.value,
|
|
268
|
+
});
|
|
269
|
+
this.#offset = literal.end;
|
|
270
|
+
}
|
|
271
|
+
#readString(start) {
|
|
272
|
+
const literal = scanString(this.#text, start);
|
|
273
|
+
for (const bad of literal.badEscapes) {
|
|
274
|
+
this.#sink.report('OS1005', this.#span(bad.offset, bad.length), { sequence: bad.text });
|
|
275
|
+
}
|
|
276
|
+
if (literal.unterminated) {
|
|
277
|
+
this.#sink.report('OS1004', this.#span(start, 1), { quote: this.#text.charAt(start) });
|
|
278
|
+
}
|
|
279
|
+
// The token is emitted either way. The reader is told once that the quote is
|
|
280
|
+
// missing; they do not also need to be told that the statement around it
|
|
281
|
+
// makes no sense without it.
|
|
282
|
+
this.#emit({
|
|
283
|
+
kind: 'stringLiteral',
|
|
284
|
+
span: this.#span(start, literal.end - start),
|
|
285
|
+
text: this.#text.slice(start, literal.end),
|
|
286
|
+
value: literal.value,
|
|
287
|
+
});
|
|
288
|
+
this.#offset = literal.end;
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* `#rrggbb` and `#rrggbbaa` (3.8).
|
|
292
|
+
*
|
|
293
|
+
* A run of the wrong length, or one carrying a character that is not a
|
|
294
|
+
* hexadecimal digit, is a colour the writer had nearly right, and it is
|
|
295
|
+
* OS1027 over the whole of what they wrote. The OS1001 sentence about `#`
|
|
296
|
+
* says to delete the character or to put the text in a string, which is the
|
|
297
|
+
* answer for a `#` standing on its own and would throw the colour away here.
|
|
298
|
+
*/
|
|
299
|
+
#readColour(start) {
|
|
300
|
+
const word = this.#word(start + 1);
|
|
301
|
+
const digits = this.#text.slice(start + 1, word.end);
|
|
302
|
+
const isColour = word.foreign === undefined &&
|
|
303
|
+
(digits.length === 6 || digits.length === 8) &&
|
|
304
|
+
HEX_ONLY.test(digits);
|
|
305
|
+
if (isColour) {
|
|
306
|
+
this.#emit({
|
|
307
|
+
kind: 'hexColor',
|
|
308
|
+
span: this.#span(start, word.end - start),
|
|
309
|
+
text: this.#text.slice(start, word.end),
|
|
310
|
+
});
|
|
311
|
+
this.#offset = word.end;
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
if (digits.length === 0) {
|
|
315
|
+
// Nothing was written against it, so there is no colour here to have got
|
|
316
|
+
// wrong: this is the character on its own (3.1).
|
|
317
|
+
this.#sink.report('OS1001', this.#span(start, 1), describeUnexpected('#'));
|
|
318
|
+
this.#droppedAfterToken = true;
|
|
319
|
+
this.#offset = start + 1;
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
this.#sink.report('OS1027', this.#span(start, word.end - start), {
|
|
323
|
+
written: this.#text.slice(start, word.end),
|
|
324
|
+
});
|
|
325
|
+
this.#droppedAfterToken = true;
|
|
326
|
+
this.#offset = word.end;
|
|
327
|
+
}
|
|
328
|
+
#readSemicolon(start) {
|
|
329
|
+
this.#sink.report('OS1007', this.#span(start, 1), {});
|
|
330
|
+
this.#droppedAfterToken = true;
|
|
331
|
+
this.#offset = start + 1;
|
|
332
|
+
// The fix is to put the second statement on its own line, so the token
|
|
333
|
+
// stream is given exactly that and the rest of the line is read as the
|
|
334
|
+
// statement the writer meant. Inside brackets there is no statement to end,
|
|
335
|
+
// so there the character is only dropped.
|
|
336
|
+
if (this.#brackets > 0 || !this.#lineHasToken)
|
|
337
|
+
return;
|
|
338
|
+
this.#layout.endStatement();
|
|
339
|
+
this.#emitNewline(this.#span(start, 1));
|
|
340
|
+
this.#layout.beginStatement(this.#line, this.#indent);
|
|
341
|
+
}
|
|
342
|
+
#readPunctuation(start) {
|
|
343
|
+
const pair = this.#text.slice(start, start + 2);
|
|
344
|
+
if (REJECTED_PAIRS.has(pair)) {
|
|
345
|
+
this.#sink.report('OS1001', this.#span(start, 2), describeUnexpected(pair));
|
|
346
|
+
this.#droppedAfterToken = true;
|
|
347
|
+
this.#offset = start + 2;
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
if (TWO_CHARACTER.has(pair)) {
|
|
351
|
+
this.#emit({ kind: pair, span: this.#span(start, 2), text: pair });
|
|
352
|
+
this.#offset = start + 2;
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
const one = this.#text.charAt(start);
|
|
356
|
+
if (ONE_CHARACTER.has(one)) {
|
|
357
|
+
if (OPENING_BRACKETS.has(one))
|
|
358
|
+
this.#brackets++;
|
|
359
|
+
else if (CLOSING_BRACKETS.has(one) && this.#brackets > 0)
|
|
360
|
+
this.#brackets--;
|
|
361
|
+
this.#emit({ kind: one, span: this.#span(start, 1), text: one });
|
|
362
|
+
this.#offset = start + 1;
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
// Everything the language does not have, reported where it sits rather than
|
|
366
|
+
// three tokens later (3.1). An astral character is two code units and is
|
|
367
|
+
// taken whole, so a message never quotes half of one.
|
|
368
|
+
const written = String.fromCodePoint(this.#text.codePointAt(start) ?? 0);
|
|
369
|
+
this.#sink.report('OS1001', this.#span(start, written.length), describeUnexpected(written));
|
|
370
|
+
this.#droppedAfterToken = true;
|
|
371
|
+
this.#offset = start + written.length;
|
|
372
|
+
}
|
|
373
|
+
#word(from) {
|
|
374
|
+
let i = from;
|
|
375
|
+
let foreign;
|
|
376
|
+
for (;;) {
|
|
377
|
+
while (isNamePart(this.#text.charCodeAt(i)))
|
|
378
|
+
i++;
|
|
379
|
+
const point = this.#text.codePointAt(i);
|
|
380
|
+
if (point === undefined || !isNonAsciiLetter(point))
|
|
381
|
+
return { end: i, foreign };
|
|
382
|
+
const written = String.fromCodePoint(point);
|
|
383
|
+
foreign ??= { offset: i, written };
|
|
384
|
+
i += written.length;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
// -------------------------------------------------------------------------
|
|
388
|
+
// Emitting
|
|
389
|
+
// -------------------------------------------------------------------------
|
|
390
|
+
#emit(token) {
|
|
391
|
+
this.#layout.admit(this.#continuing);
|
|
392
|
+
this.#layout.observe(token.kind);
|
|
393
|
+
this.#lineHasToken = true;
|
|
394
|
+
this.#droppedAfterToken = false;
|
|
395
|
+
this.#tokens.push(token);
|
|
396
|
+
}
|
|
397
|
+
/** One newline per statement, never two, and never one before a statement has begun. */
|
|
398
|
+
#emitNewline(span) {
|
|
399
|
+
const last = this.#tokens[this.#tokens.length - 1];
|
|
400
|
+
if (last === undefined || last.kind === 'newline')
|
|
401
|
+
return;
|
|
402
|
+
this.#tokens.push({ kind: 'newline', span, text: '' });
|
|
403
|
+
}
|
|
404
|
+
#span(offset, length) {
|
|
405
|
+
return this.#file.spanAt(offset, length);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Reads a file into tokens, reporting what it cannot read and carrying on.
|
|
410
|
+
*
|
|
411
|
+
* Nothing here throws. One character the language does not have should cost the
|
|
412
|
+
* reader that character and not the rest of the file, so every lexical error is
|
|
413
|
+
* reported against its own span and the scan resumes at the next thing it can
|
|
414
|
+
* recognise.
|
|
415
|
+
*/
|
|
416
|
+
export function lex(file, diagnostics) {
|
|
417
|
+
return new Lexer(file, diagnostics).run();
|
|
418
|
+
}
|
|
419
|
+
//# sourceMappingURL=lexer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lexer.js","sourceRoot":"","sources":["../../../src/core/lex/lexer.ts"],"names":[],"mappings":"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"}
|