Enable parsing member expressions

This commit is contained in:
Sam Vervaeck 2020-05-24 21:18:54 +02:00
parent aad00c5024
commit 8f661f49a7
3 changed files with 171 additions and 132 deletions

View file

@ -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
View file

@ -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;

View file

@ -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]);
} }
while (true) {
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();
} }
public parseExpression(tokens: BoltTokenStream): BoltExpression { if (path.length > 0) {
return this.parseCallOrPrimitiveExpression(tokens) 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();