ifc-expressions
Version:
Parsing and evaluation of IFC expressions
83 lines (82 loc) • 5.14 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.IF = void 0;
const Func_js_1 = require("../Func.js");
const ExprEvalResult_js_1 = require("../../ExprEvalResult.js");
const Types_js_1 = require("../../../type/Types.js");
const FuncArgAny_js_1 = require("../arg/FuncArgAny.js");
const FuncArgLogicalOrBoolean_js_1 = require("../arg/FuncArgLogicalOrBoolean.js");
const ExprKind_js_1 = require("../../ExprKind.js");
const SpuriousFunctionArgumentException_js_1 = require("../../../error/SpuriousFunctionArgumentException.js");
const MissingFunctionArgumentException_js_1 = require("../../../error/MissingFunctionArgumentException.js");
const LogicalValue_js_1 = require("../../../value/LogicalValue.js");
class IF extends Func_js_1.Func {
constructor() {
super("IF", [
new FuncArgLogicalOrBoolean_js_1.FuncArgLogicalOrBoolean(true, IF.ARG_NAME_CONDITION),
new FuncArgAny_js_1.FuncArgAny(true, IF.ARG_NAME_THEN),
new FuncArgAny_js_1.FuncArgAny(true, IF.ARG_NAME_ELSE),
new FuncArgAny_js_1.FuncArgAny(false, IF.ARG_NAME_UNKNOWN),
]);
}
getReturnType(argumentTypes) {
if (argumentTypes.length == 3) {
return Types_js_1.Types.or(argumentTypes[1], argumentTypes[2]);
}
if (argumentTypes.length == 4) {
return Types_js_1.Types.or(argumentTypes[1], argumentTypes[2], argumentTypes[3]);
}
throw new Error("Unexpected argument types: " + JSON.stringify(argumentTypes));
}
checkArgumentTypes(providedArgumentTypes, ctx) {
super.checkArgumentTypes(providedArgumentTypes, ctx);
//extra check: if our value to be checked is a Logical, the unknownValue must be provided
if (providedArgumentTypes[0][1].isSameTypeAs(Types_js_1.Type.LOGICAL)) {
if (providedArgumentTypes.length < 4) {
throw new MissingFunctionArgumentException_js_1.MissingFunctionArgumentException(this.name, IF.ARG_NAME_UNKNOWN, 3, ctx, `Argument ${IF.ARG_NAME_UNKNOWN} is required if the argument ${IF.ARG_NAME_CONDITION} is of type logical (i.e., can be true, false or unknown)`);
}
}
else if (providedArgumentTypes[0][1].isSameTypeAs(Types_js_1.Type.BOOLEAN)) {
if (providedArgumentTypes.length > 3) {
throw new SpuriousFunctionArgumentException_js_1.SpuriousFunctionArgumentException(this.name, IF.ARG_NAME_UNKNOWN, 3, providedArgumentTypes[3][0], `Argument ${IF.ARG_NAME_UNKNOWN} is not allowed if the argument ${IF.ARG_NAME_CONDITION} is of type boolean (i.e., can only be true or false)`);
}
}
}
transformArguments(callingExpr, evaluatedArguments) {
const cond = evaluatedArguments.get(IF.ARG_NAME_CONDITION);
if ((0, ExprEvalResult_js_1.isExprEvalSuccess)(cond)) {
if (cond.result.getType().isSameTypeAs(Types_js_1.Type.LOGICAL)) {
if (evaluatedArguments.size < 4) {
evaluatedArguments.set(IF.ARG_NAME_UNKNOWN, new ExprEvalResult_js_1.ExprEvalMissingRequiredFunctionArgumentErrorObj(ExprKind_js_1.ExprKind.FUNCTION_ARGUMENTS, `Argument ${IF.ARG_NAME_UNKNOWN} is required if the argument ${IF.ARG_NAME_CONDITION} is of type logical (i.e., can be true, false or unknown)`, this.name, IF.ARG_NAME_UNKNOWN, 3, callingExpr.getTextSpan()));
}
}
else if (cond.result.getType().isSameTypeAs(Types_js_1.Type.BOOLEAN)) {
if (evaluatedArguments.size > 3) {
evaluatedArguments.set(IF.ARG_NAME_UNKNOWN, new ExprEvalResult_js_1.ExprEvalSpuriousFunctionArgumentErrorObj(`Argument ${IF.ARG_NAME_UNKNOWN} is not allowed if the argument ${IF.ARG_NAME_CONDITION} is of type boolean (i.e., can only be true or false)`, this.name, IF.ARG_NAME_UNKNOWN, 3, callingExpr.getTextSpan()));
}
}
}
}
calculateResult(callingExpr, evaluatedArguments) {
const condition = evaluatedArguments.get(IF.ARG_NAME_CONDITION);
if (condition.isTrue()) {
const thenValue = evaluatedArguments.get(IF.ARG_NAME_THEN);
return new ExprEvalResult_js_1.ExprEvalSuccessObj(thenValue);
}
else if (condition.isFalse()) {
const elseValue = evaluatedArguments.get(IF.ARG_NAME_ELSE);
return new ExprEvalResult_js_1.ExprEvalSuccessObj(elseValue);
}
else if (LogicalValue_js_1.LogicalValue.isUnknown(condition.getValue())) {
const unknownValue = evaluatedArguments.get(IF.ARG_NAME_UNKNOWN);
return new ExprEvalResult_js_1.ExprEvalSuccessObj(unknownValue);
}
return new ExprEvalResult_js_1.ExprEvalFunctionEvaluationErrorObj(ExprKind_js_1.ExprKind.FUNCTION, ExprEvalResult_js_1.ExprEvalStatus.ERROR, "Cannot handle value of condtition: " + JSON.stringify(condition), this.name, callingExpr.getTextSpan());
}
}
exports.IF = IF;
IF.ARG_NAME_CONDITION = "condition";
IF.ARG_NAME_THEN = "thenValue";
IF.ARG_NAME_ELSE = "elseValue";
IF.ARG_NAME_UNKNOWN = "unknownValue";
//# sourceMappingURL=IF.js.map