code: private boolean calcBool() {
          int cmp;
  
          switch (left.getType()) { // same as right.getType()
          case BOOL:
              switch (op) {
              case AND:
                  return left.evalBool() && right.evalBool();
              case OR:
                  return left.evalBool() || right.evalBool();
              case EQ:
                  return left.evalBool() == right.evalBool();
              case NE:
                  return left.evalBool() != right.evalBool();
              default:
                  throw new RuntimeException("illegal bool op: " + op);
              }
          case INT:
              cmp = left.evalInt() - right.evalInt();
              break;
          case STR:
              cmp = left.evalString().compareTo(right.evalString());
              break;
          default:
              throw new RuntimeException("unknown type: " + left.getType());
          }
  
          switch (op) { // same for string and int
          case LT:
              return cmp < 0;
          case GT:
              return cmp > 0;
          case LE:
              return cmp <= 0;
          case GE:
              return cmp >= 0;
          case EQ:
              return cmp == 0;
          case NE:
              return cmp != 0;
          default:
              throw new RuntimeException("illegal non-bool op: " +op);
          }
      }
docs: -----------------------------------------------------------------