Extend parser and scanner to support more constructs
This commit is contained in:
parent
9b5cb6ad38
commit
1a349244a0
5 changed files with 468 additions and 222 deletions
31
spec/ast.txt
31
spec/ast.txt
|
@ -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
422
src/ast.d.ts
vendored
|
@ -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;
|
||||
|
|
169
src/parser.ts
169
src/parser.ts
|
@ -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;
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue