Enable parsing enum-declarations
This commit is contained in:
parent
7b3f1948bb
commit
3611dedf24
4 changed files with 182 additions and 2 deletions
104
src/cst.ts
104
src/cst.ts
|
@ -92,6 +92,7 @@ export const enum SyntaxKind {
|
|||
ModKeyword,
|
||||
ImportKeyword,
|
||||
StructKeyword,
|
||||
EnumKeyword,
|
||||
TypeKeyword,
|
||||
ReturnKeyword,
|
||||
MatchKeyword,
|
||||
|
@ -150,6 +151,7 @@ export const enum SyntaxKind {
|
|||
SuffixFuncDecl,
|
||||
LetDeclaration,
|
||||
StructDeclaration,
|
||||
EnumDeclaration,
|
||||
ImportDeclaration,
|
||||
TypeAliasDeclaration,
|
||||
|
||||
|
@ -160,6 +162,10 @@ export const enum SyntaxKind {
|
|||
// Structure declaration members
|
||||
StructDeclarationField,
|
||||
|
||||
// Enum declaration elements
|
||||
EnumDeclarationStructElement,
|
||||
EnumDeclarationTupleElement,
|
||||
|
||||
// Other nodes
|
||||
WrappedOperator,
|
||||
Initializer,
|
||||
|
@ -745,6 +751,16 @@ export class StructKeyword extends TokenBase {
|
|||
|
||||
}
|
||||
|
||||
export class EnumKeyword extends TokenBase {
|
||||
|
||||
public readonly kind = SyntaxKind.EnumKeyword;
|
||||
|
||||
public get text(): string {
|
||||
return 'enum';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class ReturnKeyword extends TokenBase {
|
||||
|
||||
public readonly kind = SyntaxKind.ReturnKeyword;
|
||||
|
@ -870,6 +886,7 @@ export type Token
|
|||
| IfKeyword
|
||||
| ElseKeyword
|
||||
| ElifKeyword
|
||||
| EnumKeyword
|
||||
|
||||
export type TokenKind
|
||||
= Token['kind']
|
||||
|
@ -1557,6 +1574,88 @@ export class Param extends SyntaxBase {
|
|||
|
||||
}
|
||||
|
||||
export class EnumDeclarationStructElement extends SyntaxBase {
|
||||
|
||||
public readonly kind = SyntaxKind.EnumDeclarationStructElement;
|
||||
|
||||
public constructor(
|
||||
public name: IdentifierAlt,
|
||||
public blockStart: BlockStart,
|
||||
public members: StructDeclarationField[],
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
public getFirstToken(): Token {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public getLastToken(): Token {
|
||||
if (this.members.length > 0) {
|
||||
return this.members[this.members.length-1].getLastToken();
|
||||
}
|
||||
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;
|
||||
|
||||
public constructor(
|
||||
public pubKeyword: PubKeyword | null,
|
||||
public enumKeyword: EnumKeyword,
|
||||
public name: IdentifierAlt,
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class StructDeclarationField extends SyntaxBase {
|
||||
|
||||
public readonly kind = SyntaxKind.StructDeclarationField;
|
||||
|
@ -1584,6 +1683,7 @@ export class StructDeclaration extends SyntaxBase {
|
|||
public readonly kind = SyntaxKind.StructDeclaration;
|
||||
|
||||
public constructor(
|
||||
public pubKeyword: PubKeyword | null,
|
||||
public structKeyword: StructKeyword,
|
||||
public name: IdentifierAlt,
|
||||
public members: StructDeclarationField[] | null,
|
||||
|
@ -1592,6 +1692,9 @@ export class StructDeclaration extends SyntaxBase {
|
|||
}
|
||||
|
||||
public getFirstToken(): Token {
|
||||
if (this.pubKeyword !== null) {
|
||||
return this.pubKeyword;
|
||||
}
|
||||
return this.structKeyword;
|
||||
}
|
||||
|
||||
|
@ -1769,6 +1872,7 @@ export type Declaration
|
|||
= LetDeclaration
|
||||
| ImportDeclaration
|
||||
| StructDeclaration
|
||||
| EnumDeclaration
|
||||
|
||||
export class Initializer extends SyntaxBase {
|
||||
|
||||
|
|
|
@ -70,6 +70,7 @@ const DESCRIPTIONS: Partial<Record<SyntaxKind, string>> = {
|
|||
[SyntaxKind.RBrace]: "'}'",
|
||||
[SyntaxKind.LBracket]: "'['",
|
||||
[SyntaxKind.RBracket]: "']'",
|
||||
[SyntaxKind.IdentifierAlt]: 'an identifier starting with an uppercase letter',
|
||||
[SyntaxKind.ConstantExpression]: 'a constant expression',
|
||||
[SyntaxKind.ReferenceExpression]: 'a reference expression',
|
||||
[SyntaxKind.LineFoldEnd]: 'the end of the current line-fold',
|
||||
|
|
|
@ -48,6 +48,9 @@ import {
|
|||
IdentifierAlt,
|
||||
WrappedOperator,
|
||||
ArrowTypeExpression,
|
||||
EnumDeclarationStructElement,
|
||||
EnumDeclaration,
|
||||
EnumDeclarationTupleElement,
|
||||
} from "./cst"
|
||||
import { Stream } from "./util";
|
||||
|
||||
|
@ -407,8 +410,76 @@ export class Parser {
|
|||
return this.parseBinaryOperatorAfterExpr(lhs, 0);
|
||||
}
|
||||
|
||||
public parseEnumDeclaration(): EnumDeclaration {
|
||||
let pubKeyword = null;
|
||||
let t0 = this.getToken();
|
||||
if (t0.kind == SyntaxKind.PubKeyword) {
|
||||
pubKeyword = t0;
|
||||
t0 = this.getToken();
|
||||
}
|
||||
if (t0.kind !== SyntaxKind.EnumKeyword) {
|
||||
this.raiseParseError(t0, [ SyntaxKind.EnumKeyword ]);
|
||||
}
|
||||
const name = this.expectToken(SyntaxKind.IdentifierAlt);
|
||||
const t1 = this.peekToken();
|
||||
let members = null;
|
||||
if (t1.kind === SyntaxKind.BlockStart) {
|
||||
members = [];
|
||||
this.getToken();
|
||||
for (;;) {
|
||||
const t2 = this.peekToken();
|
||||
if (t2.kind === SyntaxKind.BlockEnd) {
|
||||
this.getToken();
|
||||
break;
|
||||
}
|
||||
const name = this.expectToken(SyntaxKind.IdentifierAlt);
|
||||
const t3 = this.peekToken();
|
||||
let member;
|
||||
if (t3.kind === SyntaxKind.BlockStart) {
|
||||
this.getToken();
|
||||
const members = [];
|
||||
for (;;) {
|
||||
const name = this.expectToken(SyntaxKind.Identifier);
|
||||
const colon = this.expectToken(SyntaxKind.Colon);
|
||||
const typeExpr = this.parseTypeExpression();
|
||||
members.push(new StructDeclarationField(name, colon, typeExpr));
|
||||
const t4 = this.peekToken();
|
||||
if (t4.kind === SyntaxKind.BlockEnd) {
|
||||
this.getToken();
|
||||
break;
|
||||
}
|
||||
}
|
||||
member = new EnumDeclarationStructElement(name, t3, members);
|
||||
} else {
|
||||
const typeExps = [];
|
||||
for (;;) {
|
||||
const t3 = this.peekToken();
|
||||
if (t3.kind === SyntaxKind.LineFoldEnd) {
|
||||
break;
|
||||
}
|
||||
const typeExpr = this.parsePrimitiveTypeExpression();
|
||||
typeExps.push(typeExpr);
|
||||
}
|
||||
member = new EnumDeclarationTupleElement(name, typeExps);
|
||||
}
|
||||
members.push(member);
|
||||
this.expectToken(SyntaxKind.LineFoldEnd);
|
||||
}
|
||||
}
|
||||
this.expectToken(SyntaxKind.LineFoldEnd);
|
||||
return new EnumDeclaration(pubKeyword, t0, name, members);
|
||||
}
|
||||
|
||||
public parseStructDeclaration(): StructDeclaration {
|
||||
const structKeyword = this.expectToken(SyntaxKind.StructKeyword);
|
||||
let pubKeyword = null;
|
||||
let t0 = this.getToken();
|
||||
if (t0.kind === SyntaxKind.PubKeyword) {
|
||||
pubKeyword = t0;
|
||||
t0 = this.getToken();
|
||||
}
|
||||
if (t0.kind !== SyntaxKind.StructKeyword) {
|
||||
this.raiseParseError(t0, [ SyntaxKind.StructKeyword ]);
|
||||
}
|
||||
const name = this.expectToken(SyntaxKind.IdentifierAlt);
|
||||
const t2 = this.peekToken()
|
||||
let members = null;
|
||||
|
@ -430,7 +501,7 @@ export class Parser {
|
|||
}
|
||||
}
|
||||
this.expectToken(SyntaxKind.LineFoldEnd);
|
||||
return new StructDeclaration(structKeyword, name, members);
|
||||
return new StructDeclaration(pubKeyword, t0, name, members);
|
||||
}
|
||||
|
||||
private parsePatternStartingWithConstructor() {
|
||||
|
@ -731,6 +802,8 @@ export class Parser {
|
|||
return this.parseImportDeclaration();
|
||||
case SyntaxKind.StructKeyword:
|
||||
return this.parseStructDeclaration();
|
||||
case SyntaxKind.EnumKeyword:
|
||||
return this.parseEnumDeclaration();
|
||||
case SyntaxKind.IfKeyword:
|
||||
return this.parseIfStatement();
|
||||
default:
|
||||
|
|
|
@ -36,6 +36,7 @@ import {
|
|||
IfKeyword,
|
||||
StructKeyword,
|
||||
RArrow,
|
||||
EnumKeyword,
|
||||
} from "./cst"
|
||||
import { Diagnostics, UnexpectedCharDiagnostic } from "./diagnostics"
|
||||
import { Stream, BufferedStream, assert } from "./util";
|
||||
|
@ -356,6 +357,7 @@ export class Scanner extends BufferedStream<Token> {
|
|||
case 'else': return new ElseKeyword(startPos);
|
||||
case 'elif': return new ElifKeyword(startPos);
|
||||
case 'struct': return new StructKeyword(startPos);
|
||||
case 'enum': return new EnumKeyword(startPos);
|
||||
default:
|
||||
if (isUpper(text[0])) {
|
||||
return new IdentifierAlt(text, startPos);
|
||||
|
|
Loading…
Reference in a new issue