diff --git a/src/cst.ts b/src/cst.ts index e6fbaef6e..ac855f080 100644 --- a/src/cst.ts +++ b/src/cst.ts @@ -102,6 +102,7 @@ export const enum SyntaxKind { TypeKeyword, ReturnKeyword, MatchKeyword, + ForeignKeyword, IfKeyword, ElifKeyword, 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 { public readonly kind = SyntaxKind.ModKeyword; @@ -992,6 +1003,7 @@ export type Token | ElseKeyword | ElifKeyword | EnumKeyword + | ForeignKeyword export type TokenKind = Token['kind'] @@ -2101,6 +2113,7 @@ export class LetDeclaration extends SyntaxBase { public constructor( public pubKeyword: PubKeyword | null, public letKeyword: LetKeyword, + public foreignKeyword: ForeignKeyword | null, public mutKeyword: MutKeyword | null, public pattern: Pattern | WrappedOperator, public params: Param[], diff --git a/src/parser.ts b/src/parser.ts index e9d8f901b..f0468b6c1 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -784,6 +784,7 @@ export class Parser { let t0 = this.getToken(); let pubKeyword = null; let mutKeyword = null; + let foreignKeyword = null; if (t0.kind === SyntaxKind.PubKeyword) { pubKeyword = t0; t0 = this.getToken(); @@ -791,20 +792,25 @@ export class Parser { if (t0.kind !== 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) { this.getToken(); mutKeyword = t1; + t1 = this.peekToken(); } - const t2 = this.peekToken(); - const t3 = this.peekToken(2); - const t4 = this.peekToken(3); + const t2 = this.peekToken(2); + const t3 = this.peekToken(3); 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(); - pattern = new WrappedOperator(t2, t3, t4); + pattern = new WrappedOperator(t1, t2, t3); } else { pattern = this.parsePattern(); } @@ -859,6 +865,7 @@ export class Parser { return new LetDeclaration( pubKeyword, t0, + foreignKeyword, mutKeyword, pattern, params, diff --git a/src/scanner.ts b/src/scanner.ts index 6f8a962a1..93a147905 100644 --- a/src/scanner.ts +++ b/src/scanner.ts @@ -40,6 +40,7 @@ import { MatchKeyword, RArrowAlt, VBar, + ForeignKeyword, } from "./cst" import { Diagnostics, UnexpectedCharDiagnostic } from "./diagnostics" import { Stream, BufferedStream, assert } from "./util"; @@ -366,6 +367,7 @@ export class Scanner extends BufferedStream { case 'struct': return new StructKeyword(startPos); case 'enum': return new EnumKeyword(startPos); case 'match': return new MatchKeyword(startPos); + case 'foreign': return new ForeignKeyword(startPos); default: if (isUpper(text[0])) { return new IdentifierAlt(text, startPos);