Extend parser and scanner to support more constructs

This commit is contained in:
Sam Vervaeck 2020-05-24 20:17:42 +02:00
parent 9b5cb6ad38
commit 1a349244a0
5 changed files with 468 additions and 222 deletions

View file

@ -3,6 +3,8 @@
@language JS;
node EndOfFile > BoltToken, JSToken;
node Token;
node SourceFile;
// Bolt language AST definitions
@ -10,7 +12,7 @@ type BoltValue = Integer | bool | String;
node FunctionBody;
node BoltToken;
node BoltToken > Token;
node BoltStringLiteral > BoltToken {
value: String,
@ -50,6 +52,7 @@ node BoltLtSign > BoltToken;
node BoltKeyword;
node BoltQuoteKeyword > BoltToken, BoltKeyword;
node BoltFnKeyword > BoltToken, BoltKeyword;
node BoltForeignKeyword > BoltToken, BoltKeyword;
node BoltForKeyword > BoltToken, BoltKeyword;
@ -76,7 +79,7 @@ node BoltParenthesized > BoltPunctuated;
node BoltBraced > BoltPunctuated;
node BoltBracketed > BoltPunctuated;
node BoltSourceFile {
node BoltSourceFile > SourceFile {
elements: Vec<BoltSourceElement>,
}
@ -92,6 +95,11 @@ node BoltReferenceTypeExpression > BoltTypeExpression {
arguments: Option<Vec<BoltTypeExpression>>,
}
node BoltFunctionTypeExpression > BoltTypeExpression {
params: Vec<BoltParameter>,
returnType: Option<BoltTypeExpression>,
}
node BoltTypeParameter {
index: usize,
name: BoltIdentifier,
@ -122,18 +130,23 @@ node BoltTuplePattern > BoltPattern {
elements: Vec<BoltTuplePatternElement>,
}
node BoltRecordPatternField {
name: BoltIdentifier,
pattern: BoltPattern,
node BoltRecordFieldPattern {
isRest: bool,
name: Option<BoltIdentifier>,
pattern: Option<BoltPattern>,
}
node BoltRecordPattern > BoltPattern {
name: BoltTypeExpression,
fields: Vec<BoltRecordPatternField>,
name: BoltQualName,
fields: Vec<BoltRecordFieldPattern>,
}
node BoltExpression;
node BoltQuoteExpression > BoltExpression {
tokens: Vec<Token>,
}
node BoltReferenceExpression > BoltExpression {
name: BoltQualName,
}
@ -297,7 +310,7 @@ node BoltMacroCall > BoltRecordMember, BoltStatement, BoltDeclaration, BoltExpre
type JSValue = Int | String | Bool | Void;
node JSToken;
node JSToken > Token;
node JSOperator > JSToken {
text: String,
@ -489,7 +502,7 @@ node JSLetDeclaration > JSDeclaration, JSFunctionBodyElement {
value: Option<JSExpression>,
}
node JSSourceFile {
node JSSourceFile > SourceFile {
elements: Vec<JSSourceElement>,
}

422
src/ast.d.ts vendored
View file

@ -1,143 +1,146 @@
export const enum SyntaxKind {
EndOfFile = 2,
FunctionBody = 4,
BoltStringLiteral = 6,
BoltIntegerLiteral = 7,
BoltIdentifier = 9,
BoltOperator = 10,
BoltAssignment = 11,
BoltComma = 12,
BoltSemi = 13,
BoltColon = 14,
BoltDot = 15,
BoltDotDot = 16,
BoltRArrow = 17,
BoltRArrowAlt = 18,
BoltLArrow = 19,
BoltEqSign = 20,
BoltGtSign = 21,
BoltLtSign = 22,
BoltFnKeyword = 24,
BoltForeignKeyword = 25,
BoltForKeyword = 26,
BoltLetKeyword = 27,
BoltReturnKeyword = 28,
BoltLoopKeyword = 29,
BoltYieldKeyword = 30,
BoltMatchKeyword = 31,
BoltImportKeyword = 32,
BoltPubKeyword = 33,
BoltModKeyword = 34,
BoltMutKeyword = 35,
BoltEnumKeyword = 36,
BoltStructKeyword = 37,
BoltTypeKeyword = 38,
BoltTraitKeyword = 39,
BoltImplKeyword = 40,
BoltParenthesized = 42,
BoltBraced = 43,
BoltBracketed = 44,
BoltSourceFile = 45,
BoltQualName = 46,
BoltReferenceTypeExpression = 48,
BoltTypeParameter = 49,
BoltBindPattern = 51,
BoltTypePattern = 52,
BoltExpressionPattern = 53,
BoltTuplePatternElement = 54,
BoltTuplePattern = 55,
BoltRecordPatternField = 56,
BoltRecordPattern = 57,
BoltReferenceExpression = 59,
BoltCallExpression = 60,
BoltYieldExpression = 61,
BoltMatchArm = 62,
BoltMatchExpression = 63,
BoltCase = 64,
BoltCaseExpression = 65,
BoltBlockExpression = 66,
BoltConstantExpression = 67,
BoltReturnStatement = 69,
BoltConditionalCase = 70,
BoltConditionalStatement = 71,
BoltResumeStatement = 72,
BoltExpressionStatement = 73,
BoltParameter = 74,
BoltModule = 78,
BoltFunctionDeclaration = 80,
BoltVariableDeclaration = 81,
BoltPlainImportSymbol = 83,
BoltImportDeclaration = 84,
BoltTraitDeclaration = 85,
BoltImplDeclaration = 86,
BoltTypeAliasDeclaration = 87,
BoltRecordField = 89,
BoltRecordDeclaration = 90,
BoltMacroCall = 92,
JSOperator = 95,
JSIdentifier = 96,
JSString = 97,
JSInteger = 98,
JSFromKeyword = 99,
JSReturnKeyword = 100,
JSTryKeyword = 101,
JSFinallyKeyword = 102,
JSCatchKeyword = 103,
JSImportKeyword = 104,
JSAsKeyword = 105,
JSConstKeyword = 106,
JSLetKeyword = 107,
JSExportKeyword = 108,
JSFunctionKeyword = 109,
JSWhileKeyword = 110,
JSForKeyword = 111,
JSCloseBrace = 112,
JSCloseBracket = 113,
JSCloseParen = 114,
JSOpenBrace = 115,
JSOpenBracket = 116,
JSOpenParen = 117,
JSSemi = 118,
JSComma = 119,
JSDot = 120,
JSDotDotDot = 121,
JSMulOp = 122,
JSAddOp = 123,
JSDivOp = 124,
JSSubOp = 125,
JSLtOp = 126,
JSGtOp = 127,
JSBOrOp = 128,
JSBXorOp = 129,
JSBAndOp = 130,
JSBNotOp = 131,
JSNotOp = 132,
JSBindPattern = 134,
JSConstantExpression = 136,
JSMemberExpression = 137,
JSCallExpression = 138,
JSBinaryExpression = 139,
JSUnaryExpression = 140,
JSNewExpression = 141,
JSSequenceExpression = 142,
JSConditionalExpression = 143,
JSLiteralExpression = 145,
JSReferenceExpression = 146,
JSCatchBlock = 150,
JSTryCatchStatement = 151,
JSExpressionStatement = 152,
JSConditionalCase = 153,
JSConditionalStatement = 154,
JSReturnStatement = 155,
JSParameter = 156,
JSImportStarBinding = 160,
JSImportAsBinding = 161,
JSImportDeclaration = 162,
JSFunctionDeclaration = 163,
JSArrowFunctionDeclaration = 164,
JSLetDeclaration = 165,
JSSourceFile = 166,
FunctionBody = 6,
BoltStringLiteral = 8,
BoltIntegerLiteral = 9,
BoltIdentifier = 11,
BoltOperator = 12,
BoltAssignment = 13,
BoltComma = 14,
BoltSemi = 15,
BoltColon = 16,
BoltDot = 17,
BoltDotDot = 18,
BoltRArrow = 19,
BoltRArrowAlt = 20,
BoltLArrow = 21,
BoltEqSign = 22,
BoltGtSign = 23,
BoltLtSign = 24,
BoltQuoteKeyword = 26,
BoltFnKeyword = 27,
BoltForeignKeyword = 28,
BoltForKeyword = 29,
BoltLetKeyword = 30,
BoltReturnKeyword = 31,
BoltLoopKeyword = 32,
BoltYieldKeyword = 33,
BoltMatchKeyword = 34,
BoltImportKeyword = 35,
BoltPubKeyword = 36,
BoltModKeyword = 37,
BoltMutKeyword = 38,
BoltEnumKeyword = 39,
BoltStructKeyword = 40,
BoltTypeKeyword = 41,
BoltTraitKeyword = 42,
BoltImplKeyword = 43,
BoltParenthesized = 45,
BoltBraced = 46,
BoltBracketed = 47,
BoltSourceFile = 48,
BoltQualName = 49,
BoltReferenceTypeExpression = 51,
BoltFunctionTypeExpression = 52,
BoltTypeParameter = 53,
BoltBindPattern = 55,
BoltTypePattern = 56,
BoltExpressionPattern = 57,
BoltTuplePatternElement = 58,
BoltTuplePattern = 59,
BoltRecordFieldPattern = 60,
BoltRecordPattern = 61,
BoltQuoteExpression = 63,
BoltReferenceExpression = 64,
BoltCallExpression = 65,
BoltYieldExpression = 66,
BoltMatchArm = 67,
BoltMatchExpression = 68,
BoltCase = 69,
BoltCaseExpression = 70,
BoltBlockExpression = 71,
BoltConstantExpression = 72,
BoltReturnStatement = 74,
BoltConditionalCase = 75,
BoltConditionalStatement = 76,
BoltResumeStatement = 77,
BoltExpressionStatement = 78,
BoltParameter = 79,
BoltModule = 83,
BoltFunctionDeclaration = 85,
BoltVariableDeclaration = 86,
BoltPlainImportSymbol = 88,
BoltImportDeclaration = 89,
BoltTraitDeclaration = 90,
BoltImplDeclaration = 91,
BoltTypeAliasDeclaration = 92,
BoltRecordField = 94,
BoltRecordDeclaration = 95,
BoltMacroCall = 97,
JSOperator = 100,
JSIdentifier = 101,
JSString = 102,
JSInteger = 103,
JSFromKeyword = 104,
JSReturnKeyword = 105,
JSTryKeyword = 106,
JSFinallyKeyword = 107,
JSCatchKeyword = 108,
JSImportKeyword = 109,
JSAsKeyword = 110,
JSConstKeyword = 111,
JSLetKeyword = 112,
JSExportKeyword = 113,
JSFunctionKeyword = 114,
JSWhileKeyword = 115,
JSForKeyword = 116,
JSCloseBrace = 117,
JSCloseBracket = 118,
JSCloseParen = 119,
JSOpenBrace = 120,
JSOpenBracket = 121,
JSOpenParen = 122,
JSSemi = 123,
JSComma = 124,
JSDot = 125,
JSDotDotDot = 126,
JSMulOp = 127,
JSAddOp = 128,
JSDivOp = 129,
JSSubOp = 130,
JSLtOp = 131,
JSGtOp = 132,
JSBOrOp = 133,
JSBXorOp = 134,
JSBAndOp = 135,
JSBNotOp = 136,
JSNotOp = 137,
JSBindPattern = 139,
JSConstantExpression = 141,
JSMemberExpression = 142,
JSCallExpression = 143,
JSBinaryExpression = 144,
JSUnaryExpression = 145,
JSNewExpression = 146,
JSSequenceExpression = 147,
JSConditionalExpression = 148,
JSLiteralExpression = 150,
JSReferenceExpression = 151,
JSCatchBlock = 155,
JSTryCatchStatement = 156,
JSExpressionStatement = 157,
JSConditionalCase = 158,
JSConditionalStatement = 159,
JSReturnStatement = 160,
JSParameter = 161,
JSImportStarBinding = 165,
JSImportAsBinding = 166,
JSImportDeclaration = 167,
JSFunctionDeclaration = 168,
JSArrowFunctionDeclaration = 169,
JSLetDeclaration = 170,
JSSourceFile = 171,
}
@ -162,6 +165,91 @@ export interface EndOfFile extends SyntaxBase<SyntaxKind.EndOfFile> {
kind: SyntaxKind.EndOfFile;
}
export type Token
= EndOfFile
| BoltStringLiteral
| BoltIntegerLiteral
| BoltIdentifier
| BoltOperator
| BoltAssignment
| BoltComma
| BoltSemi
| BoltColon
| BoltDot
| BoltDotDot
| BoltRArrow
| BoltRArrowAlt
| BoltLArrow
| BoltEqSign
| BoltGtSign
| BoltLtSign
| BoltQuoteKeyword
| BoltFnKeyword
| BoltForeignKeyword
| BoltForKeyword
| BoltLetKeyword
| BoltReturnKeyword
| BoltLoopKeyword
| BoltYieldKeyword
| BoltMatchKeyword
| BoltImportKeyword
| BoltPubKeyword
| BoltModKeyword
| BoltMutKeyword
| BoltEnumKeyword
| BoltStructKeyword
| BoltTypeKeyword
| BoltTraitKeyword
| BoltImplKeyword
| BoltParenthesized
| BoltBraced
| BoltBracketed
| EndOfFile
| JSOperator
| JSIdentifier
| JSString
| JSInteger
| JSFromKeyword
| JSReturnKeyword
| JSTryKeyword
| JSFinallyKeyword
| JSCatchKeyword
| JSImportKeyword
| JSAsKeyword
| JSConstKeyword
| JSLetKeyword
| JSExportKeyword
| JSFunctionKeyword
| JSWhileKeyword
| JSForKeyword
| JSCloseBrace
| JSCloseBracket
| JSCloseParen
| JSOpenBrace
| JSOpenBracket
| JSOpenParen
| JSSemi
| JSComma
| JSDot
| JSDotDotDot
| JSMulOp
| JSAddOp
| JSDivOp
| JSSubOp
| JSLtOp
| JSGtOp
| JSBOrOp
| JSBXorOp
| JSBAndOp
| JSBNotOp
| JSNotOp
export type SourceFile
= BoltSourceFile
| JSSourceFile
export interface FunctionBody extends SyntaxBase<SyntaxKind.FunctionBody> {
kind: SyntaxKind.FunctionBody;
}
@ -184,6 +272,7 @@ export type BoltToken
| BoltEqSign
| BoltGtSign
| BoltLtSign
| BoltQuoteKeyword
| BoltFnKeyword
| BoltForeignKeyword
| BoltForKeyword
@ -281,7 +370,8 @@ export interface BoltLtSign extends SyntaxBase<SyntaxKind.BoltLtSign> {
}
export type BoltKeyword
= BoltFnKeyword
= BoltQuoteKeyword
| BoltFnKeyword
| BoltForeignKeyword
| BoltForKeyword
| BoltLetKeyword
@ -300,6 +390,10 @@ export type BoltKeyword
| BoltImplKeyword
export interface BoltQuoteKeyword extends SyntaxBase<SyntaxKind.BoltQuoteKeyword> {
kind: SyntaxKind.BoltQuoteKeyword;
}
export interface BoltFnKeyword extends SyntaxBase<SyntaxKind.BoltFnKeyword> {
kind: SyntaxKind.BoltFnKeyword;
}
@ -402,6 +496,7 @@ export interface BoltQualName extends SyntaxBase<SyntaxKind.BoltQualName> {
export type BoltTypeExpression
= BoltReferenceTypeExpression
| BoltFunctionTypeExpression
export interface BoltReferenceTypeExpression extends SyntaxBase<SyntaxKind.BoltReferenceTypeExpression> {
@ -410,6 +505,12 @@ export interface BoltReferenceTypeExpression extends SyntaxBase<SyntaxKind.BoltR
arguments: BoltTypeExpression[] | null;
}
export interface BoltFunctionTypeExpression extends SyntaxBase<SyntaxKind.BoltFunctionTypeExpression> {
kind: SyntaxKind.BoltFunctionTypeExpression;
params: BoltParameter[];
returnType: BoltTypeExpression | null;
}
export interface BoltTypeParameter extends SyntaxBase<SyntaxKind.BoltTypeParameter> {
kind: SyntaxKind.BoltTypeParameter;
index: number;
@ -452,20 +553,22 @@ export interface BoltTuplePattern extends SyntaxBase<SyntaxKind.BoltTuplePattern
elements: BoltTuplePatternElement[];
}
export interface BoltRecordPatternField extends SyntaxBase<SyntaxKind.BoltRecordPatternField> {
kind: SyntaxKind.BoltRecordPatternField;
name: BoltIdentifier;
pattern: BoltPattern;
export interface BoltRecordFieldPattern extends SyntaxBase<SyntaxKind.BoltRecordFieldPattern> {
kind: SyntaxKind.BoltRecordFieldPattern;
isRest: boolean;
name: BoltIdentifier | null;
pattern: BoltPattern | null;
}
export interface BoltRecordPattern extends SyntaxBase<SyntaxKind.BoltRecordPattern> {
kind: SyntaxKind.BoltRecordPattern;
name: BoltTypeExpression;
fields: BoltRecordPatternField[];
name: BoltQualName;
fields: BoltRecordFieldPattern[];
}
export type BoltExpression
= BoltReferenceExpression
= BoltQuoteExpression
| BoltReferenceExpression
| BoltCallExpression
| BoltYieldExpression
| BoltMatchExpression
@ -475,6 +578,11 @@ export type BoltExpression
| BoltMacroCall
export interface BoltQuoteExpression extends SyntaxBase<SyntaxKind.BoltQuoteExpression> {
kind: SyntaxKind.BoltQuoteExpression;
tokens: Token[];
}
export interface BoltReferenceExpression extends SyntaxBase<SyntaxKind.BoltReferenceExpression> {
kind: SyntaxKind.BoltReferenceExpression;
name: BoltQualName;
@ -1126,6 +1234,7 @@ export type BoltSyntax
| BoltEqSign
| BoltGtSign
| BoltLtSign
| BoltQuoteKeyword
| BoltFnKeyword
| BoltForeignKeyword
| BoltForKeyword
@ -1149,14 +1258,16 @@ export type BoltSyntax
| BoltSourceFile
| BoltQualName
| BoltReferenceTypeExpression
| BoltFunctionTypeExpression
| BoltTypeParameter
| BoltBindPattern
| BoltTypePattern
| BoltExpressionPattern
| BoltTuplePatternElement
| BoltTuplePattern
| BoltRecordPatternField
| BoltRecordFieldPattern
| BoltRecordPattern
| BoltQuoteExpression
| BoltReferenceExpression
| BoltCallExpression
| BoltYieldExpression
@ -1270,6 +1381,7 @@ export type Syntax
| BoltEqSign
| BoltGtSign
| BoltLtSign
| BoltQuoteKeyword
| BoltFnKeyword
| BoltForeignKeyword
| BoltForKeyword
@ -1293,14 +1405,16 @@ export type Syntax
| BoltSourceFile
| BoltQualName
| BoltReferenceTypeExpression
| BoltFunctionTypeExpression
| BoltTypeParameter
| BoltBindPattern
| BoltTypePattern
| BoltExpressionPattern
| BoltTuplePatternElement
| BoltTuplePattern
| BoltRecordPatternField
| BoltRecordFieldPattern
| BoltRecordPattern
| BoltQuoteExpression
| BoltReferenceExpression
| BoltCallExpression
| BoltYieldExpression
@ -1412,6 +1526,7 @@ export function createBoltLArrow(span?: TextSpan | null): BoltLArrow;
export function createBoltEqSign(span?: TextSpan | null): BoltEqSign;
export function createBoltGtSign(span?: TextSpan | null): BoltGtSign;
export function createBoltLtSign(span?: TextSpan | null): BoltLtSign;
export function createBoltQuoteKeyword(span?: TextSpan | null): BoltQuoteKeyword;
export function createBoltFnKeyword(span?: TextSpan | null): BoltFnKeyword;
export function createBoltForeignKeyword(span?: TextSpan | null): BoltForeignKeyword;
export function createBoltForKeyword(span?: TextSpan | null): BoltForKeyword;
@ -1435,14 +1550,16 @@ export function createBoltBracketed(text: string, span?: TextSpan | null): BoltB
export function createBoltSourceFile(elements: BoltSourceElement[], span?: TextSpan | null): BoltSourceFile;
export function createBoltQualName(modulePath: BoltIdentifier[] | null, name: BoltSymbol, span?: TextSpan | null): BoltQualName;
export function createBoltReferenceTypeExpression(name: BoltQualName, arguments: BoltTypeExpression[] | null, span?: TextSpan | null): BoltReferenceTypeExpression;
export function createBoltFunctionTypeExpression(params: BoltParameter[], returnType: BoltTypeExpression | null, span?: TextSpan | null): BoltFunctionTypeExpression;
export function createBoltTypeParameter(index: number, name: BoltIdentifier, defaultType: BoltTypeExpression | null, span?: TextSpan | null): BoltTypeParameter;
export function createBoltBindPattern(name: BoltIdentifier, span?: TextSpan | null): BoltBindPattern;
export function createBoltTypePattern(type: BoltTypeExpression, nestedPattern: BoltPattern, span?: TextSpan | null): BoltTypePattern;
export function createBoltExpressionPattern(expression: BoltExpression, span?: TextSpan | null): BoltExpressionPattern;
export function createBoltTuplePatternElement(index: number, pattern: BoltPattern, span?: TextSpan | null): BoltTuplePatternElement;
export function createBoltTuplePattern(elements: BoltTuplePatternElement[], span?: TextSpan | null): BoltTuplePattern;
export function createBoltRecordPatternField(name: BoltIdentifier, pattern: BoltPattern, span?: TextSpan | null): BoltRecordPatternField;
export function createBoltRecordPattern(name: BoltTypeExpression, fields: BoltRecordPatternField[], span?: TextSpan | null): BoltRecordPattern;
export function createBoltRecordFieldPattern(isRest: boolean, name: BoltIdentifier | null, pattern: BoltPattern | null, span?: TextSpan | null): BoltRecordFieldPattern;
export function createBoltRecordPattern(name: BoltQualName, fields: BoltRecordFieldPattern[], span?: TextSpan | null): BoltRecordPattern;
export function createBoltQuoteExpression(tokens: Token[], span?: TextSpan | null): BoltQuoteExpression;
export function createBoltReferenceExpression(name: BoltQualName, span?: TextSpan | null): BoltReferenceExpression;
export function createBoltCallExpression(operator: BoltExpression, operands: BoltExpression[], span?: TextSpan | null): BoltCallExpression;
export function createBoltYieldExpression(value: BoltExpression, span?: TextSpan | null): BoltYieldExpression;
@ -1534,6 +1651,8 @@ export function createJSLetDeclaration(bindings: JSPattern, value: JSExpression
export function createJSSourceFile(elements: JSSourceElement[], span?: TextSpan | null): JSSourceFile;
export function isEndOfFile(value: any): value is EndOfFile;
export function isToken(value: any): value is Token;
export function isSourceFile(value: any): value is SourceFile;
export function isFunctionBody(value: any): value is FunctionBody;
export function isBoltToken(value: any): value is BoltToken;
export function isBoltStringLiteral(value: any): value is BoltStringLiteral;
@ -1554,6 +1673,7 @@ export function isBoltEqSign(value: any): value is BoltEqSign;
export function isBoltGtSign(value: any): value is BoltGtSign;
export function isBoltLtSign(value: any): value is BoltLtSign;
export function isBoltKeyword(value: any): value is BoltKeyword;
export function isBoltQuoteKeyword(value: any): value is BoltQuoteKeyword;
export function isBoltFnKeyword(value: any): value is BoltFnKeyword;
export function isBoltForeignKeyword(value: any): value is BoltForeignKeyword;
export function isBoltForKeyword(value: any): value is BoltForKeyword;
@ -1579,6 +1699,7 @@ export function isBoltSourceFile(value: any): value is BoltSourceFile;
export function isBoltQualName(value: any): value is BoltQualName;
export function isBoltTypeExpression(value: any): value is BoltTypeExpression;
export function isBoltReferenceTypeExpression(value: any): value is BoltReferenceTypeExpression;
export function isBoltFunctionTypeExpression(value: any): value is BoltFunctionTypeExpression;
export function isBoltTypeParameter(value: any): value is BoltTypeParameter;
export function isBoltPattern(value: any): value is BoltPattern;
export function isBoltBindPattern(value: any): value is BoltBindPattern;
@ -1586,9 +1707,10 @@ export function isBoltTypePattern(value: any): value is BoltTypePattern;
export function isBoltExpressionPattern(value: any): value is BoltExpressionPattern;
export function isBoltTuplePatternElement(value: any): value is BoltTuplePatternElement;
export function isBoltTuplePattern(value: any): value is BoltTuplePattern;
export function isBoltRecordPatternField(value: any): value is BoltRecordPatternField;
export function isBoltRecordFieldPattern(value: any): value is BoltRecordFieldPattern;
export function isBoltRecordPattern(value: any): value is BoltRecordPattern;
export function isBoltExpression(value: any): value is BoltExpression;
export function isBoltQuoteExpression(value: any): value is BoltQuoteExpression;
export function isBoltReferenceExpression(value: any): value is BoltReferenceExpression;
export function isBoltCallExpression(value: any): value is BoltCallExpression;
export function isBoltYieldExpression(value: any): value is BoltYieldExpression;

View file

@ -64,6 +64,19 @@ import {
BoltMatchArm,
createBoltMatchExpression,
createBoltExpressionPattern,
BoltFunctionTypeExpression,
BoltReferenceTypeExpression,
createBoltFunctionTypeExpression,
BoltRecordPattern,
createBoltRecordPattern,
createBoltRecordFieldPattern,
BoltQuoteKeyword,
isBoltPunctuated,
Token,
createBoltQuoteExpression,
BoltQuoteExpression,
BoltBlockExpression,
createBoltBlockExpression,
} from "./ast"
import { parseForeignLanguage } from "./foreign"
@ -77,6 +90,7 @@ import {
setOrigNodeRange,
createTokenStream,
uniq,
assert,
} from "./util"
export type BoltTokenStream = Stream<BoltToken>;
@ -99,6 +113,7 @@ const KIND_EXPRESSION_T0 = [
SyntaxKind.BoltIdentifier,
SyntaxKind.BoltOperator,
SyntaxKind.BoltMatchKeyword,
SyntaxKind.BoltQuoteKeyword,
SyntaxKind.BoltYieldKeyword,
]
@ -205,9 +220,62 @@ export class Parser {
return node;
}
public parseRecordPattern(tokens: BoltTokenStream): BoltRecordPattern {
const name = this.parseQualName(tokens);
const t1 = tokens.get();
assertToken(t1, SyntaxKind.BoltBraced);
const innerTokens = createTokenStream(t1);
const members = [];
while (true) {
let t0 = innerTokens.get();
const firstToken = t0;
if (t0.kind === SyntaxKind.EndOfFile) {
break;
}
let isRest = false;
let name = null;
let pattern = null;
if (t0.kind === SyntaxKind.BoltDotDot) {
isRest = true;
t0 = innerTokens.peek();
}
if (t0.kind === SyntaxKind.BoltIdentifier) {
name = t0;
t0 = innerTokens.peek();
} else if (!isRest) {
throw new ParseError(t0, [SyntaxKind.BoltIdentifier]);
}
if (t0.kind === SyntaxKind.BoltEqSign) {
pattern = this.parsePattern(innerTokens);
}
let member = createBoltRecordFieldPattern(isRest, name, pattern);
setOrigNodeRange(member, firstToken, t0);
members.push(member);
if (t0.kind === SyntaxKind.EndOfFile) {
break;
}
assertToken(t0, SyntaxKind.BoltComma);
}
const result = createBoltRecordPattern(name, members);
setOrigNodeRange(result, name, t1);
return result;
}
public parsePattern(tokens: BoltTokenStream): BoltPattern {
const t0 = tokens.peek(1);
if (t0.kind === SyntaxKind.BoltIdentifier) {
const t1 = tokens.peek(2);
if (t0.kind === SyntaxKind.BoltIdentifier && t1.kind === SyntaxKind.BoltBraced) {
return this.parseRecordPattern(tokens);
} else if (t0.kind === SyntaxKind.BoltIdentifier) {
return this.parseBindPattern(tokens);
} else if (t0.kind === SyntaxKind.BoltOperator && t0.text === '^') {
tokens.get();
@ -242,7 +310,40 @@ export class Parser {
return node;
}
public parseReferenceTypeExpression(tokens: BoltTokenStream) {
public parseFunctionTypeExpression(tokens: BoltTokenStream): BoltFunctionTypeExpression {
const t0 = tokens.get();
assertToken(t0, SyntaxKind.BoltFnKeyword);
const t1 = tokens.get();
assertToken(t1, SyntaxKind.BoltParenthesized);
const innerTokens = createTokenStream(t1);
let i = 0;
const params: BoltParameter[] = [];
while (true) {
const t2 = innerTokens.peek();
if (t2.kind === SyntaxKind.EndOfFile) {
break;
}
const param = this.parseParameter(innerTokens, i++)
params.push(param);
const t3 = innerTokens.peek()
if (t3.kind === SyntaxKind.EndOfFile) {
break;
}
const t4 = innerTokens.get();
assertToken(t4, SyntaxKind.BoltComma);
}
const t3 = tokens.peek();
let returnType = null;
if (t3.kind === SyntaxKind.BoltRArrow) {
tokens.get();
returnType = this.parseTypeExpression(tokens);
}
const result = createBoltFunctionTypeExpression(params, returnType)
setOrigNodeRange(result, t0, returnType !== null ? returnType : t1);
return result;
}
public parseReferenceTypeExpression(tokens: BoltTokenStream): BoltReferenceTypeExpression {
const name = this.parseQualName(tokens)
@ -278,7 +379,9 @@ export class Parser {
private parsePrimTypeExpression(tokens: BoltTokenStream): BoltTypeExpression {
const t0 = tokens.peek();
if (t0.kind === SyntaxKind.BoltIdentifier) {
if (t0.kind === SyntaxKind.BoltFnKeyword) {
return this.parseFunctionTypeExpression(tokens);
} else if (t0.kind === SyntaxKind.BoltIdentifier) {
return this.parseReferenceTypeExpression(tokens);
} else {
throw new ParseError(t0, [SyntaxKind.BoltIdentifier]);
@ -376,9 +479,58 @@ export class Parser {
return result;
}
protected parsePrimitiveExpression(tokens: BoltTokenStream): BoltExpression {
public parseQuoteExpression(tokens: BoltTokenStream): BoltQuoteExpression {
const t0 = tokens.get();
assertToken(t0, SyntaxKind.BoltQuoteKeyword);
let t1 = tokens.get();
let target = "Bolt";
if (t1.kind === SyntaxKind.BoltStringLiteral) {
target = t1.value;
t1 = tokens.get();
}
if (!isBoltPunctuated(t1)) {
throw new ParseError(t1, [SyntaxKind.BoltBraced, SyntaxKind.BoltParenthesized, SyntaxKind.BoltBracketed]);
}
let scanner;
switch (target) {
case "Bolt":
scanner = new Scanner(t1.span!.file, t1.text, t1.span!.start.clone());
break;
case "JS":
scanner = new JSScanner(t1.span!.file, t1.text, t1.span!.start.clone());
break;
default:
throw new Error(`Unrecognised language.`);
}
const scanned: Token[] = [];
while (true) {
const t2 = scanner.scan();
if (t2.kind === SyntaxKind.EndOfFile) {
break;
}
scanned.push(t2);
}
const result = createBoltQuoteExpression(scanned);
setOrigNodeRange(result, t0, t1);
return result;
}
public parseBlockExpression(tokens: BoltTokenStream): BoltBlockExpression {
const t0 = tokens.get();
const innerTokens = createTokenStream(t0);
const elements = this.parseFunctionBodyElements(innerTokens)
const result = createBoltBlockExpression(elements);
setOrigNodeRange(result, t0, t0);
return result;
}
private parsePrimitiveExpression(tokens: BoltTokenStream): BoltExpression {
const t0 = tokens.peek();
if (t0.kind === SyntaxKind.BoltMatchKeyword) {
if (t0.kind === SyntaxKind.BoltBraced) {
return this.parseBlockExpression(tokens);
} else if (t0.kind === SyntaxKind.BoltQuoteKeyword) {
return this.parseQuoteExpression(tokens);
} else if (t0.kind === SyntaxKind.BoltMatchKeyword) {
return this.parseMatchExpression(tokens);
} else if (t0.kind === SyntaxKind.BoltIntegerLiteral || t0.kind === SyntaxKind.BoltStringLiteral) {
return this.parseConstantExpression(tokens);
@ -393,7 +545,7 @@ export class Parser {
return this.parseCallOrPrimitiveExpression(tokens)
}
public parseParameter(tokens: BoltTokenStream): BoltParameter {
public parseParameter(tokens: BoltTokenStream, index: number): BoltParameter {
let defaultValue = null;
let typeDecl = null;
@ -414,7 +566,7 @@ export class Parser {
endNode = defaultValue;
}
const node = createBoltParameter(0, pattern, typeDecl, defaultValue)
const node = createBoltParameter(index, pattern, typeDecl, defaultValue)
setOrigNodeRange(node, pattern, endNode);
return node;
@ -1236,6 +1388,7 @@ export class Parser {
import { Scanner } from "./scanner"
import { TextFile, TextSpan, TextPos } from "./text"
import * as fs from "fs"
import {JSScanner} from "./foreign/js/scanner";
export function parseSourceFile(filepath: string): BoltSourceFile {
const file = new TextFile(filepath);
@ -1246,4 +1399,4 @@ export function parseSourceFile(filepath: string): BoltSourceFile {
setParents(sourceFile);
return sourceFile;
}
;

View file

@ -46,6 +46,8 @@ import {
createBoltTraitKeyword,
createBoltImplKeyword,
createBoltMatchKeyword,
createBoltQuoteKeyword,
createBoltLetKeyword,
} from "./ast"
export enum PunctType {
@ -114,7 +116,7 @@ function isIdentPart(ch: string) {
}
function isSymbol(ch: string) {
return /[=+\/\-*%$!><&^|]/.test(ch)
return /[=+\/\-*%$!><&^|\.]/.test(ch)
}
export class Scanner {
@ -176,7 +178,7 @@ export class Scanner {
return text;
}
scanToken(): BoltToken {
public scan(): BoltToken {
while (true) {
@ -301,9 +303,10 @@ export class Scanner {
case 'impl': return createBoltImplKeyword(span);
case 'type': return createBoltTypeKeyword(span);
case 'foreign': return createBoltForeignKeyword(span);
case 'let': return createBoltPubKeyword(span);
case 'let': return createBoltLetKeyword(span);
case 'mut': return createBoltMutKeyword(span);
case 'struct': return createBoltStructKeyword(span);
case 'quote': return createBoltQuoteKeyword(span);
case 'enum': return createBoltEnumKeyword(span);
default: return createBoltIdentifier(name, span);
}
@ -376,7 +379,7 @@ export class Scanner {
public peek(count = 1): BoltToken {
while (this.scanned.length < count) {
this.scanned.push(this.scanToken());
this.scanned.push(this.scan());
}
return this.scanned[count - 1];
}
@ -384,56 +387,7 @@ export class Scanner {
public get(): BoltToken {
return this.scanned.length > 0
? this.scanned.shift()!
: this.scanToken();
}
scanTokens() {
const elements: BoltSentence[] = []
outer: while (true) {
const tokens: BoltToken[] = [];
inner: while (true) {
const token = this.scanToken();
if (token.kind === SyntaxKind.EndOfFile) {
if (tokens.length === 0) {
break outer;
} else {
break inner;
}
}
if (token.kind === SyntaxKind.BoltSemi) {
break;
}
tokens.push(token)
if (token.kind === SyntaxKind.BoltBraced) {
break;
}
}
if (tokens.length > 0) {
elements.push(
createBoltSentence(
tokens,
new TextSpan(this.file, tokens[0].span!.start.clone(), tokens[tokens.length-1].span!.end.clone())
)
)
}
}
return elements
}
public scan() {
const startPos = this.currPos.clone();
const elements = this.scanTokens();
const endPos = this.currPos.clone();
const sourceFile = createBoltSourceFile(elements, new TextSpan(this.file, startPos, endPos));
setParents(sourceFile);
return sourceFile;
: this.scan();
}
}

View file

@ -249,6 +249,10 @@ export function describeKind(kind: SyntaxKind): string {
return "an integer"
case SyntaxKind.BoltFnKeyword:
return "'fn'"
case SyntaxKind.BoltQuoteKeyword:
return "'quote'";
case SyntaxKind.BoltModKeyword:
return "'mod'";
case SyntaxKind.BoltForeignKeyword:
return "'foreign'"
case SyntaxKind.BoltMatchKeyword: