bolt/src/emitter.ts

63 lines
1.4 KiB
TypeScript
Raw Normal View History

2020-02-25 17:55:17 +01:00
2020-05-10 15:56:34 +02:00
import { Syntax, SyntaxKind, kindToString } from "./ast"
2020-02-25 17:55:17 +01:00
export class Emitter {
emit(node: Syntax) {
2020-05-10 23:50:42 +02:00
let out = '';
2020-05-10 18:21:44 +02:00
2020-02-25 17:55:17 +01:00
switch (node.kind) {
2020-05-10 18:21:44 +02:00
case SyntaxKind.JSReferenceExpression:
2020-05-10 23:50:42 +02:00
out += node.name;
break;
case SyntaxKind.JSConstantExpression:
if (typeof node.value === 'string') {
out += '"' + node.value + '"';
} else if (typeof node.value === 'bigint') {
out += node.value.toString();
} else {
throw new Error(`Could not emit the value of a specific JSConstantExpression.`);
}
break;
case SyntaxKind.JSFunctionDeclaration:
out += 'function ' + node.name.text + '(';
//out += node.params.map(p => this.emit(p)).join(', ');
out += ') {\n';
out += '}\n\n'
break;
case SyntaxKind.JSCallExpression:
out += this.emit(node.operator) + '(';
out += node.operands.map(op => this.emit(op)).join(', ');
out += ')'
break;
2020-05-10 18:21:44 +02:00
2020-05-10 15:56:34 +02:00
case SyntaxKind.JSSourceFile:
2020-02-25 17:55:17 +01:00
for (const element of node.elements) {
out += this.emit(element);
}
2020-05-10 23:50:42 +02:00
break;
2020-02-25 17:55:17 +01:00
default:
2020-05-10 15:56:34 +02:00
throw new Error(`Could not emit source code for ${kindToString(node.kind)}`)
2020-02-25 17:55:17 +01:00
}
2020-05-10 23:50:42 +02:00
return out;
2020-02-25 17:55:17 +01:00
}
}
/**
* A wrapper around `Emitter` for quick emission of AST nodes with sane defaults.
*/
export function emit(node: Syntax) {
const emitter = new Emitter();
return emitter.emit(node);
}