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

422
src/ast.d.ts vendored
View file

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

View file

@ -64,6 +64,19 @@ import {
BoltMatchArm, BoltMatchArm,
createBoltMatchExpression, createBoltMatchExpression,
createBoltExpressionPattern, createBoltExpressionPattern,
BoltFunctionTypeExpression,
BoltReferenceTypeExpression,
createBoltFunctionTypeExpression,
BoltRecordPattern,
createBoltRecordPattern,
createBoltRecordFieldPattern,
BoltQuoteKeyword,
isBoltPunctuated,
Token,
createBoltQuoteExpression,
BoltQuoteExpression,
BoltBlockExpression,
createBoltBlockExpression,
} from "./ast" } from "./ast"
import { parseForeignLanguage } from "./foreign" import { parseForeignLanguage } from "./foreign"
@ -77,6 +90,7 @@ import {
setOrigNodeRange, setOrigNodeRange,
createTokenStream, createTokenStream,
uniq, uniq,
assert,
} from "./util" } from "./util"
export type BoltTokenStream = Stream<BoltToken>; export type BoltTokenStream = Stream<BoltToken>;
@ -99,6 +113,7 @@ const KIND_EXPRESSION_T0 = [
SyntaxKind.BoltIdentifier, SyntaxKind.BoltIdentifier,
SyntaxKind.BoltOperator, SyntaxKind.BoltOperator,
SyntaxKind.BoltMatchKeyword, SyntaxKind.BoltMatchKeyword,
SyntaxKind.BoltQuoteKeyword,
SyntaxKind.BoltYieldKeyword, SyntaxKind.BoltYieldKeyword,
] ]
@ -205,9 +220,62 @@ export class Parser {
return node; 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 { public parsePattern(tokens: BoltTokenStream): BoltPattern {
const t0 = tokens.peek(1); 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); return this.parseBindPattern(tokens);
} else if (t0.kind === SyntaxKind.BoltOperator && t0.text === '^') { } else if (t0.kind === SyntaxKind.BoltOperator && t0.text === '^') {
tokens.get(); tokens.get();
@ -242,7 +310,40 @@ export class Parser {
return node; 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) const name = this.parseQualName(tokens)
@ -278,7 +379,9 @@ export class Parser {
private parsePrimTypeExpression(tokens: BoltTokenStream): BoltTypeExpression { private parsePrimTypeExpression(tokens: BoltTokenStream): BoltTypeExpression {
const t0 = tokens.peek(); 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); return this.parseReferenceTypeExpression(tokens);
} else { } else {
throw new ParseError(t0, [SyntaxKind.BoltIdentifier]); throw new ParseError(t0, [SyntaxKind.BoltIdentifier]);
@ -376,9 +479,58 @@ export class Parser {
return result; 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(); 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); return this.parseMatchExpression(tokens);
} else if (t0.kind === SyntaxKind.BoltIntegerLiteral || t0.kind === SyntaxKind.BoltStringLiteral) { } else if (t0.kind === SyntaxKind.BoltIntegerLiteral || t0.kind === SyntaxKind.BoltStringLiteral) {
return this.parseConstantExpression(tokens); return this.parseConstantExpression(tokens);
@ -393,7 +545,7 @@ export class Parser {
return this.parseCallOrPrimitiveExpression(tokens) return this.parseCallOrPrimitiveExpression(tokens)
} }
public parseParameter(tokens: BoltTokenStream): BoltParameter { public parseParameter(tokens: BoltTokenStream, index: number): BoltParameter {
let defaultValue = null; let defaultValue = null;
let typeDecl = null; let typeDecl = null;
@ -414,7 +566,7 @@ export class Parser {
endNode = defaultValue; endNode = defaultValue;
} }
const node = createBoltParameter(0, pattern, typeDecl, defaultValue) const node = createBoltParameter(index, pattern, typeDecl, defaultValue)
setOrigNodeRange(node, pattern, endNode); setOrigNodeRange(node, pattern, endNode);
return node; return node;
@ -970,7 +1122,7 @@ export class Parser {
i += 2; i += 2;
t0 = tokens.peek(i); t0 = tokens.peek(i);
} }
if (mustBeFunctionOrVariable if (mustBeFunctionOrVariable
&& t0.kind !== SyntaxKind.BoltStructKeyword && t0.kind !== SyntaxKind.BoltStructKeyword
&& t0.kind !== SyntaxKind.BoltFnKeyword) { && t0.kind !== SyntaxKind.BoltFnKeyword) {
throw new ParseError(t0, [SyntaxKind.BoltStructKeyword, SyntaxKind.BoltFnKeyword]); throw new ParseError(t0, [SyntaxKind.BoltStructKeyword, SyntaxKind.BoltFnKeyword]);
@ -1236,6 +1388,7 @@ export class Parser {
import { Scanner } from "./scanner" import { Scanner } from "./scanner"
import { TextFile, TextSpan, TextPos } from "./text" import { TextFile, TextSpan, TextPos } from "./text"
import * as fs from "fs" import * as fs from "fs"
import {JSScanner} from "./foreign/js/scanner";
export function parseSourceFile(filepath: string): BoltSourceFile { export function parseSourceFile(filepath: string): BoltSourceFile {
const file = new TextFile(filepath); const file = new TextFile(filepath);
@ -1246,4 +1399,4 @@ export function parseSourceFile(filepath: string): BoltSourceFile {
setParents(sourceFile); setParents(sourceFile);
return sourceFile; return sourceFile;
} }
;

View file

@ -46,6 +46,8 @@ import {
createBoltTraitKeyword, createBoltTraitKeyword,
createBoltImplKeyword, createBoltImplKeyword,
createBoltMatchKeyword, createBoltMatchKeyword,
createBoltQuoteKeyword,
createBoltLetKeyword,
} from "./ast" } from "./ast"
export enum PunctType { export enum PunctType {
@ -114,7 +116,7 @@ function isIdentPart(ch: string) {
} }
function isSymbol(ch: string) { function isSymbol(ch: string) {
return /[=+\/\-*%$!><&^|]/.test(ch) return /[=+\/\-*%$!><&^|\.]/.test(ch)
} }
export class Scanner { export class Scanner {
@ -176,7 +178,7 @@ export class Scanner {
return text; return text;
} }
scanToken(): BoltToken { public scan(): BoltToken {
while (true) { while (true) {
@ -301,9 +303,10 @@ export class Scanner {
case 'impl': return createBoltImplKeyword(span); case 'impl': return createBoltImplKeyword(span);
case 'type': return createBoltTypeKeyword(span); case 'type': return createBoltTypeKeyword(span);
case 'foreign': return createBoltForeignKeyword(span); case 'foreign': return createBoltForeignKeyword(span);
case 'let': return createBoltPubKeyword(span); case 'let': return createBoltLetKeyword(span);
case 'mut': return createBoltMutKeyword(span); case 'mut': return createBoltMutKeyword(span);
case 'struct': return createBoltStructKeyword(span); case 'struct': return createBoltStructKeyword(span);
case 'quote': return createBoltQuoteKeyword(span);
case 'enum': return createBoltEnumKeyword(span); case 'enum': return createBoltEnumKeyword(span);
default: return createBoltIdentifier(name, span); default: return createBoltIdentifier(name, span);
} }
@ -376,7 +379,7 @@ export class Scanner {
public peek(count = 1): BoltToken { public peek(count = 1): BoltToken {
while (this.scanned.length < count) { while (this.scanned.length < count) {
this.scanned.push(this.scanToken()); this.scanned.push(this.scan());
} }
return this.scanned[count - 1]; return this.scanned[count - 1];
} }
@ -384,56 +387,7 @@ export class Scanner {
public get(): BoltToken { public get(): BoltToken {
return this.scanned.length > 0 return this.scanned.length > 0
? this.scanned.shift()! ? this.scanned.shift()!
: this.scanToken(); : this.scan();
}
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;
} }
} }

View file

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