Add support for parsing the 'foreign' keyword in let-declarations

This commit is contained in:
Sam Vervaeck 2022-09-16 19:50:18 +02:00
parent f43a66f453
commit 117f49f343
3 changed files with 28 additions and 6 deletions

View file

@ -102,6 +102,7 @@ export const enum SyntaxKind {
TypeKeyword, TypeKeyword,
ReturnKeyword, ReturnKeyword,
MatchKeyword, MatchKeyword,
ForeignKeyword,
IfKeyword, IfKeyword,
ElifKeyword, ElifKeyword,
ElseKeyword, ElseKeyword,
@ -864,6 +865,16 @@ export class MatchKeyword extends TokenBase {
} }
export class ForeignKeyword extends TokenBase {
public readonly kind = SyntaxKind.ForeignKeyword;
public get text(): string {
return 'foreign';
}
}
export class ModKeyword extends TokenBase { export class ModKeyword extends TokenBase {
public readonly kind = SyntaxKind.ModKeyword; public readonly kind = SyntaxKind.ModKeyword;
@ -992,6 +1003,7 @@ export type Token
| ElseKeyword | ElseKeyword
| ElifKeyword | ElifKeyword
| EnumKeyword | EnumKeyword
| ForeignKeyword
export type TokenKind export type TokenKind
= Token['kind'] = Token['kind']
@ -2101,6 +2113,7 @@ export class LetDeclaration extends SyntaxBase {
public constructor( public constructor(
public pubKeyword: PubKeyword | null, public pubKeyword: PubKeyword | null,
public letKeyword: LetKeyword, public letKeyword: LetKeyword,
public foreignKeyword: ForeignKeyword | null,
public mutKeyword: MutKeyword | null, public mutKeyword: MutKeyword | null,
public pattern: Pattern | WrappedOperator, public pattern: Pattern | WrappedOperator,
public params: Param[], public params: Param[],

View file

@ -784,6 +784,7 @@ export class Parser {
let t0 = this.getToken(); let t0 = this.getToken();
let pubKeyword = null; let pubKeyword = null;
let mutKeyword = null; let mutKeyword = null;
let foreignKeyword = null;
if (t0.kind === SyntaxKind.PubKeyword) { if (t0.kind === SyntaxKind.PubKeyword) {
pubKeyword = t0; pubKeyword = t0;
t0 = this.getToken(); t0 = this.getToken();
@ -791,20 +792,25 @@ export class Parser {
if (t0.kind !== SyntaxKind.LetKeyword) { if (t0.kind !== SyntaxKind.LetKeyword) {
this.raiseParseError(t0, [ SyntaxKind.LetKeyword ]); this.raiseParseError(t0, [ SyntaxKind.LetKeyword ]);
} }
const t1 = this.peekToken(); let t1 = this.peekToken();
if (t1.kind === SyntaxKind.ForeignKeyword) {
this.getToken();
foreignKeyword = t1;
t1 = this.peekToken();
}
if (t1.kind === SyntaxKind.MutKeyword) { if (t1.kind === SyntaxKind.MutKeyword) {
this.getToken(); this.getToken();
mutKeyword = t1; mutKeyword = t1;
t1 = this.peekToken();
} }
const t2 = this.peekToken(); const t2 = this.peekToken(2);
const t3 = this.peekToken(2); const t3 = this.peekToken(3);
const t4 = this.peekToken(3);
let pattern; let pattern;
if (t2.kind === SyntaxKind.LParen && t3.kind === SyntaxKind.CustomOperator && t4.kind === SyntaxKind.RParen) { if (t1.kind === SyntaxKind.LParen && t2.kind === SyntaxKind.CustomOperator && t3.kind === SyntaxKind.RParen) {
this.getToken() this.getToken()
this.getToken(); this.getToken();
this.getToken(); this.getToken();
pattern = new WrappedOperator(t2, t3, t4); pattern = new WrappedOperator(t1, t2, t3);
} else { } else {
pattern = this.parsePattern(); pattern = this.parsePattern();
} }
@ -859,6 +865,7 @@ export class Parser {
return new LetDeclaration( return new LetDeclaration(
pubKeyword, pubKeyword,
t0, t0,
foreignKeyword,
mutKeyword, mutKeyword,
pattern, pattern,
params, params,

View file

@ -40,6 +40,7 @@ import {
MatchKeyword, MatchKeyword,
RArrowAlt, RArrowAlt,
VBar, VBar,
ForeignKeyword,
} from "./cst" } from "./cst"
import { Diagnostics, UnexpectedCharDiagnostic } from "./diagnostics" import { Diagnostics, UnexpectedCharDiagnostic } from "./diagnostics"
import { Stream, BufferedStream, assert } from "./util"; import { Stream, BufferedStream, assert } from "./util";
@ -366,6 +367,7 @@ export class Scanner extends BufferedStream<Token> {
case 'struct': return new StructKeyword(startPos); case 'struct': return new StructKeyword(startPos);
case 'enum': return new EnumKeyword(startPos); case 'enum': return new EnumKeyword(startPos);
case 'match': return new MatchKeyword(startPos); case 'match': return new MatchKeyword(startPos);
case 'foreign': return new ForeignKeyword(startPos);
default: default:
if (isUpper(text[0])) { if (isUpper(text[0])) {
return new IdentifierAlt(text, startPos); return new IdentifierAlt(text, startPos);