package org.rascalmpl.library.experiments.Compiler.RVM.Interpreter; import org.rascalmpl.interpreter.types.DefaultRascalTypeVisitor; import org.rascalmpl.interpreter.types.RascalType; import org.rascalmpl.value.IConstructor; import org.rascalmpl.value.INode; import org.rascalmpl.value.ITuple; import org.rascalmpl.value.IValue; import org.rascalmpl.value.type.Type; import org.rascalmpl.values.uptr.ITree; public enum ToplevelType { VOID (0, "void"), BOOL (1, "bool"), INT (2, "int"), REAL (3, "real"), RAT (4, "rat"), NUM (5, "num"), STR (6, "str"), LOC (7, "loc"), DATETIME (8, "datetime"), LIST (9, "list"), NODE (10, "node"), CONSTRUCTOR (11, "constructor"), LREL (12, "lrel"), MAP (13, "map"), SET (14, "set"), REL (15, "rel"), TUPLE (16, "tuple"), ADT (17, "adt"), VALUE (18, "value"); private final int toplevelType; private final String representation; private static final ToplevelType[] values = ToplevelType.values(); public static ToplevelType fromInteger(int prim){ return values[prim]; } ToplevelType(int n, String repr){ this.toplevelType = n; this.representation = repr; } public int getToplevelTypeAsInt(){ return toplevelType; } public String getToplevelTypeAsString(){ return representation; } public static String getToplevelTypeAsString(final Type t){ return getToplevelType(t).representation; } public static ToplevelType getToplevelType(final Type t){ return t.accept(new DefaultRascalTypeVisitor<ToplevelType,RuntimeException>(VOID) { @Override public ToplevelType visitReal(Type type) throws RuntimeException { return REAL; } @Override public ToplevelType visitInteger(Type type) throws RuntimeException { return INT; } @Override public ToplevelType visitRational(Type type) throws RuntimeException { return RAT; } @Override public ToplevelType visitList(Type type) throws RuntimeException { return LIST; } @Override public ToplevelType visitMap(Type type) throws RuntimeException { return MAP; } @Override public ToplevelType visitNumber(Type type) throws RuntimeException { return NUM; } @Override public ToplevelType visitAlias(Type type) throws RuntimeException { throw new CompilerError("Alias cannot occur as toplevel type"); } @Override public ToplevelType visitSet(Type type) throws RuntimeException { return SET; } @Override public ToplevelType visitSourceLocation(Type type) throws RuntimeException { return LOC; } @Override public ToplevelType visitString(Type type) throws RuntimeException { return STR; } @Override public ToplevelType visitNode(Type type) throws RuntimeException { return NODE; } @Override public ToplevelType visitConstructor(Type type) throws RuntimeException { return CONSTRUCTOR; } @Override public ToplevelType visitAbstractData(Type type) throws RuntimeException { return ADT; } @Override public ToplevelType visitTuple(Type type) throws RuntimeException { return TUPLE; } @Override public ToplevelType visitValue(Type type) throws RuntimeException { return VALUE; } @Override public ToplevelType visitVoid(Type type) throws RuntimeException { return VOID; } @Override public ToplevelType visitBool(Type type) throws RuntimeException { return BOOL; } @Override public ToplevelType visitParameter(Type type) throws RuntimeException { throw new CompilerError("Parameter cannot occur as toplevel type"); } @Override public ToplevelType visitExternal(Type type) throws RuntimeException { throw new CompilerError("External cannot occur as toplevel type: " + type); } @Override public ToplevelType visitNonTerminal(RascalType type) throws RuntimeException { // TODO: @paulk review return CONSTRUCTOR; } @Override public ToplevelType visitReified(RascalType type) throws RuntimeException { // TODO: @paulk review return CONSTRUCTOR; } @Override public ToplevelType visitFunction(RascalType type) throws RuntimeException { // TODO: @paulk review return VALUE; } @Override public ToplevelType visitOverloadedFunction(RascalType type) throws RuntimeException { // TODO: @paulk review return VALUE; } @Override public ToplevelType visitDateTime(Type type) throws RuntimeException { return DATETIME; }}); } public static int getToplevelTypeAsInt(Type t){ return getToplevelType(t).getToplevelTypeAsInt(); } private static final Integer listHashCode = "list".hashCode(); private static final Integer mapHashCode = "map".hashCode(); private static final Integer setHashCode = "set".hashCode(); private static final Integer tupleHashCode = "tuple".hashCode(); private static final Integer valueHashCode = "value".hashCode(); public static int getFingerprintNode(INode nd){ //System.err.println("getFingerprintNode: " + nd.hashCode() + " for " + nd); return nd.hashCode(); } public static int getFingerprint(final IValue v, final boolean useConcreteFingerprint){ int res = v.getType().accept(new DefaultRascalTypeVisitor<Integer,RuntimeException>(v.hashCode()) { @Override public Integer visitList(final Type type) throws RuntimeException { return listHashCode; } @Override public Integer visitMap(final Type type) throws RuntimeException { return mapHashCode; } @Override public Integer visitSet(final Type type) throws RuntimeException { return setHashCode; } @Override public Integer visitNode(final Type type) throws RuntimeException { return ((INode) v).getName().hashCode() << 2 + ((INode) v).arity(); } @Override public Integer visitConstructor(final Type type) throws RuntimeException { IConstructor cons = (IConstructor) v; return cons.getName().hashCode() << 2 + cons.arity(); } @Override public Integer visitAbstractData(final Type type) throws RuntimeException { return visitConstructor(type); } @Override public Integer visitTuple(final Type type) throws RuntimeException { return tupleHashCode << 2 + ((ITuple) v).arity(); } @Override public Integer visitValue(final Type type) throws RuntimeException { return valueHashCode; } @Override public Integer visitReified(RascalType type) throws RuntimeException { // TODO: this might work; need to check return visitConstructor(type); } @Override public Integer visitNonTerminal(RascalType type) throws RuntimeException { assert v instanceof ITree; if (useConcreteFingerprint && ((ITree) v).isAppl()) { return ((ITree) v).getProduction().hashCode(); } return visitAbstractData(type.asAbstractDataType()); } }); return res; } }