evaluateOpUnary method

EvaluateOutput evaluateOpUnary(
  1. EvaluateInput input
)

Implementation

EvaluateOutput evaluateOpUnary(EvaluateInput input) {
  final op = input.expr.opUnary;
  final o =
      evaluateExpr(EvaluateInput(defStack: input.defStack, expr: op.operand));
  if (o.status != EvaluateOutput_Status.OK) {
    return o;
  }
  final operand = o.value;
  switch (op.op) {
    case OpUnary_Op.LEN:
      switch (operand.type) {
        case Value_Type.STR:
          return EvaluateOutput(
              value: numValue(operand.str.runes.length.toDouble()));
        case Value_Type.ARR:
          return EvaluateOutput(
              value: numValue(operand.arr.length.toDouble()));
        case Value_Type.OBJ:
          return EvaluateOutput(
              value: numValue(operand.obj.length.toDouble()));
        default:
          return _errorUnexpectedType(input.expr.path.append(['len']),
              operand.type, [Value_Type.STR, Value_Type.ARR, Value_Type.OBJ]);
      }
    case OpUnary_Op.NOT:
      if (operand.type != Value_Type.BOOL) {
        return _errorUnexpectedType(
            input.expr.path.append(['not']), operand.type, [Value_Type.BOOL]);
      }
      return EvaluateOutput(value: boolValue(!operand.bool_2));
    case OpUnary_Op.FLAT:
      if (operand.type != Value_Type.ARR) {
        return _errorUnexpectedType(
            input.expr.path.append(['flat']), operand.type, [Value_Type.ARR]);
      }
      final v = <Value>[];
      for (final elem in operand.arr) {
        if (elem.type != Value_Type.ARR) {
          return _errorUnexpectedType(
              input.expr.path.append(['flat']), elem.type, [Value_Type.ARR]);
        }
        v.addAll(elem.arr);
      }
      return EvaluateOutput(value: arrValue(v));
    case OpUnary_Op.FLOOR:
      if (operand.type != Value_Type.NUM) {
        return _errorUnexpectedType(input.expr.path.append(['floor']),
            operand.type, [Value_Type.NUM]);
      }
      return EvaluateOutput(value: numValue(operand.num.floorToDouble()));
    case OpUnary_Op.CEIL:
      if (operand.type != Value_Type.NUM) {
        return _errorUnexpectedType(
            input.expr.path.append(['ceil']), operand.type, [Value_Type.NUM]);
      }
      return EvaluateOutput(value: numValue(operand.num.ceilToDouble()));
    case OpUnary_Op.ABORT:
      if (operand.type != Value_Type.STR) {
        return _errorUnexpectedType(input.expr.path.append(['abort']),
            operand.type, [Value_Type.STR]);
      }
      return EvaluateOutput(
          status: EvaluateOutput_Status.ABORTED, errorMessage: operand.str);
    default:
      throw ArgumentError('unexpected unary operator ${op.op}');
  }
}