Update the parser and related files
- Extend the parser to support many more constructs - Add basic structure for parsing embedded JavaScript - Remove and update some AST definitions - Fix some bugs
This commit is contained in:
parent
9e139c40a9
commit
70b219d6df
9 changed files with 755 additions and 245 deletions
59
spec/ast.txt
59
spec/ast.txt
|
@ -2,6 +2,8 @@
|
|||
@language Bolt;
|
||||
@language JS;
|
||||
|
||||
node EndOfFile > BoltToken, JSToken;
|
||||
|
||||
// Bolt language AST definitions
|
||||
|
||||
type BoltValue = Integer | bool | String;
|
||||
|
@ -34,8 +36,6 @@ node BoltAssignment > BoltToken {
|
|||
operator: Option<String>,
|
||||
}
|
||||
|
||||
node BoltEOS > BoltToken;
|
||||
|
||||
node BoltComma > BoltToken;
|
||||
node BoltSemi > BoltToken;
|
||||
node BoltColon > BoltToken;
|
||||
|
@ -62,7 +62,8 @@ node BoltModKeyword > BoltToken, BoltKeyword;
|
|||
node BoltMutKeyword > BoltToken, BoltKeyword;
|
||||
node BoltEnumKeyword > BoltToken, BoltKeyword;
|
||||
node BoltStructKeyword > BoltToken, BoltKeyword;
|
||||
node BoltNewTypeKeyword > BoltToken, BoltKeyword;
|
||||
node BoltTypeKeyword > BoltToken, BoltKeyword;
|
||||
node BoltTraitKeyworkd > BoltToken, BoltKeyword;
|
||||
|
||||
node BoltPunctuated > BoltToken {
|
||||
text: String,
|
||||
|
@ -85,11 +86,17 @@ node BoltSentence > BoltSourceElement {
|
|||
tokens: Vec<BoltToken>,
|
||||
}
|
||||
|
||||
node BoltTypeNode;
|
||||
node BoltTypeExpression;
|
||||
|
||||
node BoltReferenceTypeNode > BoltTypeNode {
|
||||
node BoltReferenceTypeExpression > BoltTypeExpression {
|
||||
name: BoltQualName,
|
||||
arguments: Option<Vec<BoltTypeNode>>,
|
||||
arguments: Option<Vec<BoltTypeExpression>>,
|
||||
}
|
||||
|
||||
node BoltTypeParameter {
|
||||
index: usize,
|
||||
name: BoltIdentifier,
|
||||
defaultType: Option<BoltTypeExpression>,
|
||||
}
|
||||
|
||||
node BoltPattern;
|
||||
|
@ -99,7 +106,7 @@ node BoltBindPattern > BoltPattern {
|
|||
}
|
||||
|
||||
node BoltTypePattern > BoltPattern {
|
||||
type: BoltTypeNode,
|
||||
type: BoltTypeExpression,
|
||||
nestedPattern: BoltPattern,
|
||||
}
|
||||
|
||||
|
@ -122,7 +129,7 @@ node BoltRecordPatternField {
|
|||
}
|
||||
|
||||
node BoltRecordPattern > BoltPattern {
|
||||
name: BoltTypeNode,
|
||||
name: BoltTypeExpression,
|
||||
fields: Vec<BoltRecordPatternField>,
|
||||
}
|
||||
|
||||
|
@ -185,12 +192,14 @@ node BoltExpressionStatement > BoltStatement {
|
|||
node BoltParameter {
|
||||
index: usize,
|
||||
bindings: BoltPattern,
|
||||
type: Option<BoltTypeNode>,
|
||||
type: Option<BoltTypeExpression>,
|
||||
defaultValue: Option<BoltExpression>,
|
||||
}
|
||||
|
||||
node BoltDeclaration > BoltSourceElement;
|
||||
|
||||
node BoltTypeDeclaration > BoltDeclaration;
|
||||
|
||||
enum BoltDeclarationModifiers {
|
||||
Mutable = 0x1,
|
||||
Public = 0x2,
|
||||
|
@ -198,10 +207,6 @@ enum BoltDeclarationModifiers {
|
|||
IsForeign = 0x8,
|
||||
}
|
||||
|
||||
node BoltNewTypeDeclaration > BoltDeclaration {
|
||||
modifiers: BoltDeclarationModifiers,
|
||||
name: BoltIdentifier,
|
||||
}
|
||||
|
||||
node BoltModule > BoltDeclaration {
|
||||
modifiers: BoltDeclarationModifiers,
|
||||
|
@ -214,14 +219,14 @@ node BoltFunctionDeclaration > BoltDeclaration {
|
|||
target: String,
|
||||
name: BoltSymbol,
|
||||
params: Vec<BoltParameter>,
|
||||
returnType: Option<BoltTypeNode>,
|
||||
returnType: Option<BoltTypeExpression>,
|
||||
body: Vec<BoltStatement>,
|
||||
}
|
||||
|
||||
node BoltVariableDeclaration > BoltDeclaration {
|
||||
modifiers: BoltDeclarationModifiers,
|
||||
bindings: BoltPattern,
|
||||
type: Option<BoltTypeNode>,
|
||||
type: Option<BoltTypeExpression>,
|
||||
value: Option<BoltExpression>,
|
||||
}
|
||||
|
||||
|
@ -238,14 +243,22 @@ node BoltImportDeclaration > BoltDeclaration {
|
|||
|
||||
node BoltRecordDeclarationField {
|
||||
name: BoltIdentifier,
|
||||
type: BoltTypeNode,
|
||||
type: BoltTypeExpression,
|
||||
}
|
||||
|
||||
node BoltTypeAliasDeclaration > BoltTypeDeclaration {
|
||||
modifiers: BoltDeclarationModifiers,
|
||||
name: BoltIdentifier,
|
||||
typeParams: Option<Vec<BoltTypeParameter>>,
|
||||
typeExpr: BoltTypeExpression,
|
||||
}
|
||||
|
||||
node BoltSourceElement;
|
||||
|
||||
node BoltRecordDeclaration > BoltDeclaration {
|
||||
node BoltRecordDeclaration > BoltTypeDeclaration {
|
||||
modifiers: BoltDeclarationModifiers,
|
||||
name: BoltQualName,
|
||||
typeParms: Option<Vec<BoltTypeParameter>>,
|
||||
fields: Vec<BoltRecordDeclarationField>,
|
||||
}
|
||||
|
||||
|
@ -263,6 +276,10 @@ node JSIdentifier > JSToken {
|
|||
text: String,
|
||||
}
|
||||
|
||||
node JSReturnKeyword > JSToken;
|
||||
node JSTryKeyword > JSToken;
|
||||
node JSCatchKeyword > JSToken;
|
||||
|
||||
node JSPattern;
|
||||
|
||||
node JSBindPattern > JSPattern {
|
||||
|
@ -320,7 +337,9 @@ node JSReferenceExpression > JSExpression {
|
|||
name: String,
|
||||
}
|
||||
|
||||
node JSStatement;
|
||||
node JSSourceElement;
|
||||
|
||||
node JSStatement > JSSourceElement;
|
||||
|
||||
node JSExpressionStatement > JSStatement {
|
||||
expression: JSExpression,
|
||||
|
@ -338,7 +357,7 @@ node JSParameter {
|
|||
defaultValue: Option<JSExpression>,
|
||||
}
|
||||
|
||||
node JSDeclaration;
|
||||
node JSDeclaration > JSSourceElement;
|
||||
|
||||
enum JSDeclarationModifiers {
|
||||
IsExported = 0x1,
|
||||
|
@ -366,5 +385,3 @@ node JSSourceFile {
|
|||
elements: Vec<JSSourceElement>,
|
||||
}
|
||||
|
||||
node JSSourceElement > JSDeclaration, JSStatement;
|
||||
|
||||
|
|
318
src/ast.d.ts
vendored
318
src/ast.d.ts
vendored
|
@ -1,12 +1,12 @@
|
|||
|
||||
export const enum SyntaxKind {
|
||||
FunctionBody = 3,
|
||||
BoltStringLiteral = 5,
|
||||
BoltIntegerLiteral = 6,
|
||||
BoltIdentifier = 8,
|
||||
BoltOperator = 9,
|
||||
BoltAssignment = 10,
|
||||
BoltEOS = 11,
|
||||
EndOfFile = 2,
|
||||
FunctionBody = 4,
|
||||
BoltStringLiteral = 6,
|
||||
BoltIntegerLiteral = 7,
|
||||
BoltIdentifier = 9,
|
||||
BoltOperator = 10,
|
||||
BoltAssignment = 11,
|
||||
BoltComma = 12,
|
||||
BoltSemi = 13,
|
||||
BoltColon = 14,
|
||||
|
@ -30,62 +30,66 @@ export const enum SyntaxKind {
|
|||
BoltMutKeyword = 33,
|
||||
BoltEnumKeyword = 34,
|
||||
BoltStructKeyword = 35,
|
||||
BoltNewTypeKeyword = 36,
|
||||
BoltParenthesized = 38,
|
||||
BoltBraced = 39,
|
||||
BoltBracketed = 40,
|
||||
BoltSourceFile = 41,
|
||||
BoltQualName = 42,
|
||||
BoltSentence = 43,
|
||||
BoltReferenceTypeNode = 45,
|
||||
BoltBindPattern = 47,
|
||||
BoltTypePattern = 48,
|
||||
BoltExpressionPattern = 49,
|
||||
BoltTuplePatternElement = 50,
|
||||
BoltTuplePattern = 51,
|
||||
BoltRecordPatternField = 52,
|
||||
BoltRecordPattern = 53,
|
||||
BoltReferenceExpression = 55,
|
||||
BoltCallExpression = 56,
|
||||
BoltYieldExpression = 57,
|
||||
BoltMatchArm = 58,
|
||||
BoltMatchExpression = 59,
|
||||
BoltCase = 60,
|
||||
BoltCaseExpression = 61,
|
||||
BoltBlockExpression = 62,
|
||||
BoltConstantExpression = 63,
|
||||
BoltReturnStatement = 65,
|
||||
BoltResumeStatement = 66,
|
||||
BoltExpressionStatement = 67,
|
||||
BoltParameter = 68,
|
||||
BoltNewTypeDeclaration = 71,
|
||||
BoltModule = 72,
|
||||
BoltFunctionDeclaration = 73,
|
||||
BoltVariableDeclaration = 74,
|
||||
BoltPlainImportSymbol = 76,
|
||||
BoltImportDeclaration = 77,
|
||||
BoltRecordDeclarationField = 78,
|
||||
BoltRecordDeclaration = 80,
|
||||
JSOperator = 83,
|
||||
JSIdentifier = 84,
|
||||
JSBindPattern = 86,
|
||||
JSConstantExpression = 88,
|
||||
JSMemberExpression = 90,
|
||||
JSCallExpression = 91,
|
||||
JSBinaryExpression = 92,
|
||||
JSUnaryExpression = 93,
|
||||
JSNewExpression = 94,
|
||||
JSSequenceExpression = 95,
|
||||
JSConditionalExpression = 96,
|
||||
JSReferenceExpression = 97,
|
||||
JSExpressionStatement = 99,
|
||||
JSConditionalStatement = 100,
|
||||
JSParameter = 101,
|
||||
JSFunctionDeclaration = 104,
|
||||
JSArrowFunctionDeclaration = 105,
|
||||
JSLetDeclaration = 106,
|
||||
JSSourceFile = 107,
|
||||
JSSourceElement = 108,
|
||||
BoltTypeKeyword = 36,
|
||||
BoltTraitKeyworkd = 37,
|
||||
BoltParenthesized = 39,
|
||||
BoltBraced = 40,
|
||||
BoltBracketed = 41,
|
||||
BoltSourceFile = 42,
|
||||
BoltQualName = 43,
|
||||
BoltSentence = 44,
|
||||
BoltReferenceTypeExpression = 46,
|
||||
BoltTypeParameter = 47,
|
||||
BoltBindPattern = 49,
|
||||
BoltTypePattern = 50,
|
||||
BoltExpressionPattern = 51,
|
||||
BoltTuplePatternElement = 52,
|
||||
BoltTuplePattern = 53,
|
||||
BoltRecordPatternField = 54,
|
||||
BoltRecordPattern = 55,
|
||||
BoltReferenceExpression = 57,
|
||||
BoltCallExpression = 58,
|
||||
BoltYieldExpression = 59,
|
||||
BoltMatchArm = 60,
|
||||
BoltMatchExpression = 61,
|
||||
BoltCase = 62,
|
||||
BoltCaseExpression = 63,
|
||||
BoltBlockExpression = 64,
|
||||
BoltConstantExpression = 65,
|
||||
BoltReturnStatement = 67,
|
||||
BoltResumeStatement = 68,
|
||||
BoltExpressionStatement = 69,
|
||||
BoltParameter = 70,
|
||||
BoltModule = 74,
|
||||
BoltFunctionDeclaration = 75,
|
||||
BoltVariableDeclaration = 76,
|
||||
BoltPlainImportSymbol = 78,
|
||||
BoltImportDeclaration = 79,
|
||||
BoltRecordDeclarationField = 80,
|
||||
BoltTypeAliasDeclaration = 81,
|
||||
BoltRecordDeclaration = 83,
|
||||
JSOperator = 86,
|
||||
JSIdentifier = 87,
|
||||
JSReturnKeyword = 88,
|
||||
JSTryKeyword = 89,
|
||||
JSCatchKeyword = 90,
|
||||
JSBindPattern = 92,
|
||||
JSConstantExpression = 94,
|
||||
JSMemberExpression = 96,
|
||||
JSCallExpression = 97,
|
||||
JSBinaryExpression = 98,
|
||||
JSUnaryExpression = 99,
|
||||
JSNewExpression = 100,
|
||||
JSSequenceExpression = 101,
|
||||
JSConditionalExpression = 102,
|
||||
JSReferenceExpression = 103,
|
||||
JSExpressionStatement = 106,
|
||||
JSConditionalStatement = 107,
|
||||
JSParameter = 108,
|
||||
JSFunctionDeclaration = 111,
|
||||
JSArrowFunctionDeclaration = 112,
|
||||
JSLetDeclaration = 113,
|
||||
JSSourceFile = 114,
|
||||
}
|
||||
|
||||
|
||||
|
@ -101,17 +105,21 @@ interface SyntaxBase {
|
|||
parentNode: Syntax | null;
|
||||
span: TextSpan | null;
|
||||
}
|
||||
export interface EndOfFile extends SyntaxBase {
|
||||
kind: SyntaxKind.EndOfFile;
|
||||
}
|
||||
|
||||
export interface FunctionBody extends SyntaxBase {
|
||||
kind: SyntaxKind.FunctionBody;
|
||||
}
|
||||
|
||||
export type BoltToken
|
||||
= BoltStringLiteral
|
||||
= EndOfFile
|
||||
| BoltStringLiteral
|
||||
| BoltIntegerLiteral
|
||||
| BoltIdentifier
|
||||
| BoltOperator
|
||||
| BoltAssignment
|
||||
| BoltEOS
|
||||
| BoltComma
|
||||
| BoltSemi
|
||||
| BoltColon
|
||||
|
@ -135,7 +143,8 @@ export type BoltToken
|
|||
| BoltMutKeyword
|
||||
| BoltEnumKeyword
|
||||
| BoltStructKeyword
|
||||
| BoltNewTypeKeyword
|
||||
| BoltTypeKeyword
|
||||
| BoltTraitKeyworkd
|
||||
| BoltParenthesized
|
||||
| BoltBraced
|
||||
| BoltBracketed
|
||||
|
@ -171,10 +180,6 @@ export interface BoltAssignment extends SyntaxBase {
|
|||
operator: string | null;
|
||||
}
|
||||
|
||||
export interface BoltEOS extends SyntaxBase {
|
||||
kind: SyntaxKind.BoltEOS;
|
||||
}
|
||||
|
||||
export interface BoltComma extends SyntaxBase {
|
||||
kind: SyntaxKind.BoltComma;
|
||||
}
|
||||
|
@ -229,7 +234,8 @@ export type BoltKeyword
|
|||
| BoltMutKeyword
|
||||
| BoltEnumKeyword
|
||||
| BoltStructKeyword
|
||||
| BoltNewTypeKeyword
|
||||
| BoltTypeKeyword
|
||||
| BoltTraitKeyworkd
|
||||
|
||||
|
||||
export interface BoltFnKeyword extends SyntaxBase {
|
||||
|
@ -284,8 +290,12 @@ export interface BoltStructKeyword extends SyntaxBase {
|
|||
kind: SyntaxKind.BoltStructKeyword;
|
||||
}
|
||||
|
||||
export interface BoltNewTypeKeyword extends SyntaxBase {
|
||||
kind: SyntaxKind.BoltNewTypeKeyword;
|
||||
export interface BoltTypeKeyword extends SyntaxBase {
|
||||
kind: SyntaxKind.BoltTypeKeyword;
|
||||
}
|
||||
|
||||
export interface BoltTraitKeyworkd extends SyntaxBase {
|
||||
kind: SyntaxKind.BoltTraitKeyworkd;
|
||||
}
|
||||
|
||||
export type BoltPunctuated
|
||||
|
@ -325,14 +335,21 @@ export interface BoltSentence extends SyntaxBase {
|
|||
tokens: BoltToken[];
|
||||
}
|
||||
|
||||
export type BoltTypeNode
|
||||
= BoltReferenceTypeNode
|
||||
export type BoltTypeExpression
|
||||
= BoltReferenceTypeExpression
|
||||
|
||||
|
||||
export interface BoltReferenceTypeNode extends SyntaxBase {
|
||||
kind: SyntaxKind.BoltReferenceTypeNode;
|
||||
export interface BoltReferenceTypeExpression extends SyntaxBase {
|
||||
kind: SyntaxKind.BoltReferenceTypeExpression;
|
||||
name: BoltQualName;
|
||||
arguments: BoltTypeNode[] | null;
|
||||
arguments: BoltTypeExpression[] | null;
|
||||
}
|
||||
|
||||
export interface BoltTypeParameter extends SyntaxBase {
|
||||
kind: SyntaxKind.BoltTypeParameter;
|
||||
index: number;
|
||||
name: BoltIdentifier;
|
||||
defaultType: BoltTypeExpression | null;
|
||||
}
|
||||
|
||||
export type BoltPattern
|
||||
|
@ -350,7 +367,7 @@ export interface BoltBindPattern extends SyntaxBase {
|
|||
|
||||
export interface BoltTypePattern extends SyntaxBase {
|
||||
kind: SyntaxKind.BoltTypePattern;
|
||||
type: BoltTypeNode;
|
||||
type: BoltTypeExpression;
|
||||
nestedPattern: BoltPattern;
|
||||
}
|
||||
|
||||
|
@ -378,7 +395,7 @@ export interface BoltRecordPatternField extends SyntaxBase {
|
|||
|
||||
export interface BoltRecordPattern extends SyntaxBase {
|
||||
kind: SyntaxKind.BoltRecordPattern;
|
||||
name: BoltTypeNode;
|
||||
name: BoltTypeExpression;
|
||||
fields: BoltRecordPatternField[];
|
||||
}
|
||||
|
||||
|
@ -466,28 +483,27 @@ export interface BoltParameter extends SyntaxBase {
|
|||
kind: SyntaxKind.BoltParameter;
|
||||
index: number;
|
||||
bindings: BoltPattern;
|
||||
type: BoltTypeNode | null;
|
||||
type: BoltTypeExpression | null;
|
||||
defaultValue: BoltExpression | null;
|
||||
}
|
||||
|
||||
export type BoltDeclaration
|
||||
= BoltNewTypeDeclaration
|
||||
= BoltTypeAliasDeclaration
|
||||
| BoltRecordDeclaration
|
||||
| BoltModule
|
||||
| BoltFunctionDeclaration
|
||||
| BoltVariableDeclaration
|
||||
| BoltImportDeclaration
|
||||
|
||||
|
||||
export type BoltTypeDeclaration
|
||||
= BoltTypeAliasDeclaration
|
||||
| BoltRecordDeclaration
|
||||
|
||||
|
||||
export const enum BoltDeclarationModifiers {
|
||||
Mutable = 1,Public = 2,IsType = 4,IsForeign = 8,}
|
||||
|
||||
export interface BoltNewTypeDeclaration extends SyntaxBase {
|
||||
kind: SyntaxKind.BoltNewTypeDeclaration;
|
||||
modifiers: BoltDeclarationModifiers;
|
||||
name: BoltIdentifier;
|
||||
}
|
||||
|
||||
export interface BoltModule extends SyntaxBase {
|
||||
kind: SyntaxKind.BoltModule;
|
||||
modifiers: BoltDeclarationModifiers;
|
||||
|
@ -501,7 +517,7 @@ export interface BoltFunctionDeclaration extends SyntaxBase {
|
|||
target: string;
|
||||
name: BoltSymbol;
|
||||
params: BoltParameter[];
|
||||
returnType: BoltTypeNode | null;
|
||||
returnType: BoltTypeExpression | null;
|
||||
body: BoltStatement[];
|
||||
}
|
||||
|
||||
|
@ -509,7 +525,7 @@ export interface BoltVariableDeclaration extends SyntaxBase {
|
|||
kind: SyntaxKind.BoltVariableDeclaration;
|
||||
modifiers: BoltDeclarationModifiers;
|
||||
bindings: BoltPattern;
|
||||
type: BoltTypeNode | null;
|
||||
type: BoltTypeExpression | null;
|
||||
value: BoltExpression | null;
|
||||
}
|
||||
|
||||
|
@ -531,7 +547,15 @@ export interface BoltImportDeclaration extends SyntaxBase {
|
|||
export interface BoltRecordDeclarationField extends SyntaxBase {
|
||||
kind: SyntaxKind.BoltRecordDeclarationField;
|
||||
name: BoltIdentifier;
|
||||
type: BoltTypeNode;
|
||||
type: BoltTypeExpression;
|
||||
}
|
||||
|
||||
export interface BoltTypeAliasDeclaration extends SyntaxBase {
|
||||
kind: SyntaxKind.BoltTypeAliasDeclaration;
|
||||
modifiers: BoltDeclarationModifiers;
|
||||
name: BoltIdentifier;
|
||||
typeParams: BoltTypeParameter[] | null;
|
||||
typeExpr: BoltTypeExpression;
|
||||
}
|
||||
|
||||
export type BoltSourceElement
|
||||
|
@ -539,24 +563,29 @@ export type BoltSourceElement
|
|||
| BoltReturnStatement
|
||||
| BoltResumeStatement
|
||||
| BoltExpressionStatement
|
||||
| BoltNewTypeDeclaration
|
||||
| BoltTypeAliasDeclaration
|
||||
| BoltRecordDeclaration
|
||||
| BoltModule
|
||||
| BoltFunctionDeclaration
|
||||
| BoltVariableDeclaration
|
||||
| BoltImportDeclaration
|
||||
| BoltRecordDeclaration
|
||||
|
||||
|
||||
export interface BoltRecordDeclaration extends SyntaxBase {
|
||||
kind: SyntaxKind.BoltRecordDeclaration;
|
||||
modifiers: BoltDeclarationModifiers;
|
||||
name: BoltQualName;
|
||||
typeParms: BoltTypeParameter[] | null;
|
||||
fields: BoltRecordDeclarationField[];
|
||||
}
|
||||
|
||||
export type JSToken
|
||||
= JSOperator
|
||||
= EndOfFile
|
||||
| JSOperator
|
||||
| JSIdentifier
|
||||
| JSReturnKeyword
|
||||
| JSTryKeyword
|
||||
| JSCatchKeyword
|
||||
|
||||
|
||||
export interface JSOperator extends SyntaxBase {
|
||||
|
@ -569,6 +598,18 @@ export interface JSIdentifier extends SyntaxBase {
|
|||
text: string;
|
||||
}
|
||||
|
||||
export interface JSReturnKeyword extends SyntaxBase {
|
||||
kind: SyntaxKind.JSReturnKeyword;
|
||||
}
|
||||
|
||||
export interface JSTryKeyword extends SyntaxBase {
|
||||
kind: SyntaxKind.JSTryKeyword;
|
||||
}
|
||||
|
||||
export interface JSCatchKeyword extends SyntaxBase {
|
||||
kind: SyntaxKind.JSCatchKeyword;
|
||||
}
|
||||
|
||||
export type JSPattern
|
||||
= JSBindPattern
|
||||
|
||||
|
@ -647,10 +688,17 @@ export interface JSReferenceExpression extends SyntaxBase {
|
|||
name: string;
|
||||
}
|
||||
|
||||
export type JSSourceElement
|
||||
= JSExpressionStatement
|
||||
| JSConditionalStatement
|
||||
| JSFunctionDeclaration
|
||||
| JSArrowFunctionDeclaration
|
||||
| JSLetDeclaration
|
||||
|
||||
|
||||
export type JSStatement
|
||||
= JSExpressionStatement
|
||||
| JSConditionalStatement
|
||||
| JSSourceElement
|
||||
|
||||
|
||||
export interface JSExpressionStatement extends SyntaxBase {
|
||||
|
@ -676,7 +724,6 @@ export type JSDeclaration
|
|||
= JSFunctionDeclaration
|
||||
| JSArrowFunctionDeclaration
|
||||
| JSLetDeclaration
|
||||
| JSSourceElement
|
||||
|
||||
|
||||
export const enum JSDeclarationModifiers {
|
||||
|
@ -708,17 +755,12 @@ export interface JSSourceFile extends SyntaxBase {
|
|||
elements: JSSourceElement[];
|
||||
}
|
||||
|
||||
export interface JSSourceElement extends SyntaxBase {
|
||||
kind: SyntaxKind.JSSourceElement;
|
||||
}
|
||||
|
||||
export type BoltSyntax
|
||||
= BoltStringLiteral
|
||||
| BoltIntegerLiteral
|
||||
| BoltIdentifier
|
||||
| BoltOperator
|
||||
| BoltAssignment
|
||||
| BoltEOS
|
||||
| BoltComma
|
||||
| BoltSemi
|
||||
| BoltColon
|
||||
|
@ -742,14 +784,16 @@ export type BoltSyntax
|
|||
| BoltMutKeyword
|
||||
| BoltEnumKeyword
|
||||
| BoltStructKeyword
|
||||
| BoltNewTypeKeyword
|
||||
| BoltTypeKeyword
|
||||
| BoltTraitKeyworkd
|
||||
| BoltParenthesized
|
||||
| BoltBraced
|
||||
| BoltBracketed
|
||||
| BoltSourceFile
|
||||
| BoltQualName
|
||||
| BoltSentence
|
||||
| BoltReferenceTypeNode
|
||||
| BoltReferenceTypeExpression
|
||||
| BoltTypeParameter
|
||||
| BoltBindPattern
|
||||
| BoltTypePattern
|
||||
| BoltExpressionPattern
|
||||
|
@ -770,19 +814,22 @@ export type BoltSyntax
|
|||
| BoltResumeStatement
|
||||
| BoltExpressionStatement
|
||||
| BoltParameter
|
||||
| BoltNewTypeDeclaration
|
||||
| BoltModule
|
||||
| BoltFunctionDeclaration
|
||||
| BoltVariableDeclaration
|
||||
| BoltPlainImportSymbol
|
||||
| BoltImportDeclaration
|
||||
| BoltRecordDeclarationField
|
||||
| BoltTypeAliasDeclaration
|
||||
| BoltRecordDeclaration
|
||||
|
||||
|
||||
export type JSSyntax
|
||||
= JSOperator
|
||||
| JSIdentifier
|
||||
| JSReturnKeyword
|
||||
| JSTryKeyword
|
||||
| JSCatchKeyword
|
||||
| JSBindPattern
|
||||
| JSConstantExpression
|
||||
| JSMemberExpression
|
||||
|
@ -800,17 +847,16 @@ export type JSSyntax
|
|||
| JSArrowFunctionDeclaration
|
||||
| JSLetDeclaration
|
||||
| JSSourceFile
|
||||
| JSSourceElement
|
||||
|
||||
|
||||
export type Syntax
|
||||
= FunctionBody
|
||||
= EndOfFile
|
||||
| FunctionBody
|
||||
| BoltStringLiteral
|
||||
| BoltIntegerLiteral
|
||||
| BoltIdentifier
|
||||
| BoltOperator
|
||||
| BoltAssignment
|
||||
| BoltEOS
|
||||
| BoltComma
|
||||
| BoltSemi
|
||||
| BoltColon
|
||||
|
@ -834,14 +880,16 @@ export type Syntax
|
|||
| BoltMutKeyword
|
||||
| BoltEnumKeyword
|
||||
| BoltStructKeyword
|
||||
| BoltNewTypeKeyword
|
||||
| BoltTypeKeyword
|
||||
| BoltTraitKeyworkd
|
||||
| BoltParenthesized
|
||||
| BoltBraced
|
||||
| BoltBracketed
|
||||
| BoltSourceFile
|
||||
| BoltQualName
|
||||
| BoltSentence
|
||||
| BoltReferenceTypeNode
|
||||
| BoltReferenceTypeExpression
|
||||
| BoltTypeParameter
|
||||
| BoltBindPattern
|
||||
| BoltTypePattern
|
||||
| BoltExpressionPattern
|
||||
|
@ -862,16 +910,19 @@ export type Syntax
|
|||
| BoltResumeStatement
|
||||
| BoltExpressionStatement
|
||||
| BoltParameter
|
||||
| BoltNewTypeDeclaration
|
||||
| BoltModule
|
||||
| BoltFunctionDeclaration
|
||||
| BoltVariableDeclaration
|
||||
| BoltPlainImportSymbol
|
||||
| BoltImportDeclaration
|
||||
| BoltRecordDeclarationField
|
||||
| BoltTypeAliasDeclaration
|
||||
| BoltRecordDeclaration
|
||||
| JSOperator
|
||||
| JSIdentifier
|
||||
| JSReturnKeyword
|
||||
| JSTryKeyword
|
||||
| JSCatchKeyword
|
||||
| JSBindPattern
|
||||
| JSConstantExpression
|
||||
| JSMemberExpression
|
||||
|
@ -889,18 +940,17 @@ export type Syntax
|
|||
| JSArrowFunctionDeclaration
|
||||
| JSLetDeclaration
|
||||
| JSSourceFile
|
||||
| JSSourceElement
|
||||
|
||||
|
||||
export function kindToString(kind: SyntaxKind): string;
|
||||
|
||||
export function createEndOfFile(span?: TextSpan | null): EndOfFile;
|
||||
export function createFunctionBody(span?: TextSpan | null): FunctionBody;
|
||||
export function createBoltStringLiteral(value: string, span?: TextSpan | null): BoltStringLiteral;
|
||||
export function createBoltIntegerLiteral(value: bigint, span?: TextSpan | null): BoltIntegerLiteral;
|
||||
export function createBoltIdentifier(text: string, span?: TextSpan | null): BoltIdentifier;
|
||||
export function createBoltOperator(text: string, span?: TextSpan | null): BoltOperator;
|
||||
export function createBoltAssignment(operator: string | null, span?: TextSpan | null): BoltAssignment;
|
||||
export function createBoltEOS(span?: TextSpan | null): BoltEOS;
|
||||
export function createBoltComma(span?: TextSpan | null): BoltComma;
|
||||
export function createBoltSemi(span?: TextSpan | null): BoltSemi;
|
||||
export function createBoltColon(span?: TextSpan | null): BoltColon;
|
||||
|
@ -924,21 +974,23 @@ export function createBoltModKeyword(span?: TextSpan | null): BoltModKeyword;
|
|||
export function createBoltMutKeyword(span?: TextSpan | null): BoltMutKeyword;
|
||||
export function createBoltEnumKeyword(span?: TextSpan | null): BoltEnumKeyword;
|
||||
export function createBoltStructKeyword(span?: TextSpan | null): BoltStructKeyword;
|
||||
export function createBoltNewTypeKeyword(span?: TextSpan | null): BoltNewTypeKeyword;
|
||||
export function createBoltTypeKeyword(span?: TextSpan | null): BoltTypeKeyword;
|
||||
export function createBoltTraitKeyworkd(span?: TextSpan | null): BoltTraitKeyworkd;
|
||||
export function createBoltParenthesized(text: string, span?: TextSpan | null): BoltParenthesized;
|
||||
export function createBoltBraced(text: string, span?: TextSpan | null): BoltBraced;
|
||||
export function createBoltBracketed(text: string, span?: TextSpan | null): BoltBracketed;
|
||||
export function createBoltSourceFile(elements: BoltSourceElement[], span?: TextSpan | null): BoltSourceFile;
|
||||
export function createBoltQualName(modulePath: BoltIdentifier[], name: BoltSymbol, span?: TextSpan | null): BoltQualName;
|
||||
export function createBoltSentence(tokens: BoltToken[], span?: TextSpan | null): BoltSentence;
|
||||
export function createBoltReferenceTypeNode(name: BoltQualName, arguments: BoltTypeNode[] | null, span?: TextSpan | null): BoltReferenceTypeNode;
|
||||
export function createBoltReferenceTypeExpression(name: BoltQualName, arguments: BoltTypeExpression[] | null, span?: TextSpan | null): BoltReferenceTypeExpression;
|
||||
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: BoltTypeNode, 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 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: BoltTypeNode, fields: BoltRecordPatternField[], span?: TextSpan | null): BoltRecordPattern;
|
||||
export function createBoltRecordPattern(name: BoltTypeExpression, fields: BoltRecordPatternField[], span?: TextSpan | null): BoltRecordPattern;
|
||||
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;
|
||||
|
@ -951,17 +1003,20 @@ export function createBoltConstantExpression(value: BoltValue, span?: TextSpan |
|
|||
export function createBoltReturnStatement(value: BoltExpression | null, span?: TextSpan | null): BoltReturnStatement;
|
||||
export function createBoltResumeStatement(value: BoltExpression, span?: TextSpan | null): BoltResumeStatement;
|
||||
export function createBoltExpressionStatement(expression: BoltExpression, span?: TextSpan | null): BoltExpressionStatement;
|
||||
export function createBoltParameter(index: number, bindings: BoltPattern, type: BoltTypeNode | null, defaultValue: BoltExpression | null, span?: TextSpan | null): BoltParameter;
|
||||
export function createBoltNewTypeDeclaration(modifiers: BoltDeclarationModifiers, name: BoltIdentifier, span?: TextSpan | null): BoltNewTypeDeclaration;
|
||||
export function createBoltParameter(index: number, bindings: BoltPattern, type: BoltTypeExpression | null, defaultValue: BoltExpression | null, span?: TextSpan | null): BoltParameter;
|
||||
export function createBoltModule(modifiers: BoltDeclarationModifiers, name: BoltQualName, elements: BoltSourceElement[], span?: TextSpan | null): BoltModule;
|
||||
export function createBoltFunctionDeclaration(modifiers: BoltDeclarationModifiers, target: string, name: BoltSymbol, params: BoltParameter[], returnType: BoltTypeNode | null, body: BoltStatement[], span?: TextSpan | null): BoltFunctionDeclaration;
|
||||
export function createBoltVariableDeclaration(modifiers: BoltDeclarationModifiers, bindings: BoltPattern, type: BoltTypeNode | null, value: BoltExpression | null, span?: TextSpan | null): BoltVariableDeclaration;
|
||||
export function createBoltFunctionDeclaration(modifiers: BoltDeclarationModifiers, target: string, name: BoltSymbol, params: BoltParameter[], returnType: BoltTypeExpression | null, body: BoltStatement[], span?: TextSpan | null): BoltFunctionDeclaration;
|
||||
export function createBoltVariableDeclaration(modifiers: BoltDeclarationModifiers, bindings: BoltPattern, type: BoltTypeExpression | null, value: BoltExpression | null, span?: TextSpan | null): BoltVariableDeclaration;
|
||||
export function createBoltPlainImportSymbol(name: BoltQualName, span?: TextSpan | null): BoltPlainImportSymbol;
|
||||
export function createBoltImportDeclaration(file: string, symbols: BoltImportSymbol[], span?: TextSpan | null): BoltImportDeclaration;
|
||||
export function createBoltRecordDeclarationField(name: BoltIdentifier, type: BoltTypeNode, span?: TextSpan | null): BoltRecordDeclarationField;
|
||||
export function createBoltRecordDeclaration(modifiers: BoltDeclarationModifiers, name: BoltQualName, fields: BoltRecordDeclarationField[], span?: TextSpan | null): BoltRecordDeclaration;
|
||||
export function createBoltRecordDeclarationField(name: BoltIdentifier, type: BoltTypeExpression, span?: TextSpan | null): BoltRecordDeclarationField;
|
||||
export function createBoltTypeAliasDeclaration(modifiers: BoltDeclarationModifiers, name: BoltIdentifier, typeParams: BoltTypeParameter[] | null, typeExpr: BoltTypeExpression, span?: TextSpan | null): BoltTypeAliasDeclaration;
|
||||
export function createBoltRecordDeclaration(modifiers: BoltDeclarationModifiers, name: BoltQualName, typeParms: BoltTypeParameter[] | null, fields: BoltRecordDeclarationField[], span?: TextSpan | null): BoltRecordDeclaration;
|
||||
export function createJSOperator(text: string, span?: TextSpan | null): JSOperator;
|
||||
export function createJSIdentifier(text: string, span?: TextSpan | null): JSIdentifier;
|
||||
export function createJSReturnKeyword(span?: TextSpan | null): JSReturnKeyword;
|
||||
export function createJSTryKeyword(span?: TextSpan | null): JSTryKeyword;
|
||||
export function createJSCatchKeyword(span?: TextSpan | null): JSCatchKeyword;
|
||||
export function createJSBindPattern(name: JSIdentifier, span?: TextSpan | null): JSBindPattern;
|
||||
export function createJSConstantExpression(value: BoltValue, span?: TextSpan | null): JSConstantExpression;
|
||||
export function createJSMemberExpression(value: JSExpression, property: JSExpression, modifiers: JSMemberExpressionModifiers, span?: TextSpan | null): JSMemberExpression;
|
||||
|
@ -979,8 +1034,8 @@ export function createJSFunctionDeclaration(modifiers: JSDeclarationModifiers, n
|
|||
export function createJSArrowFunctionDeclaration(name: JSIdentifier, params: JSParameter[], body: JSExpression, span?: TextSpan | null): JSArrowFunctionDeclaration;
|
||||
export function createJSLetDeclaration(bindings: JSPattern, value: JSExpression | null, span?: TextSpan | null): JSLetDeclaration;
|
||||
export function createJSSourceFile(elements: JSSourceElement[], span?: TextSpan | null): JSSourceFile;
|
||||
export function createJSSourceElement(span?: TextSpan | null): JSSourceElement;
|
||||
|
||||
export function isEndOfFile(value: any): value is EndOfFile;
|
||||
export function isFunctionBody(value: any): value is FunctionBody;
|
||||
export function isBoltToken(value: any): value is BoltToken;
|
||||
export function isBoltStringLiteral(value: any): value is BoltStringLiteral;
|
||||
|
@ -989,7 +1044,6 @@ export function isBoltSymbol(value: any): value is BoltSymbol;
|
|||
export function isBoltIdentifier(value: any): value is BoltIdentifier;
|
||||
export function isBoltOperator(value: any): value is BoltOperator;
|
||||
export function isBoltAssignment(value: any): value is BoltAssignment;
|
||||
export function isBoltEOS(value: any): value is BoltEOS;
|
||||
export function isBoltComma(value: any): value is BoltComma;
|
||||
export function isBoltSemi(value: any): value is BoltSemi;
|
||||
export function isBoltColon(value: any): value is BoltColon;
|
||||
|
@ -1014,7 +1068,8 @@ export function isBoltModKeyword(value: any): value is BoltModKeyword;
|
|||
export function isBoltMutKeyword(value: any): value is BoltMutKeyword;
|
||||
export function isBoltEnumKeyword(value: any): value is BoltEnumKeyword;
|
||||
export function isBoltStructKeyword(value: any): value is BoltStructKeyword;
|
||||
export function isBoltNewTypeKeyword(value: any): value is BoltNewTypeKeyword;
|
||||
export function isBoltTypeKeyword(value: any): value is BoltTypeKeyword;
|
||||
export function isBoltTraitKeyworkd(value: any): value is BoltTraitKeyworkd;
|
||||
export function isBoltPunctuated(value: any): value is BoltPunctuated;
|
||||
export function isBoltParenthesized(value: any): value is BoltParenthesized;
|
||||
export function isBoltBraced(value: any): value is BoltBraced;
|
||||
|
@ -1022,8 +1077,9 @@ export function isBoltBracketed(value: any): value is BoltBracketed;
|
|||
export function isBoltSourceFile(value: any): value is BoltSourceFile;
|
||||
export function isBoltQualName(value: any): value is BoltQualName;
|
||||
export function isBoltSentence(value: any): value is BoltSentence;
|
||||
export function isBoltTypeNode(value: any): value is BoltTypeNode;
|
||||
export function isBoltReferenceTypeNode(value: any): value is BoltReferenceTypeNode;
|
||||
export function isBoltTypeExpression(value: any): value is BoltTypeExpression;
|
||||
export function isBoltReferenceTypeExpression(value: any): value is BoltReferenceTypeExpression;
|
||||
export function isBoltTypeParameter(value: any): value is BoltTypeParameter;
|
||||
export function isBoltPattern(value: any): value is BoltPattern;
|
||||
export function isBoltBindPattern(value: any): value is BoltBindPattern;
|
||||
export function isBoltTypePattern(value: any): value is BoltTypePattern;
|
||||
|
@ -1048,7 +1104,7 @@ export function isBoltResumeStatement(value: any): value is BoltResumeStatement;
|
|||
export function isBoltExpressionStatement(value: any): value is BoltExpressionStatement;
|
||||
export function isBoltParameter(value: any): value is BoltParameter;
|
||||
export function isBoltDeclaration(value: any): value is BoltDeclaration;
|
||||
export function isBoltNewTypeDeclaration(value: any): value is BoltNewTypeDeclaration;
|
||||
export function isBoltTypeDeclaration(value: any): value is BoltTypeDeclaration;
|
||||
export function isBoltModule(value: any): value is BoltModule;
|
||||
export function isBoltFunctionDeclaration(value: any): value is BoltFunctionDeclaration;
|
||||
export function isBoltVariableDeclaration(value: any): value is BoltVariableDeclaration;
|
||||
|
@ -1056,11 +1112,15 @@ export function isBoltImportSymbol(value: any): value is BoltImportSymbol;
|
|||
export function isBoltPlainImportSymbol(value: any): value is BoltPlainImportSymbol;
|
||||
export function isBoltImportDeclaration(value: any): value is BoltImportDeclaration;
|
||||
export function isBoltRecordDeclarationField(value: any): value is BoltRecordDeclarationField;
|
||||
export function isBoltTypeAliasDeclaration(value: any): value is BoltTypeAliasDeclaration;
|
||||
export function isBoltSourceElement(value: any): value is BoltSourceElement;
|
||||
export function isBoltRecordDeclaration(value: any): value is BoltRecordDeclaration;
|
||||
export function isJSToken(value: any): value is JSToken;
|
||||
export function isJSOperator(value: any): value is JSOperator;
|
||||
export function isJSIdentifier(value: any): value is JSIdentifier;
|
||||
export function isJSReturnKeyword(value: any): value is JSReturnKeyword;
|
||||
export function isJSTryKeyword(value: any): value is JSTryKeyword;
|
||||
export function isJSCatchKeyword(value: any): value is JSCatchKeyword;
|
||||
export function isJSPattern(value: any): value is JSPattern;
|
||||
export function isJSBindPattern(value: any): value is JSBindPattern;
|
||||
export function isJSExpression(value: any): value is JSExpression;
|
||||
|
@ -1073,6 +1133,7 @@ export function isJSNewExpression(value: any): value is JSNewExpression;
|
|||
export function isJSSequenceExpression(value: any): value is JSSequenceExpression;
|
||||
export function isJSConditionalExpression(value: any): value is JSConditionalExpression;
|
||||
export function isJSReferenceExpression(value: any): value is JSReferenceExpression;
|
||||
export function isJSSourceElement(value: any): value is JSSourceElement;
|
||||
export function isJSStatement(value: any): value is JSStatement;
|
||||
export function isJSExpressionStatement(value: any): value is JSExpressionStatement;
|
||||
export function isJSConditionalStatement(value: any): value is JSConditionalStatement;
|
||||
|
@ -1082,4 +1143,3 @@ export function isJSFunctionDeclaration(value: any): value is JSFunctionDeclarat
|
|||
export function isJSArrowFunctionDeclaration(value: any): value is JSArrowFunctionDeclaration;
|
||||
export function isJSLetDeclaration(value: any): value is JSLetDeclaration;
|
||||
export function isJSSourceFile(value: any): value is JSSourceFile;
|
||||
export function isJSSourceElement(value: any): value is JSSourceElement;
|
||||
|
|
|
@ -125,7 +125,7 @@ export class Compiler {
|
|||
// TODO
|
||||
break;
|
||||
|
||||
case SyntaxKind.BoltNewTypeDeclaration:
|
||||
case SyntaxKind.BoltTypeAliasDeclaration:
|
||||
break;
|
||||
|
||||
case SyntaxKind.BoltVariableDeclaration:
|
||||
|
|
5
src/debugServer.ts
Normal file
5
src/debugServer.ts
Normal file
|
@ -0,0 +1,5 @@
|
|||
|
||||
export function connectToInspector(address: string) {
|
||||
|
||||
}
|
||||
|
|
@ -228,7 +228,7 @@ export class Expander {
|
|||
|
||||
} else {
|
||||
|
||||
this.checker.check(node);
|
||||
//this.checker.check(node);
|
||||
|
||||
return node;
|
||||
|
||||
|
|
328
src/parser.ts
328
src/parser.ts
|
@ -1,4 +1,4 @@
|
|||
|
||||
)
|
||||
import * as acorn from "acorn"
|
||||
|
||||
import {
|
||||
|
@ -19,8 +19,8 @@ import {
|
|||
BoltPattern,
|
||||
createBoltBindPattern,
|
||||
BoltImportDeclaration,
|
||||
BoltTypeNode,
|
||||
createBoltReferenceTypeNode,
|
||||
BoltTypeExpression,
|
||||
createBoltReferenceTypeExpression,
|
||||
createBoltConstantExpression,
|
||||
createBoltReferenceExpression,
|
||||
createBoltParameter,
|
||||
|
@ -42,18 +42,27 @@ import {
|
|||
BoltRecordDeclarationField,
|
||||
BoltModule,
|
||||
createBoltModule,
|
||||
BoltNewTypeDeclaration,
|
||||
createBoltNewTypeDeclaration,
|
||||
BoltTypeAliasDeclaration,
|
||||
createBoltTypeAliasDeclaration,
|
||||
BoltFunctionDeclaration,
|
||||
createBoltFunctionDeclaration,
|
||||
createBoltCallExpression,
|
||||
BoltSymbol,
|
||||
JSSourceElement,
|
||||
JSStatement,
|
||||
BoltTypeParameter,
|
||||
createBoltTypePattern,
|
||||
createBoltTypeParameter,
|
||||
} from "./ast"
|
||||
|
||||
import { Stream, setOrigNodeRange, createTokenStream, uniq } from "./util"
|
||||
import { Scanner } from "./scanner"
|
||||
|
||||
import { Stream, setOrigNodeRange, createTokenStream, uniq, FastStringMap } from "./util"
|
||||
|
||||
export type BoltTokenStream = Stream<BoltToken>;
|
||||
|
||||
export type JSTokenStream = Stream<JSToken>;
|
||||
|
||||
function describeKind(kind: SyntaxKind): string {
|
||||
switch (kind) {
|
||||
case SyntaxKind.BoltIdentifier:
|
||||
|
@ -94,16 +103,22 @@ function describeKind(kind: SyntaxKind): string {
|
|||
return "'struct'"
|
||||
case SyntaxKind.BoltEnumKeyword:
|
||||
return "'enum'"
|
||||
case SyntaxKind.BoltNewTypeKeyword:
|
||||
return "'newtype'";
|
||||
case SyntaxKind.BoltTypeKeyword:
|
||||
return "'type'";
|
||||
case SyntaxKind.BoltBraced:
|
||||
return "'{' .. '}'"
|
||||
case SyntaxKind.BoltBracketed:
|
||||
return "'[' .. ']'"
|
||||
case SyntaxKind.BoltParenthesized:
|
||||
return "'(' .. ')'"
|
||||
case SyntaxKind.BoltEOS:
|
||||
case SyntaxKind.EndOfFile:
|
||||
return "'}', ')', ']' or end-of-file"
|
||||
case SyntaxKind.BoltLtSign:
|
||||
return "'<'";
|
||||
case SyntaxKind.BoltGtSign:
|
||||
return "'<'";
|
||||
case SyntaxKind.BoltEqSign:
|
||||
return "'='";
|
||||
default:
|
||||
throw new Error(`failed to describe ${kindToString(kind)}`)
|
||||
}
|
||||
|
@ -117,7 +132,6 @@ function enumerate(elements: string[]) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
export class ParseError extends Error {
|
||||
constructor(public actual: BoltToken, public expected: SyntaxKind[]) {
|
||||
super(`${actual.span!.file.origPath}:${actual.span!.start.line}:${actual.span!.start.column}: expected ${enumerate(expected.map(e => describeKind(e)))} but got ${describeKind(actual.kind)}`)
|
||||
|
@ -131,6 +145,10 @@ enum OperatorKind {
|
|||
Suffix,
|
||||
}
|
||||
|
||||
function isRightAssoc(kind: OperatorKind) {
|
||||
return kind === OperatorKind.InfixR;
|
||||
}
|
||||
|
||||
interface OperatorInfo {
|
||||
kind: OperatorKind;
|
||||
arity: number;
|
||||
|
@ -162,9 +180,9 @@ const KIND_DECLARATION_KEYWORD = [
|
|||
SyntaxKind.BoltFnKeyword,
|
||||
SyntaxKind.BoltEnumKeyword,
|
||||
SyntaxKind.BoltLetKeyword,
|
||||
SyntaxKind.BoltNewTypeKeyword,
|
||||
SyntaxKind.BoltModKeyword,
|
||||
SyntaxKind.BoltStructKeyword,
|
||||
SyntaxKind.BoltTypeKeyword,
|
||||
]
|
||||
|
||||
const KIND_DECLARATION_T0 = uniq([
|
||||
|
@ -180,9 +198,37 @@ const KIND_SOURCEELEMENT_T0 = uniq([
|
|||
...KIND_DECLARATION_T0,
|
||||
])
|
||||
|
||||
type OperatorTableMatrix = [OperatorKind, number, string][][];
|
||||
|
||||
class OperatorTable {
|
||||
|
||||
private operatorsByName = new FastStringMap<string, OperatorInfo>();
|
||||
//private operatorsByPrecedence = FastStringMap<number, OperatorInfo>();
|
||||
|
||||
constructor(definitions: OperatorTableMatrix) {
|
||||
let i = 0;
|
||||
for (const group of definitions) {
|
||||
for (const [kind, arity, name] of group) {
|
||||
const info = { kind, arity, name, precedence: i }
|
||||
this.operatorsByName.set(name, info);
|
||||
//this.operatorsByPrecedence[i] = info;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
public lookup(name: string): OperatorInfo | null {
|
||||
if (!this.operatorsByName.has(name)) {
|
||||
return null;
|
||||
}
|
||||
return this.operatorsByName.get(name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class Parser {
|
||||
|
||||
operatorTable = [
|
||||
exprOperatorTable = new OperatorTable([
|
||||
[
|
||||
[OperatorKind.InfixL, 2, '&&'],
|
||||
[OperatorKind.InfixL, 2, '||']
|
||||
|
@ -207,14 +253,20 @@ export class Parser {
|
|||
[OperatorKind.InfixL, 2, '%'],
|
||||
],
|
||||
[
|
||||
[OperatorKind.Prefix, '!']
|
||||
[OperatorKind.Prefix, 1, '!']
|
||||
],
|
||||
];
|
||||
]);
|
||||
|
||||
typeOperatorTable = new OperatorTable([
|
||||
[
|
||||
[OperatorKind.InfixL, 2, '|'],
|
||||
]
|
||||
]);
|
||||
|
||||
protected assertEmpty(tokens: BoltTokenStream) {
|
||||
const t0 = tokens.peek(1);
|
||||
if (t0.kind !== SyntaxKind.BoltEOS) {
|
||||
throw new ParseError(t0, [SyntaxKind.BoltEOS]);
|
||||
if (t0.kind !== SyntaxKind.EndOfFile) {
|
||||
throw new ParseError(t0, [SyntaxKind.EndOfFile]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -280,15 +332,16 @@ export class Parser {
|
|||
return node;
|
||||
}
|
||||
|
||||
public parseReferenceTypeNode(tokens: BoltTokenStream) {
|
||||
public parseReferenceTypeExpression(tokens: BoltTokenStream) {
|
||||
|
||||
const name = this.parseQualName(tokens)
|
||||
|
||||
const t1 = tokens.peek();
|
||||
|
||||
let typeArgs: BoltTypeNode[] | null = null;
|
||||
let typeArgs: BoltTypeExpression[] | null = null;
|
||||
|
||||
if (t1.kind === SyntaxKind.BoltLtSign) {
|
||||
typeArgs = [];
|
||||
tokens.get();
|
||||
let first = true;
|
||||
while (true) {
|
||||
|
@ -302,26 +355,63 @@ export class Parser {
|
|||
assertToken(t2, SyntaxKind.BoltComma);
|
||||
tokens.get();
|
||||
}
|
||||
typeArgs!.push(this.parseTypeNode(tokens));
|
||||
typeArgs!.push(this.parseTypeExpression(tokens));
|
||||
}
|
||||
const t4 = tokens.get();
|
||||
assertToken(t4, SyntaxKind.BoltGtSign);
|
||||
}
|
||||
|
||||
const node = createBoltReferenceTypeNode(name, typeArgs);
|
||||
const node = createBoltReferenceTypeExpression(name, typeArgs);
|
||||
setOrigNodeRange(node, name, name);
|
||||
return node;
|
||||
}
|
||||
|
||||
public parseTypeNode(tokens: BoltTokenStream): BoltTypeNode {
|
||||
private parsePrimTypeExpression(tokens: BoltTokenStream): BoltTypeExpression {
|
||||
const t0 = tokens.peek();
|
||||
if (t0.kind === SyntaxKind.BoltIdentifier) {
|
||||
return this.parseReferenceTypeNode(tokens);
|
||||
return this.parseReferenceTypeExpression(tokens);
|
||||
} else {
|
||||
throw new ParseError(t0, [SyntaxKind.BoltIdentifier]);
|
||||
}
|
||||
}
|
||||
|
||||
private parseTypeExpressionOperators(tokens: BoltTokenStream, lhs: BoltTypeExpression, minPrecedence: number): BoltTypeExpression {
|
||||
while (true) {
|
||||
const t0 = tokens.peek();
|
||||
if (t0.kind !== SyntaxKind.BoltOperator) {
|
||||
break;
|
||||
}
|
||||
let desc0 = this.typeOperatorTable.lookup(t0.text);
|
||||
if (desc0 === null || desc0.arity !== 2 || desc0.precedence < minPrecedence) {
|
||||
break;
|
||||
}
|
||||
console.log(desc0)
|
||||
tokens.get();
|
||||
let rhs = this.parsePrimTypeExpression(tokens);
|
||||
while (true) {
|
||||
const t1 = tokens.peek()
|
||||
if (t1.kind !== SyntaxKind.BoltOperator) {
|
||||
break;
|
||||
}
|
||||
const desc1 = this.typeOperatorTable.lookup(t1.text)
|
||||
if (desc1 === null || desc1.arity !== 2 || desc1.precedence < desc0.precedence || !isRightAssoc(desc1.kind)) {
|
||||
break;
|
||||
}
|
||||
rhs = this.parseTypeExpressionOperators(tokens, rhs, desc1.precedence);
|
||||
}
|
||||
const name = createBoltQualName([], t0);
|
||||
setOrigNodeRange(name, t0, t0);
|
||||
lhs = createBoltReferenceTypeExpression(name, [lhs, rhs]);
|
||||
setOrigNodeRange(lhs, t0, rhs);
|
||||
}
|
||||
return lhs
|
||||
}
|
||||
|
||||
public parseTypeExpression(tokens: BoltTokenStream) {
|
||||
const lhs = this.parsePrimTypeExpression(tokens);
|
||||
return this.parseTypeExpressionOperators(tokens, lhs, 0);
|
||||
}
|
||||
|
||||
public parseConstantExpression(tokens: BoltTokenStream): BoltConstantExpression {
|
||||
const t0 = tokens.get();
|
||||
let value: boolean | string | bigint;
|
||||
|
@ -396,7 +486,7 @@ export class Parser {
|
|||
let endNode: BoltSyntax = pattern;
|
||||
if (t0.kind === SyntaxKind.BoltColon) {
|
||||
tokens.get();
|
||||
typeDecl = this.parseTypeNode(tokens);
|
||||
typeDecl = this.parseTypeExpression(tokens);
|
||||
endNode = typeDecl;
|
||||
t0 = tokens.get();
|
||||
}
|
||||
|
@ -434,7 +524,7 @@ export class Parser {
|
|||
|
||||
if (t2.kind === SyntaxKind.BoltColon) {
|
||||
tokens.get();
|
||||
lastNode = typeDecl = this.parseTypeNode(tokens);
|
||||
lastNode = typeDecl = this.parseTypeExpression(tokens);
|
||||
t2 = tokens.peek();
|
||||
}
|
||||
|
||||
|
@ -456,7 +546,7 @@ export class Parser {
|
|||
let expr = null;
|
||||
|
||||
const t1 = tokens.peek();
|
||||
if (t1.kind !== SyntaxKind.BoltEOS) {
|
||||
if (t1.kind !== SyntaxKind.EndOfFile) {
|
||||
expr = this.parseExpression(tokens)
|
||||
}
|
||||
|
||||
|
@ -506,9 +596,49 @@ export class Parser {
|
|||
}
|
||||
}
|
||||
|
||||
public parseGenericTypeParameter(tokens: BoltTokenStream) {
|
||||
const t0 = tokens.peek();
|
||||
if (t0.kind === SyntaxKind.BoltIdentifier) {
|
||||
tokens.get();
|
||||
const node = createBoltTypeParameter(0, t0, null)
|
||||
setOrigNodeRange(node, t0, t0);
|
||||
return node;
|
||||
} else {
|
||||
throw new ParseError(t0, [SyntaxKind.BoltIdentifier]);
|
||||
}
|
||||
}
|
||||
|
||||
private parseGenericTypeParameters(tokens: BoltTokenStream) {
|
||||
let typeParams: BoltTypeParameter[] = [];
|
||||
const t0 = tokens.get();
|
||||
assertToken(t0, SyntaxKind.BoltLtSign);
|
||||
while (true) {
|
||||
let t1 = tokens.peek();
|
||||
if (t1.kind === SyntaxKind.BoltGtSign) {
|
||||
break;
|
||||
}
|
||||
if (t1.kind === SyntaxKind.EndOfFile) {
|
||||
throw new ParseError(t1, [SyntaxKind.BoltGtSign, SyntaxKind.BoltIdentifier, SyntaxKind.BoltComma]);
|
||||
}
|
||||
if (typeParams.length > 0) {
|
||||
tokens.get();
|
||||
assertToken(t1, SyntaxKind.BoltComma);
|
||||
t1 = tokens.peek();
|
||||
}
|
||||
if (t1.kind === SyntaxKind.EndOfFile) {
|
||||
throw new ParseError(t1, [SyntaxKind.BoltGtSign, SyntaxKind.BoltIdentifier]);
|
||||
}
|
||||
typeParams.push(this.parseGenericTypeParameter(tokens));
|
||||
}
|
||||
const t3 = tokens.get();
|
||||
assertToken(t3, SyntaxKind.BoltGtSign);
|
||||
return typeParams;
|
||||
}
|
||||
|
||||
public parseRecordDeclaration(tokens: BoltTokenStream): BoltRecordDeclaration {
|
||||
|
||||
let modifiers = 0;
|
||||
let typeParams = null;
|
||||
|
||||
let t0 = tokens.get();
|
||||
const firstToken = t0;
|
||||
|
@ -525,31 +655,49 @@ export class Parser {
|
|||
assertToken(t1, SyntaxKind.BoltIdentifier);
|
||||
const name = createBoltQualName([], t1 as BoltIdentifier);
|
||||
|
||||
const t2 = tokens.get();
|
||||
let t2 = tokens.peek();
|
||||
|
||||
if (t2.kind === SyntaxKind.EndOfFile) {
|
||||
const node = createBoltRecordDeclaration(modifiers, name, null, []);
|
||||
setOrigNodeRange(node, firstToken, t2);
|
||||
return node;
|
||||
}
|
||||
|
||||
if (t2.kind === SyntaxKind.BoltLtSign) {
|
||||
typeParams = this.parseGenericTypeParameters(tokens);
|
||||
t2 = tokens.peek();
|
||||
}
|
||||
|
||||
if (t2.kind !== SyntaxKind.BoltBraced) {
|
||||
throw new ParseError(t2, [SyntaxKind.BoltBraced])
|
||||
}
|
||||
|
||||
let fields: BoltRecordDeclarationField[] = [];
|
||||
tokens.get();
|
||||
const innerTokens = createTokenStream(t2);
|
||||
|
||||
while (true) {
|
||||
const t3 = innerTokens.get();
|
||||
if (t3.kind === SyntaxKind.BoltEOS) {
|
||||
const t3 = innerTokens.peek();
|
||||
if (t3.kind === SyntaxKind.EndOfFile) {
|
||||
break;
|
||||
}
|
||||
const name = innerTokens.get();
|
||||
assertToken(name, SyntaxKind.BoltIdentifier);
|
||||
assertToken(t3, SyntaxKind.BoltIdentifier);
|
||||
innerTokens.get();
|
||||
const name = t3 as BoltIdentifier;
|
||||
const t4 = innerTokens.get();
|
||||
assertToken(t4, SyntaxKind.BoltColon);
|
||||
const type = this.parseTypeNode(innerTokens);
|
||||
const type = this.parseTypeExpression(innerTokens);
|
||||
const field = createBoltRecordDeclarationField(name as BoltIdentifier, type);
|
||||
const t5 = innerTokens.get();
|
||||
if (t5.kind === SyntaxKind.EndOfFile) {
|
||||
break;
|
||||
}
|
||||
assertToken(t5, SyntaxKind.BoltComma);
|
||||
setOrigNodeRange(field, name, type);
|
||||
fields.push(field);
|
||||
}
|
||||
|
||||
const node = createBoltRecordDeclaration(modifiers, name, fields);
|
||||
const node = createBoltRecordDeclaration(modifiers, name, typeParams, fields);
|
||||
setOrigNodeRange(node, firstToken, t2);
|
||||
return node;
|
||||
}
|
||||
|
@ -558,7 +706,7 @@ export class Parser {
|
|||
const statements: BoltStatement[] = [];
|
||||
while (true) {
|
||||
const t0 = tokens.peek();
|
||||
if (t0.kind === SyntaxKind.BoltEOS) {
|
||||
if (t0.kind === SyntaxKind.EndOfFile) {
|
||||
break;
|
||||
}
|
||||
const statement = this.parseStatement(tokens);
|
||||
|
@ -579,7 +727,7 @@ export class Parser {
|
|||
t0 = tokens.peek();
|
||||
}
|
||||
|
||||
if (t0.kind !== SyntaxKind.BoltIdentifier || t0.text !== 'mod') {
|
||||
if (t0.kind !== SyntaxKind.BoltModKeyword) {
|
||||
throw new ParseError(t0, [SyntaxKind.BoltModKeyword])
|
||||
}
|
||||
|
||||
|
@ -589,7 +737,7 @@ export class Parser {
|
|||
if (t1.kind !== SyntaxKind.BoltBraced) {
|
||||
throw new ParseError(t1, [SyntaxKind.BoltBraced])
|
||||
}
|
||||
const sentences = this.parseSentences(createTokenStream(t1));
|
||||
const sentences = this.parseSourceElementList(createTokenStream(t1));
|
||||
|
||||
const node = createBoltModule(modifiers, name, sentences);
|
||||
setOrigNodeRange(node, firstToken, t1);
|
||||
|
@ -597,33 +745,38 @@ export class Parser {
|
|||
}
|
||||
|
||||
|
||||
public parseNewTypeDeclaration(tokens: BoltTokenStream): BoltNewTypeDeclaration {
|
||||
public parseTypeAliasDeclaration(tokens: BoltTokenStream): BoltTypeAliasDeclaration {
|
||||
|
||||
let modifiers = 0;
|
||||
let typeParams = null;
|
||||
|
||||
let t0 = tokens.get();
|
||||
const firstToken = t0;
|
||||
|
||||
if (t0.kind === SyntaxKind.BoltPubKeyword) {
|
||||
tokens.get();
|
||||
modifiers |= BoltDeclarationModifiers.Public;
|
||||
t0 = tokens.peek();
|
||||
if (t0.kind !== SyntaxKind.BoltIdentifier) {
|
||||
throw new ParseError(t0, [SyntaxKind.BoltNewTypeKeyword])
|
||||
}
|
||||
t0 = tokens.get();
|
||||
}
|
||||
|
||||
if (t0.kind !== SyntaxKind.BoltNewTypeKeyword) {
|
||||
throw new ParseError(t0, [SyntaxKind.BoltNewTypeKeyword])
|
||||
}
|
||||
assertToken(t0, SyntaxKind.BoltTypeKeyword);
|
||||
|
||||
const name = tokens.get();
|
||||
if (name.kind !== SyntaxKind.BoltIdentifier) {
|
||||
throw new ParseError(name, [SyntaxKind.BoltIdentifier])
|
||||
}
|
||||
|
||||
const node = createBoltNewTypeDeclaration(modifiers, name)
|
||||
setOrigNodeRange(node, firstToken, name);
|
||||
const t2 = tokens.peek();
|
||||
if (t2.kind === SyntaxKind.BoltLtSign) {
|
||||
typeParams = this.parseGenericTypeParameters(tokens);
|
||||
}
|
||||
|
||||
const t3 = tokens.get();
|
||||
assertToken(t3, SyntaxKind.BoltEqSign);
|
||||
|
||||
const typeExpr = this.parseTypeExpression(tokens);
|
||||
|
||||
const node = createBoltTypeAliasDeclaration(modifiers, name, typeParams, typeExpr)
|
||||
setOrigNodeRange(node, firstToken, typeExpr);
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -725,17 +878,17 @@ export class Parser {
|
|||
const innerTokens = createTokenStream(t2);
|
||||
while (true) {
|
||||
const t3 = innerTokens.peek();
|
||||
if (t3.kind === SyntaxKind.BoltEOS) {
|
||||
if (t3.kind === SyntaxKind.EndOfFile) {
|
||||
break;
|
||||
}
|
||||
params.push(this.parseParameter(innerTokens, i++))
|
||||
const t4 = innerTokens.get();
|
||||
if (t4.kind === SyntaxKind.BoltComma) {
|
||||
continue;
|
||||
} else if (t4.kind === SyntaxKind.BoltEOS) {
|
||||
} else if (t4.kind === SyntaxKind.EndOfFile) {
|
||||
break;
|
||||
} else {
|
||||
throw new ParseError(t4, [SyntaxKind.BoltComma, SyntaxKind.BoltEOS])
|
||||
throw new ParseError(t4, [SyntaxKind.BoltComma, SyntaxKind.EndOfFile])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -756,7 +909,7 @@ export class Parser {
|
|||
if (t2.kind === SyntaxKind.BoltRArrow) {
|
||||
lastToken = t2;
|
||||
tokens.get();
|
||||
returnType = this.parseTypeNode(tokens);
|
||||
returnType = this.parseTypeExpression(tokens);
|
||||
}
|
||||
|
||||
// Parse function body
|
||||
|
@ -770,7 +923,8 @@ export class Parser {
|
|||
body = this.parseStatements(tokens);
|
||||
break;
|
||||
case "JS":
|
||||
body = acorn.parse(t3.text);
|
||||
const scanner = new Scanner(t3.span!.file, t3.text);
|
||||
body = this.parseJSSourceElementList(scanner);
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unrecognised language: ${target}`);
|
||||
|
@ -790,6 +944,23 @@ export class Parser {
|
|||
|
||||
}
|
||||
|
||||
//public parseModuleDeclaration(tokens: BoltTokenStream): BoltModule {
|
||||
//let modifiers = 0;
|
||||
//let t0 = tokens.get();
|
||||
//if (t0.kind === SyntaxKind.BoltPubKeyword) {
|
||||
//modifiers |= BoltDeclarationModifiers.Public;
|
||||
//t0 = tokens.get();
|
||||
//}
|
||||
//assertToken(t0, SyntaxKind.BoltModKeyword);
|
||||
//const name = this.parseQualName(tokens);
|
||||
//const t1 = tokens.get();
|
||||
//assertToken(t1, SyntaxKind.BoltBraced);
|
||||
//const elements = this.parseSourceElementList(createTokenStream(t1));
|
||||
//const node = createBoltModule(modifiers, name, elements);
|
||||
//setOrigNodeRange(node, t0, t1);
|
||||
//return node;
|
||||
//}
|
||||
|
||||
public parseDeclaration(tokens: BoltTokenStream): BoltDeclaration {
|
||||
let t0 = tokens.peek(1);
|
||||
let i = 1;
|
||||
|
@ -810,8 +981,8 @@ export class Parser {
|
|||
}
|
||||
}
|
||||
switch (t0.kind) {
|
||||
case SyntaxKind.BoltNewTypeKeyword:
|
||||
return this.parseNewTypeDeclaration(tokens);
|
||||
case SyntaxKind.BoltTypeKeyword:
|
||||
return this.parseTypeAliasDeclaration(tokens);
|
||||
case SyntaxKind.BoltModKeyword:
|
||||
return this.parseModuleDeclaration(tokens);
|
||||
case SyntaxKind.BoltFnKeyword:
|
||||
|
@ -826,9 +997,8 @@ export class Parser {
|
|||
throw new ParseError(t0, KIND_DECLARATION_T0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public parseSourceElement(tokens: BoltTokenStream): BoltSourceElement {
|
||||
const t0 = tokens.peek();
|
||||
try {
|
||||
return this.parseDeclaration(tokens)
|
||||
} catch (e1) {
|
||||
|
@ -846,19 +1016,20 @@ export class Parser {
|
|||
}
|
||||
}
|
||||
|
||||
protected getOperatorDesc(seekArity: number, seekName: string): OperatorInfo {
|
||||
for (let i = 0; i < this.operatorTable.length; ++i) {
|
||||
for (const [kind, arity, name] of this.operatorTable[i]) {
|
||||
if (arity == seekArity && name === seekName) {
|
||||
return {
|
||||
kind,
|
||||
name,
|
||||
arity,
|
||||
precedence: i
|
||||
}
|
||||
}
|
||||
public parseSourceElementList(tokens: BoltTokenStream): BoltSourceElement[] {
|
||||
const elements: BoltSourceElement[] = []
|
||||
while (true) {
|
||||
const t0 = tokens.peek();
|
||||
if (t0.kind === SyntaxKind.EndOfFile) {
|
||||
break;
|
||||
}
|
||||
if (t0.kind === SyntaxKind.BoltSemi) {
|
||||
tokens.get();
|
||||
continue;
|
||||
}
|
||||
elements.push(this.parseSourceElement(tokens));
|
||||
}
|
||||
return elements
|
||||
}
|
||||
|
||||
//parseBinOp(tokens: TokenStream, lhs: Expr , minPrecedence: number) {
|
||||
|
@ -887,12 +1058,12 @@ export class Parser {
|
|||
// return lhs
|
||||
//}
|
||||
|
||||
public parseCallOrPrimitiveExpression(tokens: BoltTokenStream): BoltExpression {
|
||||
private parseCallOrPrimitiveExpression(tokens: BoltTokenStream): BoltExpression {
|
||||
|
||||
const operator = this.parsePrimitiveExpression(tokens)
|
||||
|
||||
const t2 = tokens.get();
|
||||
if (t2.kind === SyntaxKind.BoltEOS) {
|
||||
if (t2.kind === SyntaxKind.EndOfFile) {
|
||||
return operator;
|
||||
}
|
||||
assertToken(t2, SyntaxKind.BoltParenthesized);
|
||||
|
@ -902,12 +1073,12 @@ export class Parser {
|
|||
|
||||
while (true) {
|
||||
const t3 = innerTokens.peek();
|
||||
if (t3.kind === SyntaxKind.BoltEOS) {
|
||||
if (t3.kind === SyntaxKind.EndOfFile) {
|
||||
break;
|
||||
}
|
||||
args.push(this.parseExpression(innerTokens))
|
||||
const t4 = innerTokens.get();
|
||||
if (t4.kind === SyntaxKind.BoltEOS) {
|
||||
if (t4.kind === SyntaxKind.EndOfFile) {
|
||||
break
|
||||
} else if (t4.kind !== SyntaxKind.BoltComma){
|
||||
throw new ParseError(t4, [SyntaxKind.BoltComma])
|
||||
|
@ -920,5 +1091,22 @@ export class Parser {
|
|||
|
||||
}
|
||||
|
||||
public parseJSStatement(tokens: JSTokenStream): JSStatement {
|
||||
return this.parseJSExpressionStatement(tokens);
|
||||
}
|
||||
|
||||
public parseJSSourceElementList(tokens: JSTokenStream): JSSourceElement[] {
|
||||
const elements: JSSourceElement[] = [];
|
||||
while (true) {
|
||||
const t0 = tokens.peek();
|
||||
if (t0.kind === SyntaxKind.EndOfFile) {
|
||||
break;
|
||||
}
|
||||
const statement = this.parseJSStatement(tokens)
|
||||
elements.push(statement);
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
248
src/scanner.ts
248
src/scanner.ts
|
@ -12,6 +12,7 @@ import {
|
|||
SyntaxKind,
|
||||
BoltToken,
|
||||
BoltSentence,
|
||||
createEndOfFile,
|
||||
createBoltSentence,
|
||||
createBoltIdentifier,
|
||||
createBoltRArrow,
|
||||
|
@ -25,7 +26,6 @@ import {
|
|||
createBoltStringLiteral,
|
||||
createBoltIntegerLiteral,
|
||||
createBoltColon,
|
||||
createBoltEOS,
|
||||
createBoltDot,
|
||||
createBoltEqSign,
|
||||
createBoltPubKeyword,
|
||||
|
@ -39,7 +39,12 @@ import {
|
|||
createBoltFnKeyword,
|
||||
createBoltLArrow,
|
||||
createBoltDotDot,
|
||||
createBoltNewTypeKeyword,
|
||||
createJSIdentifier,
|
||||
JSToken,
|
||||
createBoltLtSign,
|
||||
createBoltGtSign,
|
||||
createBoltModKeyword,
|
||||
createBoltTypeKeyword,
|
||||
} from "./ast"
|
||||
|
||||
export enum PunctType {
|
||||
|
@ -136,7 +141,27 @@ function isIdentPart(ch: string) {
|
|||
}
|
||||
|
||||
function isSymbol(ch: string) {
|
||||
return /[=+\/-*%$!><&^|]/.test(ch)
|
||||
return /[=+\/\-*%$!><&^|]/.test(ch)
|
||||
}
|
||||
|
||||
|
||||
function isJSWhiteSpace(ch: string): boolean {
|
||||
return ch === '\u0009'
|
||||
|| ch === '\u000B'
|
||||
|| ch === '\u000C'
|
||||
|| ch === '\u0020'
|
||||
|| ch === '\u00A0'
|
||||
|| ch === '\u000B'
|
||||
|| ch === '\uFEFF'
|
||||
|| XRegExp('\\p{Zs}').test(ch)
|
||||
}
|
||||
|
||||
function isJSIdentStart(ch: string): boolean {
|
||||
return XRegExp('[\\p{ID_Start}$_\\]').test(ch)
|
||||
}
|
||||
|
||||
function isJSIdentPart(ch: string): boolean {
|
||||
return XRegExp('[\u200C\u200D\\p{ID_Continue}$\\]').test(ch)
|
||||
}
|
||||
|
||||
//function isOperatorPart(ch: string) {
|
||||
|
@ -218,7 +243,7 @@ export class Scanner {
|
|||
const startPos = this.currPos.clone()
|
||||
|
||||
if (c0 == EOF) {
|
||||
return createBoltEOS(new TextSpan(this.file, startPos, startPos));
|
||||
return createEndOfFile(new TextSpan(this.file, startPos, startPos));
|
||||
}
|
||||
|
||||
switch (c0) {
|
||||
|
@ -313,15 +338,16 @@ export class Scanner {
|
|||
const span = new TextSpan(this.file, startPos, endPos);
|
||||
switch (name) {
|
||||
case 'pub': return createBoltPubKeyword(span);
|
||||
case 'mod': return createBoltModKeyword(span);
|
||||
case 'fn': return createBoltFnKeyword(span);
|
||||
case 'return': return createBoltReturnKeyword(span);
|
||||
case 'yield': return createBoltYieldKeyword(span);
|
||||
case 'type': return createBoltTypeKeyword(span);
|
||||
case 'foreign': return createBoltForeignKeyword(span);
|
||||
case 'let': return createBoltPubKeyword(span);
|
||||
case 'mut': return createBoltMutKeyword(span);
|
||||
case 'struct': return createBoltStructKeyword(span);
|
||||
case 'enum': return createBoltEnumKeyword(span);
|
||||
case 'newtype': return createBoltNewTypeKeyword(span);
|
||||
default: return createBoltIdentifier(name, span);
|
||||
}
|
||||
|
||||
|
@ -331,23 +357,24 @@ export class Scanner {
|
|||
const endPos = this.currPos.clone()
|
||||
const span = new TextSpan(this.file, startPos, endPos);
|
||||
|
||||
if (text.endsWith('=')) {
|
||||
const operator = text.substring(0, text.length-1);
|
||||
if (text === '==') {
|
||||
return createBoltOperator(text, span);
|
||||
}
|
||||
return createBoltAssignment(operator.length === 0 ? null : operator, span);
|
||||
}
|
||||
|
||||
switch (text) {
|
||||
case '->': return createBoltRArrow(span);
|
||||
case '<-': return createBoltLArrow(span);
|
||||
case '<': return createBoltLtSign(span);
|
||||
case '>': return createBoltGtSign(span);
|
||||
case '.': return createBoltDot(span);
|
||||
case '..': return createBoltDotDot(span);
|
||||
case '=': return createBoltEqSign(span);
|
||||
default: return createBoltOperator(text, span);
|
||||
case '==': return createBoltOperator(text, span);
|
||||
}
|
||||
|
||||
if (text.endsWith('=')) {
|
||||
const operator = text.substring(0, text.length-1);
|
||||
return createBoltAssignment(operator.length === 0 ? null : operator, span);
|
||||
}
|
||||
|
||||
return createBoltOperator(text, span);
|
||||
|
||||
} else {
|
||||
|
||||
throw new ScanError(this.file, this.currPos.clone(), c0);
|
||||
|
@ -358,14 +385,14 @@ export class Scanner {
|
|||
|
||||
}
|
||||
|
||||
peek(count = 1): BoltToken {
|
||||
public peek(count = 1): BoltToken {
|
||||
while (this.scanned.length < count) {
|
||||
this.scanned.push(this.scanToken());
|
||||
}
|
||||
return this.scanned[count - 1];
|
||||
}
|
||||
|
||||
get(): BoltToken {
|
||||
public get(): BoltToken {
|
||||
return this.scanned.length > 0
|
||||
? this.scanned.shift()!
|
||||
: this.scanToken();
|
||||
|
@ -381,7 +408,7 @@ export class Scanner {
|
|||
|
||||
inner: while (true) {
|
||||
const token = this.scanToken();
|
||||
if (token.kind === SyntaxKind.BoltEOS) {
|
||||
if (token.kind === SyntaxKind.EndOfFile) {
|
||||
if (tokens.length === 0) {
|
||||
break outer;
|
||||
} else {
|
||||
|
@ -411,7 +438,7 @@ export class Scanner {
|
|||
return elements
|
||||
}
|
||||
|
||||
scan() {
|
||||
public scan() {
|
||||
const startPos = this.currPos.clone();
|
||||
const elements = this.scanTokens();
|
||||
const endPos = this.currPos.clone();
|
||||
|
@ -421,3 +448,188 @@ export class Scanner {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
export class JSScanner {
|
||||
|
||||
private buffer: string[] = [];
|
||||
private scanned: JSToken[] = [];
|
||||
private offset = 0;
|
||||
|
||||
constructor(
|
||||
private file: TextFile,
|
||||
private input: string,
|
||||
private currPos: TextPos = new TextPos(0,1,1),
|
||||
) {
|
||||
|
||||
}
|
||||
|
||||
protected readChar() {
|
||||
if (this.offset == this.input.length) {
|
||||
return EOF
|
||||
}
|
||||
return this.input[this.offset++]
|
||||
}
|
||||
|
||||
protected peekChar(count = 1) {
|
||||
while (this.buffer.length < count) {
|
||||
this.buffer.push(this.readChar());
|
||||
}
|
||||
return this.buffer[count - 1];
|
||||
}
|
||||
|
||||
protected getChar() {
|
||||
|
||||
const ch = this.buffer.length > 0
|
||||
? this.buffer.shift()!
|
||||
: this.readChar()
|
||||
|
||||
if (ch == EOF) {
|
||||
return EOF
|
||||
}
|
||||
|
||||
if (isNewLine(ch)) {
|
||||
this.currPos.line += 1;
|
||||
this.currPos.column = 1;
|
||||
} else {
|
||||
this.currPos.column += 1;
|
||||
}
|
||||
this.currPos.offset += 1;
|
||||
|
||||
return ch
|
||||
}
|
||||
|
||||
private assertChar(expected: string) {
|
||||
const actual = this.getChar();
|
||||
if (actual !== expected) {
|
||||
throw new ScanError(this.file, this.currPos.clone(), actual);
|
||||
}
|
||||
}
|
||||
|
||||
private scanLineComment(): string {
|
||||
let text = '';
|
||||
this.assertChar('/');
|
||||
this.assertChar('/')
|
||||
while (true) {
|
||||
const c2 = this.peekChar();
|
||||
if (c2 === '\n') {
|
||||
this.getChar();
|
||||
if (this.peekChar() === '\r') {
|
||||
this.getChar();
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (c2 === EOF) {
|
||||
break;
|
||||
}
|
||||
text += this.getChar();
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
private scanMultiLineComment(): string {
|
||||
let text = '';
|
||||
while (true) {
|
||||
const c2 = this.getChar();
|
||||
if (c2 === '*') {
|
||||
const c3 = this.getChar();
|
||||
if (c3 === '/') {
|
||||
break;
|
||||
}
|
||||
text += c2 + c3;
|
||||
} else if (c2 === EOF) {
|
||||
throw new ScanError(this.file, this.currPos.clone(), c2);
|
||||
} else {
|
||||
text += c2;
|
||||
}
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
private skipComments() {
|
||||
while (true) {
|
||||
const c0 = this.peekChar();
|
||||
if (c0 === '/') {
|
||||
const c1 = this.peekChar(2);
|
||||
if (c1 == '/') {
|
||||
this.scanLineComment();
|
||||
} else if (c1 === '*') {
|
||||
this.scanMultiLineComment();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else if (isWhiteSpace(c0)) {
|
||||
this.getChar();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private scanHexDigit(): number {
|
||||
const startPos = this.currPos.clone();
|
||||
const c0 = this.getChar();
|
||||
switch (c0.toLowerCase()) {
|
||||
case '0': return 0;
|
||||
case '1': return 1;
|
||||
case '2': return 2;
|
||||
case '3': return 3;
|
||||
case '4': return 4;
|
||||
case '5': return 5;
|
||||
case '6': return 6;
|
||||
case '7': return 7;
|
||||
case '8': return 8;
|
||||
case '9': return 0;
|
||||
case 'a': return 10;
|
||||
case 'b': return 11;
|
||||
case 'c': return 12;
|
||||
case 'd': return 13;
|
||||
case 'e': return 14;
|
||||
case 'f': return 15;
|
||||
default:
|
||||
throw new ScanError(this.file, startPos, c0);
|
||||
}
|
||||
}
|
||||
|
||||
private scanUnicodeEscapeSequence() {
|
||||
throw new Error(`Scanning unicode escape sequences is not yet implemented.`);
|
||||
}
|
||||
|
||||
public scan(): JSToken {
|
||||
this.skipComments();
|
||||
const c0 = this.peekChar();
|
||||
const startPos = this.currPos.clone();
|
||||
if (isJSIdentStart(c0)) {
|
||||
let name = '';
|
||||
while (true) {
|
||||
const c0 = this.peekChar();
|
||||
if (!isJSIdentPart(c0)) {
|
||||
break;
|
||||
}
|
||||
if (c0 === '\\') {
|
||||
name += this.scanUnicodeEscapeSequence();
|
||||
} else {
|
||||
name += this.getChar();
|
||||
}
|
||||
}
|
||||
const endPos = this.currPos.clone();
|
||||
return createJSIdentifier(name, new TextSpan(this.file, startPos, endPos))
|
||||
} else {
|
||||
throw new ScanError(this.file, this.currPos.clone(), c0);
|
||||
}
|
||||
}
|
||||
|
||||
public peek(count = 1): JSToken {
|
||||
while (this.scanned.length < count) {
|
||||
this.scanned.push(this.scan());
|
||||
}
|
||||
return this.scanned[count - 1];
|
||||
}
|
||||
|
||||
public get(): JSToken {
|
||||
return this.scanned.length > 0
|
||||
? this.scanned.shift()!
|
||||
: this.scan();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
36
src/util.ts
36
src/util.ts
|
@ -6,7 +6,7 @@ import chalk from "chalk"
|
|||
|
||||
import { TextSpan, TextPos } from "./text"
|
||||
import { Scanner } from "./scanner"
|
||||
import { kindToString, Syntax, BoltQualName, BoltDeclaration, BoltDeclarationModifiers, createBoltEOS, SyntaxKind, isBoltPunctuated } from "./ast"
|
||||
import { kindToString, Syntax, BoltQualName, BoltDeclaration, BoltDeclarationModifiers, createEndOfFile, SyntaxKind, isBoltPunctuated } from "./ast"
|
||||
|
||||
export function createTokenStream(node: Syntax) {
|
||||
if (isBoltPunctuated(node)) {
|
||||
|
@ -16,7 +16,7 @@ export function createTokenStream(node: Syntax) {
|
|||
} else if (node.kind === SyntaxKind.BoltSentence) {
|
||||
return new StreamWrapper(
|
||||
node.tokens,
|
||||
() => createBoltEOS(new TextSpan(node.span!.file, node.span!.end.clone(), node.span!.end.clone()))
|
||||
() => createEndOfFile(new TextSpan(node.span!.file, node.span!.end.clone(), node.span!.end.clone()))
|
||||
);
|
||||
} else {
|
||||
throw new Error(`Could not convert ${kindToString(node.kind)} to a token stream.`);
|
||||
|
@ -40,8 +40,36 @@ export function uniq<T>(elements: T[]): T[] {
|
|||
return out;
|
||||
}
|
||||
|
||||
export interface FastStringMap<T> {
|
||||
[key: string]: T
|
||||
|
||||
export class FastStringMap<K extends PropertyKey, V> {
|
||||
|
||||
private mapping = Object.create(null);
|
||||
|
||||
public get(key: K): V {
|
||||
if (!(key in this.mapping)) {
|
||||
throw new Error(`No value found for key '${key}'.`);
|
||||
}
|
||||
return this.mapping[key];
|
||||
}
|
||||
|
||||
public set(key: K, value: V): void {
|
||||
if (key in this.mapping) {
|
||||
throw new Error(`A value for key '${key}' already exists.`);
|
||||
}
|
||||
this.mapping[key] = value
|
||||
}
|
||||
|
||||
public has(key: K): boolean {
|
||||
return key in this.mapping;
|
||||
}
|
||||
|
||||
public delete(key: K): void {
|
||||
if (!(key in this.mapping)) {
|
||||
throw new Error(`No value found for key '${key}'.`);
|
||||
}
|
||||
delete this.mapping[key];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class DeepMap {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"outDir": "./lib",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"inlineSourceMap": true,
|
||||
"sourceMap": true,
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue