consys
Version:
consys is a flexible tool to evaluate models using generic and readable constraints.
82 lines (81 loc) • 2.94 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const Token_1 = require("./Token");
class Emitter {
constructor(ast) {
this.ast = ast;
}
emit() {
var _a;
return ((_a = this.ast.root) === null || _a === void 0 ? void 0 : _a.accept(this)) || '';
}
visitBinaryExpression(rule) {
return `${rule.left.accept(this)}${rule.operator.lexeme}${rule.right.accept(this)}`;
}
visitConstraintExpression(rule) {
const activation = rule.activation.accept(this);
const assertion = rule.assertion.accept(this);
const assertFn = `function assert(e,n){if(!e){throw Error(n)}};`;
let validInputCheck = ``;
for (const modelVar of Object.keys(this.ast.statistics.counts.model)) {
validInputCheck += `assert(this.model.${modelVar}!==undefined,"$${modelVar}");`;
}
for (const stateVar of Object.keys(this.ast.statistics.counts.state)) {
validInputCheck += `assert(this.state.${stateVar}!==undefined,"#${stateVar}");`;
}
return `${assertFn}${validInputCheck}if(${activation}){return(${assertion});}else{return(true);}`;
}
visitFunctionExpression(rule) {
let args = `this.model,this.state`;
if (rule.args.length > 0) {
args = rule.args
.map((rule) => rule.accept(this))
.join(`,`);
}
return `this.functions['${rule.name.lexeme}'](${args})`;
}
visitGroupingExpression(rule) {
return `(${rule.expression.accept(this)})`;
}
visitLiteralExpression(rule) {
switch (rule.value.type) {
case Token_1.TokenType.STRING:
return `'${rule.value.lexeme}'`;
case Token_1.TokenType.NUMBER:
return `${rule.value.lexeme}`;
default:
return 'true';
}
}
visitLogicalExpression(rule) {
let operator = `${rule.operator.lexeme}`;
switch (rule.operator.type) {
case Token_1.TokenType.OR:
operator = `||`;
break;
case Token_1.TokenType.AND:
operator = `&&`;
break;
}
return `${rule.left.accept(this)}${operator}${rule.right.accept(this)}`;
}
visitUnaryExpression(rule) {
const expression = rule.right.accept(this);
let operator = `${rule.operator.lexeme}`;
if (rule.operator.type === Token_1.TokenType.NOT) {
operator = `!`;
}
return `${operator}${expression}`;
}
visitVariableExpression(rule) {
let variable = `this.model`;
if (rule.prefix.type === Token_1.TokenType.HASH) {
variable = `this.state`;
}
for (const identifier of rule.name) {
variable += `.${identifier.lexeme}`;
}
return variable;
}
}
exports.default = Emitter;