ifc-expressions
Version:
Parsing and evaluation of IFC expressions
65 lines (64 loc) • 3.14 kB
JavaScript
import { Func } from "../Func.js";
import { ExprEvalFunctionEvaluationErrorObj, ExprEvalStatus, ExprEvalSuccessObj, } from "../../ExprEvalResult.js";
import { FuncArg } from "../FuncArg.js";
import { ExprKind } from "../../ExprKind.js";
import { isNullish } from "../../../util/IfcExpressionUtils.js";
import { FuncArgMappings } from "../arg/FuncArgMappings.js";
import { Types } from "../../../type/Types.js";
import { WrongFunctionArgumentTypeException } from "../../../error/WrongFunctionArgumentTypeException.js";
export class MAP extends Func {
constructor() {
super("MAP", [
new FuncArg(true, MAP.ARG_NAME_MAPPING_INPUT),
new FuncArgMappings(true, MAP.ARG_NAME_MAPPINGS),
new FuncArg(false, MAP.ARG_NAME_DEFAULT_VALUE),
]);
}
getReturnType(argumentTypes) {
const returnTypes = argumentTypes[1]
.getTypes()
.map((t) => t.getTypes()[1]);
return Types.or(...returnTypes);
}
checkArgumentsAndGetReturnType(argumentTypes, ctx) {
const returnType = super.checkArgumentsAndGetReturnType(argumentTypes, ctx);
const tupleTypes = argumentTypes[1][1]
.toArrayType()
.getElementType().getTypes()[0].getTypes();
const inType = tupleTypes[0];
const outType = tupleTypes[1];
if (!argumentTypes[0][1].overlapsWith(inType)) {
throw new WrongFunctionArgumentTypeException(this.name, this.formalArguments[0].name, inType, argumentTypes[0][1], 0, argumentTypes[0][0]);
}
if (argumentTypes.length > 2 &&
!argumentTypes[2][1].overlapsWith(outType)) {
throw new WrongFunctionArgumentTypeException(this.name, this.formalArguments[2].name, inType, argumentTypes[2][1], 2, argumentTypes[2][0]);
}
return returnType;
}
calculateResult(callingExpr, evaluatedArguments) {
const mappings = evaluatedArguments.get(MAP.ARG_NAME_MAPPINGS);
const input = evaluatedArguments.get(MAP.ARG_NAME_MAPPING_INPUT);
const defaultValue = evaluatedArguments.get(MAP.ARG_NAME_DEFAULT_VALUE);
const outerArray = mappings.getValue();
const numMappings = outerArray.length;
for (let i = 0; i < numMappings; i++) {
const error = FuncArgMappings.checkSingleMapping(callingExpr, outerArray, i);
if (!isNullish(error)) {
return error;
}
const pair = outerArray[i].getValue();
if (pair[0].equals(input)) {
return new ExprEvalSuccessObj(pair[1]);
}
}
if (isNullish(defaultValue)) {
return new ExprEvalFunctionEvaluationErrorObj(ExprKind.FUNCTION, ExprEvalStatus.UNDEFINED_RESULT, "Input value not found in left column. No default return value specified, therefore the result of MAP() is undefined ", this.name, callingExpr.getTextSpan());
}
return new ExprEvalSuccessObj(defaultValue);
}
}
MAP.ARG_NAME_MAPPINGS = "mappings";
MAP.ARG_NAME_MAPPING_INPUT = "input";
MAP.ARG_NAME_DEFAULT_VALUE = "defaultValue";
//# sourceMappingURL=MAP.js.map