Add a first version of Lang.Bolt module

This commit is contained in:
Sam Vervaeck 2020-05-24 17:47:04 +02:00
parent 02b759a05b
commit 9b5cb6ad38
10 changed files with 265 additions and 196 deletions

View file

@ -180,6 +180,15 @@ node BoltReturnStatement > BoltStatement {
value: Option<BoltExpression>, value: Option<BoltExpression>,
} }
node BoltConditionalCase {
test: Option<BoltExpression>,
body: Vec<BoltFunctionBodyElement>,
}
node BoltConditionalStatement > BoltStatement {
cases: Vec<BoltConditionalCase>,
}
node BoltResumeStatement > BoltStatement { node BoltResumeStatement > BoltStatement {
value: BoltExpression, value: BoltExpression,
} }
@ -402,7 +411,9 @@ node JSReferenceExpression > JSExpression {
node JSSourceElement; node JSSourceElement;
node JSStatement > JSSourceElement; node JSFunctionBodyElement;
node JSStatement > JSSourceElement, JSFunctionBodyElement;
node JSCatchBlock { node JSCatchBlock {
bindings: Option<JSPattern>, bindings: Option<JSPattern>,
@ -419,10 +430,13 @@ node JSExpressionStatement > JSStatement {
expression: JSExpression, expression: JSExpression,
} }
node JSConditionalCase {
test: Option<JSExpression>,
body: Vec<JSFunctionBodyElement>,
}
node JSConditionalStatement > JSStatement { node JSConditionalStatement > JSStatement {
test: JSExpression, cases: Vec<JSConditionalCase>,
consequent: Vec<JSStatement>,
alternate: Vec<JSStatement>,
} }
node JSReturnStatement > JSStatement { node JSReturnStatement > JSStatement {
@ -457,20 +471,20 @@ node JSImportDeclaration > JSDeclaration {
filename: JSString, filename: JSString,
} }
node JSFunctionDeclaration > JSDeclaration { node JSFunctionDeclaration > JSDeclaration, JSFunctionBodyElement {
modifiers: JSDeclarationModifiers, modifiers: JSDeclarationModifiers,
name: JSIdentifier, name: JSIdentifier,
params: Vec<JSParameter>, params: Vec<JSParameter>,
body: Vec<JSStatement>, body: Vec<JSStatement>,
} }
node JSArrowFunctionDeclaration > JSDeclaration { node JSArrowFunctionDeclaration > JSDeclaration, JSFunctionBodyElement {
name: JSIdentifier, name: JSIdentifier,
params: Vec<JSParameter>, params: Vec<JSParameter>,
body: JSExpression, body: JSExpression,
} }
node JSLetDeclaration > JSDeclaration { node JSLetDeclaration > JSDeclaration, JSFunctionBodyElement {
bindings: JSPattern, bindings: JSPattern,
value: Option<JSExpression>, value: Option<JSExpression>,
} }

203
src/ast.d.ts vendored
View file

@ -59,82 +59,85 @@ export const enum SyntaxKind {
BoltBlockExpression = 66, BoltBlockExpression = 66,
BoltConstantExpression = 67, BoltConstantExpression = 67,
BoltReturnStatement = 69, BoltReturnStatement = 69,
BoltResumeStatement = 70, BoltConditionalCase = 70,
BoltExpressionStatement = 71, BoltConditionalStatement = 71,
BoltParameter = 72, BoltResumeStatement = 72,
BoltModule = 76, BoltExpressionStatement = 73,
BoltFunctionDeclaration = 78, BoltParameter = 74,
BoltVariableDeclaration = 79, BoltModule = 78,
BoltPlainImportSymbol = 81, BoltFunctionDeclaration = 80,
BoltImportDeclaration = 82, BoltVariableDeclaration = 81,
BoltTraitDeclaration = 83, BoltPlainImportSymbol = 83,
BoltImplDeclaration = 84, BoltImportDeclaration = 84,
BoltTypeAliasDeclaration = 85, BoltTraitDeclaration = 85,
BoltRecordField = 87, BoltImplDeclaration = 86,
BoltRecordDeclaration = 88, BoltTypeAliasDeclaration = 87,
BoltMacroCall = 90, BoltRecordField = 89,
JSOperator = 93, BoltRecordDeclaration = 90,
JSIdentifier = 94, BoltMacroCall = 92,
JSString = 95, JSOperator = 95,
JSInteger = 96, JSIdentifier = 96,
JSFromKeyword = 97, JSString = 97,
JSReturnKeyword = 98, JSInteger = 98,
JSTryKeyword = 99, JSFromKeyword = 99,
JSFinallyKeyword = 100, JSReturnKeyword = 100,
JSCatchKeyword = 101, JSTryKeyword = 101,
JSImportKeyword = 102, JSFinallyKeyword = 102,
JSAsKeyword = 103, JSCatchKeyword = 103,
JSConstKeyword = 104, JSImportKeyword = 104,
JSLetKeyword = 105, JSAsKeyword = 105,
JSExportKeyword = 106, JSConstKeyword = 106,
JSFunctionKeyword = 107, JSLetKeyword = 107,
JSWhileKeyword = 108, JSExportKeyword = 108,
JSForKeyword = 109, JSFunctionKeyword = 109,
JSCloseBrace = 110, JSWhileKeyword = 110,
JSCloseBracket = 111, JSForKeyword = 111,
JSCloseParen = 112, JSCloseBrace = 112,
JSOpenBrace = 113, JSCloseBracket = 113,
JSOpenBracket = 114, JSCloseParen = 114,
JSOpenParen = 115, JSOpenBrace = 115,
JSSemi = 116, JSOpenBracket = 116,
JSComma = 117, JSOpenParen = 117,
JSDot = 118, JSSemi = 118,
JSDotDotDot = 119, JSComma = 119,
JSMulOp = 120, JSDot = 120,
JSAddOp = 121, JSDotDotDot = 121,
JSDivOp = 122, JSMulOp = 122,
JSSubOp = 123, JSAddOp = 123,
JSLtOp = 124, JSDivOp = 124,
JSGtOp = 125, JSSubOp = 125,
JSBOrOp = 126, JSLtOp = 126,
JSBXorOp = 127, JSGtOp = 127,
JSBAndOp = 128, JSBOrOp = 128,
JSBNotOp = 129, JSBXorOp = 129,
JSNotOp = 130, JSBAndOp = 130,
JSBindPattern = 132, JSBNotOp = 131,
JSConstantExpression = 134, JSNotOp = 132,
JSMemberExpression = 135, JSBindPattern = 134,
JSCallExpression = 136, JSConstantExpression = 136,
JSBinaryExpression = 137, JSMemberExpression = 137,
JSUnaryExpression = 138, JSCallExpression = 138,
JSNewExpression = 139, JSBinaryExpression = 139,
JSSequenceExpression = 140, JSUnaryExpression = 140,
JSConditionalExpression = 141, JSNewExpression = 141,
JSLiteralExpression = 143, JSSequenceExpression = 142,
JSReferenceExpression = 144, JSConditionalExpression = 143,
JSCatchBlock = 147, JSLiteralExpression = 145,
JSTryCatchStatement = 148, JSReferenceExpression = 146,
JSExpressionStatement = 149, JSCatchBlock = 150,
JSConditionalStatement = 150, JSTryCatchStatement = 151,
JSReturnStatement = 151, JSExpressionStatement = 152,
JSParameter = 152, JSConditionalCase = 153,
JSImportStarBinding = 156, JSConditionalStatement = 154,
JSImportAsBinding = 157, JSReturnStatement = 155,
JSImportDeclaration = 158, JSParameter = 156,
JSFunctionDeclaration = 159, JSImportStarBinding = 160,
JSArrowFunctionDeclaration = 160, JSImportAsBinding = 161,
JSLetDeclaration = 161, JSImportDeclaration = 162,
JSSourceFile = 162, JSFunctionDeclaration = 163,
JSArrowFunctionDeclaration = 164,
JSLetDeclaration = 165,
JSSourceFile = 166,
} }
@ -523,6 +526,7 @@ export interface BoltConstantExpression extends SyntaxBase<SyntaxKind.BoltConsta
export type BoltStatement export type BoltStatement
= BoltReturnStatement = BoltReturnStatement
| BoltConditionalStatement
| BoltResumeStatement | BoltResumeStatement
| BoltExpressionStatement | BoltExpressionStatement
| BoltMacroCall | BoltMacroCall
@ -533,6 +537,17 @@ export interface BoltReturnStatement extends SyntaxBase<SyntaxKind.BoltReturnSta
value: BoltExpression | null; value: BoltExpression | null;
} }
export interface BoltConditionalCase extends SyntaxBase<SyntaxKind.BoltConditionalCase> {
kind: SyntaxKind.BoltConditionalCase;
test: BoltExpression | null;
body: BoltFunctionBodyElement[];
}
export interface BoltConditionalStatement extends SyntaxBase<SyntaxKind.BoltConditionalStatement> {
kind: SyntaxKind.BoltConditionalStatement;
cases: BoltConditionalCase[];
}
export interface BoltResumeStatement extends SyntaxBase<SyntaxKind.BoltResumeStatement> { export interface BoltResumeStatement extends SyntaxBase<SyntaxKind.BoltResumeStatement> {
kind: SyntaxKind.BoltResumeStatement; kind: SyntaxKind.BoltResumeStatement;
value: BoltExpression; value: BoltExpression;
@ -581,6 +596,7 @@ export interface BoltModule extends SyntaxBase<SyntaxKind.BoltModule> {
export type BoltFunctionBodyElement export type BoltFunctionBodyElement
= BoltReturnStatement = BoltReturnStatement
| BoltConditionalStatement
| BoltResumeStatement | BoltResumeStatement
| BoltExpressionStatement | BoltExpressionStatement
| BoltMacroCall | BoltMacroCall
@ -667,6 +683,7 @@ export interface BoltRecordDeclaration extends SyntaxBase<SyntaxKind.BoltRecordD
export type BoltSourceElement export type BoltSourceElement
= BoltReturnStatement = BoltReturnStatement
| BoltConditionalStatement
| BoltResumeStatement | BoltResumeStatement
| BoltExpressionStatement | BoltExpressionStatement
| BoltMacroCall | BoltMacroCall
@ -978,6 +995,15 @@ export type JSSourceElement
| JSLetDeclaration | JSLetDeclaration
export type JSFunctionBodyElement
= JSExpressionStatement
| JSConditionalStatement
| JSReturnStatement
| JSFunctionDeclaration
| JSArrowFunctionDeclaration
| JSLetDeclaration
export type JSStatement export type JSStatement
= JSExpressionStatement = JSExpressionStatement
| JSConditionalStatement | JSConditionalStatement
@ -1002,11 +1028,15 @@ export interface JSExpressionStatement extends SyntaxBase<SyntaxKind.JSExpressio
expression: JSExpression; expression: JSExpression;
} }
export interface JSConditionalCase extends SyntaxBase<SyntaxKind.JSConditionalCase> {
kind: SyntaxKind.JSConditionalCase;
test: JSExpression | null;
body: JSFunctionBodyElement[];
}
export interface JSConditionalStatement extends SyntaxBase<SyntaxKind.JSConditionalStatement> { export interface JSConditionalStatement extends SyntaxBase<SyntaxKind.JSConditionalStatement> {
kind: SyntaxKind.JSConditionalStatement; kind: SyntaxKind.JSConditionalStatement;
test: JSExpression; cases: JSConditionalCase[];
consequent: JSStatement[];
alternate: JSStatement[];
} }
export interface JSReturnStatement extends SyntaxBase<SyntaxKind.JSReturnStatement> { export interface JSReturnStatement extends SyntaxBase<SyntaxKind.JSReturnStatement> {
@ -1137,6 +1167,8 @@ export type BoltSyntax
| BoltBlockExpression | BoltBlockExpression
| BoltConstantExpression | BoltConstantExpression
| BoltReturnStatement | BoltReturnStatement
| BoltConditionalCase
| BoltConditionalStatement
| BoltResumeStatement | BoltResumeStatement
| BoltExpressionStatement | BoltExpressionStatement
| BoltParameter | BoltParameter
@ -1206,6 +1238,7 @@ export type JSSyntax
| JSCatchBlock | JSCatchBlock
| JSTryCatchStatement | JSTryCatchStatement
| JSExpressionStatement | JSExpressionStatement
| JSConditionalCase
| JSConditionalStatement | JSConditionalStatement
| JSReturnStatement | JSReturnStatement
| JSParameter | JSParameter
@ -1278,6 +1311,8 @@ export type Syntax
| BoltBlockExpression | BoltBlockExpression
| BoltConstantExpression | BoltConstantExpression
| BoltReturnStatement | BoltReturnStatement
| BoltConditionalCase
| BoltConditionalStatement
| BoltResumeStatement | BoltResumeStatement
| BoltExpressionStatement | BoltExpressionStatement
| BoltParameter | BoltParameter
@ -1344,6 +1379,7 @@ export type Syntax
| JSCatchBlock | JSCatchBlock
| JSTryCatchStatement | JSTryCatchStatement
| JSExpressionStatement | JSExpressionStatement
| JSConditionalCase
| JSConditionalStatement | JSConditionalStatement
| JSReturnStatement | JSReturnStatement
| JSParameter | JSParameter
@ -1417,6 +1453,8 @@ export function createBoltCaseExpression(cases: BoltCase[], span?: TextSpan | nu
export function createBoltBlockExpression(elements: BoltFunctionBodyElement[], span?: TextSpan | null): BoltBlockExpression; export function createBoltBlockExpression(elements: BoltFunctionBodyElement[], span?: TextSpan | null): BoltBlockExpression;
export function createBoltConstantExpression(value: BoltValue, span?: TextSpan | null): BoltConstantExpression; export function createBoltConstantExpression(value: BoltValue, span?: TextSpan | null): BoltConstantExpression;
export function createBoltReturnStatement(value: BoltExpression | null, span?: TextSpan | null): BoltReturnStatement; export function createBoltReturnStatement(value: BoltExpression | null, span?: TextSpan | null): BoltReturnStatement;
export function createBoltConditionalCase(test: BoltExpression | null, body: BoltFunctionBodyElement[], span?: TextSpan | null): BoltConditionalCase;
export function createBoltConditionalStatement(cases: BoltConditionalCase[], span?: TextSpan | null): BoltConditionalStatement;
export function createBoltResumeStatement(value: BoltExpression, span?: TextSpan | null): BoltResumeStatement; export function createBoltResumeStatement(value: BoltExpression, span?: TextSpan | null): BoltResumeStatement;
export function createBoltExpressionStatement(expression: BoltExpression, span?: TextSpan | null): BoltExpressionStatement; export function createBoltExpressionStatement(expression: BoltExpression, span?: TextSpan | null): BoltExpressionStatement;
export function createBoltParameter(index: number, bindings: BoltPattern, type: BoltTypeExpression | null, defaultValue: BoltExpression | null, span?: TextSpan | null): BoltParameter; export function createBoltParameter(index: number, bindings: BoltPattern, type: BoltTypeExpression | null, defaultValue: BoltExpression | null, span?: TextSpan | null): BoltParameter;
@ -1483,7 +1521,8 @@ export function createJSReferenceExpression(name: string, span?: TextSpan | null
export function createJSCatchBlock(bindings: JSPattern | null, elements: JSSourceElement[], span?: TextSpan | null): JSCatchBlock; export function createJSCatchBlock(bindings: JSPattern | null, elements: JSSourceElement[], span?: TextSpan | null): JSCatchBlock;
export function createJSTryCatchStatement(tryBlock: JSSourceElement[], catchBlock: JSCatchBlock | null, finalBlock: JSSourceElement[] | null, span?: TextSpan | null): JSTryCatchStatement; export function createJSTryCatchStatement(tryBlock: JSSourceElement[], catchBlock: JSCatchBlock | null, finalBlock: JSSourceElement[] | null, span?: TextSpan | null): JSTryCatchStatement;
export function createJSExpressionStatement(expression: JSExpression, span?: TextSpan | null): JSExpressionStatement; export function createJSExpressionStatement(expression: JSExpression, span?: TextSpan | null): JSExpressionStatement;
export function createJSConditionalStatement(test: JSExpression, consequent: JSStatement[], alternate: JSStatement[], span?: TextSpan | null): JSConditionalStatement; export function createJSConditionalCase(test: JSExpression | null, body: JSFunctionBodyElement[], span?: TextSpan | null): JSConditionalCase;
export function createJSConditionalStatement(cases: JSConditionalCase[], span?: TextSpan | null): JSConditionalStatement;
export function createJSReturnStatement(value: JSExpression | null, span?: TextSpan | null): JSReturnStatement; export function createJSReturnStatement(value: JSExpression | null, span?: TextSpan | null): JSReturnStatement;
export function createJSParameter(index: number, bindings: JSPattern, defaultValue: JSExpression | null, span?: TextSpan | null): JSParameter; export function createJSParameter(index: number, bindings: JSPattern, defaultValue: JSExpression | null, span?: TextSpan | null): JSParameter;
export function createJSImportStarBinding(local: JSIdentifier, span?: TextSpan | null): JSImportStarBinding; export function createJSImportStarBinding(local: JSIdentifier, span?: TextSpan | null): JSImportStarBinding;
@ -1561,6 +1600,8 @@ export function isBoltBlockExpression(value: any): value is BoltBlockExpression;
export function isBoltConstantExpression(value: any): value is BoltConstantExpression; export function isBoltConstantExpression(value: any): value is BoltConstantExpression;
export function isBoltStatement(value: any): value is BoltStatement; export function isBoltStatement(value: any): value is BoltStatement;
export function isBoltReturnStatement(value: any): value is BoltReturnStatement; export function isBoltReturnStatement(value: any): value is BoltReturnStatement;
export function isBoltConditionalCase(value: any): value is BoltConditionalCase;
export function isBoltConditionalStatement(value: any): value is BoltConditionalStatement;
export function isBoltResumeStatement(value: any): value is BoltResumeStatement; export function isBoltResumeStatement(value: any): value is BoltResumeStatement;
export function isBoltExpressionStatement(value: any): value is BoltExpressionStatement; export function isBoltExpressionStatement(value: any): value is BoltExpressionStatement;
export function isBoltParameter(value: any): value is BoltParameter; export function isBoltParameter(value: any): value is BoltParameter;
@ -1634,10 +1675,12 @@ export function isJSConditionalExpression(value: any): value is JSConditionalExp
export function isJSLiteralExpression(value: any): value is JSLiteralExpression; export function isJSLiteralExpression(value: any): value is JSLiteralExpression;
export function isJSReferenceExpression(value: any): value is JSReferenceExpression; export function isJSReferenceExpression(value: any): value is JSReferenceExpression;
export function isJSSourceElement(value: any): value is JSSourceElement; export function isJSSourceElement(value: any): value is JSSourceElement;
export function isJSFunctionBodyElement(value: any): value is JSFunctionBodyElement;
export function isJSStatement(value: any): value is JSStatement; export function isJSStatement(value: any): value is JSStatement;
export function isJSCatchBlock(value: any): value is JSCatchBlock; export function isJSCatchBlock(value: any): value is JSCatchBlock;
export function isJSTryCatchStatement(value: any): value is JSTryCatchStatement; export function isJSTryCatchStatement(value: any): value is JSTryCatchStatement;
export function isJSExpressionStatement(value: any): value is JSExpressionStatement; export function isJSExpressionStatement(value: any): value is JSExpressionStatement;
export function isJSConditionalCase(value: any): value is JSConditionalCase;
export function isJSConditionalStatement(value: any): value is JSConditionalStatement; export function isJSConditionalStatement(value: any): value is JSConditionalStatement;
export function isJSReturnStatement(value: any): value is JSReturnStatement; export function isJSReturnStatement(value: any): value is JSReturnStatement;
export function isJSParameter(value: any): value is JSParameter; export function isJSParameter(value: any): value is JSParameter;

View file

@ -2,9 +2,15 @@ import {
BoltFunctionBodyElement, BoltFunctionBodyElement,
BoltReturnStatement, BoltReturnStatement,
SyntaxKind, SyntaxKind,
BoltExpression BoltExpression,
BoltSourceFile,
JSSourceFile
} from "./ast"; } from "./ast";
export type SourceFile
= BoltSourceFile
| JSSourceFile
export type BoltFunctionBody = BoltFunctionBodyElement[]; export type BoltFunctionBody = BoltFunctionBodyElement[];
export function getReturnStatementsInFunctionBody(body: BoltFunctionBody): BoltReturnStatement[] { export function getReturnStatementsInFunctionBody(body: BoltFunctionBody): BoltReturnStatement[] {

View file

@ -104,7 +104,6 @@ export class Frontend {
case "JS": case "JS":
const transforms = new TransformManager(this.container); const transforms = new TransformManager(this.container);
transforms.register(ExpandBoltTransform); transforms.register(ExpandBoltTransform);
transforms.register(EliminateModulesTransform);
transforms.register(CompileBoltToJSTransform); transforms.register(CompileBoltToJSTransform);
transforms.register(ConstFoldTransform); transforms.register(ConstFoldTransform);
transforms.apply(program); transforms.apply(program);

View file

@ -1,11 +1,8 @@
import { BoltSourceFile, JSSourceFile } from "./ast" import { SourceFile } from "./common"
import { BoltSourceFile } from "./ast"
import { FastStringMap } from "./util"; import { FastStringMap } from "./util";
export type SourceFile
= BoltSourceFile
| JSSourceFile
export class Program { export class Program {
private transformed = new FastStringMap<string, SourceFile>(); private transformed = new FastStringMap<string, SourceFile>();

View file

@ -39,6 +39,7 @@ import {
isBoltStatement, isBoltStatement,
JSBindPattern, JSBindPattern,
BoltSourceElement, BoltSourceElement,
createJSParameter,
} from "../ast" } from "../ast"
import { hasPublicModifier, setOrigNodeRange } from "../util" import { hasPublicModifier, setOrigNodeRange } from "../util"
@ -69,7 +70,7 @@ class CompileContext {
private generatedNodes: JSSyntax[] = []; private generatedNodes: JSSyntax[] = [];
constructor(public scope: Scope) { constructor() {
} }
@ -98,7 +99,7 @@ export class BoltToJSTransform implements Transformer {
} }
public transform(sourceFile: BoltSourceFile): JSSourceFile { public transform(sourceFile: BoltSourceFile): JSSourceFile {
const ctx = new CompileContext(this.checker.getScope(sourceFile)) const ctx = new CompileContext()
for (const element of sourceFile.elements) { for (const element of sourceFile.elements) {
this.compileSourceElement(element, ctx); this.compileSourceElement(element, ctx);
} }
@ -110,6 +111,7 @@ export class BoltToJSTransform implements Transformer {
switch (node.kind) { switch (node.kind) {
case SyntaxKind.BoltCallExpression: case SyntaxKind.BoltCallExpression:
{
const compiledOperator = this.compileExpression(node.operator, ctx); const compiledOperator = this.compileExpression(node.operator, ctx);
const compiledArgs = node.operands.map(arg => this.compileExpression(arg, ctx)) const compiledArgs = node.operands.map(arg => this.compileExpression(arg, ctx))
return createJSCallExpression( return createJSCallExpression(
@ -117,19 +119,22 @@ export class BoltToJSTransform implements Transformer {
compiledArgs, compiledArgs,
node.span, node.span,
); );
}
case SyntaxKind.BoltReferenceExpression: case SyntaxKind.BoltReferenceExpression:
{
assert(node.name.modulePath === null); assert(node.name.modulePath === null);
return createJSReferenceExpression( const result = createJSReferenceExpression(node.name.name.text);
node.name.name.text, setOrigNodeRange(result, node, node);
node.span, return result;
); }
case SyntaxKind.BoltConstantExpression: case SyntaxKind.BoltConstantExpression:
return createJSConstantExpression( {
node.value, const result = createJSConstantExpression(node.value);
node.span, setOrigNodeRange(result, node, node);
); return result;
}
default: default:
throw new Error(`Could not compile expression node ${kindToString(node.kind)}`) throw new Error(`Could not compile expression node ${kindToString(node.kind)}`)
@ -147,7 +152,7 @@ export class BoltToJSTransform implements Transformer {
return jsBindPatt; return jsBindPatt;
} }
protected compileSourceElement(node: BoltSourceElement, ctx: CompileContext) { private compileSourceElement(node: BoltSourceElement, ctx: CompileContext) {
switch (node.kind) { switch (node.kind) {
@ -167,6 +172,7 @@ export class BoltToJSTransform implements Transformer {
break; break;
case SyntaxKind.BoltVariableDeclaration: case SyntaxKind.BoltVariableDeclaration:
{
const jsValue = node.value !== null ? this.compileExpression(node.value, ctx) : null; const jsValue = node.value !== null ? this.compileExpression(node.value, ctx) : null;
const jsValueBindPatt = this.convertPattern(node.bindings); const jsValueBindPatt = this.convertPattern(node.bindings);
const jsValueDecl = createJSLetDeclaration( const jsValueDecl = createJSLetDeclaration(
@ -175,35 +181,50 @@ export class BoltToJSTransform implements Transformer {
); );
ctx.appendNode(jsValueDecl); ctx.appendNode(jsValueDecl);
break; break;
}
case SyntaxKind.BoltFunctionDeclaration: case SyntaxKind.BoltFunctionDeclaration:
{
if (node.body === null) { if (node.body === null) {
break; break;
} }
if (node.target === "JS") {
const params: JSParameter[] = []; const params: JSParameter[] = [];
let body: JSStatement[] = []; let body: JSStatement[] = [];
let modifiers = 0;
if (hasPublicModifier(node)) {
modifiers |= JSDeclarationModifiers.IsExported;;
}
let i = 0;
for (const param of node.params) { for (const param of node.params) {
assert(param.defaultValue === null); assert(param.defaultValue === null);
const jsPatt = this.convertPattern(param.bindings) const jsPatt = this.convertPattern(param.bindings)
params.push(jsPatt); const jsParam = createJSParameter(i, jsPatt, null);
params.push(jsParam);
i++;
} }
let result = createJSFunctionDeclaration( const name = createJSIdentifier(node.name.text)
0, setOrigNodeRange(name, node.name, node.name);
createJSIdentifier(node.name.text, node.name.span), const bodyCtx = new CompileContext();
if (node.target === "JS") {
for (const element of node.body) {
this.compileJSStatement(element, bodyCtx);
}
} else {
for (const element of node.body) {
this.compileSourceElement(element, bodyCtx);
}
}
const result = createJSFunctionDeclaration(
modifiers,
name,
params, params,
body, bodyCtx.getGeneratedNodes() as JSStatement[],
node.span, node.span,
); );
if (hasPublicModifier(node)) { setOrigNodeRange(result, node, node);
result.modifiers |= JSDeclarationModifiers.IsExported;;
}
ctx.appendNode(result) ctx.appendNode(result)
} else {
// TODO
throw new Error(`Compiling native functions is not yet implemented.`);
}
break; break;
}
default: default:
throw new Error(`Could not compile node ${kindToString(node.kind)}`); throw new Error(`Could not compile node ${kindToString(node.kind)}`);

View file

@ -1,55 +0,0 @@
import {TransformManager} from ".";
import {SourceFile} from "../program";
import {isBoltSourceFile, createBoltSourceFile, BoltSourceElement, SyntaxKind, BoltModule, isBoltModule} from "../ast";
import {setOrigNodeRange} from "../util";
export class EliminateModulesTransform {
constructor(private transformers: TransformManager) {
}
public isApplicable(sourceFile: SourceFile) {
return isBoltSourceFile(sourceFile);
}
public transform(sourceFile: SourceFile): SourceFile {
let needsUpdate = false;
const elements: BoltSourceElement[] = [];
for (const element of sourceFile.elements) {
if (element.kind === SyntaxKind.BoltModule) {
this.extractModuleElements(element, elements);
needsUpdate = true;
} else {
elements.push(element);
}
}
if (!needsUpdate) {
return sourceFile;
}
const newSourceFile = createBoltSourceFile(elements);
setOrigNodeRange(newSourceFile, sourceFile, sourceFile);
return newSourceFile;
}
public extractModuleElements(node: BoltModule, out: BoltSourceElement[]) {
for (const element of node.elements) {
switch (element.kind) {
case SyntaxKind.BoltModule:
this.extractModuleElements(node, out);
break;
case SyntaxKind.BoltRecordDeclaration:
// TODO
break;
}
}
}
}
export default EliminateModulesTransform;

View file

@ -1,5 +1,5 @@
mod Lang.Bolt.AST { mod Bolt.Lang {
pub struct Pos { pub struct Pos {
offset: Int, offset: Int,
@ -20,5 +20,55 @@ mod Lang.Bolt.AST {
parent: Option<Node>, parent: Option<Node>,
} }
pub type Token
= Identifier
pub struct ConditionalCase {
test: Option<Expression>,
result: Vec<FunctionBodyElement>,
}
pub struct ConditionalStatement {
cases: Vec<ConditionalCase>,
}
pub type Statement
= ReturnStatement
| ConditionalStatement
pub type Expression
= ReferenceExpression
pub type Transformer = fn (node: Node) -> Node;
fn build_predicate_from_pattern(pattern: Pattern) -> Expression {
match pattern {
BindPattern { name } => quote(true).taint(pattern),
VariantPatten { elements } => quote(or($(elements),*)),
RecordPattern { members } => quote(and($elements),*)),
}
}
fn eliminate_match_rule(stx: Syntax) {
match stx {
quote {
match $value: Expression {
$patterns @ ( $pattern: Pattern => $expression: Expression ),* (,)?
}
} => {
let cases = patterns.map(|pattern| {
ConditionalCase::from_node(
pattern,
build_predicate_from_pattern(pattern),
value
)
});
return ConditionalStatement::from_node(stx, cases);
}
}
}
register_transformer!(elminate_match_rule);
} }

View file

@ -1,11 +1,5 @@
syntax { import "lang/bolt" (
quote { Identifier,
macro $name: QualName { Syntax,
);
}
} => {
}
}