UNPKG

consys

Version:

consys is a flexible tool to evaluate models using generic and readable constraints.

82 lines (81 loc) 2.94 kB
"use strict"; 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;