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,68 @@
|
|
|
1
|
+
import type { Positioned } from '../span/index.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A type as a script writes it, on a parameter, a `var` or a function result.
|
|
5
|
+
*
|
|
6
|
+
* The tree keeps the words rather than a resolved type. A resolved type is the
|
|
7
|
+
* checker's, it has no source position, and it exists for expressions that were
|
|
8
|
+
* never annotated at all; an annotation is a piece of syntax with a span that a
|
|
9
|
+
* caret can land on.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/** The types a value can have, language.md 5.1. */
|
|
13
|
+
export const VALUE_TYPE_NAMES = ['number', 'string', 'bool', 'color'] as const;
|
|
14
|
+
export type ValueTypeName = (typeof VALUE_TYPE_NAMES)[number];
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The runtime object types of language.md 5.4.
|
|
18
|
+
*
|
|
19
|
+
* These five are recognised in a type position only and are ordinary global
|
|
20
|
+
* function names everywhere else, which is why they are not reserved words. The
|
|
21
|
+
* declaration handle types `plot`, `fill` and `level` are deliberately missing:
|
|
22
|
+
* a handle can never be a `var`, a parameter, a result or an array element, so
|
|
23
|
+
* it can never be annotated.
|
|
24
|
+
*/
|
|
25
|
+
export const OBJECT_TYPE_NAMES = ['line', 'label', 'box', 'polyline', 'table'] as const;
|
|
26
|
+
export type ObjectTypeName = (typeof OBJECT_TYPE_NAMES)[number];
|
|
27
|
+
|
|
28
|
+
export function isValueTypeName(text: string): text is ValueTypeName {
|
|
29
|
+
return (VALUE_TYPE_NAMES as readonly string[]).includes(text);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function isObjectTypeName(text: string): text is ObjectTypeName {
|
|
33
|
+
return (OBJECT_TYPE_NAMES as readonly string[]).includes(text);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* A type written as one word.
|
|
38
|
+
*
|
|
39
|
+
* The word is an arbitrary string rather than one of the two unions above,
|
|
40
|
+
* because "that is not a type" is OS2016 and OS2016 is a check, not a parse
|
|
41
|
+
* error. A parser that could only build a legal annotation would have to report
|
|
42
|
+
* a syntax error at `len: whole`, and the reader would get a caret and no
|
|
43
|
+
* sentence naming the types that do exist.
|
|
44
|
+
*/
|
|
45
|
+
export interface NamedType extends Positioned {
|
|
46
|
+
readonly kind: 'namedType';
|
|
47
|
+
readonly name: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** `series number`: one value of the element type per bar, language.md 5.2. */
|
|
51
|
+
export interface SeriesType extends Positioned {
|
|
52
|
+
readonly kind: 'seriesType';
|
|
53
|
+
readonly element: TypeAnnotation;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* `array<number>`, language.md 14.1.
|
|
58
|
+
*
|
|
59
|
+
* The element is any annotation and not just a legal element type, for the
|
|
60
|
+
* reason `namedType` holds any word: `array<plot>` has to reach the checker so
|
|
61
|
+
* that OS2019 can name the types an array does hold.
|
|
62
|
+
*/
|
|
63
|
+
export interface ArrayType extends Positioned {
|
|
64
|
+
readonly kind: 'arrayType';
|
|
65
|
+
readonly element: TypeAnnotation;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export type TypeAnnotation = NamedType | SeriesType | ArrayType;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { Span } from '../span/index.js';
|
|
2
|
+
import type { NodeKind, NodeOfKind } from './node.js';
|
|
3
|
+
|
|
4
|
+
/** Everything a node of one kind carries beyond its kind and its span. */
|
|
5
|
+
export type NodeFields<K extends NodeKind> = Omit<NodeOfKind<K>, 'kind' | 'span'>;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Builds any node.
|
|
9
|
+
*
|
|
10
|
+
* One constructor rather than forty two, because forty two would be a second
|
|
11
|
+
* place that has to agree with the interfaces, and the day one of them drifts
|
|
12
|
+
* is the day a field goes missing from a tree that still type checks at every
|
|
13
|
+
* call site. Here the fields are the interface, minus the two parts every node
|
|
14
|
+
* has, so a missing field, a misspelt one and a stray one are each a compile
|
|
15
|
+
* error at the parser's own line.
|
|
16
|
+
*
|
|
17
|
+
* It also reads as what it builds. `makeNode('binary', span, { operator, left,
|
|
18
|
+
* right })` names its three parts, where a positional constructor of the same
|
|
19
|
+
* arity would let a parser swap two of them and compile.
|
|
20
|
+
*
|
|
21
|
+
* No field is optional. A slot a script may leave out, such as a `step` or an
|
|
22
|
+
* `else`, is `undefined` and still has to be passed, because a parser that
|
|
23
|
+
* forgets one should hear about it rather than produce a node that is missing
|
|
24
|
+
* a branch.
|
|
25
|
+
*/
|
|
26
|
+
export function makeNode<K extends NodeKind>(
|
|
27
|
+
kind: K,
|
|
28
|
+
span: Span,
|
|
29
|
+
fields: NodeFields<K>,
|
|
30
|
+
): NodeOfKind<K> {
|
|
31
|
+
// The spread of a generic Omit cannot be proved to reconstruct the node it
|
|
32
|
+
// was taken from, so the one assertion in the module is here, where the
|
|
33
|
+
// signature above has already checked every field of every call.
|
|
34
|
+
return { ...fields, kind, span } as unknown as NodeOfKind<K>;
|
|
35
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import type { AstNode } from './node.js';
|
|
2
|
+
|
|
3
|
+
const NO_CHILDREN: readonly AstNode[] = [];
|
|
4
|
+
|
|
5
|
+
/** The nodes among these that are there, keeping the order they were given in. */
|
|
6
|
+
function present(...nodes: readonly (AstNode | undefined)[]): readonly AstNode[] {
|
|
7
|
+
return nodes.filter((node): node is AstNode => node !== undefined);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* The children of a node, in source order.
|
|
12
|
+
*
|
|
13
|
+
* This is the only place the shape of the tree is written down twice, and it is
|
|
14
|
+
* deliberately the only one. Everything that walks the tree walks it through
|
|
15
|
+
* here, so a field added to a node is connected once and every pass sees it,
|
|
16
|
+
* rather than being connected in the checker, forgotten in the code generator,
|
|
17
|
+
* and found by a user whose script compiled to something with a hole in it.
|
|
18
|
+
*
|
|
19
|
+
* The switch has no default arm on purpose: a new node kind stops the build
|
|
20
|
+
* here, at the one place that has to know about it.
|
|
21
|
+
*/
|
|
22
|
+
export function childrenOf(node: AstNode): readonly AstNode[] {
|
|
23
|
+
switch (node.kind) {
|
|
24
|
+
// The file and what only the file holds.
|
|
25
|
+
case 'script':
|
|
26
|
+
return node.items;
|
|
27
|
+
case 'functionDeclaration':
|
|
28
|
+
return [node.name, ...node.parameters, node.body];
|
|
29
|
+
case 'parameter':
|
|
30
|
+
return present(node.name, node.annotation, node.defaultValue);
|
|
31
|
+
|
|
32
|
+
// The header lines, which are statements wherever they are written.
|
|
33
|
+
case 'versionLine':
|
|
34
|
+
return [node.version];
|
|
35
|
+
case 'scriptDeclaration':
|
|
36
|
+
return node.args;
|
|
37
|
+
case 'limitsLine':
|
|
38
|
+
return node.args;
|
|
39
|
+
|
|
40
|
+
// Statements.
|
|
41
|
+
case 'expressionStatement':
|
|
42
|
+
return [node.expression];
|
|
43
|
+
case 'assignment':
|
|
44
|
+
return [node.target, node.value];
|
|
45
|
+
case 'varDeclaration':
|
|
46
|
+
return present(node.name, node.annotation, node.initialiser);
|
|
47
|
+
case 'ifStatement':
|
|
48
|
+
return present(...node.branches, node.elseBranch);
|
|
49
|
+
case 'ifBranch':
|
|
50
|
+
return [node.condition, node.body];
|
|
51
|
+
case 'elseBranch':
|
|
52
|
+
return [node.body];
|
|
53
|
+
case 'forRangeStatement':
|
|
54
|
+
return present(node.variable, node.from, node.to, node.step, node.body);
|
|
55
|
+
case 'forInStatement':
|
|
56
|
+
return [node.variable, node.iterable, node.body];
|
|
57
|
+
case 'whileStatement':
|
|
58
|
+
return [node.condition, node.body];
|
|
59
|
+
case 'switchStatement':
|
|
60
|
+
return present(node.subject, ...node.cases, node.defaultCase);
|
|
61
|
+
case 'switchCase':
|
|
62
|
+
return [...node.values, node.body];
|
|
63
|
+
case 'switchDefault':
|
|
64
|
+
return [node.body];
|
|
65
|
+
case 'breakStatement':
|
|
66
|
+
case 'continueStatement':
|
|
67
|
+
return NO_CHILDREN;
|
|
68
|
+
case 'returnStatement':
|
|
69
|
+
return present(node.value);
|
|
70
|
+
case 'block':
|
|
71
|
+
return node.statements;
|
|
72
|
+
|
|
73
|
+
// Expressions.
|
|
74
|
+
case 'numberLiteral':
|
|
75
|
+
case 'stringLiteral':
|
|
76
|
+
case 'booleanLiteral':
|
|
77
|
+
case 'colorLiteral':
|
|
78
|
+
case 'noneLiteral':
|
|
79
|
+
case 'nameReference':
|
|
80
|
+
case 'missingExpression':
|
|
81
|
+
return NO_CHILDREN;
|
|
82
|
+
case 'arrayLiteral':
|
|
83
|
+
return node.elements;
|
|
84
|
+
case 'grouping':
|
|
85
|
+
return [node.expression];
|
|
86
|
+
case 'unary':
|
|
87
|
+
return [node.operand];
|
|
88
|
+
case 'binary':
|
|
89
|
+
return [node.left, node.right];
|
|
90
|
+
case 'ternary':
|
|
91
|
+
return [node.condition, node.whenTrue, node.whenFalse];
|
|
92
|
+
case 'call':
|
|
93
|
+
return [node.callee, ...node.args];
|
|
94
|
+
case 'argument':
|
|
95
|
+
return present(node.label, node.value);
|
|
96
|
+
case 'index':
|
|
97
|
+
return [node.target, node.index];
|
|
98
|
+
case 'member':
|
|
99
|
+
return [node.object, node.member];
|
|
100
|
+
|
|
101
|
+
// Type annotations, and a name where one is written.
|
|
102
|
+
case 'namedType':
|
|
103
|
+
return NO_CHILDREN;
|
|
104
|
+
case 'seriesType':
|
|
105
|
+
case 'arrayType':
|
|
106
|
+
return [node.element];
|
|
107
|
+
case 'name':
|
|
108
|
+
return NO_CHILDREN;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import type { Positioned } from '../span/index.js';
|
|
2
|
+
import type { Name } from './name.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Every expression form of language.md section 9.
|
|
6
|
+
*
|
|
7
|
+
* Precedence is not a field anywhere below. It is in the shape of the tree: the
|
|
8
|
+
* parser reads the levels of 9.1 and the result is already grouped, so a later
|
|
9
|
+
* pass never has to know that `*` binds tighter than `+`. The one thing the
|
|
10
|
+
* tree does keep is the brackets a script wrote, because they are the
|
|
11
|
+
* difference between a caret under `(a < b)` and a caret under a whole line.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
export const ARITHMETIC_OPERATORS = ['+', '-', '*', '/', '%'] as const;
|
|
15
|
+
export type ArithmeticOperator = (typeof ARITHMETIC_OPERATORS)[number];
|
|
16
|
+
|
|
17
|
+
export const COMPARISON_OPERATORS = ['<', '<=', '>', '>='] as const;
|
|
18
|
+
export type ComparisonOperator = (typeof COMPARISON_OPERATORS)[number];
|
|
19
|
+
|
|
20
|
+
export const EQUALITY_OPERATORS = ['==', '!='] as const;
|
|
21
|
+
export type EqualityOperator = (typeof EQUALITY_OPERATORS)[number];
|
|
22
|
+
|
|
23
|
+
export const LOGICAL_OPERATORS = ['and', 'or'] as const;
|
|
24
|
+
export type LogicalOperator = (typeof LOGICAL_OPERATORS)[number];
|
|
25
|
+
|
|
26
|
+
export type BinaryOperator =
|
|
27
|
+
| ArithmeticOperator
|
|
28
|
+
| ComparisonOperator
|
|
29
|
+
| EqualityOperator
|
|
30
|
+
| LogicalOperator;
|
|
31
|
+
|
|
32
|
+
export const UNARY_OPERATORS = ['-', '+', 'not'] as const;
|
|
33
|
+
export type UnaryOperator = (typeof UNARY_OPERATORS)[number];
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The level each binary operator sits at in language.md 9.1, where a lower
|
|
37
|
+
* number binds more tightly.
|
|
38
|
+
*
|
|
39
|
+
* The numbers are the specification's own rather than a private scale that runs
|
|
40
|
+
* the other way, so a reader can check this table against language.md 9.1
|
|
41
|
+
* without translating it as they read. It sits next to the operators because a
|
|
42
|
+
* parser and a formatter that each kept a copy would disagree about one
|
|
43
|
+
* operator eventually, and that disagreement reaches a chart as a wrong number.
|
|
44
|
+
*/
|
|
45
|
+
const BINARY_PRECEDENCE: Readonly<Record<BinaryOperator, number>> = {
|
|
46
|
+
'*': 3,
|
|
47
|
+
'/': 3,
|
|
48
|
+
'%': 3,
|
|
49
|
+
'+': 4,
|
|
50
|
+
'-': 4,
|
|
51
|
+
'<': 5,
|
|
52
|
+
'<=': 5,
|
|
53
|
+
'>': 5,
|
|
54
|
+
'>=': 5,
|
|
55
|
+
'==': 6,
|
|
56
|
+
'!=': 6,
|
|
57
|
+
and: 7,
|
|
58
|
+
or: 8,
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export function binaryPrecedence(operator: BinaryOperator): number {
|
|
62
|
+
return BINARY_PRECEDENCE[operator];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* The value a number literal denotes, already read.
|
|
67
|
+
*
|
|
68
|
+
* The digit group underscores and the hexadecimal form of language.md 3.5 are
|
|
69
|
+
* resolved by the lexer, so nothing downstream reads the text a second time and
|
|
70
|
+
* nothing downstream can disagree with the lexer about what it meant.
|
|
71
|
+
*/
|
|
72
|
+
export interface NumberLiteral extends Positioned {
|
|
73
|
+
readonly kind: 'numberLiteral';
|
|
74
|
+
readonly value: number;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** A string literal with its escape sequences already resolved. */
|
|
78
|
+
export interface StringLiteral extends Positioned {
|
|
79
|
+
readonly kind: 'stringLiteral';
|
|
80
|
+
readonly value: string;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface BooleanLiteral extends Positioned {
|
|
84
|
+
readonly kind: 'booleanLiteral';
|
|
85
|
+
readonly value: boolean;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* The `#rrggbb` and `#rrggbbaa` forms of language.md 3.8, text and all.
|
|
90
|
+
*
|
|
91
|
+
* A named colour is not one of these. The nineteen names are ordinary globals
|
|
92
|
+
* so the standard library can add more without a grammar change, so `aqua` is a
|
|
93
|
+
* `nameReference` and the checker resolves it like any other name.
|
|
94
|
+
*
|
|
95
|
+
* The text is kept rather than four channel numbers, because the channels are
|
|
96
|
+
* the checker's reading of it and a diagnostic about a malformed colour has to
|
|
97
|
+
* quote what was written.
|
|
98
|
+
*/
|
|
99
|
+
export interface ColorLiteral extends Positioned {
|
|
100
|
+
readonly kind: 'colorLiteral';
|
|
101
|
+
readonly text: string;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** `none`, the absent value of language.md section 6. */
|
|
105
|
+
export interface NoneLiteral extends Positioned {
|
|
106
|
+
readonly kind: 'noneLiteral';
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* `[1, 2, 3]`, and `[]`.
|
|
111
|
+
*
|
|
112
|
+
* An empty literal is legal here. Its element type is unknown until the checker
|
|
113
|
+
* finds an annotation or a first use, and OS2015 when it finds neither.
|
|
114
|
+
*/
|
|
115
|
+
export interface ArrayLiteral extends Positioned {
|
|
116
|
+
readonly kind: 'arrayLiteral';
|
|
117
|
+
readonly elements: readonly Expression[];
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** A name used as a value. Its span is the name, so it carries no child. */
|
|
121
|
+
export interface NameReference extends Positioned {
|
|
122
|
+
readonly kind: 'nameReference';
|
|
123
|
+
readonly name: string;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* `(expression)`.
|
|
128
|
+
*
|
|
129
|
+
* Kept rather than folded away, because both passes that point back at source
|
|
130
|
+
* need it: a diagnostic about a grouped expression underlines the brackets a
|
|
131
|
+
* reader can see, and a formatter that dropped them would turn `(a + b) * c`
|
|
132
|
+
* into something else on its first reprint. A pass that wants the value inside
|
|
133
|
+
* calls `withoutGrouping`.
|
|
134
|
+
*/
|
|
135
|
+
export interface Grouping extends Positioned {
|
|
136
|
+
readonly kind: 'grouping';
|
|
137
|
+
readonly expression: Expression;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export interface Unary extends Positioned {
|
|
141
|
+
readonly kind: 'unary';
|
|
142
|
+
readonly operator: UnaryOperator;
|
|
143
|
+
readonly operand: Expression;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export interface Binary extends Positioned {
|
|
147
|
+
readonly kind: 'binary';
|
|
148
|
+
readonly operator: BinaryOperator;
|
|
149
|
+
readonly left: Expression;
|
|
150
|
+
readonly right: Expression;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/** `condition ? whenTrue : whenFalse`, language.md 9.5. */
|
|
154
|
+
export interface Ternary extends Positioned {
|
|
155
|
+
readonly kind: 'ternary';
|
|
156
|
+
readonly condition: Expression;
|
|
157
|
+
readonly whenTrue: Expression;
|
|
158
|
+
readonly whenFalse: Expression;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* One argument of a call, of `study()`, of `strategy()` or of `limits()`.
|
|
163
|
+
*
|
|
164
|
+
* A label is a `Name` and not a `nameReference` because it is never resolved.
|
|
165
|
+
* It is matched against the callee's parameter list, which is what lets a
|
|
166
|
+
* reserved word stand as one (language.md 3.4).
|
|
167
|
+
*/
|
|
168
|
+
export interface Argument extends Positioned {
|
|
169
|
+
readonly kind: 'argument';
|
|
170
|
+
readonly label: Name | undefined;
|
|
171
|
+
readonly value: Expression;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* A call, with its arguments in the order they were written.
|
|
176
|
+
*
|
|
177
|
+
* Positional after named is OS3005, a check rather than a shape, so nothing is
|
|
178
|
+
* sorted on the way in and the tree keeps the order that error has to quote.
|
|
179
|
+
* The callee is an expression because `draw.box(...)` is an argument list
|
|
180
|
+
* applied to a member access, and because `f(1)(2)` has to parse before it can
|
|
181
|
+
* be told that it is not a thing OpenScript does.
|
|
182
|
+
*/
|
|
183
|
+
export interface Call extends Positioned {
|
|
184
|
+
readonly kind: 'call';
|
|
185
|
+
readonly callee: Expression;
|
|
186
|
+
readonly args: readonly Argument[];
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* `target[index]`: history when the target is a series, element access when it
|
|
191
|
+
* is an array, and the checker decides which from the target's type
|
|
192
|
+
* (language.md 9.6). There is no run-time dispatch and no third meaning.
|
|
193
|
+
*
|
|
194
|
+
* The explicit forms `history(expr, n)` and `element(arr, i)` are ordinary
|
|
195
|
+
* calls and are not this node.
|
|
196
|
+
*/
|
|
197
|
+
export interface Index extends Positioned {
|
|
198
|
+
readonly kind: 'index';
|
|
199
|
+
readonly target: Expression;
|
|
200
|
+
readonly index: Expression;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* `object.member`.
|
|
205
|
+
*
|
|
206
|
+
* A namespace read such as `bar.index` and a field of a runtime object are one
|
|
207
|
+
* shape here. Which of the two it is, and whether the member exists at all
|
|
208
|
+
* (OS2009), is the checker's answer.
|
|
209
|
+
*/
|
|
210
|
+
export interface Member extends Positioned {
|
|
211
|
+
readonly kind: 'member';
|
|
212
|
+
readonly object: Expression;
|
|
213
|
+
readonly member: Name;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* A hole where an expression was required and none was written.
|
|
218
|
+
*
|
|
219
|
+
* The parser puts one here after reporting OS1022, OS1011 or OS1015, so a file
|
|
220
|
+
* with a mistake in it still produces a tree. Everything downstream runs on
|
|
221
|
+
* broken files by definition: an editor asks for completions inside a half
|
|
222
|
+
* typed line, and a checker that stopped at the first syntax error would report
|
|
223
|
+
* one mistake per compile.
|
|
224
|
+
*
|
|
225
|
+
* The span is where the expression should have been, and is usually empty, so
|
|
226
|
+
* it never takes a caret meant for its neighbour.
|
|
227
|
+
*/
|
|
228
|
+
export interface MissingExpression extends Positioned {
|
|
229
|
+
readonly kind: 'missingExpression';
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
export type Expression =
|
|
233
|
+
| NumberLiteral
|
|
234
|
+
| StringLiteral
|
|
235
|
+
| BooleanLiteral
|
|
236
|
+
| ColorLiteral
|
|
237
|
+
| NoneLiteral
|
|
238
|
+
| ArrayLiteral
|
|
239
|
+
| NameReference
|
|
240
|
+
| Grouping
|
|
241
|
+
| Unary
|
|
242
|
+
| Binary
|
|
243
|
+
| Ternary
|
|
244
|
+
| Call
|
|
245
|
+
| Index
|
|
246
|
+
| Member
|
|
247
|
+
| MissingExpression;
|
|
248
|
+
|
|
249
|
+
/** The expression inside however many brackets were written around it. */
|
|
250
|
+
export function withoutGrouping(expression: Expression): Expression {
|
|
251
|
+
let inner = expression;
|
|
252
|
+
while (inner.kind === 'grouping') inner = inner.expression;
|
|
253
|
+
return inner;
|
|
254
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { Positioned } from '../span/index.js';
|
|
2
|
+
import type { Argument, NumberLiteral } from './expressions.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The three lines that describe the file rather than compute anything: the
|
|
6
|
+
* version line, the study or strategy declaration, and the limits line.
|
|
7
|
+
*
|
|
8
|
+
* All three are statements, and the tree lets them appear anywhere a statement
|
|
9
|
+
* appears. The specification calls each one a statement (4, 13.1 and 10.7), and
|
|
10
|
+
* more to the point the errors for putting one in the wrong place are OS1021,
|
|
11
|
+
* OS2007 and OS2008, which name a line and suggest a move. A tree with one slot
|
|
12
|
+
* for the declaration could not hold the second one long enough for OS2008 to
|
|
13
|
+
* say where it was, and a tree that refused a file with no declaration at all
|
|
14
|
+
* would turn OS2007 into a parse failure with nothing else checked.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* `version 1`.
|
|
19
|
+
*
|
|
20
|
+
* `version` is not a reserved word: it is an ordinary identifier to the lexer,
|
|
21
|
+
* recognised here by its position, so that a script written before the word
|
|
22
|
+
* existed keeps compiling (language.md 3.4 and 4.1).
|
|
23
|
+
*/
|
|
24
|
+
export interface VersionLine extends Positioned {
|
|
25
|
+
readonly kind: 'versionLine';
|
|
26
|
+
readonly version: NumberLiteral;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* `study("Name", ...)` or `strategy("Name", ...)`, language.md 13.1.
|
|
31
|
+
*
|
|
32
|
+
* The form is kept as the word that was written rather than as a boolean,
|
|
33
|
+
* because it is what OS2008 and OS7001 quote back to the reader, and because a
|
|
34
|
+
* later version that adds a third form adds a member here rather than a second
|
|
35
|
+
* flag.
|
|
36
|
+
*/
|
|
37
|
+
export interface ScriptDeclaration extends Positioned {
|
|
38
|
+
readonly kind: 'scriptDeclaration';
|
|
39
|
+
readonly form: 'study' | 'strategy';
|
|
40
|
+
readonly args: readonly Argument[];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* `limits(loops = 50_000_000)`, language.md 10.7.
|
|
45
|
+
*
|
|
46
|
+
* Which options exist, that the values are literal numbers, and that the host
|
|
47
|
+
* is willing to run them (OS5003) are all decided later. The tree carries the
|
|
48
|
+
* arguments as written.
|
|
49
|
+
*/
|
|
50
|
+
export interface LimitsLine extends Positioned {
|
|
51
|
+
readonly kind: 'limitsLine';
|
|
52
|
+
readonly args: readonly Argument[];
|
|
53
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The syntax tree of language.md, and the one traversal over it.
|
|
3
|
+
*
|
|
4
|
+
* Types and constructors, and no parsing: the tree is what the parser produces
|
|
5
|
+
* and what the checker, the code generator and the editor's intelligence all
|
|
6
|
+
* read, so it is defined on its own and none of the four owns it.
|
|
7
|
+
*
|
|
8
|
+
* Two things here are worth knowing before reading the rest. Every node carries
|
|
9
|
+
* a `Span`, so anything the compiler says about a node has a caret. And every
|
|
10
|
+
* node is a member of one discriminated union, `AstNode`, so a pass that
|
|
11
|
+
* switches on `kind` without a default arm is told at compile time about the
|
|
12
|
+
* kinds it has not handled.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
export type { Name } from './name.js';
|
|
16
|
+
|
|
17
|
+
export type {
|
|
18
|
+
ArrayType,
|
|
19
|
+
NamedType,
|
|
20
|
+
ObjectTypeName,
|
|
21
|
+
SeriesType,
|
|
22
|
+
TypeAnnotation,
|
|
23
|
+
ValueTypeName,
|
|
24
|
+
} from './annotations.js';
|
|
25
|
+
export {
|
|
26
|
+
OBJECT_TYPE_NAMES,
|
|
27
|
+
VALUE_TYPE_NAMES,
|
|
28
|
+
isObjectTypeName,
|
|
29
|
+
isValueTypeName,
|
|
30
|
+
} from './annotations.js';
|
|
31
|
+
|
|
32
|
+
export type {
|
|
33
|
+
ArithmeticOperator,
|
|
34
|
+
Argument,
|
|
35
|
+
ArrayLiteral,
|
|
36
|
+
Binary,
|
|
37
|
+
BinaryOperator,
|
|
38
|
+
BooleanLiteral,
|
|
39
|
+
Call,
|
|
40
|
+
ColorLiteral,
|
|
41
|
+
ComparisonOperator,
|
|
42
|
+
EqualityOperator,
|
|
43
|
+
Expression,
|
|
44
|
+
Grouping,
|
|
45
|
+
Index,
|
|
46
|
+
LogicalOperator,
|
|
47
|
+
Member,
|
|
48
|
+
MissingExpression,
|
|
49
|
+
NameReference,
|
|
50
|
+
NoneLiteral,
|
|
51
|
+
NumberLiteral,
|
|
52
|
+
StringLiteral,
|
|
53
|
+
Ternary,
|
|
54
|
+
Unary,
|
|
55
|
+
UnaryOperator,
|
|
56
|
+
} from './expressions.js';
|
|
57
|
+
export {
|
|
58
|
+
ARITHMETIC_OPERATORS,
|
|
59
|
+
COMPARISON_OPERATORS,
|
|
60
|
+
EQUALITY_OPERATORS,
|
|
61
|
+
LOGICAL_OPERATORS,
|
|
62
|
+
UNARY_OPERATORS,
|
|
63
|
+
binaryPrecedence,
|
|
64
|
+
withoutGrouping,
|
|
65
|
+
} from './expressions.js';
|
|
66
|
+
|
|
67
|
+
export type { LimitsLine, ScriptDeclaration, VersionLine } from './header.js';
|
|
68
|
+
|
|
69
|
+
export type {
|
|
70
|
+
Assignment,
|
|
71
|
+
AssignmentOperator,
|
|
72
|
+
Block,
|
|
73
|
+
BreakStatement,
|
|
74
|
+
ContinueStatement,
|
|
75
|
+
ElseBranch,
|
|
76
|
+
ExpressionStatement,
|
|
77
|
+
ForInStatement,
|
|
78
|
+
ForRangeStatement,
|
|
79
|
+
IfBranch,
|
|
80
|
+
IfStatement,
|
|
81
|
+
ReturnStatement,
|
|
82
|
+
Statement,
|
|
83
|
+
SwitchCase,
|
|
84
|
+
SwitchDefault,
|
|
85
|
+
SwitchStatement,
|
|
86
|
+
VarDeclaration,
|
|
87
|
+
WhileStatement,
|
|
88
|
+
} from './statements.js';
|
|
89
|
+
export { ASSIGNMENT_OPERATORS } from './statements.js';
|
|
90
|
+
|
|
91
|
+
export type { FunctionDeclaration, Parameter, Script, TopLevelItem } from './script.js';
|
|
92
|
+
|
|
93
|
+
export type { AstNode, NodeKind, NodeOfKind } from './node.js';
|
|
94
|
+
export { isExpression, isStatement, isTypeAnnotation, typeAnnotationText } from './node.js';
|
|
95
|
+
|
|
96
|
+
export type { NodeFields } from './build.js';
|
|
97
|
+
export { makeNode } from './build.js';
|
|
98
|
+
|
|
99
|
+
export { childrenOf } from './children.js';
|
|
100
|
+
|
|
101
|
+
export type { Visit, Visitor } from './walk.js';
|
|
102
|
+
export { nodeAtOffset, pathAtOffset, walk } from './walk.js';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Positioned } from '../span/index.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A name at the place it is written rather than the place it is read.
|
|
5
|
+
*
|
|
6
|
+
* A name used as a value is a `nameReference`, which the checker resolves
|
|
7
|
+
* against a scope. Every other name in the language is this node instead: the
|
|
8
|
+
* left side of an assignment, the name a `var` introduces, a loop variable, a
|
|
9
|
+
* function's name, a parameter's name, the word after a dot, and the label of a
|
|
10
|
+
* named argument.
|
|
11
|
+
*
|
|
12
|
+
* The two are separate kinds because a pass that walks the tree collecting uses
|
|
13
|
+
* of a name must not collect the places that introduce one. With a single kind
|
|
14
|
+
* every such pass has to ask the parent what it is holding, and the pass that
|
|
15
|
+
* forgets reports OS2001 on the very name being declared.
|
|
16
|
+
*
|
|
17
|
+
* The text is not always a legal identifier: a named argument's label may be a
|
|
18
|
+
* reserved word, because a label is matched against a parameter list and is
|
|
19
|
+
* never looked up in a scope (language.md 3.4).
|
|
20
|
+
*/
|
|
21
|
+
export interface Name extends Positioned {
|
|
22
|
+
readonly kind: 'name';
|
|
23
|
+
readonly text: string;
|
|
24
|
+
}
|