]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/types/JavaTypeTranslator.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / internal / codegen / types / JavaTypeTranslator.java
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/types/JavaTypeTranslator.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/types/JavaTypeTranslator.java
new file mode 100644 (file)
index 0000000..2e2dcef
--- /dev/null
@@ -0,0 +1,134 @@
+package org.simantics.scl.compiler.internal.codegen.types;
+
+import org.cojen.classfile.TypeDesc;
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
+import org.simantics.scl.compiler.elaboration.modules.TypeConstructor;
+import org.simantics.scl.compiler.environment.Environment;
+import org.simantics.scl.compiler.internal.codegen.utils.Constants;
+import org.simantics.scl.compiler.types.TApply;
+import org.simantics.scl.compiler.types.TCon;
+import org.simantics.scl.compiler.types.TForAll;
+import org.simantics.scl.compiler.types.TFun;
+import org.simantics.scl.compiler.types.TMetaVar;
+import org.simantics.scl.compiler.types.TPred;
+import org.simantics.scl.compiler.types.TVar;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
+import org.simantics.scl.compiler.types.util.Typed;
+
+public class JavaTypeTranslator {
+
+    Environment environment;
+    Type[] parameters = new Type[32];
+    
+    public JavaTypeTranslator(Environment environment) {
+        this.environment = environment;
+    }
+    
+    private void reverseParameters(int len) {
+        len >>= 1;
+        for(int i=0;i<len;++i) {
+            Type temp = parameters[i];
+            parameters[i] = parameters[len-i-1];
+            parameters[len-i-1] = temp;
+        }
+    }
+        
+    public TypeDesc toTypeDesc(Type type) {
+        while(true) {
+            if(type instanceof TCon) {
+                TCon con = (TCon)type;
+                TypeConstructor typeConstructor = environment.getTypeConstructor(con);
+                if(typeConstructor == null)
+                    throw new InternalCompilerError("Didn't find type constructor " + con.module + "/" + con.name + ".");
+                return typeConstructor.construct(this, Type.EMPTY_ARRAY);
+            }
+            else if(type instanceof TApply) {
+                int i=0;
+                while(true) {
+                    TApply apply = (TApply)type;
+                    parameters[i++] = Types.canonical(apply.parameter);
+                    type = Types.canonical(apply.function);
+                    if(type instanceof TCon) {
+                        reverseParameters(i);
+                        return environment.getTypeConstructor((TCon)type).construct(this, parameters);
+                    }
+                    else if(type instanceof TApply)
+                        ;
+                    else if(type instanceof TVar)
+                        return TypeDesc.OBJECT;
+                    else
+                        break;
+                }
+            }
+            else if(type instanceof TVar)
+                return TypeDesc.OBJECT;
+            else if(type instanceof TFun) 
+                return Constants.FUNCTION;
+            else if(type instanceof TForAll)
+                type = ((TForAll)type).type;            
+            else if(type instanceof TPred) {
+                TPred funcApply = (TPred)type;
+                return environment.getTypeClass(funcApply.typeClass)
+                        .construct(this, funcApply.parameters);
+            }
+            else if(type instanceof TMetaVar) {
+                TMetaVar metaVar = (TMetaVar)type;
+                type = Types.canonical(metaVar);
+                if(type instanceof TMetaVar)
+                    return TypeDesc.OBJECT;
+            }
+            else {
+                throw new IllegalArgumentException("Invalid type " + type + ".");
+            }
+        }
+    }
+    
+    public TypeDesc getTypeDesc(Typed typed) {
+        return toTypeDesc(typed.getType());
+    }
+    
+    public TypeDesc[] toTypeDescs(Type[] types) {
+        TypeDesc[] result = new TypeDesc[types.length];
+        for(int i=0;i<types.length;++i)
+            result[i] = toTypeDesc(types[i]);
+        return result;
+    }
+    
+    public TypeDesc[] toTypeDescs(Type[] types, Type type) {
+        TypeDesc[] result = new TypeDesc[types.length+1];
+        for(int i=0;i<types.length;++i)
+            result[i] = toTypeDesc(types[i]);
+        result[types.length] = toTypeDesc(type);
+        return result;
+    }
+    
+    public TypeDesc[] getTypeDescs(Typed[] typeds) {
+        TypeDesc[] result = new TypeDesc[typeds.length];
+        for(int i=0;i<typeds.length;++i)
+            result[i] = getTypeDesc(typeds[i]);
+        return result;
+    }
+    
+    public static TypeDesc[] filterVoid(TypeDesc[] tds) {
+        int length = tds.length;
+        for(TypeDesc td : tds)
+            if(td.equals(TypeDesc.VOID))
+                --length;
+        if(length == tds.length)
+            return tds;
+        TypeDesc[] result = new TypeDesc[length];
+        int j=0;
+        for(TypeDesc td : tds)
+            if(!td.equals(TypeDesc.VOID))
+                result[j++] = td;
+        return result;
+    }
+    
+    public static TypeDesc toObjectType(TypeDesc td) {
+        if(td.equals(TypeDesc.VOID))
+            return Constants.TUPLE0;
+        else
+            return td.toObjectType();
+    }
+}