evaluateOpVariadic method
Implementation
EvaluateExprOutput evaluateOpVariadic(EvaluateExprInput input) {
final operator = input.expr.obj.keys.first;
final pathOp = pathAppendKey(input.path, operator);
final operands = <Value>[];
for (final (pos, o) in input.expr.obj[operator]!.arr.indexed) {
final op = evaluateExpr(EvaluateExprInput(
path: pathAppendIndex(pathOp, pos), defs: input.defs, expr: o));
if (op.status != EvaluateExprOutput_Status.OK) {
return op;
}
operands.add(op.value);
}
if (operator == opVariadicKeyName(OpVariadic_Operator.ADD)) {
var add = 0.0;
for (final operand in operands) {
if (operand.type != Type.TYPE_NUM) {
return _errorUnexpectedType(pathOp, [Type.TYPE_NUM], operand.type);
}
add += operand.num;
}
final v = Value(type: Type.TYPE_NUM, num: add);
if (!_isFiniteNumber(v)) {
return _errorArithmeticError(pathOp,
"add(${operands.map((o) => o.num.toInt().toString()).join(',')}) is not a finite number");
}
return EvaluateExprOutput(value: v);
} else if (operator == opVariadicKeyName(OpVariadic_Operator.MUL)) {
var mul = 1.0;
for (final operand in operands) {
if (operand.type != Type.TYPE_NUM) {
return _errorUnexpectedType(pathOp, [Type.TYPE_NUM], operand.type);
}
mul *= operand.num;
}
final v = Value(type: Type.TYPE_NUM, num: mul);
if (!_isFiniteNumber(v)) {
return _errorArithmeticError(pathOp,
"mul(${operands.map((e) => e.num.toInt().toString()).join(',')}) is not a finite number");
}
return EvaluateExprOutput(value: v);
} else if (operator == opVariadicKeyName(OpVariadic_Operator.AND)) {
for (final operand in operands) {
if (operand.type != Type.TYPE_BOOL) {
return _errorUnexpectedType(pathOp, [Type.TYPE_BOOL], operand.type);
}
if (!operand.bool_2) {
return EvaluateExprOutput(
value: Value(type: Type.TYPE_BOOL, bool_2: false));
}
}
return EvaluateExprOutput(
value: Value(type: Type.TYPE_BOOL, bool_2: true));
} else if (operator == opVariadicKeyName(OpVariadic_Operator.OR)) {
for (final operand in operands) {
if (operand.type != Type.TYPE_BOOL) {
return _errorUnexpectedType(pathOp, [Type.TYPE_BOOL], operand.type);
}
if (operand.bool_2) {
return EvaluateExprOutput(
value: Value(type: Type.TYPE_BOOL, bool_2: true));
}
}
return EvaluateExprOutput(
value: Value(type: Type.TYPE_BOOL, bool_2: false));
} else if (operator == opVariadicKeyName(OpVariadic_Operator.CAT)) {
var cat = '';
for (final operand in operands) {
if (operand.type != Type.TYPE_STR) {
return _errorUnexpectedType(pathOp, [Type.TYPE_STR], operand.type);
}
cat += operand.str;
}
return EvaluateExprOutput(value: Value(type: Type.TYPE_STR, str: cat));
} else if (operator == opVariadicKeyName(OpVariadic_Operator.MIN)) {
var min_ = double.infinity;
for (final operand in operands) {
if (operand.type != Type.TYPE_NUM) {
return _errorUnexpectedType(pathOp, [Type.TYPE_NUM], operand.type);
}
min_ = min(min_, operand.num);
}
return EvaluateExprOutput(value: Value(type: Type.TYPE_NUM, num: min_));
} else if (operator == opVariadicKeyName(OpVariadic_Operator.MAX)) {
var max_ = double.negativeInfinity;
for (final operand in operands) {
if (operand.type != Type.TYPE_NUM) {
return _errorUnexpectedType(pathOp, [Type.TYPE_NUM], operand.type);
}
max_ = max(max_, operand.num);
}
return EvaluateExprOutput(value: Value(type: Type.TYPE_NUM, num: max_));
} else if (operator == opVariadicKeyName(OpVariadic_Operator.MERGE)) {
final merge = <String, Value>{};
for (final operand in operands) {
if (operand.type != Type.TYPE_OBJ) {
return _errorUnexpectedType(pathOp, [Type.TYPE_OBJ], operand.type);
}
for (final k in operand.obj.keys) {
merge[k] = operand.obj[k]!;
}
}
return EvaluateExprOutput(value: Value(type: Type.TYPE_OBJ, obj: merge));
}
return _errorUnsupportedOperation(input.path, operator);
}