1 package org.simantics.scl.compiler.internal.codegen.types;
3 import org.cojen.classfile.TypeDesc;
4 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
5 import org.simantics.scl.compiler.elaboration.modules.TypeAlias;
6 import org.simantics.scl.compiler.elaboration.modules.TypeConstructor;
7 import org.simantics.scl.compiler.elaboration.modules.TypeDescriptor;
8 import org.simantics.scl.compiler.environment.Environment;
9 import org.simantics.scl.compiler.internal.codegen.utils.Constants;
10 import org.simantics.scl.compiler.types.TApply;
11 import org.simantics.scl.compiler.types.TCon;
12 import org.simantics.scl.compiler.types.TForAll;
13 import org.simantics.scl.compiler.types.TFun;
14 import org.simantics.scl.compiler.types.TMetaVar;
15 import org.simantics.scl.compiler.types.TPred;
16 import org.simantics.scl.compiler.types.TVar;
17 import org.simantics.scl.compiler.types.Type;
18 import org.simantics.scl.compiler.types.Types;
19 import org.simantics.scl.compiler.types.util.Typed;
21 public class JavaTypeTranslator {
23 Environment environment;
24 Type[] parameters = new Type[32];
26 public JavaTypeTranslator(Environment environment) {
27 this.environment = environment;
30 private void reverseParameters(int len) {
32 for(int i=0;i<len;++i) {
33 Type temp = parameters[i];
34 parameters[i] = parameters[len-i-1];
35 parameters[len-i-1] = temp;
39 private TypeConstructor getTypeConstructor(TCon con) {
40 TypeDescriptor typeDescriptor = environment.getTypeDescriptor(con);
41 if(typeDescriptor == null)
42 throw new InternalCompilerError("Didn't find type constructor " + con.module + "/" + con.name + ".");
43 if(typeDescriptor instanceof TypeAlias)
44 throw new InternalCompilerError("Type " + con.module + "/" + con.name + " is a type alias.");
45 return (TypeConstructor)typeDescriptor;
48 public TypeDesc toTypeDesc(Type type) {
50 if(type instanceof TCon)
51 return getTypeConstructor((TCon)type).construct(this, Type.EMPTY_ARRAY);
52 else if(type instanceof TApply) {
55 TApply apply = (TApply)type;
56 parameters[i++] = Types.canonical(apply.parameter);
57 type = Types.canonical(apply.function);
58 if(type instanceof TCon) {
60 return getTypeConstructor((TCon)type).construct(this, parameters);
62 else if(type instanceof TApply)
64 else if(type instanceof TVar)
65 return TypeDesc.OBJECT;
70 else if(type instanceof TVar)
71 return TypeDesc.OBJECT;
72 else if(type instanceof TFun)
73 return Constants.FUNCTION;
74 else if(type instanceof TForAll)
75 type = ((TForAll)type).type;
76 else if(type instanceof TPred) {
77 TPred funcApply = (TPred)type;
78 return environment.getTypeClass(funcApply.typeClass)
79 .construct(this, funcApply.parameters);
81 else if(type instanceof TMetaVar) {
82 TMetaVar metaVar = (TMetaVar)type;
83 type = Types.canonical(metaVar);
84 if(type instanceof TMetaVar)
85 return TypeDesc.OBJECT;
88 throw new IllegalArgumentException("Invalid type " + type + ".");
93 public TypeDesc getTypeDesc(Typed typed) {
94 return toTypeDesc(typed.getType());
97 public TypeDesc[] toTypeDescs(Type[] types) {
98 TypeDesc[] result = new TypeDesc[types.length];
99 for(int i=0;i<types.length;++i)
100 result[i] = toTypeDesc(types[i]);
104 public TypeDesc[] toTypeDescs(Type[] types, Type type) {
105 TypeDesc[] result = new TypeDesc[types.length+1];
106 for(int i=0;i<types.length;++i)
107 result[i] = toTypeDesc(types[i]);
108 result[types.length] = toTypeDesc(type);
112 public TypeDesc[] getTypeDescs(Typed[] typeds) {
113 TypeDesc[] result = new TypeDesc[typeds.length];
114 for(int i=0;i<typeds.length;++i)
115 result[i] = getTypeDesc(typeds[i]);
119 public static TypeDesc[] filterVoid(TypeDesc[] tds) {
120 int length = tds.length;
121 for(TypeDesc td : tds)
122 if(td.equals(TypeDesc.VOID))
124 if(length == tds.length)
126 TypeDesc[] result = new TypeDesc[length];
128 for(TypeDesc td : tds)
129 if(!td.equals(TypeDesc.VOID))
134 public static TypeDesc toObjectType(TypeDesc td) {
135 if(td.equals(TypeDesc.VOID))
136 return Constants.TUPLE0;
138 return td.toObjectType();