evaluateOpVariadic method
Implementation
EvaluateOutput evaluateOpVariadic(EvaluateInput input) {
final op = input.expr.opVariadic;
final operands = <Value>[];
for (final elem in op.operands) {
final val =
evaluateExpr(EvaluateInput(defStack: input.defStack, expr: elem));
if (val.status != EvaluateOutput_Status.OK) {
return val;
}
operands.add(val.value);
}
switch (op.op) {
case OpVariadic_Op.ADD:
var addVal = 0.0;
for (final (i, operand) in operands.indexed) {
if (operand.type != Value_Type.NUM) {
return _errorUnexpectedType(input.expr.path.append(['add', i]),
operand.type, [Value_Type.NUM]);
}
addVal += operand.num;
}
if (!addVal.isFinite) {
return _errorNotFiniteNumber(input.expr.path.append(['add']));
}
return EvaluateOutput(value: numValue(addVal));
case OpVariadic_Op.MUL:
var mulVal = 1.0;
for (final (i, operand) in operands.indexed) {
if (operand.type != Value_Type.NUM) {
return _errorUnexpectedType(input.expr.path.append(['mul', i]),
operand.type, [Value_Type.NUM]);
}
mulVal *= operand.num;
}
if (!mulVal.isFinite) {
return _errorNotFiniteNumber(input.expr.path.append(['mul']));
}
return EvaluateOutput(value: numValue(mulVal));
case OpVariadic_Op.AND:
for (final (i, operand) in operands.indexed) {
if (operand.type != Value_Type.BOOL) {
return _errorUnexpectedType(input.expr.path.append(['and', i]),
operand.type, [Value_Type.BOOL]);
}
if (!operand.bool_2) {
return EvaluateOutput(value: boolValue(false));
}
}
return EvaluateOutput(value: boolValue(true));
case OpVariadic_Op.OR:
for (final (i, operand) in operands.indexed) {
if (operand.type != Value_Type.BOOL) {
return _errorUnexpectedType(input.expr.path.append(['or', i]),
operand.type, [Value_Type.BOOL]);
}
if (operand.bool_2) {
return EvaluateOutput(value: boolValue(true));
}
}
return EvaluateOutput(value: boolValue(false));
case OpVariadic_Op.CAT:
var catVal = '';
for (final (i, operand) in operands.indexed) {
if (operand.type != Value_Type.STR) {
return _errorUnexpectedType(input.expr.path.append(['cat', i]),
operand.type, [Value_Type.STR]);
}
catVal += operand.str;
}
return EvaluateOutput(value: strValue(catVal));
case OpVariadic_Op.MIN:
var minVal = double.infinity;
for (final (i, operand) in operands.indexed) {
if (operand.type != Value_Type.NUM) {
return _errorUnexpectedType(input.expr.path.append(['min', i]),
operand.type, [Value_Type.NUM]);
}
minVal = min(minVal, operand.num);
}
return EvaluateOutput(value: numValue(minVal));
case OpVariadic_Op.MAX:
var maxVal = double.negativeInfinity;
for (final (i, operand) in operands.indexed) {
if (operand.type != Value_Type.NUM) {
return _errorUnexpectedType(input.expr.path.append(['max', i]),
operand.type, [Value_Type.NUM]);
}
maxVal = max(maxVal, operand.num);
}
return EvaluateOutput(value: numValue(maxVal));
case OpVariadic_Op.MERGE:
final mergeVal = <String, Value>{};
for (final (i, operand) in operands.indexed) {
if (operand.type != Value_Type.OBJ) {
return _errorUnexpectedType(input.expr.path.append(['merge', i]),
operand.type, [Value_Type.OBJ]);
}
mergeVal.addEntries(operand.obj.entries);
}
return EvaluateOutput(value: objValue(mergeVal));
default:
throw ArgumentError('unexpected variadic operator ${op.op}');
}
}