From f8918bfa79cc6180ca7d90cecd8ce21ffebd8dce Mon Sep 17 00:00:00 2001 From: Sam Vervaeck Date: Sun, 10 May 2020 18:54:57 +0200 Subject: [PATCH] Fix even more errors --- spec/ast.txt | 11 +--- src/ast.d.ts | 105 ++++++++++++++++----------------- src/checker.ts | 7 +++ src/parser.ts | 157 +++++++++++++++++++++++++++++++------------------ 4 files changed, 160 insertions(+), 120 deletions(-) diff --git a/spec/ast.txt b/spec/ast.txt index 8799a2d23..2416535ac 100644 --- a/spec/ast.txt +++ b/spec/ast.txt @@ -51,6 +51,7 @@ node BoltLetKeyword > BoltToken, BoltKeyword; node BoltReturnKeyword > BoltToken, BoltKeyword; node BoltLoopKeyword > BoltToken, BoltKeyword; node BoltYieldKeyword > BoltToken, BoltKeyword; +node BoltMatchKeyword > BoltToken, BoltKeyword; node BoltImportKeyword > BoltToken, BoltKeyword; node BoltPubKeyword > BoltToken, BoltKeyword; node BoltModKeyword > BoltToken, BoltKeyword; @@ -205,20 +206,12 @@ node BoltModule > BoltDeclaration { } node BoltFunctionDeclaration > BoltDeclaration { - modifiers: BoltDeclarationModifiers, - name: BoltSymbol, - params: Vec, - returnType: Option, - body: BoltExpression, -} - -node BoltForeignFunctionDeclaration > BoltDeclaration { modifiers: BoltDeclarationModifiers, target: String, name: BoltSymbol, params: Vec, returnType: Option, - body: FunctionBody, + body: Vec, } node BoltVariableDeclaration > BoltDeclaration { diff --git a/src/ast.d.ts b/src/ast.d.ts index ebba7b430..58066a005 100644 --- a/src/ast.d.ts +++ b/src/ast.d.ts @@ -22,44 +22,44 @@ export const enum SyntaxKind { BoltReturnKeyword = 25, BoltLoopKeyword = 26, BoltYieldKeyword = 27, - BoltImportKeyword = 28, - BoltPubKeyword = 29, - BoltModKeyword = 30, - BoltMutKeyword = 31, - BoltEnumKeyword = 32, - BoltStructKeyword = 33, - BoltNewTypeKeyword = 34, - BoltParenthesized = 36, - BoltBraced = 37, - BoltBracketed = 38, - BoltSourceFile = 39, - BoltQualName = 40, - BoltSentence = 41, - BoltReferenceTypeNode = 43, - BoltBindPattern = 45, - BoltTypePattern = 46, - BoltExpressionPattern = 47, - BoltTuplePatternElement = 48, - BoltTuplePattern = 49, - BoltRecordPatternField = 50, - BoltRecordPattern = 51, - BoltReferenceExpression = 53, - BoltCallExpression = 54, - BoltYieldExpression = 55, - BoltMatchArm = 56, - BoltMatchExpression = 57, - BoltCase = 58, - BoltCaseExpression = 59, - BoltBlockExpression = 60, - BoltConstantExpression = 61, - BoltReturnStatement = 63, - BoltResumeStatement = 64, - BoltExpressionStatement = 65, - BoltParameter = 66, - BoltNewTypeDeclaration = 69, - BoltModule = 70, - BoltFunctionDeclaration = 71, - BoltForeignFunctionDeclaration = 72, + BoltMatchKeyword = 28, + BoltImportKeyword = 29, + BoltPubKeyword = 30, + BoltModKeyword = 31, + BoltMutKeyword = 32, + BoltEnumKeyword = 33, + BoltStructKeyword = 34, + BoltNewTypeKeyword = 35, + BoltParenthesized = 37, + BoltBraced = 38, + BoltBracketed = 39, + BoltSourceFile = 40, + BoltQualName = 41, + BoltSentence = 42, + BoltReferenceTypeNode = 44, + BoltBindPattern = 46, + BoltTypePattern = 47, + BoltExpressionPattern = 48, + BoltTuplePatternElement = 49, + BoltTuplePattern = 50, + BoltRecordPatternField = 51, + BoltRecordPattern = 52, + BoltReferenceExpression = 54, + BoltCallExpression = 55, + BoltYieldExpression = 56, + BoltMatchArm = 57, + BoltMatchExpression = 58, + BoltCase = 59, + BoltCaseExpression = 60, + BoltBlockExpression = 61, + BoltConstantExpression = 62, + BoltReturnStatement = 64, + BoltResumeStatement = 65, + BoltExpressionStatement = 66, + BoltParameter = 67, + BoltNewTypeDeclaration = 70, + BoltModule = 71, + BoltFunctionDeclaration = 72, BoltVariableDeclaration = 73, BoltPlainImportSymbol = 75, BoltImportDeclaration = 76, @@ -124,6 +124,7 @@ export type BoltToken | BoltReturnKeyword | BoltLoopKeyword | BoltYieldKeyword + | BoltMatchKeyword | BoltImportKeyword | BoltPubKeyword | BoltModKeyword @@ -212,6 +213,7 @@ export type BoltKeyword | BoltReturnKeyword | BoltLoopKeyword | BoltYieldKeyword + | BoltMatchKeyword | BoltImportKeyword | BoltPubKeyword | BoltModKeyword @@ -245,6 +247,10 @@ export interface BoltYieldKeyword extends SyntaxBase { kind: SyntaxKind.BoltYieldKeyword; } +export interface BoltMatchKeyword extends SyntaxBase { + kind: SyntaxKind.BoltMatchKeyword; +} + export interface BoltImportKeyword extends SyntaxBase { kind: SyntaxKind.BoltImportKeyword; } @@ -459,7 +465,6 @@ export type BoltDeclaration = BoltNewTypeDeclaration | BoltModule | BoltFunctionDeclaration - | BoltForeignFunctionDeclaration | BoltVariableDeclaration | BoltImportDeclaration | BoltRecordDeclaration @@ -484,20 +489,11 @@ export interface BoltModule extends SyntaxBase { export interface BoltFunctionDeclaration extends SyntaxBase { kind: SyntaxKind.BoltFunctionDeclaration; modifiers: BoltDeclarationModifiers; - name: BoltSymbol; - params: BoltParameter[]; - returnType: BoltTypeNode | null; - body: BoltExpression; -} - -export interface BoltForeignFunctionDeclaration extends SyntaxBase { - kind: SyntaxKind.BoltForeignFunctionDeclaration; - modifiers: BoltDeclarationModifiers; target: string; name: BoltSymbol; params: BoltParameter[]; returnType: BoltTypeNode | null; - body: FunctionBody; + body: BoltStatement[]; } export interface BoltVariableDeclaration extends SyntaxBase { @@ -537,7 +533,6 @@ export type BoltSourceElement | BoltNewTypeDeclaration | BoltModule | BoltFunctionDeclaration - | BoltForeignFunctionDeclaration | BoltVariableDeclaration | BoltImportDeclaration | BoltRecordDeclaration @@ -729,6 +724,7 @@ export type BoltSyntax | BoltReturnKeyword | BoltLoopKeyword | BoltYieldKeyword + | BoltMatchKeyword | BoltImportKeyword | BoltPubKeyword | BoltModKeyword @@ -766,7 +762,6 @@ export type BoltSyntax | BoltNewTypeDeclaration | BoltModule | BoltFunctionDeclaration - | BoltForeignFunctionDeclaration | BoltVariableDeclaration | BoltPlainImportSymbol | BoltImportDeclaration @@ -820,6 +815,7 @@ export type Syntax | BoltReturnKeyword | BoltLoopKeyword | BoltYieldKeyword + | BoltMatchKeyword | BoltImportKeyword | BoltPubKeyword | BoltModKeyword @@ -857,7 +853,6 @@ export type Syntax | BoltNewTypeDeclaration | BoltModule | BoltFunctionDeclaration - | BoltForeignFunctionDeclaration | BoltVariableDeclaration | BoltPlainImportSymbol | BoltImportDeclaration @@ -909,6 +904,7 @@ export function createBoltLetKeyword(span?: TextSpan | null): BoltLetKeyword; export function createBoltReturnKeyword(span?: TextSpan | null): BoltReturnKeyword; export function createBoltLoopKeyword(span?: TextSpan | null): BoltLoopKeyword; export function createBoltYieldKeyword(span?: TextSpan | null): BoltYieldKeyword; +export function createBoltMatchKeyword(span?: TextSpan | null): BoltMatchKeyword; export function createBoltImportKeyword(span?: TextSpan | null): BoltImportKeyword; export function createBoltPubKeyword(span?: TextSpan | null): BoltPubKeyword; export function createBoltModKeyword(span?: TextSpan | null): BoltModKeyword; @@ -945,8 +941,7 @@ export function createBoltExpressionStatement(expression: BoltExpression, span?: 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 createBoltModule(modifiers: BoltDeclarationModifiers, name: BoltQualName, elements: BoltSourceElement[], span?: TextSpan | null): BoltModule; -export function createBoltFunctionDeclaration(modifiers: BoltDeclarationModifiers, name: BoltSymbol, params: BoltParameter[], returnType: BoltTypeNode | null, body: BoltExpression, span?: TextSpan | null): BoltFunctionDeclaration; -export function createBoltForeignFunctionDeclaration(modifiers: BoltDeclarationModifiers, target: string, name: BoltSymbol, params: BoltParameter[], returnType: BoltTypeNode | null, body: FunctionBody, span?: TextSpan | null): BoltForeignFunctionDeclaration; +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 createBoltPlainImportSymbol(name: BoltQualName, span?: TextSpan | null): BoltPlainImportSymbol; export function createBoltImportDeclaration(file: string, symbols: BoltImportSymbol[], span?: TextSpan | null): BoltImportDeclaration; @@ -998,6 +993,7 @@ export function isBoltLetKeyword(value: any): value is BoltLetKeyword; export function isBoltReturnKeyword(value: any): value is BoltReturnKeyword; export function isBoltLoopKeyword(value: any): value is BoltLoopKeyword; export function isBoltYieldKeyword(value: any): value is BoltYieldKeyword; +export function isBoltMatchKeyword(value: any): value is BoltMatchKeyword; export function isBoltImportKeyword(value: any): value is BoltImportKeyword; export function isBoltPubKeyword(value: any): value is BoltPubKeyword; export function isBoltModKeyword(value: any): value is BoltModKeyword; @@ -1041,7 +1037,6 @@ export function isBoltDeclaration(value: any): value is BoltDeclaration; export function isBoltNewTypeDeclaration(value: any): value is BoltNewTypeDeclaration; export function isBoltModule(value: any): value is BoltModule; export function isBoltFunctionDeclaration(value: any): value is BoltFunctionDeclaration; -export function isBoltForeignFunctionDeclaration(value: any): value is BoltForeignFunctionDeclaration; export function isBoltVariableDeclaration(value: any): value is BoltVariableDeclaration; export function isBoltImportSymbol(value: any): value is BoltImportSymbol; export function isBoltPlainImportSymbol(value: any): value is BoltPlainImportSymbol; diff --git a/src/checker.ts b/src/checker.ts index 80f5eb24c..ae94354c5 100644 --- a/src/checker.ts +++ b/src/checker.ts @@ -142,6 +142,9 @@ export class TypeChecker { this.symbols[getFullName(node.name)] = new PrimType(); return noneType; + case SyntaxKind.BoltExpressionStatement: + return voidType; + case SyntaxKind.BoltFunctionDeclaration: let returnType = anyType; if (node.returnType !== null) { @@ -217,6 +220,10 @@ export class TypeChecker { case SyntaxKind.BoltNewTypeDeclaration: break; + case SyntaxKind.BoltExpressionStatement: + this.check(node.expression); + break; + case SyntaxKind.BoltFunctionDeclaration: if (node.body !== null) { if (Array.isArray(node.body)) { diff --git a/src/parser.ts b/src/parser.ts index a28cdaac2..ae9ff1525 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -9,6 +9,8 @@ import { BoltExpression, BoltRecordDeclaration, BoltStatement, + BoltDeclaration, + BoltSourceElement, createBoltQualName, BoltQualName, BoltPattern, @@ -26,6 +28,9 @@ import { BoltDeclarationModifiers, BoltStringLiteral, BoltImportSymbol, + BoltCallExpression, + BoltExpressionStatement, + createBoltExpressionStatement, } from "./ast" import { BoltTokenStream, setOrigNodeRange } from "./util" @@ -44,6 +49,12 @@ function describeKind(kind: SyntaxKind): string { return "'fn'" case SyntaxKind.BoltForeignKeyword: return "'foreign'" + case SyntaxKind.BoltMatchKeyword: + return "'match'"; + case SyntaxKind.BoltYieldKeyword: + return "'yield'"; + case SyntaxKind.BoltReturnKeyword: + return "'return'"; case SyntaxKind.BoltPubKeyword: return "'pub'" case SyntaxKind.BoltLetKeyword: @@ -64,6 +75,8 @@ function describeKind(kind: SyntaxKind): string { return "'struct'" case SyntaxKind.BoltEnumKeyword: return "'enum'" + case SyntaxKind.BoltNewTypeKeyword: + return "'newtype'"; case SyntaxKind.BoltBraced: return "'{' .. '}'" case SyntaxKind.BoltBracketed: @@ -81,7 +94,7 @@ function enumerate(elements: string[]) { if (elements.length === 1) { return elements[0] } else { - return elements.slice(0, elements.length-1).join(',') + ' or ' + elements[elements.length-1] + return elements.slice(0, elements.length-1).join(', ') + ' or ' + elements[elements.length-1] } } @@ -117,13 +130,37 @@ const KIND_EXPRESSION_T0 = [ SyntaxKind.BoltIntegerLiteral, SyntaxKind.BoltIdentifier, SyntaxKind.BoltOperator, - ] + SyntaxKind.BoltMatchKeyword, + SyntaxKind.BoltYieldKeyword, +] const KIND_STATEMENT_T0 = [ SyntaxKind.BoltReturnKeyword, ...KIND_EXPRESSION_T0, ] +const KIND_DECLARATION_KEYWORD = [ + SyntaxKind.BoltFnKeyword, + SyntaxKind.BoltEnumKeyword, + SyntaxKind.BoltLetKeyword, + SyntaxKind.BoltNewTypeKeyword, + SyntaxKind.BoltModKeyword, + SyntaxKind.BoltStructKeyword, +] + +const KIND_DECLARATION_T0 = [ + SyntaxKind.BoltPubKeyword, + SyntaxKind.BoltForeignKeyword, + ...KIND_DECLARATION_KEYWORD, +] + +const KIND_SOURCEELEMENT_T0 = [ + SyntaxKind.BoltModKeyword, + ...KIND_EXPRESSION_T0, + ...KIND_STATEMENT_T0, + ...KIND_DECLARATION_T0, +] + export class Parser { operatorTable = [ @@ -416,6 +453,13 @@ export class Parser { || (t0.kind === SyntaxKind.BoltOperator && this.isUnaryOperator(t0.text)); } + public parseExpressionStatement(tokens: BoltTokenStream): BoltExpressionStatement { + const expression = this.parseExpression(tokens) + const node = createBoltExpressionStatement(expression) + setOrigNodeRange(node, expression, expression); + return node; + } + public parseStatement(tokens: BoltTokenStream): BoltStatement { const t0 = tokens.peek(); if (t0.kind === SyntaxKind.BoltReturnKeyword) { @@ -553,7 +597,7 @@ export class Parser { return node; } - private parseFunctionDeclarationMaybeForeign(tokens: BoltTokenStream): BoltFunctionDeclaration | BoltForeignFunctionDeclaration { + private parseFunctionDeclaration(tokens: BoltTokenStream): BoltFunctionDeclaration | BoltForeignFunctionDeclaration { let target = "Bolt"; let modifiers = 0; @@ -707,63 +751,66 @@ export class Parser { body ); setOrigNodeRange(node, firstToken, lastNode); + return node; } - parseSourceElement(tokens: BoltTokenStream): SourceElement { - const t0 = tokens.peek(1); - if (t0.kind === SyntaxKind.BoltIdentifier) { - let i = 1; - let kw: Token = t0; - if (t0.text === 'pub') { - i++; - kw = tokens.peek(i); - if (kw.kind !== SyntaxKind.BoltIdentifier) { - throw new ParseError(kw, [SyntaxKind.BoltForeignKeyword, SyntaxKind.BoltModKeyword, - SyntaxKind.BoltLetKeyword, SyntaxKind.BoltFnKeyword, SyntaxKind.BoltEnumKeyword, SyntaxKind.BoltStructKeyword]) + public parseDeclaration(tokens: BoltTokenStream): BoltDeclaration { + let t0 = tokens.peek(1); + let i = 1; + if (t0.kind === SyntaxKind.BoltPubKeyword) { + t0 = tokens.peek(i++); + if (t0.kind !== SyntaxKind.BoltForeignKeyword) { + if (KIND_DECLARATION_KEYWORD.indexOf(t0.kind) === -1) { + throw new ParseError(t0, KIND_DECLARATION_KEYWORD); } } - if (t0.text === 'foreign') { - i += 2; - kw = tokens.peek(i); - if (kw.kind !== SyntaxKind.BoltIdentifier) { - throw new ParseError(kw, [SyntaxKind.BoltModKeyword, SyntaxKind.BoltLetKeyword, - SyntaxKind.BoltFnKeyword, SyntaxKind.BoltEnumKeyword, SyntaxKind.BoltStructKeyword]) + } + if (t0.kind === SyntaxKind.BoltForeignKeyword) { + i += 2; + t0 = tokens.peek(i); + if (KIND_DECLARATION_KEYWORD.indexOf(t0.kind) === -1) { + throw new ParseError(t0, KIND_DECLARATION_KEYWORD); + } + } + switch (t0.kind) { + case SyntaxKind.BoltNewTypeKeyword: + return this.parseNewTypeDeclaration(tokens); + case SyntaxKind.BoltModKeyword: + return this.parseModuleDeclaration(tokens); + case SyntaxKind.BoltFnKeyword: + return this.parseFunctionDeclaration(tokens); + case SyntaxKind.BoltLetKeyword: + return this.parseVariableDeclaration(tokens); + case SyntaxKind.BoltStructKeyword: + return this.parseRecordDeclaration(tokens); + case SyntaxKind.BoltStructKeyword: + return this.parseVariableDeclaration(tokens); + default: + throw new ParseError(t0, KIND_DECLARATION_T0); + } + } + + public parseSourceElement(tokens: BoltTokenStream): BoltSourceElement { + const t0 = tokens.peek(); + try { + return this.parseDeclaration(tokens) + } catch (e) { + if (!(e instanceof ParseError)) { + throw e; + } + try { + return this.parseStatement(tokens); + } catch (e) { + if (!(e instanceof ParseError)) { + throw e; } + throw new ParseError(t0, KIND_SOURCEELEMENT_T0) } - switch (kw.text) { - case 'newtype': - return this.parseNewType(tokens); - case 'syntax': - return this.parseSyntax(tokens); - case 'mod': - return this.parseModDecl(tokens); - case 'fn': - return this.parseFuncDecl(tokens, null); - case 'let': - return this.parseVarDecl(tokens); - case 'struct': - return this.parseRecordDecl(tokens); - case 'enum': - return this.parseVariantDecl(tokens); - default: - try { - return this.parseExpression(tokens) - } catch (e) { - if (e instanceof ParseError) { - throw new ParseError(kw, [...e.expected, SyntaxKind.BoltModKeyword, SyntaxKind.BoltLetKeyword, - SyntaxKind.BoltFnKeyword, SyntaxKind.BoltEnumKeyword, SyntaxKind.BoltStructKeyword]) - } else { - throw e; - } - } - } - } else { - return this.parseStatement(tokens) } } - getOperatorDesc(seekArity: number, seekName: string): OperatorInfo { + 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) { @@ -804,17 +851,15 @@ export class Parser { // return lhs //} - parseCallExpr(tokens: TokenStream): CallExpr { + public parseCallExpression(tokens: BoltTokenStream): BoltCallExpression { const operator = this.parsePrimitiveExpression(tokens) - const args: Expr[] = [] + const args: BoltExpression[] = [] const t2 = tokens.get(); - if (t2.kind !== SyntaxKind.BoltParenthesized) { - throw new ParseError(t2, [SyntaxKind.BoltParenthesized]) - } + assertToken(t2, SyntaxKind.BoltParenthesized); - const innerTokens = t2.toTokenStream(); + const innerTokens = createTokenStream(t2); while (true) { const t3 = innerTokens.peek();