2022-09-18 14:33:22 +02:00
|
|
|
import { assert, JSONObject, JSONValue, MultiMap } from "./util";
|
2022-09-15 22:39:20 +02:00
|
|
|
import type { InferContext, Kind, Scheme, Type, TypeEnv } from "./checker"
|
2022-08-28 21:12:25 +02:00
|
|
|
|
|
|
|
export type TextSpan = [number, number];
|
|
|
|
|
2022-09-16 19:43:52 +02:00
|
|
|
export type Value
|
|
|
|
= bigint
|
|
|
|
| string
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
export class TextPosition {
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public offset: number,
|
|
|
|
public line: number,
|
|
|
|
public column: number,
|
|
|
|
) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public clone(): TextPosition {
|
|
|
|
return new TextPosition(
|
|
|
|
this.offset,
|
|
|
|
this.line,
|
|
|
|
this.column,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public advance(text: string): void {
|
|
|
|
for (const ch of text) {
|
|
|
|
if (ch === '\n') {
|
|
|
|
this.line++;
|
|
|
|
this.column = 1;
|
|
|
|
} else {
|
|
|
|
this.column++;
|
|
|
|
}
|
|
|
|
this.offset += text.length;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class TextRange {
|
|
|
|
|
|
|
|
constructor(
|
|
|
|
public start: TextPosition,
|
|
|
|
public end: TextPosition,
|
|
|
|
) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public clone(): TextRange {
|
|
|
|
return new TextRange(
|
|
|
|
this.start.clone(),
|
|
|
|
this.end.clone(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class TextFile {
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public origPath: string,
|
|
|
|
public text: string,
|
|
|
|
) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export const enum SyntaxKind {
|
|
|
|
|
|
|
|
// Tokens
|
|
|
|
Identifier,
|
2022-09-01 20:18:47 +02:00
|
|
|
IdentifierAlt,
|
2022-08-28 21:12:25 +02:00
|
|
|
CustomOperator,
|
2022-09-01 20:06:43 +02:00
|
|
|
Assignment,
|
2022-08-28 21:12:25 +02:00
|
|
|
LParen,
|
|
|
|
RParen,
|
|
|
|
LBrace,
|
|
|
|
RBrace,
|
|
|
|
LBracket,
|
|
|
|
RBracket,
|
2022-09-09 22:37:14 +02:00
|
|
|
RArrow,
|
2022-09-16 11:31:34 +02:00
|
|
|
RArrowAlt,
|
|
|
|
VBar,
|
2022-08-28 21:12:25 +02:00
|
|
|
Dot,
|
|
|
|
DotDot,
|
|
|
|
Comma,
|
|
|
|
Colon,
|
|
|
|
Equals,
|
|
|
|
Integer,
|
|
|
|
StringLiteral,
|
|
|
|
LetKeyword,
|
|
|
|
PubKeyword,
|
|
|
|
MutKeyword,
|
|
|
|
ModKeyword,
|
|
|
|
ImportKeyword,
|
|
|
|
StructKeyword,
|
2022-09-10 14:11:04 +02:00
|
|
|
EnumKeyword,
|
2022-08-28 21:12:25 +02:00
|
|
|
TypeKeyword,
|
2022-08-29 16:17:55 +02:00
|
|
|
ReturnKeyword,
|
|
|
|
MatchKeyword,
|
2022-09-16 19:50:18 +02:00
|
|
|
ForeignKeyword,
|
2022-08-29 16:17:55 +02:00
|
|
|
IfKeyword,
|
|
|
|
ElifKeyword,
|
|
|
|
ElseKeyword,
|
2022-08-28 21:12:25 +02:00
|
|
|
LineFoldEnd,
|
|
|
|
BlockEnd,
|
|
|
|
BlockStart,
|
|
|
|
EndOfFile,
|
|
|
|
|
|
|
|
// Type expressions
|
|
|
|
ReferenceTypeExpression,
|
2022-09-09 22:37:14 +02:00
|
|
|
ArrowTypeExpression,
|
2022-09-10 16:52:14 +02:00
|
|
|
VarTypeExpression,
|
2022-09-11 11:20:21 +02:00
|
|
|
AppTypeExpression,
|
2022-09-14 16:46:30 +02:00
|
|
|
NestedTypeExpression,
|
2022-09-16 12:43:06 +02:00
|
|
|
TupleTypeExpression,
|
2022-08-28 21:12:25 +02:00
|
|
|
|
|
|
|
// Patterns
|
|
|
|
BindPattern,
|
|
|
|
TuplePattern,
|
2022-08-29 16:17:55 +02:00
|
|
|
StructPattern,
|
|
|
|
NestedPattern,
|
|
|
|
NamedTuplePattern,
|
2022-09-16 11:31:34 +02:00
|
|
|
LiteralPattern,
|
|
|
|
DisjunctivePattern,
|
2022-08-29 16:17:55 +02:00
|
|
|
|
2022-09-01 20:06:43 +02:00
|
|
|
// Struct expression elements
|
|
|
|
StructExpressionField,
|
|
|
|
PunnedStructExpressionField,
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
// Struct pattern elements
|
2022-09-01 20:06:43 +02:00
|
|
|
StructPatternField,
|
|
|
|
PunnedStructPatternField,
|
2022-08-29 16:17:55 +02:00
|
|
|
VariadicStructPatternElement,
|
2022-08-28 21:12:25 +02:00
|
|
|
|
|
|
|
// Expressions
|
2022-09-16 11:31:34 +02:00
|
|
|
MatchExpression,
|
2022-09-09 00:00:28 +02:00
|
|
|
MemberExpression,
|
2022-08-31 13:29:56 +02:00
|
|
|
CallExpression,
|
2022-08-28 21:12:25 +02:00
|
|
|
ReferenceExpression,
|
2022-08-31 13:29:56 +02:00
|
|
|
StructExpression,
|
2022-08-28 21:12:25 +02:00
|
|
|
TupleExpression,
|
|
|
|
NestedExpression,
|
|
|
|
ConstantExpression,
|
|
|
|
PrefixExpression,
|
|
|
|
PostfixExpression,
|
|
|
|
InfixExpression,
|
|
|
|
|
|
|
|
// Statements
|
|
|
|
ReturnStatement,
|
|
|
|
ExpressionStatement,
|
2022-09-01 20:06:43 +02:00
|
|
|
IfStatement,
|
2022-08-28 21:12:25 +02:00
|
|
|
|
2022-09-09 22:37:14 +02:00
|
|
|
// If statement elements
|
|
|
|
IfStatementCase,
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
// Declarations
|
|
|
|
LetDeclaration,
|
|
|
|
StructDeclaration,
|
2022-09-10 14:11:04 +02:00
|
|
|
EnumDeclaration,
|
2022-08-28 21:12:25 +02:00
|
|
|
ImportDeclaration,
|
2022-09-11 11:20:21 +02:00
|
|
|
TypeDeclaration,
|
2022-08-28 21:12:25 +02:00
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
// Let declaration body members
|
2022-08-28 21:12:25 +02:00
|
|
|
ExprBody,
|
|
|
|
BlockBody,
|
2022-08-29 16:17:55 +02:00
|
|
|
|
|
|
|
// Structure declaration members
|
|
|
|
StructDeclarationField,
|
|
|
|
|
2022-09-10 14:11:04 +02:00
|
|
|
// Enum declaration elements
|
|
|
|
EnumDeclarationStructElement,
|
|
|
|
EnumDeclarationTupleElement,
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
// Other nodes
|
2022-09-09 22:37:14 +02:00
|
|
|
WrappedOperator,
|
2022-09-16 11:31:34 +02:00
|
|
|
MatchArm,
|
2022-08-29 16:17:55 +02:00
|
|
|
Initializer,
|
2022-08-28 21:12:25 +02:00
|
|
|
TypeAssert,
|
|
|
|
Param,
|
2022-09-17 13:20:49 +02:00
|
|
|
ModuleDeclaration,
|
2022-08-28 21:12:25 +02:00
|
|
|
SourceFile,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export type Syntax
|
|
|
|
= SourceFile
|
2022-09-17 13:20:49 +02:00
|
|
|
| ModuleDeclaration
|
2022-08-31 13:29:56 +02:00
|
|
|
| Token
|
2022-08-28 21:12:25 +02:00
|
|
|
| Param
|
2022-08-31 13:29:56 +02:00
|
|
|
| Body
|
2022-08-28 21:12:25 +02:00
|
|
|
| StructDeclarationField
|
2022-09-11 11:20:21 +02:00
|
|
|
| EnumDeclarationElement
|
2022-09-05 17:25:55 +02:00
|
|
|
| TypeAssert
|
2022-08-28 21:12:25 +02:00
|
|
|
| Declaration
|
|
|
|
| Statement
|
|
|
|
| Expression
|
|
|
|
| TypeExpression
|
|
|
|
| Pattern
|
2022-09-07 12:45:38 +02:00
|
|
|
| StructExpressionElement
|
|
|
|
| StructPatternElement
|
2022-08-28 21:12:25 +02:00
|
|
|
|
2022-08-31 13:29:56 +02:00
|
|
|
function isIgnoredProperty(key: string): boolean {
|
|
|
|
return key === 'kind' || key === 'parent';
|
|
|
|
}
|
|
|
|
|
2022-09-01 20:06:43 +02:00
|
|
|
type NodeWithScope
|
|
|
|
= SourceFile
|
|
|
|
| LetDeclaration
|
|
|
|
|
|
|
|
function isNodeWithScope(node: Syntax): node is NodeWithScope {
|
|
|
|
return node.kind === SyntaxKind.SourceFile
|
|
|
|
|| node.kind === SyntaxKind.LetDeclaration;
|
|
|
|
}
|
|
|
|
|
2022-09-11 11:20:21 +02:00
|
|
|
export const enum Symkind {
|
|
|
|
Var = 1,
|
|
|
|
Type = 2,
|
2022-09-17 13:20:49 +02:00
|
|
|
Module = 4,
|
|
|
|
Any = Var | Type | Module
|
2022-09-11 11:20:21 +02:00
|
|
|
}
|
|
|
|
|
2022-09-01 20:06:43 +02:00
|
|
|
export class Scope {
|
|
|
|
|
2022-09-15 11:49:53 +02:00
|
|
|
private mapping = new MultiMap<string, [Symkind, Syntax]>();
|
2022-09-01 20:06:43 +02:00
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public node: NodeWithScope,
|
|
|
|
) {
|
|
|
|
this.scan(node);
|
|
|
|
}
|
|
|
|
|
2022-09-15 16:04:49 +02:00
|
|
|
public get depth(): number {
|
|
|
|
let out = 0;
|
|
|
|
let curr = this.getParent();
|
|
|
|
while (curr !== null) {
|
|
|
|
out++;
|
|
|
|
curr = curr.getParent();
|
|
|
|
}
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
2022-09-01 20:06:43 +02:00
|
|
|
private getParent(): Scope | null {
|
|
|
|
let curr = this.node.parent;
|
|
|
|
while (curr !== null) {
|
|
|
|
if (isNodeWithScope(curr)) {
|
|
|
|
return curr.getScope();
|
|
|
|
}
|
2022-09-01 20:18:47 +02:00
|
|
|
curr = curr.parent;
|
2022-09-01 20:06:43 +02:00
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2022-09-11 11:20:21 +02:00
|
|
|
private add(name: string, node: Syntax, kind: Symkind): void {
|
2022-09-15 11:49:53 +02:00
|
|
|
this.mapping.add(name, [kind, node]);
|
2022-09-11 11:20:21 +02:00
|
|
|
}
|
|
|
|
|
2022-09-01 20:06:43 +02:00
|
|
|
private scan(node: Syntax): void {
|
|
|
|
switch (node.kind) {
|
|
|
|
case SyntaxKind.SourceFile:
|
|
|
|
{
|
|
|
|
for (const element of node.elements) {
|
|
|
|
this.scan(element);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2022-09-17 13:20:49 +02:00
|
|
|
case SyntaxKind.ModuleDeclaration:
|
|
|
|
{
|
|
|
|
this.add(node.name.text, node, Symkind.Module);
|
|
|
|
for (const element of node.elements) {
|
|
|
|
this.scan(element);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2022-09-01 20:06:43 +02:00
|
|
|
case SyntaxKind.ExpressionStatement:
|
|
|
|
case SyntaxKind.ReturnStatement:
|
2022-09-06 15:17:27 +02:00
|
|
|
case SyntaxKind.IfStatement:
|
2022-09-01 20:06:43 +02:00
|
|
|
break;
|
2022-09-11 11:20:21 +02:00
|
|
|
case SyntaxKind.TypeDeclaration:
|
|
|
|
{
|
|
|
|
this.add(node.name.text, node, Symkind.Type);
|
|
|
|
break;
|
|
|
|
}
|
2022-09-10 16:52:14 +02:00
|
|
|
case SyntaxKind.EnumDeclaration:
|
2022-09-14 16:46:30 +02:00
|
|
|
{
|
|
|
|
this.add(node.name.text, node, Symkind.Type);
|
|
|
|
if (node.members !== null) {
|
|
|
|
for (const member of node.members) {
|
2022-09-15 11:49:53 +02:00
|
|
|
this.add(member.name.text, member, Symkind.Var);
|
2022-09-14 16:46:30 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-09-07 12:45:38 +02:00
|
|
|
case SyntaxKind.StructDeclaration:
|
2022-09-11 11:20:21 +02:00
|
|
|
{
|
2022-09-15 11:49:53 +02:00
|
|
|
this.add(node.name.text, node, Symkind.Type);
|
|
|
|
this.add(node.name.text, node, Symkind.Var);
|
2022-09-07 12:45:38 +02:00
|
|
|
break;
|
2022-09-11 11:20:21 +02:00
|
|
|
}
|
2022-09-01 20:06:43 +02:00
|
|
|
case SyntaxKind.LetDeclaration:
|
|
|
|
{
|
|
|
|
for (const param of node.params) {
|
|
|
|
this.scanPattern(param.pattern, param);
|
|
|
|
}
|
2022-09-05 19:33:08 +02:00
|
|
|
if (node === this.node) {
|
|
|
|
if (node.body !== null && node.body.kind === SyntaxKind.BlockBody) {
|
|
|
|
for (const element of node.body.elements) {
|
|
|
|
this.scan(element);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2022-09-09 22:37:14 +02:00
|
|
|
if (node.pattern.kind === SyntaxKind.WrappedOperator) {
|
2022-09-11 11:20:21 +02:00
|
|
|
this.add(node.pattern.operator.text, node, Symkind.Var);
|
2022-09-09 22:37:14 +02:00
|
|
|
} else {
|
|
|
|
this.scanPattern(node.pattern, node);
|
|
|
|
}
|
2022-09-01 20:06:43 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
throw new Error(`Unexpected ${node.constructor.name}`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private scanPattern(node: Pattern, decl: Syntax): void {
|
|
|
|
switch (node.kind) {
|
|
|
|
case SyntaxKind.BindPattern:
|
|
|
|
{
|
2022-09-11 11:20:21 +02:00
|
|
|
this.add(node.name.text, decl, Symkind.Var);
|
2022-09-01 20:06:43 +02:00
|
|
|
break;
|
|
|
|
}
|
2022-09-07 12:45:38 +02:00
|
|
|
case SyntaxKind.StructPattern:
|
|
|
|
{
|
|
|
|
for (const member of node.members) {
|
|
|
|
switch (member.kind) {
|
|
|
|
case SyntaxKind.StructPatternField:
|
|
|
|
{
|
|
|
|
this.scanPattern(member.pattern, decl);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case SyntaxKind.PunnedStructPatternField:
|
|
|
|
{
|
2022-09-11 11:20:21 +02:00
|
|
|
this.add(node.name.text, decl, Symkind.Var);
|
2022-09-07 12:45:38 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2022-09-01 20:06:43 +02:00
|
|
|
default:
|
|
|
|
throw new Error(`Unexpected ${node}`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-15 11:49:53 +02:00
|
|
|
public lookup(name: string, expectedKind: Symkind = Symkind.Any): Syntax | null {
|
2022-09-01 20:06:43 +02:00
|
|
|
let curr: Scope | null = this;
|
|
|
|
do {
|
2022-09-15 11:49:53 +02:00
|
|
|
for (const [kind, decl] of curr.mapping.get(name)) {
|
2022-09-11 11:20:21 +02:00
|
|
|
if (kind & expectedKind) {
|
|
|
|
return decl;
|
|
|
|
}
|
2022-09-01 20:06:43 +02:00
|
|
|
}
|
|
|
|
curr = curr.getParent();
|
|
|
|
} while (curr !== null);
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
abstract class SyntaxBase {
|
|
|
|
|
2022-08-31 13:29:56 +02:00
|
|
|
public parent: Syntax | null = null;
|
|
|
|
|
2022-09-15 22:39:20 +02:00
|
|
|
public inferredKind?: Kind;
|
|
|
|
public inferredType?: Type;
|
2022-08-28 21:12:25 +02:00
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public abstract getFirstToken(): Token;
|
|
|
|
|
|
|
|
public abstract getLastToken(): Token;
|
|
|
|
|
2022-08-31 13:29:56 +02:00
|
|
|
public getRange(): TextRange {
|
|
|
|
return new TextRange(
|
|
|
|
this.getFirstToken().getStartPosition(),
|
|
|
|
this.getLastToken().getEndPosition(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public getSourceFile(): SourceFile {
|
|
|
|
let curr = this as any;
|
|
|
|
do {
|
|
|
|
if (curr.kind === SyntaxKind.SourceFile) {
|
|
|
|
return curr;
|
|
|
|
}
|
|
|
|
curr = curr.parent;
|
|
|
|
} while (curr != null);
|
|
|
|
throw new Error(`Could not find a SourceFile in any of the parent nodes of ${this}`);
|
|
|
|
}
|
|
|
|
|
2022-09-01 20:06:43 +02:00
|
|
|
public getScope(): Scope {
|
|
|
|
let curr: Syntax | null = this as any;
|
|
|
|
do {
|
|
|
|
if (isNodeWithScope(curr!)) {
|
|
|
|
if (curr.scope === undefined) {
|
|
|
|
curr.scope = new Scope(curr);
|
|
|
|
}
|
|
|
|
return curr.scope;
|
|
|
|
}
|
|
|
|
curr = curr!.parent;
|
|
|
|
} while (curr !== null);
|
|
|
|
throw new Error(`Could not find a scope for ${this}. Maybe the parent links are not set?`);
|
|
|
|
}
|
|
|
|
|
2022-09-18 14:33:22 +02:00
|
|
|
public getEnclosingModule(): ModuleDeclaration | SourceFile {
|
|
|
|
let curr = this.parent!;
|
|
|
|
while (curr !== null) {
|
|
|
|
if (curr.kind === SyntaxKind.SourceFile || curr.kind === SyntaxKind.ModuleDeclaration) {
|
|
|
|
return curr;
|
|
|
|
}
|
|
|
|
curr = curr.parent!;
|
|
|
|
}
|
|
|
|
throw new Error(`Unable to find an enclosing module for ${this.constructor.name}. Perhaps the parent-links are not set?`);
|
|
|
|
}
|
|
|
|
|
2022-08-31 13:29:56 +02:00
|
|
|
public setParents(): void {
|
|
|
|
|
|
|
|
const visit = (value: any) => {
|
|
|
|
if (value === null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (Array.isArray(value)) {
|
|
|
|
value.forEach(visit);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (value instanceof SyntaxBase) {
|
|
|
|
value.parent = this as any;
|
|
|
|
value.setParents();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const key of Object.getOwnPropertyNames(this)) {
|
|
|
|
if (isIgnoredProperty(key)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
visit((this as any)[key]);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public toJSON(): JSONObject {
|
|
|
|
|
|
|
|
const obj: JSONObject = {};
|
|
|
|
|
|
|
|
obj['type'] = this.constructor.name;
|
|
|
|
|
|
|
|
for (const key of Object.getOwnPropertyNames(this)) {
|
2022-08-31 13:29:56 +02:00
|
|
|
if (isIgnoredProperty(key)) {
|
2022-08-29 16:17:55 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
obj[key] = encode((this as any)[key]);
|
|
|
|
}
|
|
|
|
|
|
|
|
return obj;
|
|
|
|
|
|
|
|
function encode(value: any): JSONValue {
|
|
|
|
if (value === null) {
|
|
|
|
return null;
|
|
|
|
} else if (Array.isArray(value)) {
|
|
|
|
return value.map(encode);
|
|
|
|
} else if (value instanceof SyntaxBase) {
|
|
|
|
return value.toJSON();
|
|
|
|
} else {
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-09-18 14:33:22 +02:00
|
|
|
public resolveModule(name: string): ModuleDeclaration | null {
|
|
|
|
const node = this as unknown as Syntax;
|
|
|
|
assert(node.kind === SyntaxKind.ModuleDeclaration || node.kind === SyntaxKind.SourceFile);
|
|
|
|
for (const element of node.elements) {
|
|
|
|
if (element.kind === SyntaxKind.ModuleDeclaration && element.name.text === name) {
|
|
|
|
return element;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getModulePath(): string[] {
|
|
|
|
let curr = this.parent;
|
|
|
|
const modulePath = [];
|
|
|
|
while (curr !== null) {
|
|
|
|
if (curr.kind === SyntaxKind.ModuleDeclaration) {
|
|
|
|
modulePath.unshift(curr.name.text);
|
|
|
|
}
|
|
|
|
curr = curr.parent;
|
|
|
|
}
|
|
|
|
return modulePath;
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
2022-09-10 16:52:14 +02:00
|
|
|
export function forEachChild(node: Syntax, callback: (node: Syntax) => void): void {
|
|
|
|
|
|
|
|
for (const key of Object.getOwnPropertyNames(node)) {
|
|
|
|
if (isIgnoredProperty(key)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
visitField((node as any)[key]);
|
|
|
|
}
|
|
|
|
|
|
|
|
function visitField(field: any): void {
|
|
|
|
if (field === null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (Array.isArray(field)) {
|
|
|
|
for (const element of field) {
|
|
|
|
visitField(element);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (field instanceof SyntaxBase) {
|
|
|
|
callback(field as Syntax);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
abstract class TokenBase extends SyntaxBase {
|
|
|
|
|
|
|
|
private endPos: TextPosition | null = null;
|
|
|
|
|
2022-08-31 13:29:56 +02:00
|
|
|
public constructor(
|
2022-08-28 21:12:25 +02:00
|
|
|
private startPos: TextPosition,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
throw new Error(`Trying to get the first token of an object that is a token itself.`);
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
throw new Error(`Trying to get the last token of an object that is a token itself.`);
|
|
|
|
}
|
|
|
|
|
2022-08-31 13:29:56 +02:00
|
|
|
public getRange(): TextRange {
|
|
|
|
return new TextRange(
|
|
|
|
this.getStartPosition(),
|
|
|
|
this.getEndPosition(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
public getStartPosition(): TextPosition {
|
|
|
|
return this.startPos;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getStartLine(): number {
|
|
|
|
return this.getStartPosition().line;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getStartColumn(): number {
|
|
|
|
return this.getStartPosition().column;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getEndPosition(): TextPosition {
|
|
|
|
if (this.endPos === null) {
|
|
|
|
const endPos = this.getStartPosition().clone();
|
|
|
|
endPos.advance(this.text);
|
|
|
|
return this.endPos = endPos;
|
|
|
|
}
|
|
|
|
return this.endPos;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getEndLine(): number {
|
|
|
|
return this.getEndPosition().line;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getEndColumn(): number {
|
|
|
|
return this.getEndPosition().column;
|
|
|
|
}
|
|
|
|
|
|
|
|
public abstract readonly text: string;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
abstract class VirtualTokenBase extends TokenBase {
|
|
|
|
public get text(): string {
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export class EndOfFile extends VirtualTokenBase {
|
|
|
|
public readonly kind = SyntaxKind.EndOfFile;
|
|
|
|
}
|
|
|
|
|
|
|
|
export class BlockEnd extends VirtualTokenBase {
|
|
|
|
public readonly kind = SyntaxKind.BlockEnd;
|
|
|
|
}
|
|
|
|
|
|
|
|
export class BlockStart extends VirtualTokenBase {
|
|
|
|
public readonly kind = SyntaxKind.BlockStart;
|
|
|
|
}
|
|
|
|
|
|
|
|
export class LineFoldEnd extends VirtualTokenBase {
|
|
|
|
public readonly kind = SyntaxKind.LineFoldEnd;
|
|
|
|
}
|
|
|
|
|
|
|
|
export class Integer extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.Integer;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public value: bigint,
|
|
|
|
public radix: number,
|
2022-08-29 16:17:55 +02:00
|
|
|
startPos: TextPosition,
|
2022-08-28 21:12:25 +02:00
|
|
|
) {
|
|
|
|
super(startPos);
|
|
|
|
}
|
|
|
|
|
2022-09-16 19:43:52 +02:00
|
|
|
public getValue(): Value {
|
|
|
|
return this.value;
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
public get text(): string {
|
|
|
|
switch (this.radix) {
|
|
|
|
case 16:
|
|
|
|
return '0x' + this.value.toString(16);
|
|
|
|
case 10:
|
|
|
|
return this.value.toString(10)
|
|
|
|
case 8:
|
|
|
|
return '0o' + this.value.toString(8)
|
|
|
|
case 2:
|
|
|
|
return '0b' + this.value.toString(2);
|
|
|
|
default:
|
|
|
|
throw new Error(`Radix ${this.radix} of Integer not recognised.`)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class StringLiteral extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.StringLiteral;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public contents: string,
|
2022-08-29 16:17:55 +02:00
|
|
|
startPos: TextPosition,
|
2022-08-28 21:12:25 +02:00
|
|
|
) {
|
|
|
|
super(startPos);
|
|
|
|
}
|
|
|
|
|
2022-09-16 19:43:52 +02:00
|
|
|
public getValue(): Value {
|
|
|
|
return this.contents;
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
public get text(): string {
|
|
|
|
let out = '"';
|
|
|
|
for (const ch of this.contents) {
|
|
|
|
const code = ch.charCodeAt(0);
|
|
|
|
if (code >= 32 && code <= 127) {
|
|
|
|
out += ch;
|
|
|
|
} else if (code <= 127) {
|
|
|
|
out += '\\x' + code.toString(16).padStart(2, '0');
|
|
|
|
} else {
|
|
|
|
out += '\\u' + code.toString(17).padStart(4, '0');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
out += '"';
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-09-01 20:18:47 +02:00
|
|
|
export class IdentifierAlt extends TokenBase {
|
2022-08-29 16:17:55 +02:00
|
|
|
|
2022-09-01 20:18:47 +02:00
|
|
|
public readonly kind = SyntaxKind.IdentifierAlt;
|
2022-08-29 16:17:55 +02:00
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public text: string,
|
|
|
|
startPos: TextPosition,
|
|
|
|
) {
|
|
|
|
super(startPos);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
export class Identifier extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.Identifier;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public text: string,
|
2022-08-29 16:17:55 +02:00
|
|
|
startPos: TextPosition,
|
2022-08-28 21:12:25 +02:00
|
|
|
) {
|
|
|
|
super(startPos);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class CustomOperator extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.CustomOperator;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public text: string,
|
2022-08-29 16:17:55 +02:00
|
|
|
startPos: TextPosition,
|
2022-08-28 21:12:25 +02:00
|
|
|
) {
|
|
|
|
super(startPos);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-09-18 14:33:22 +02:00
|
|
|
export type ExprOperator
|
|
|
|
= CustomOperator
|
|
|
|
| VBar
|
|
|
|
|
|
|
|
export function isExprOperator(node: Syntax): node is ExprOperator {
|
|
|
|
return node.kind === SyntaxKind.CustomOperator
|
|
|
|
|| node.kind === SyntaxKind.VBar
|
|
|
|
}
|
|
|
|
|
2022-09-01 20:06:43 +02:00
|
|
|
export class Assignment extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.Assignment;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public text: string,
|
|
|
|
startPos: TextPosition,
|
|
|
|
) {
|
|
|
|
super(startPos);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
export class LParen extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.LParen;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return '(';
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class RParen extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.RParen;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return ')';
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class LBrace extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.LBrace;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return '{';
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class RBrace extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.RBrace;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return '}';
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class LBracket extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.LBracket;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return '[';
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class RBracket extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.RBracket;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return ']';
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class Dot extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.Dot;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return '.';
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class Comma extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.Comma;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return ',';
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class DotDot extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.DotDot;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return '..';
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class Colon extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.Colon;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return ':';
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class Equals extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.Equals;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return '=';
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-09-01 20:06:43 +02:00
|
|
|
export class IfKeyword extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.IfKeyword;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return 'if';
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class ElseKeyword extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.ElseKeyword;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return 'else';
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class ElifKeyword extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.ElifKeyword;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return 'elif';
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
export class StructKeyword extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.StructKeyword;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return 'struct';
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-09-10 14:11:04 +02:00
|
|
|
export class EnumKeyword extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.EnumKeyword;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return 'enum';
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
export class ReturnKeyword extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.ReturnKeyword;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return 'return';
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class MatchKeyword extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.MatchKeyword;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return 'match';
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-09-16 19:50:18 +02:00
|
|
|
export class ForeignKeyword extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.ForeignKeyword;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return 'foreign';
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
export class ModKeyword extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.ModKeyword;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return 'mod';
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class MutKeyword extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.MutKeyword;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return 'mut';
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class ImportKeyword extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.ImportKeyword;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return 'import'
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class TypeKeyword extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.TypeKeyword;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return 'type';
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class PubKeyword extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.PubKeyword;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return 'pub';
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class LetKeyword extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.LetKeyword;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return 'let';
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-09-09 22:37:14 +02:00
|
|
|
export class RArrow extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.RArrow;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return '->';
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-09-16 11:31:34 +02:00
|
|
|
export class RArrowAlt extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.RArrowAlt;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return '=>';
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class VBar extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.VBar;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return '|';
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
export type Token
|
2022-09-09 22:37:14 +02:00
|
|
|
= RArrow
|
2022-09-16 11:31:34 +02:00
|
|
|
| RArrowAlt
|
|
|
|
| VBar
|
2022-09-09 22:37:14 +02:00
|
|
|
| LParen
|
2022-08-28 21:12:25 +02:00
|
|
|
| RParen
|
|
|
|
| LBrace
|
|
|
|
| RBrace
|
|
|
|
| LBracket
|
|
|
|
| RBracket
|
|
|
|
| Identifier
|
2022-09-01 20:18:47 +02:00
|
|
|
| IdentifierAlt
|
2022-08-28 21:12:25 +02:00
|
|
|
| CustomOperator
|
|
|
|
| Integer
|
|
|
|
| StringLiteral
|
|
|
|
| Comma
|
|
|
|
| Dot
|
|
|
|
| DotDot
|
|
|
|
| Colon
|
|
|
|
| Equals
|
|
|
|
| LetKeyword
|
|
|
|
| PubKeyword
|
|
|
|
| MutKeyword
|
|
|
|
| ModKeyword
|
|
|
|
| ImportKeyword
|
|
|
|
| TypeKeyword
|
|
|
|
| StructKeyword
|
2022-08-29 16:17:55 +02:00
|
|
|
| ReturnKeyword
|
|
|
|
| MatchKeyword
|
2022-08-28 21:12:25 +02:00
|
|
|
| EndOfFile
|
|
|
|
| BlockStart
|
|
|
|
| BlockEnd
|
|
|
|
| LineFoldEnd
|
2022-09-01 20:06:43 +02:00
|
|
|
| Assignment
|
|
|
|
| IfKeyword
|
|
|
|
| ElseKeyword
|
|
|
|
| ElifKeyword
|
2022-09-10 14:11:04 +02:00
|
|
|
| EnumKeyword
|
2022-09-16 19:50:18 +02:00
|
|
|
| ForeignKeyword
|
2022-08-28 21:12:25 +02:00
|
|
|
|
|
|
|
export type TokenKind
|
|
|
|
= Token['kind']
|
|
|
|
|
2022-09-09 22:37:14 +02:00
|
|
|
export class ArrowTypeExpression extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.ArrowTypeExpression;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public paramTypeExprs: TypeExpression[],
|
|
|
|
public returnTypeExpr: TypeExpression
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getFirstToken(): Token {
|
|
|
|
if (this.paramTypeExprs.length > 0) {
|
|
|
|
return this.paramTypeExprs[0].getFirstToken();
|
|
|
|
}
|
|
|
|
return this.returnTypeExpr.getFirstToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.returnTypeExpr.getLastToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-09-16 12:43:06 +02:00
|
|
|
export class TupleTypeExpression extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.TupleTypeExpression;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public lparen: LParen,
|
|
|
|
public elements: TypeExpression[],
|
|
|
|
public rparen: RParen,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.lparen;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.rparen;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
export class ReferenceTypeExpression extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.ReferenceTypeExpression;
|
|
|
|
|
|
|
|
public constructor(
|
2022-09-17 16:31:05 +02:00
|
|
|
public modulePath: Array<[IdentifierAlt, Dot]>,
|
2022-09-01 20:18:47 +02:00
|
|
|
public name: IdentifierAlt,
|
2022-08-28 21:12:25 +02:00
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
if (this.modulePath.length > 0) {
|
|
|
|
return this.modulePath[0][0];
|
|
|
|
}
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
2022-09-11 11:20:21 +02:00
|
|
|
export class AppTypeExpression extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.AppTypeExpression;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public operator: TypeExpression,
|
|
|
|
public args: TypeExpression[],
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.operator.getFirstToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
if (this.args.length > 0) {
|
|
|
|
return this.args[this.args.length-1].getLastToken();
|
|
|
|
}
|
|
|
|
return this.operator.getLastToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-09-10 16:52:14 +02:00
|
|
|
export class VarTypeExpression extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.VarTypeExpression;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public name: Identifier
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-09-14 16:46:30 +02:00
|
|
|
export class NestedTypeExpression extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.NestedTypeExpression;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public lparen: LParen,
|
|
|
|
public typeExpr: TypeExpression,
|
|
|
|
public rparen: RParen,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.lparen;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.rparen;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
export type TypeExpression
|
|
|
|
= ReferenceTypeExpression
|
2022-09-09 22:37:14 +02:00
|
|
|
| ArrowTypeExpression
|
2022-09-10 16:52:14 +02:00
|
|
|
| VarTypeExpression
|
2022-09-11 11:20:21 +02:00
|
|
|
| AppTypeExpression
|
2022-09-14 16:46:30 +02:00
|
|
|
| NestedTypeExpression
|
2022-09-16 12:43:06 +02:00
|
|
|
| TupleTypeExpression
|
2022-08-28 21:12:25 +02:00
|
|
|
|
|
|
|
export class BindPattern extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.BindPattern;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public name: Identifier,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
|
|
|
public get isHole(): boolean {
|
|
|
|
return this.name.text == '_';
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class TuplePattern extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.TuplePattern;
|
|
|
|
|
|
|
|
public constructor(
|
2022-08-29 16:17:55 +02:00
|
|
|
public lparen: LParen,
|
2022-08-28 21:12:25 +02:00
|
|
|
public elements: Pattern[],
|
2022-08-29 16:17:55 +02:00
|
|
|
public rparen: RParen,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.lparen;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.rparen;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class NamedTuplePattern extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.NamedTuplePattern;
|
|
|
|
|
|
|
|
public constructor(
|
2022-09-01 20:18:47 +02:00
|
|
|
public name: IdentifierAlt,
|
2022-08-29 16:17:55 +02:00
|
|
|
public elements: Pattern[],
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
if (this.elements.length > 0) {
|
|
|
|
return this.elements[this.elements.length-1].getLastToken();
|
|
|
|
}
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-09-01 20:06:43 +02:00
|
|
|
export class StructPatternField extends SyntaxBase {
|
2022-08-29 16:17:55 +02:00
|
|
|
|
2022-09-01 20:06:43 +02:00
|
|
|
public readonly kind = SyntaxKind.StructPatternField;
|
2022-08-29 16:17:55 +02:00
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public name: Identifier,
|
|
|
|
public equals: Equals,
|
|
|
|
public pattern: Pattern,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.pattern.getLastToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class VariadicStructPatternElement extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.VariadicStructPatternElement;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public dotdot: DotDot,
|
|
|
|
public pattern: Pattern | null,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.dotdot;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
if (this.pattern !== null) {
|
|
|
|
return this.pattern.getLastToken();
|
|
|
|
}
|
|
|
|
return this.dotdot;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-09-01 20:06:43 +02:00
|
|
|
export class PunnedStructPatternField extends SyntaxBase {
|
2022-08-29 16:17:55 +02:00
|
|
|
|
2022-09-01 20:06:43 +02:00
|
|
|
public readonly kind = SyntaxKind.PunnedStructPatternField;
|
2022-08-29 16:17:55 +02:00
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public name: Identifier,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export type StructPatternElement
|
|
|
|
= VariadicStructPatternElement
|
2022-09-01 20:06:43 +02:00
|
|
|
| PunnedStructPatternField
|
|
|
|
| StructPatternField
|
2022-08-29 16:17:55 +02:00
|
|
|
|
|
|
|
export class StructPattern extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.StructPattern;
|
|
|
|
|
|
|
|
public constructor(
|
2022-09-01 20:18:47 +02:00
|
|
|
public name: IdentifierAlt,
|
2022-08-29 16:17:55 +02:00
|
|
|
public lbrace: LBrace,
|
2022-09-07 12:45:38 +02:00
|
|
|
public members: StructPatternElement[],
|
2022-08-29 16:17:55 +02:00
|
|
|
public rbrace: RBrace,
|
2022-08-28 21:12:25 +02:00
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.rbrace;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class NestedPattern extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.NestedPattern;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public lparen: LParen,
|
|
|
|
public pattern: Pattern,
|
|
|
|
public rparen: RParen,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.lparen;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.rparen;
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
2022-09-16 11:31:34 +02:00
|
|
|
export class DisjunctivePattern extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.DisjunctivePattern;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public left: Pattern,
|
|
|
|
public operator: VBar,
|
|
|
|
public right: Pattern,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.left.getFirstToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.right.getLastToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export class LiteralPattern extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.LiteralPattern;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public token: StringLiteral | Integer
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.token;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.token;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
export type Pattern
|
|
|
|
= BindPattern
|
2022-08-29 16:17:55 +02:00
|
|
|
| NestedPattern
|
|
|
|
| StructPattern
|
|
|
|
| NamedTuplePattern
|
2022-08-28 21:12:25 +02:00
|
|
|
| TuplePattern
|
2022-09-16 11:31:34 +02:00
|
|
|
| DisjunctivePattern
|
|
|
|
| LiteralPattern
|
2022-08-28 21:12:25 +02:00
|
|
|
|
|
|
|
export class TupleExpression extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.TupleExpression;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public lparen: LParen,
|
|
|
|
public elements: Expression[],
|
|
|
|
public rparen: RParen,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.lparen;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.rparen;
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class NestedExpression extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.NestedExpression;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public lparen: LParen,
|
|
|
|
public expression: Expression,
|
|
|
|
public rparen: RParen,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.lparen;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.rparen;
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class ConstantExpression extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.ConstantExpression;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public token: Integer | StringLiteral,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.token;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.token;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-31 13:29:56 +02:00
|
|
|
export class CallExpression extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.CallExpression;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public func: Expression,
|
|
|
|
public args: Expression[],
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.func.getFirstToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
if (this.args.length > 0) {
|
|
|
|
return this.args[this.args.length-1].getLastToken();
|
|
|
|
}
|
|
|
|
return this.func.getLastToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-09-01 20:06:43 +02:00
|
|
|
export class StructExpressionField extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.StructExpressionField;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public name: Identifier,
|
|
|
|
public equals: Equals,
|
|
|
|
public expression: Expression,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.expression.getLastToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class PunnedStructExpressionField extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.PunnedStructExpressionField;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public name: Identifier,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export type StructExpressionElement
|
|
|
|
= StructExpressionField
|
|
|
|
| PunnedStructExpressionField;
|
|
|
|
|
|
|
|
export class StructExpression extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.StructExpression;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public lbrace: LBrace,
|
2022-09-07 12:45:38 +02:00
|
|
|
public members: StructExpressionElement[],
|
2022-09-01 20:06:43 +02:00
|
|
|
public rbrace: RBrace,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getFirstToken(): Token {
|
2022-09-15 20:33:34 +02:00
|
|
|
return this.lbrace;
|
2022-09-01 20:06:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.rbrace;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-09-16 11:31:34 +02:00
|
|
|
export class MatchArm extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.MatchArm;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public pattern: Pattern,
|
|
|
|
public rarrowAlt: RArrowAlt,
|
|
|
|
public expression: Expression,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.pattern.getFirstToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.expression.getLastToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class MatchExpression extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.MatchExpression;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public matchKeyword: MatchKeyword,
|
|
|
|
public expression: Expression | null,
|
|
|
|
public arms: MatchArm[],
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.matchKeyword;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
if (this.arms.length > 0) {
|
|
|
|
return this.arms[this.arms.length-1].getLastToken();
|
|
|
|
}
|
|
|
|
if (this.expression !== null) {
|
|
|
|
return this.expression.getLastToken();
|
|
|
|
}
|
|
|
|
return this.matchKeyword;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
export class ReferenceExpression extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.ReferenceExpression;
|
|
|
|
|
|
|
|
public constructor(
|
2022-09-15 20:33:34 +02:00
|
|
|
public modulePath: Array<[IdentifierAlt, Dot]>,
|
|
|
|
public name: Identifier | IdentifierAlt,
|
2022-08-28 21:12:25 +02:00
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
2022-09-15 20:33:34 +02:00
|
|
|
if (this.modulePath.length > 0) {
|
|
|
|
return this.modulePath[0][0];
|
|
|
|
}
|
|
|
|
return this.name;
|
2022-08-29 16:17:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
2022-09-15 20:33:34 +02:00
|
|
|
return this.name;
|
2022-08-29 16:17:55 +02:00
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
2022-09-09 00:00:28 +02:00
|
|
|
export class MemberExpression extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.MemberExpression;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public expression: Expression,
|
|
|
|
public path: [Dot, Identifier][],
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.expression.getFirstToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.path[this.path.length-1][1];
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
export class PrefixExpression extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.PrefixExpression;
|
|
|
|
|
|
|
|
public constructor(
|
2022-09-18 14:33:22 +02:00
|
|
|
public operator: ExprOperator,
|
2022-08-28 21:12:25 +02:00
|
|
|
public expression: Expression,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.operator;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.expression.getLastToken();
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class PostfixExpression extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.PostfixExpression;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public expression: Expression,
|
2022-09-18 14:33:22 +02:00
|
|
|
public operator: ExprOperator,
|
2022-08-28 21:12:25 +02:00
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.expression.getFirstToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.operator;
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class InfixExpression extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.InfixExpression;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public left: Expression,
|
2022-09-18 14:33:22 +02:00
|
|
|
public operator: ExprOperator,
|
2022-08-28 21:12:25 +02:00
|
|
|
public right: Expression,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.left.getFirstToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.right.getLastToken();
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export type Expression
|
2022-09-09 00:00:28 +02:00
|
|
|
= MemberExpression
|
|
|
|
| CallExpression
|
2022-09-01 20:06:43 +02:00
|
|
|
| StructExpression
|
2022-08-31 13:29:56 +02:00
|
|
|
| ReferenceExpression
|
2022-08-28 21:12:25 +02:00
|
|
|
| ConstantExpression
|
|
|
|
| TupleExpression
|
2022-09-16 11:31:34 +02:00
|
|
|
| MatchExpression
|
2022-08-28 21:12:25 +02:00
|
|
|
| NestedExpression
|
|
|
|
| PrefixExpression
|
|
|
|
| InfixExpression
|
|
|
|
| PostfixExpression
|
|
|
|
|
2022-09-01 20:06:43 +02:00
|
|
|
export class IfStatementCase extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.IfStatementCase;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public keyword: IfKeyword | ElseKeyword | ElifKeyword,
|
|
|
|
public test: Expression | null,
|
|
|
|
public blockStart: BlockStart,
|
|
|
|
public elements: LetBodyElement[],
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.keyword;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
if (this.elements.length > 0) {
|
|
|
|
return this.elements[this.elements.length-1].getLastToken();
|
|
|
|
}
|
|
|
|
return this.blockStart;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class IfStatement extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.IfStatement;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public cases: IfStatementCase[],
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.cases[0].getFirstToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.cases[this.cases.length-1].getLastToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
export class ReturnStatement extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.ReturnStatement;
|
|
|
|
|
|
|
|
public constructor(
|
2022-08-29 16:17:55 +02:00
|
|
|
public returnKeyword: ReturnKeyword,
|
2022-08-31 13:54:22 +02:00
|
|
|
public expression: Expression | null
|
2022-08-28 21:12:25 +02:00
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.returnKeyword;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
if (this.expression !== null) {
|
|
|
|
return this.expression.getLastToken();
|
|
|
|
}
|
|
|
|
return this.returnKeyword;
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class ExpressionStatement extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.ExpressionStatement;
|
|
|
|
|
|
|
|
public constructor(
|
2022-08-29 16:17:55 +02:00
|
|
|
public expression: Expression,
|
2022-08-28 21:12:25 +02:00
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.expression.getFirstToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.expression.getLastToken();
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export type Statement
|
|
|
|
= ReturnStatement
|
|
|
|
| ExpressionStatement
|
2022-09-01 20:06:43 +02:00
|
|
|
| IfStatement
|
2022-08-28 21:12:25 +02:00
|
|
|
|
|
|
|
export class Param extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.Param;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public pattern: Pattern,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.pattern.getFirstToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.pattern.getLastToken();
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
2022-09-10 14:11:04 +02:00
|
|
|
export class EnumDeclarationStructElement extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.EnumDeclarationStructElement;
|
|
|
|
|
2022-09-15 16:56:02 +02:00
|
|
|
public scheme?: Scheme;
|
|
|
|
|
2022-09-10 14:11:04 +02:00
|
|
|
public constructor(
|
|
|
|
public name: IdentifierAlt,
|
|
|
|
public blockStart: BlockStart,
|
2022-09-15 20:33:34 +02:00
|
|
|
public fields: StructDeclarationField[],
|
2022-09-10 14:11:04 +02:00
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
2022-09-15 20:33:34 +02:00
|
|
|
if (this.fields.length > 0) {
|
|
|
|
return this.fields[this.fields.length-1].getLastToken();
|
2022-09-10 14:11:04 +02:00
|
|
|
}
|
|
|
|
return this.blockStart;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class EnumDeclarationTupleElement extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.EnumDeclarationTupleElement;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public name: IdentifierAlt,
|
|
|
|
public elements: TypeExpression[],
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
if (this.elements.length > 0) {
|
|
|
|
return this.elements[this.elements.length-1].getLastToken();
|
|
|
|
}
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export type EnumDeclarationElement
|
|
|
|
= EnumDeclarationStructElement
|
|
|
|
| EnumDeclarationTupleElement
|
|
|
|
|
|
|
|
export class EnumDeclaration extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.EnumDeclaration;
|
|
|
|
|
2022-09-14 22:34:53 +02:00
|
|
|
public typeEnv?: TypeEnv;
|
|
|
|
|
2022-09-10 14:11:04 +02:00
|
|
|
public constructor(
|
|
|
|
public pubKeyword: PubKeyword | null,
|
|
|
|
public enumKeyword: EnumKeyword,
|
|
|
|
public name: IdentifierAlt,
|
2022-09-14 16:46:30 +02:00
|
|
|
public varExps: Identifier[],
|
2022-09-10 14:11:04 +02:00
|
|
|
public members: EnumDeclarationElement[] | null,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getFirstToken(): Token {
|
|
|
|
if (this.pubKeyword !== null) {
|
|
|
|
return this.pubKeyword;
|
|
|
|
}
|
|
|
|
return this.enumKeyword;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
if (this.members !== null && this.members.length > 0) {
|
|
|
|
return this.members[this.members.length-1].getLastToken();
|
|
|
|
}
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
export class StructDeclarationField extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.StructDeclarationField;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public name: Identifier,
|
|
|
|
public colon: Colon,
|
|
|
|
public typeExpr: TypeExpression,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.typeExpr.getLastToken();
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class StructDeclaration extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.StructDeclaration;
|
|
|
|
|
2022-09-14 22:34:53 +02:00
|
|
|
public typeEnv?: TypeEnv;
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
public constructor(
|
2022-09-10 14:11:04 +02:00
|
|
|
public pubKeyword: PubKeyword | null,
|
2022-08-28 21:12:25 +02:00
|
|
|
public structKeyword: StructKeyword,
|
2022-09-07 12:45:38 +02:00
|
|
|
public name: IdentifierAlt,
|
2022-09-15 11:49:53 +02:00
|
|
|
public varExps: Identifier[],
|
2022-09-15 20:33:34 +02:00
|
|
|
public fields: StructDeclarationField[] | null,
|
2022-08-28 21:12:25 +02:00
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
2022-09-10 14:11:04 +02:00
|
|
|
if (this.pubKeyword !== null) {
|
|
|
|
return this.pubKeyword;
|
|
|
|
}
|
2022-08-29 16:17:55 +02:00
|
|
|
return this.structKeyword;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
2022-09-15 20:33:34 +02:00
|
|
|
if (this.fields && this.fields.length > 0) {
|
|
|
|
return this.fields[this.fields.length-1].getLastToken();
|
2022-08-29 16:17:55 +02:00
|
|
|
}
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class TypeAssert extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.TypeAssert;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public colon: Colon,
|
|
|
|
public typeExpression: TypeExpression,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.colon;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.typeExpression.getLastToken();
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export type Body
|
|
|
|
= ExprBody
|
|
|
|
| BlockBody
|
|
|
|
|
|
|
|
export class ExprBody extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.ExprBody;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public equals: Equals,
|
|
|
|
public expression: Expression,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.equals;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.expression.getLastToken();
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export type LetBodyElement
|
|
|
|
= LetDeclaration
|
|
|
|
| Statement
|
|
|
|
|
|
|
|
export class BlockBody extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.BlockBody;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public blockStart: BlockStart,
|
|
|
|
public elements: LetBodyElement[],
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.blockStart;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
if (this.elements.length > 0) {
|
|
|
|
return this.elements[this.elements.length-1].getLastToken();
|
|
|
|
}
|
|
|
|
return this.blockStart;
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
2022-09-09 22:37:14 +02:00
|
|
|
|
|
|
|
export class WrappedOperator extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.WrappedOperator;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public lparen: LParen,
|
|
|
|
public operator: CustomOperator,
|
|
|
|
public rparen: RParen,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.lparen;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.rparen;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-09-11 11:20:21 +02:00
|
|
|
export class TypeDeclaration extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.TypeDeclaration;
|
|
|
|
|
2022-09-14 22:34:53 +02:00
|
|
|
public typeEnv?: TypeEnv;
|
|
|
|
|
2022-09-11 11:20:21 +02:00
|
|
|
public constructor(
|
|
|
|
public pubKeyword: PubKeyword | null,
|
|
|
|
public typeKeyword: TypeKeyword,
|
|
|
|
public name: IdentifierAlt,
|
2022-09-15 11:49:53 +02:00
|
|
|
public varExps: Identifier[],
|
2022-09-11 11:20:21 +02:00
|
|
|
public equals: Equals,
|
|
|
|
public typeExpression: TypeExpression
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getFirstToken(): Token {
|
|
|
|
if (this.pubKeyword !== null) {
|
|
|
|
return this.pubKeyword;
|
|
|
|
}
|
|
|
|
return this.typeKeyword;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.typeExpression.getLastToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
export class LetDeclaration extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.LetDeclaration;
|
|
|
|
|
2022-09-01 20:06:43 +02:00
|
|
|
public scope?: Scope;
|
2022-09-05 19:33:08 +02:00
|
|
|
public typeEnv?: TypeEnv;
|
2022-09-15 22:39:20 +02:00
|
|
|
|
2022-09-18 14:33:22 +02:00
|
|
|
public activeCycle?: boolean;
|
2022-08-31 13:29:56 +02:00
|
|
|
public context?: InferContext;
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
public constructor(
|
|
|
|
public pubKeyword: PubKeyword | null,
|
|
|
|
public letKeyword: LetKeyword,
|
2022-09-16 19:50:18 +02:00
|
|
|
public foreignKeyword: ForeignKeyword | null,
|
2022-08-28 21:12:25 +02:00
|
|
|
public mutKeyword: MutKeyword | null,
|
2022-09-09 22:37:14 +02:00
|
|
|
public pattern: Pattern | WrappedOperator,
|
2022-08-28 21:12:25 +02:00
|
|
|
public params: Param[],
|
|
|
|
public typeAssert: TypeAssert | null,
|
|
|
|
public body: Body | null,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
if (this.pubKeyword !== null) {
|
|
|
|
return this.pubKeyword;
|
|
|
|
}
|
|
|
|
return this.letKeyword;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
if (this.body !== null) {
|
|
|
|
return this.body.getLastToken();
|
|
|
|
}
|
|
|
|
if (this.typeAssert !== null) {
|
|
|
|
return this.typeAssert.getLastToken();
|
|
|
|
}
|
|
|
|
if (this.params.length > 0) {
|
|
|
|
return this.params[this.params.length-1].getLastToken();
|
|
|
|
}
|
|
|
|
return this.pattern.getLastToken();
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class ImportDeclaration extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.ImportDeclaration;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public importKeyword: ImportKeyword,
|
|
|
|
public importSource: StringLiteral,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.importKeyword;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.importSource;
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export type Declaration
|
|
|
|
= LetDeclaration
|
|
|
|
| ImportDeclaration
|
|
|
|
| StructDeclaration
|
2022-09-10 14:11:04 +02:00
|
|
|
| EnumDeclaration
|
2022-09-11 11:20:21 +02:00
|
|
|
| TypeDeclaration
|
2022-08-28 21:12:25 +02:00
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
export class Initializer extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.Initializer;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public equals: Equals,
|
|
|
|
public expression: Expression
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.equals;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.expression.getLastToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-09-17 13:20:49 +02:00
|
|
|
export class ModuleDeclaration extends SyntaxBase {
|
2022-08-28 21:12:25 +02:00
|
|
|
|
2022-09-17 13:20:49 +02:00
|
|
|
public readonly kind = SyntaxKind.ModuleDeclaration;
|
|
|
|
|
|
|
|
public typeEnv?: TypeEnv;
|
2022-08-28 21:12:25 +02:00
|
|
|
|
|
|
|
public constructor(
|
2022-08-29 16:17:55 +02:00
|
|
|
public pubKeyword: PubKeyword | null,
|
2022-08-28 21:12:25 +02:00
|
|
|
public modKeyword: ModKeyword,
|
2022-09-17 13:20:49 +02:00
|
|
|
public name: IdentifierAlt,
|
|
|
|
public blockStart: BlockStart,
|
|
|
|
public elements: SourceFileElement[],
|
2022-08-28 21:12:25 +02:00
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
if (this.pubKeyword !== null) {
|
|
|
|
return this.pubKeyword;
|
|
|
|
}
|
|
|
|
return this.modKeyword;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
2022-09-17 13:20:49 +02:00
|
|
|
if (this.elements.length > 0) {
|
|
|
|
return this.elements[this.elements.length-1].getLastToken();
|
|
|
|
}
|
|
|
|
return this.blockStart;
|
2022-08-29 16:17:55 +02:00
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export type SourceFileElement
|
|
|
|
= Statement
|
|
|
|
| Declaration
|
2022-09-17 13:20:49 +02:00
|
|
|
| ModuleDeclaration
|
2022-08-28 21:12:25 +02:00
|
|
|
|
|
|
|
export class SourceFile extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.SourceFile;
|
|
|
|
|
2022-09-01 20:06:43 +02:00
|
|
|
public scope?: Scope;
|
2022-09-07 12:45:38 +02:00
|
|
|
public typeEnv?: TypeEnv;
|
2022-09-01 20:06:43 +02:00
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
public constructor(
|
2022-08-31 13:29:56 +02:00
|
|
|
private file: TextFile,
|
2022-08-29 16:17:55 +02:00
|
|
|
public elements: SourceFileElement[],
|
|
|
|
public eof: EndOfFile,
|
2022-08-28 21:12:25 +02:00
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
if (this.elements.length > 0) {
|
|
|
|
return this.elements[0].getFirstToken();
|
|
|
|
}
|
|
|
|
return this.eof;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
if (this.elements.length > 0) {
|
|
|
|
return this.elements[this.elements.length-1].getLastToken();
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
2022-08-29 16:17:55 +02:00
|
|
|
return this.eof;
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
2022-08-31 13:29:56 +02:00
|
|
|
public getFile() {
|
|
|
|
return this.file;
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|