Enable parsing member expressions
This commit is contained in:
parent
aad00c5024
commit
8f661f49a7
3 changed files with 171 additions and 132 deletions
|
@ -155,6 +155,11 @@ node BoltReferenceExpression > BoltExpression {
|
||||||
name: BoltQualName,
|
name: BoltQualName,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
node BoltMemberExpression > BoltExpression {
|
||||||
|
expression: BoltExpression,
|
||||||
|
path: Vec<BoltIdentifier>,
|
||||||
|
}
|
||||||
|
|
||||||
node BoltFunctionExpression > BoltExpression {
|
node BoltFunctionExpression > BoltExpression {
|
||||||
params: Vec<BoltParameter>,
|
params: Vec<BoltParameter>,
|
||||||
returnType: Option<BoltTypeExpression>,
|
returnType: Option<BoltTypeExpression>,
|
||||||
|
|
190
src/ast.d.ts
vendored
190
src/ast.d.ts
vendored
|
@ -56,95 +56,96 @@ export const enum SyntaxKind {
|
||||||
BoltRecordPattern = 65,
|
BoltRecordPattern = 65,
|
||||||
BoltQuoteExpression = 67,
|
BoltQuoteExpression = 67,
|
||||||
BoltReferenceExpression = 68,
|
BoltReferenceExpression = 68,
|
||||||
BoltFunctionExpression = 69,
|
BoltMemberExpression = 69,
|
||||||
BoltCallExpression = 70,
|
BoltFunctionExpression = 70,
|
||||||
BoltYieldExpression = 71,
|
BoltCallExpression = 71,
|
||||||
BoltMatchArm = 72,
|
BoltYieldExpression = 72,
|
||||||
BoltMatchExpression = 73,
|
BoltMatchArm = 73,
|
||||||
BoltCase = 74,
|
BoltMatchExpression = 74,
|
||||||
BoltCaseExpression = 75,
|
BoltCase = 75,
|
||||||
BoltBlockExpression = 76,
|
BoltCaseExpression = 76,
|
||||||
BoltConstantExpression = 77,
|
BoltBlockExpression = 77,
|
||||||
BoltReturnStatement = 79,
|
BoltConstantExpression = 78,
|
||||||
BoltConditionalCase = 80,
|
BoltReturnStatement = 80,
|
||||||
BoltConditionalStatement = 81,
|
BoltConditionalCase = 81,
|
||||||
BoltResumeStatement = 82,
|
BoltConditionalStatement = 82,
|
||||||
BoltExpressionStatement = 83,
|
BoltResumeStatement = 83,
|
||||||
BoltParameter = 84,
|
BoltExpressionStatement = 84,
|
||||||
BoltModule = 88,
|
BoltParameter = 85,
|
||||||
BoltFunctionDeclaration = 90,
|
BoltModule = 89,
|
||||||
BoltVariableDeclaration = 91,
|
BoltFunctionDeclaration = 91,
|
||||||
BoltPlainImportSymbol = 93,
|
BoltVariableDeclaration = 92,
|
||||||
BoltImportDeclaration = 94,
|
BoltPlainImportSymbol = 94,
|
||||||
BoltTraitDeclaration = 95,
|
BoltImportDeclaration = 95,
|
||||||
BoltImplDeclaration = 96,
|
BoltTraitDeclaration = 96,
|
||||||
BoltTypeAliasDeclaration = 97,
|
BoltImplDeclaration = 97,
|
||||||
BoltRecordField = 99,
|
BoltTypeAliasDeclaration = 98,
|
||||||
BoltRecordDeclaration = 100,
|
BoltRecordField = 100,
|
||||||
BoltMacroCall = 102,
|
BoltRecordDeclaration = 101,
|
||||||
JSOperator = 105,
|
BoltMacroCall = 103,
|
||||||
JSIdentifier = 106,
|
JSOperator = 106,
|
||||||
JSString = 107,
|
JSIdentifier = 107,
|
||||||
JSInteger = 108,
|
JSString = 108,
|
||||||
JSFromKeyword = 109,
|
JSInteger = 109,
|
||||||
JSReturnKeyword = 110,
|
JSFromKeyword = 110,
|
||||||
JSTryKeyword = 111,
|
JSReturnKeyword = 111,
|
||||||
JSFinallyKeyword = 112,
|
JSTryKeyword = 112,
|
||||||
JSCatchKeyword = 113,
|
JSFinallyKeyword = 113,
|
||||||
JSImportKeyword = 114,
|
JSCatchKeyword = 114,
|
||||||
JSAsKeyword = 115,
|
JSImportKeyword = 115,
|
||||||
JSConstKeyword = 116,
|
JSAsKeyword = 116,
|
||||||
JSLetKeyword = 117,
|
JSConstKeyword = 117,
|
||||||
JSExportKeyword = 118,
|
JSLetKeyword = 118,
|
||||||
JSFunctionKeyword = 119,
|
JSExportKeyword = 119,
|
||||||
JSWhileKeyword = 120,
|
JSFunctionKeyword = 120,
|
||||||
JSForKeyword = 121,
|
JSWhileKeyword = 121,
|
||||||
JSCloseBrace = 122,
|
JSForKeyword = 122,
|
||||||
JSCloseBracket = 123,
|
JSCloseBrace = 123,
|
||||||
JSCloseParen = 124,
|
JSCloseBracket = 124,
|
||||||
JSOpenBrace = 125,
|
JSCloseParen = 125,
|
||||||
JSOpenBracket = 126,
|
JSOpenBrace = 126,
|
||||||
JSOpenParen = 127,
|
JSOpenBracket = 127,
|
||||||
JSSemi = 128,
|
JSOpenParen = 128,
|
||||||
JSComma = 129,
|
JSSemi = 129,
|
||||||
JSDot = 130,
|
JSComma = 130,
|
||||||
JSDotDotDot = 131,
|
JSDot = 131,
|
||||||
JSMulOp = 132,
|
JSDotDotDot = 132,
|
||||||
JSAddOp = 133,
|
JSMulOp = 133,
|
||||||
JSDivOp = 134,
|
JSAddOp = 134,
|
||||||
JSSubOp = 135,
|
JSDivOp = 135,
|
||||||
JSLtOp = 136,
|
JSSubOp = 136,
|
||||||
JSGtOp = 137,
|
JSLtOp = 137,
|
||||||
JSBOrOp = 138,
|
JSGtOp = 138,
|
||||||
JSBXorOp = 139,
|
JSBOrOp = 139,
|
||||||
JSBAndOp = 140,
|
JSBXorOp = 140,
|
||||||
JSBNotOp = 141,
|
JSBAndOp = 141,
|
||||||
JSNotOp = 142,
|
JSBNotOp = 142,
|
||||||
JSBindPattern = 144,
|
JSNotOp = 143,
|
||||||
JSConstantExpression = 146,
|
JSBindPattern = 145,
|
||||||
JSMemberExpression = 147,
|
JSConstantExpression = 147,
|
||||||
JSCallExpression = 148,
|
JSMemberExpression = 148,
|
||||||
JSBinaryExpression = 149,
|
JSCallExpression = 149,
|
||||||
JSUnaryExpression = 150,
|
JSBinaryExpression = 150,
|
||||||
JSNewExpression = 151,
|
JSUnaryExpression = 151,
|
||||||
JSSequenceExpression = 152,
|
JSNewExpression = 152,
|
||||||
JSConditionalExpression = 153,
|
JSSequenceExpression = 153,
|
||||||
JSLiteralExpression = 155,
|
JSConditionalExpression = 154,
|
||||||
JSReferenceExpression = 156,
|
JSLiteralExpression = 156,
|
||||||
JSCatchBlock = 160,
|
JSReferenceExpression = 157,
|
||||||
JSTryCatchStatement = 161,
|
JSCatchBlock = 161,
|
||||||
JSExpressionStatement = 162,
|
JSTryCatchStatement = 162,
|
||||||
JSConditionalCase = 163,
|
JSExpressionStatement = 163,
|
||||||
JSConditionalStatement = 164,
|
JSConditionalCase = 164,
|
||||||
JSReturnStatement = 165,
|
JSConditionalStatement = 165,
|
||||||
JSParameter = 166,
|
JSReturnStatement = 166,
|
||||||
JSImportStarBinding = 170,
|
JSParameter = 167,
|
||||||
JSImportAsBinding = 171,
|
JSImportStarBinding = 171,
|
||||||
JSImportDeclaration = 172,
|
JSImportAsBinding = 172,
|
||||||
JSFunctionDeclaration = 173,
|
JSImportDeclaration = 173,
|
||||||
JSArrowFunctionDeclaration = 174,
|
JSFunctionDeclaration = 174,
|
||||||
JSLetDeclaration = 175,
|
JSArrowFunctionDeclaration = 175,
|
||||||
JSSourceFile = 176,
|
JSLetDeclaration = 176,
|
||||||
|
JSSourceFile = 177,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -610,6 +611,7 @@ export interface BoltRecordPattern extends SyntaxBase<SyntaxKind.BoltRecordPatte
|
||||||
export type BoltExpression
|
export type BoltExpression
|
||||||
= BoltQuoteExpression
|
= BoltQuoteExpression
|
||||||
| BoltReferenceExpression
|
| BoltReferenceExpression
|
||||||
|
| BoltMemberExpression
|
||||||
| BoltFunctionExpression
|
| BoltFunctionExpression
|
||||||
| BoltCallExpression
|
| BoltCallExpression
|
||||||
| BoltYieldExpression
|
| BoltYieldExpression
|
||||||
|
@ -630,6 +632,12 @@ export interface BoltReferenceExpression extends SyntaxBase<SyntaxKind.BoltRefer
|
||||||
name: BoltQualName;
|
name: BoltQualName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface BoltMemberExpression extends SyntaxBase<SyntaxKind.BoltMemberExpression> {
|
||||||
|
kind: SyntaxKind.BoltMemberExpression;
|
||||||
|
expression: BoltExpression;
|
||||||
|
path: BoltIdentifier[];
|
||||||
|
}
|
||||||
|
|
||||||
export interface BoltFunctionExpression extends SyntaxBase<SyntaxKind.BoltFunctionExpression> {
|
export interface BoltFunctionExpression extends SyntaxBase<SyntaxKind.BoltFunctionExpression> {
|
||||||
kind: SyntaxKind.BoltFunctionExpression;
|
kind: SyntaxKind.BoltFunctionExpression;
|
||||||
params: BoltParameter[];
|
params: BoltParameter[];
|
||||||
|
@ -1321,6 +1329,7 @@ export type BoltSyntax
|
||||||
| BoltRecordPattern
|
| BoltRecordPattern
|
||||||
| BoltQuoteExpression
|
| BoltQuoteExpression
|
||||||
| BoltReferenceExpression
|
| BoltReferenceExpression
|
||||||
|
| BoltMemberExpression
|
||||||
| BoltFunctionExpression
|
| BoltFunctionExpression
|
||||||
| BoltCallExpression
|
| BoltCallExpression
|
||||||
| BoltYieldExpression
|
| BoltYieldExpression
|
||||||
|
@ -1472,6 +1481,7 @@ export type Syntax
|
||||||
| BoltRecordPattern
|
| BoltRecordPattern
|
||||||
| BoltQuoteExpression
|
| BoltQuoteExpression
|
||||||
| BoltReferenceExpression
|
| BoltReferenceExpression
|
||||||
|
| BoltMemberExpression
|
||||||
| BoltFunctionExpression
|
| BoltFunctionExpression
|
||||||
| BoltCallExpression
|
| BoltCallExpression
|
||||||
| BoltYieldExpression
|
| BoltYieldExpression
|
||||||
|
@ -1621,6 +1631,7 @@ export function createBoltRecordFieldPattern(isRest: boolean, name: BoltIdentifi
|
||||||
export function createBoltRecordPattern(name: BoltQualName, fields: BoltRecordFieldPattern[], span?: TextSpan | null): BoltRecordPattern;
|
export function createBoltRecordPattern(name: BoltQualName, fields: BoltRecordFieldPattern[], span?: TextSpan | null): BoltRecordPattern;
|
||||||
export function createBoltQuoteExpression(tokens: Token[], span?: TextSpan | null): BoltQuoteExpression;
|
export function createBoltQuoteExpression(tokens: Token[], span?: TextSpan | null): BoltQuoteExpression;
|
||||||
export function createBoltReferenceExpression(name: BoltQualName, span?: TextSpan | null): BoltReferenceExpression;
|
export function createBoltReferenceExpression(name: BoltQualName, span?: TextSpan | null): BoltReferenceExpression;
|
||||||
|
export function createBoltMemberExpression(expression: BoltExpression, path: BoltIdentifier[], span?: TextSpan | null): BoltMemberExpression;
|
||||||
export function createBoltFunctionExpression(params: BoltParameter[], returnType: BoltTypeExpression | null, body: BoltFunctionBodyElement[], span?: TextSpan | null): BoltFunctionExpression;
|
export function createBoltFunctionExpression(params: BoltParameter[], returnType: BoltTypeExpression | null, body: BoltFunctionBodyElement[], span?: TextSpan | null): BoltFunctionExpression;
|
||||||
export function createBoltCallExpression(operator: BoltExpression, operands: BoltExpression[], span?: TextSpan | null): BoltCallExpression;
|
export function createBoltCallExpression(operator: BoltExpression, operands: BoltExpression[], span?: TextSpan | null): BoltCallExpression;
|
||||||
export function createBoltYieldExpression(value: BoltExpression, span?: TextSpan | null): BoltYieldExpression;
|
export function createBoltYieldExpression(value: BoltExpression, span?: TextSpan | null): BoltYieldExpression;
|
||||||
|
@ -1777,6 +1788,7 @@ export function isBoltRecordPattern(value: any): value is BoltRecordPattern;
|
||||||
export function isBoltExpression(value: any): value is BoltExpression;
|
export function isBoltExpression(value: any): value is BoltExpression;
|
||||||
export function isBoltQuoteExpression(value: any): value is BoltQuoteExpression;
|
export function isBoltQuoteExpression(value: any): value is BoltQuoteExpression;
|
||||||
export function isBoltReferenceExpression(value: any): value is BoltReferenceExpression;
|
export function isBoltReferenceExpression(value: any): value is BoltReferenceExpression;
|
||||||
|
export function isBoltMemberExpression(value: any): value is BoltMemberExpression;
|
||||||
export function isBoltFunctionExpression(value: any): value is BoltFunctionExpression;
|
export function isBoltFunctionExpression(value: any): value is BoltFunctionExpression;
|
||||||
export function isBoltCallExpression(value: any): value is BoltCallExpression;
|
export function isBoltCallExpression(value: any): value is BoltCallExpression;
|
||||||
export function isBoltYieldExpression(value: any): value is BoltYieldExpression;
|
export function isBoltYieldExpression(value: any): value is BoltYieldExpression;
|
||||||
|
|
108
src/parser.ts
108
src/parser.ts
|
@ -82,6 +82,8 @@ import {
|
||||||
createBoltFunctionExpression,
|
createBoltFunctionExpression,
|
||||||
BoltMacroCall,
|
BoltMacroCall,
|
||||||
createBoltMacroCall,
|
createBoltMacroCall,
|
||||||
|
BoltMemberExpression,
|
||||||
|
createBoltMemberExpression,
|
||||||
} from "./ast"
|
} from "./ast"
|
||||||
|
|
||||||
import { parseForeignLanguage } from "./foreign"
|
import { parseForeignLanguage } from "./foreign"
|
||||||
|
@ -594,27 +596,80 @@ export class Parser {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private parsePrimitiveExpression(tokens: BoltTokenStream): BoltExpression {
|
private parseExpression(tokens: BoltTokenStream): BoltExpression {
|
||||||
|
|
||||||
const t0 = tokens.peek();
|
const t0 = tokens.peek();
|
||||||
|
|
||||||
|
let result;
|
||||||
if (t0.kind === SyntaxKind.BoltVBar) {
|
if (t0.kind === SyntaxKind.BoltVBar) {
|
||||||
return this.parseFunctionExpression(tokens);
|
result = this.parseFunctionExpression(tokens);
|
||||||
} else if (t0.kind === SyntaxKind.BoltBraced) {
|
} else if (t0.kind === SyntaxKind.BoltBraced) {
|
||||||
return this.parseBlockExpression(tokens);
|
result = this.parseBlockExpression(tokens);
|
||||||
} else if (t0.kind === SyntaxKind.BoltQuoteKeyword) {
|
} else if (t0.kind === SyntaxKind.BoltQuoteKeyword) {
|
||||||
return this.parseQuoteExpression(tokens);
|
result = this.parseQuoteExpression(tokens);
|
||||||
} else if (t0.kind === SyntaxKind.BoltMatchKeyword) {
|
} else if (t0.kind === SyntaxKind.BoltMatchKeyword) {
|
||||||
return this.parseMatchExpression(tokens);
|
result = this.parseMatchExpression(tokens);
|
||||||
} else if (t0.kind === SyntaxKind.BoltIntegerLiteral || t0.kind === SyntaxKind.BoltStringLiteral) {
|
} else if (t0.kind === SyntaxKind.BoltIntegerLiteral || t0.kind === SyntaxKind.BoltStringLiteral) {
|
||||||
return this.parseConstantExpression(tokens);
|
result = this.parseConstantExpression(tokens);
|
||||||
} else if (t0.kind === SyntaxKind.BoltIdentifier) {
|
} else if (t0.kind === SyntaxKind.BoltIdentifier) {
|
||||||
return this.parseReferenceExpression(tokens);
|
result = this.parseReferenceExpression(tokens);
|
||||||
} else {
|
} else {
|
||||||
throw new ParseError(t0, [SyntaxKind.BoltStringLiteral, SyntaxKind.BoltIdentifier]);
|
throw new ParseError(t0, [SyntaxKind.BoltStringLiteral, SyntaxKind.BoltIdentifier]);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public parseExpression(tokens: BoltTokenStream): BoltExpression {
|
while (true) {
|
||||||
return this.parseCallOrPrimitiveExpression(tokens)
|
|
||||||
|
let t2 = tokens.peek();
|
||||||
|
const firstToken = t2;
|
||||||
|
|
||||||
|
const path: BoltIdentifier[] = [];
|
||||||
|
|
||||||
|
while (t2.kind === SyntaxKind.BoltDot) {
|
||||||
|
tokens.get();
|
||||||
|
const t3 = tokens.get();
|
||||||
|
assertToken(t3, SyntaxKind.BoltIdentifier);
|
||||||
|
path.push(t3 as BoltIdentifier);
|
||||||
|
t2 = tokens.peek();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.length > 0) {
|
||||||
|
const node = createBoltMemberExpression(result, path);
|
||||||
|
setOrigNodeRange(node, firstToken, t2);
|
||||||
|
result = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t2.kind !== SyntaxKind.BoltParenthesized) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
tokens.get();
|
||||||
|
|
||||||
|
const args: BoltExpression[] = []
|
||||||
|
const innerTokens = createTokenStream(t2);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
const t3 = innerTokens.peek();
|
||||||
|
if (t3.kind === SyntaxKind.EndOfFile) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
args.push(this.parseExpression(innerTokens))
|
||||||
|
const t4 = innerTokens.get();
|
||||||
|
if (t4.kind === SyntaxKind.EndOfFile) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if (t4.kind !== SyntaxKind.BoltComma) {
|
||||||
|
throw new ParseError(t4, [SyntaxKind.BoltComma])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const node = createBoltCallExpression(result, args, null)
|
||||||
|
setOrigNodeRange(node, result, t2);
|
||||||
|
result = node;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public parseParameter(tokens: BoltTokenStream, index: number): BoltParameter {
|
public parseParameter(tokens: BoltTokenStream, index: number): BoltParameter {
|
||||||
|
@ -1312,39 +1367,6 @@ export class Parser {
|
||||||
// return lhs
|
// return lhs
|
||||||
//}
|
//}
|
||||||
|
|
||||||
private parseCallOrPrimitiveExpression(tokens: BoltTokenStream): BoltExpression {
|
|
||||||
|
|
||||||
const operator = this.parsePrimitiveExpression(tokens)
|
|
||||||
|
|
||||||
const t2 = tokens.peek();
|
|
||||||
if (t2.kind !== SyntaxKind.BoltParenthesized) {
|
|
||||||
return operator;
|
|
||||||
}
|
|
||||||
tokens.get();
|
|
||||||
|
|
||||||
const args: BoltExpression[] = []
|
|
||||||
const innerTokens = createTokenStream(t2);
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
const t3 = innerTokens.peek();
|
|
||||||
if (t3.kind === SyntaxKind.EndOfFile) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
args.push(this.parseExpression(innerTokens))
|
|
||||||
const t4 = innerTokens.get();
|
|
||||||
if (t4.kind === SyntaxKind.EndOfFile) {
|
|
||||||
break
|
|
||||||
} else if (t4.kind !== SyntaxKind.BoltComma){
|
|
||||||
throw new ParseError(t4, [SyntaxKind.BoltComma])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const node = createBoltCallExpression(operator, args, null)
|
|
||||||
setOrigNodeRange(node, operator, t2);
|
|
||||||
return node;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public parseSourceFile(tokens: BoltTokenStream): BoltSourceFile {
|
public parseSourceFile(tokens: BoltTokenStream): BoltSourceFile {
|
||||||
const elements = this.parseSourceElements(tokens);
|
const elements = this.parseSourceElements(tokens);
|
||||||
const t1 = tokens.peek();
|
const t1 = tokens.peek();
|
||||||
|
|
Loading…
Reference in a new issue