node-ejs-renderer/node_modules/@jsonjoy.com/util/lib/codegen/Codegen.js

121 lines
3.5 KiB
JavaScript
Raw Permalink Normal View History

2024-06-09 13:55:01 -04:00
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Codegen = exports.CodegenStepExecJs = void 0;
const _1 = require(".");
class CodegenStepExecJs {
constructor(js) {
this.js = js;
}
}
exports.CodegenStepExecJs = CodegenStepExecJs;
class Codegen {
constructor(opts) {
this.steps = [];
this.dependencies = [];
this.dependencyNames = [];
this.linked = {};
this.constants = [];
this.constantNames = [];
this.options = {
args: ['r0'],
name: '',
prologue: '',
epilogue: '',
processSteps: (steps) => steps.filter((step) => step instanceof CodegenStepExecJs),
linkable: {},
...opts,
};
this.registerCounter = this.options.args.length;
}
js(js) {
this.steps.push(new CodegenStepExecJs(js));
}
var(expression) {
const r = this.getRegister();
if (expression)
this.js('var ' + r + ' = ' + expression + ';');
else
this.js('var ' + r + ';');
return r;
}
if(condition, then, otherwise) {
this.js('if (' + condition + ') {');
then();
if (otherwise) {
this.js('} else {');
otherwise();
}
this.js('}');
}
switch(expression, cases, def) {
this.js('switch (' + expression + ') {');
for (const [match, block, noBreak] of cases) {
this.js('case ' + match + ': {');
block();
if (!noBreak)
this.js('break;');
this.js('}');
}
if (def) {
this.js('default: {');
def();
this.js('}');
}
this.js('}');
}
return(expression) {
this.js('return ' + expression + ';');
}
step(step) {
this.steps.push(step);
}
getRegister() {
return `r${this.registerCounter++}`;
}
r() {
return this.getRegister();
}
linkDependency(dep, name = 'd' + this.dependencies.length) {
this.dependencies.push(dep);
this.dependencyNames.push(name);
return name;
}
linkDependencies(deps) {
return deps.map((dep) => this.linkDependency(dep));
}
link(name) {
if (this.linked[name])
return;
this.linked[name] = 1;
this.linkDependency(this.options.linkable[name], name);
}
addConstant(constant, name = 'c' + this.constants.length) {
this.constants.push(constant);
this.constantNames.push(name);
return name;
}
addConstants(constants) {
return constants.map((constant) => this.addConstant(constant));
}
generate(opts = {}) {
const { name, args, prologue, epilogue } = { ...this.options, ...opts };
const steps = this.options.processSteps(this.steps);
const js = `(function(${this.dependencyNames.join(', ')}) {
${this.constants.map((constant, index) => `var ${this.constantNames[index]} = (${constant});`).join('\n')}
return ${name ? `function ${name}` : 'function'}(${args.join(',')}){
${prologue}
${steps.map((step) => step.js).join('\n')}
${typeof epilogue === 'function' ? epilogue() : epilogue || ''}
}})`;
return {
deps: this.dependencies,
js: js,
};
}
compile(opts) {
const closure = this.generate(opts);
return (0, _1.compileClosure)(closure);
}
}
exports.Codegen = Codegen;
//# sourceMappingURL=Codegen.js.map