/**** * * Class Types has static methods for type equivalencing and other forms of * type interrogation. Note that this class must be compiled with a * language-specific sym.java file. It therefore must be copied in source form * and compiled together with a specific parser, since it cannot be compiled in * with a the stand-alone a4-support.jar files. * */ public class Types { /** * Return true if t1 and t2 are structurally equivalent. */ public static boolean equiv(TypeNode t1, TypeNode t2) { return samePrimitiveTypes(t1, t2) // || /* perform parallel recursive descent on type structures */; } /** * Return true if t1 and t2 are name equivalent. */ public static boolean equivName(TypeNode t1, TypeNode t2) { return samePrimitiveTypes(t1, t2) || sameIdentTypes(t1, t2); } /**** * * Return true if t1 and t2 are the same primitive types. * */ public static boolean samePrimitiveTypes(TypeNode t1, TypeNode t2) { return isInt(t1) && isInt(t2) || isFloat(t1) && isFloat(t2) || isString(t1) && isString(t2) || isBool(t1) && isBool(t2); } /** * Return true if t is a numberi type, i.e., INT or FLOAT. */ public static boolean isNumeric(TypeNode t) { return isInt(t) || isFloat(t); } /** * Return true if t1 and t2 are the same identifier type, i.e., the have * the same type name. */ public static boolean sameIdentTypes(TypeNode t1, TypeNode t2) { return (t1.id == sym.IDENT) && (t2.id == sym.IDENT) && (((LeafNode) t1.child1).value).equals( ((LeafNode) t2.child1).value); } /** * Return true if the given type is an atomic integer type. This is the * case if the TypeNode id = INT or if the id is IDENT and its string ident * value is "integer". This supports languages in which the integer type * is designated by a keyword, as well as languages where it is designated * by a pre-defined identifier named "integer". */ public static boolean isInt(TypeNode t) { return (t.id == sym.INT) || (t.id == sym.IDENT) && (((LeafNode) t.child1).value).equals("integer"); } /** * Return true if the given type is an atomic floating point type. This is * the case if the TypeNode id = FLOAT or if the id is IDENT and its string * ident value is "real". This supports languages in which the integer * type is designated by a keyword, as well as languages where it is * designated by a pre-defined identifier named "real". */ public static boolean isFloat(TypeNode t) { return (t.id == sym.FLOAT) || (t.id == sym.IDENT) && (((LeafNode) t.child1).value).equals("real"); } /** * Return true if the given type is an atomic floating point type. This is * the case if the TypeNode id = STRING or if the id is IDENT and its * string ident value is "string". This supports languages in which the * integer type is designated by a keyword, as well as languages where it * is designated by a pre-defined identifier named "string". */ public static boolean isString(TypeNode t) { return (t.id == sym.STRING) || (t.id == sym.IDENT) && (((LeafNode) t.child1).value).equals("string"); } /** * Return true if the given type is an atomic floating point type. This is * the case if the TypeNode id = BOOLEAN or if the id is IDENT and its * string ident value is "boolean". This supports languages in which the * integer type is designated by a keyword, as well as languages where it * is designated by a pre-defined identifier named "boolean". */ public static boolean isBool(TypeNode t) { return (t.id == sym.BOOLEAN) || (t.id == sym.IDENT) && (((LeafNode) t.child1).value).equals("boolean"); } /** * Return true if the given type is an atomic floating point type. This is * the case if the TypeNode id = VOID or if the id is IDENT and its string * ident value is "void". This supports languages in which the integer * type is designated by a keyword, as well as languages where it is * designated by a pre-defined identifier named "void". */ public static boolean isVoid(TypeNode t) { return (t.id == sym.VOID) || (t.id == sym.IDENT) && (((LeafNode) t.child1).value).equals("void"); } public static TypeNode IntType = new TypeNode( sym.IDENT, new LeafNode(sym.IDENT, "integer")); }