Example #1
0
  /**
   * This method gets called when we're testing a dictionary object against some type. To reduce the
   * number of cases, we can narrow down the possible types by a process of deduction. The type
   * cannot be <code>void</code> or <code>any</code> (since the test would already have been
   * eliminated). Likewise, it cannot be e.g. a record, since again the test would already have been
   * eliminated. In fact, the type can only be a dictionary or its negation.
   *
   * @param object --- object being tested against.
   * @param type --- type to test against.
   * @return
   */
  public static boolean instanceOf(Dictionary object, Type type) {
    if (type instanceof Type.Dictionary) {
      Type.Dictionary tl = (Type.Dictionary) type;
      Type key = tl.key;
      Type value = tl.value;

      if (key.kind == K_ANY && value.kind == K_ANY) {
        return true;
      } else if (key.kind == K_VOID || value.kind == K_VOID) {
        return object.isEmpty();
      } else {
        for (java.util.Map.Entry<Object, Object> elem : object.entrySet()) {
          if (!instanceOf(elem.getKey(), key) || !instanceOf(elem.getValue(), value)) {
            return false;
          }
        }
        return true;
      }
    } else {
      return instanceOf((Object) object, type);
    }
  }
Example #2
0
  /** The <code>instanceOf</code> method implements a runtime type test. */
  public static boolean instanceOf(Object obj, Type t) {
    switch (t.kind) {
      case K_ANY:
        return true;
      case K_VOID:
        return false;
      case K_NULL:
        return obj == null;
      case K_BOOL:
        return obj instanceof Boolean;
      case K_BYTE:
        return obj instanceof Byte;
      case K_CHAR:
        return obj instanceof Character;
      case K_INT:
        return obj instanceof BigInteger;
      case K_RATIONAL:
        return obj instanceof BigRational;
      case K_STRING:
        return obj instanceof String;
      case K_LIST:
        {
          if (obj instanceof List) {
            List ol = (List) obj;
            Type.List tl = (Type.List) t;
            if (tl.nonEmpty && ol.isEmpty()) {
              return false;
            }
            Type el = tl.element;
            if (el.kind == K_ANY) {
              return true;
            } else if (el.kind == K_VOID) {
              return ol.isEmpty();
            } else {
              for (Object elem : ol) {
                if (!instanceOf(elem, el)) {
                  return false;
                }
              }
              return true;
            }
          }
          break;
        }
      case K_SET:
        {
          if (obj instanceof Set) {
            Set ol = (Set) obj;
            Type.Set tl = (Type.Set) t;
            Type el = tl.element;
            if (el.kind == K_ANY) {
              return true;
            } else if (el.kind == K_VOID) {
              return ol.isEmpty();
            } else {
              for (Object elem : ol) {
                if (!instanceOf(elem, el)) {
                  return false;
                }
              }
              return true;
            }
          }
          break;
        }
      case K_TUPLE:
        {
          if (obj instanceof Tuple) {
            Tuple ol = (Tuple) obj;
            Type.Tuple tl = (Type.Tuple) t;
            Type[] types = tl.types;
            if (types.length == ol.size()) {
              int i = 0;
              for (Object o : ol) {
                if (!instanceOf(o, types[i++])) {
                  return false;
                }
              }
              return true;
            }
          }
          break;
        }
      case K_DICTIONARY:
        {
          if (obj instanceof Dictionary) {
            Dictionary ol = (Dictionary) obj;
            Type.Dictionary tl = (Type.Dictionary) t;
            Type key = tl.key;
            Type value = tl.value;

            if (key.kind == K_ANY && value.kind == K_ANY) {
              return true;
            } else if (key.kind == K_VOID || value.kind == K_VOID) {
              return ol.isEmpty();
            } else {
              for (java.util.Map.Entry<Object, Object> elem : ol.entrySet()) {
                if (!instanceOf(elem.getKey(), key) || !instanceOf(elem.getValue(), value)) {
                  return false;
                }
              }
              return true;
            }
          }
          break;
        }
      case K_RECORD:
        {
          if (obj instanceof Record) {
            Record ol = (Record) obj;
            Type.Record tl = (Type.Record) t;
            String[] names = tl.names;
            Type[] types = tl.types;
            if (!tl.isOpen && names.length != ol.size()) {
              return false;
            }
            for (int i = 0; i != names.length; ++i) {
              String name = names[i];
              if (ol.containsKey(name)) {
                Type type = types[i];
                Object val = ol.get(name);
                if (!instanceOf(val, type)) {
                  return false;
                }
              } else {
                return false;
              }
            }
            return true;
          }
          break;
        }
      case K_NEGATION:
        {
          Type.Negation not = (Type.Negation) t;
          return !instanceOf(obj, not.element);
        }
      case K_UNION:
        {
          Type.Union un = (Type.Union) t;
          for (Type bound : un.bounds) {
            if (instanceOf(obj, bound)) {
              return true;
            }
          }
          break;
        }
    }
    return false;
  }