]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/ListConstructor.java
Merge "Ensure GetElementClassRequest is not constructed without elementFactory"
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / java / ListConstructor.java
1 package org.simantics.scl.compiler.elaboration.java;
2
3 import org.cojen.classfile.TypeDesc;
4 import org.objectweb.asm.Label;
5 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
6 import org.simantics.scl.compiler.constants.FunctionValue;
7 import org.simantics.scl.compiler.constants.LocalVariableConstant;
8 import org.simantics.scl.compiler.internal.codegen.continuations.Cont;
9 import org.simantics.scl.compiler.internal.codegen.references.IVal;
10 import org.simantics.scl.compiler.internal.codegen.references.Val;
11 import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator;
12 import org.simantics.scl.compiler.internal.codegen.utils.Constants;
13 import org.simantics.scl.compiler.internal.codegen.utils.LocalVariable;
14 import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
15 import org.simantics.scl.compiler.types.TVar;
16 import org.simantics.scl.compiler.types.Type;
17 import org.simantics.scl.compiler.types.Types;
18 import org.simantics.scl.compiler.types.exceptions.MatchException;
19 import org.simantics.scl.compiler.types.kinds.Kinds;
20
21 public class ListConstructor extends FunctionValue {
22
23     private static final TVar A = Types.var(Kinds.STAR);
24     
25     public final int arity;
26     
27     public ListConstructor(int arity) {
28         super(new TVar[] {A}, Types.NO_EFFECTS, Types.list(A), parameterList(arity));
29         this.arity = arity;
30     }
31
32     private static Type[] parameterList(int arity) {
33         Type[] parameters = new Type[arity];
34         for(int i=0;i<arity;++i)
35             parameters[i] = A;  
36         return parameters;
37     }
38
39
40     @Override
41     public Type applyExact(MethodBuilder mb, Val[] parameters) {
42         mb.loadConstant(arity);
43         mb.newObject(Constants.OBJECT_ARRAY, 1);
44         for(int i=0;i<arity;++i) {
45             mb.dup();
46             mb.loadConstant(i);
47             mb.pushBoxed(parameters[i]);
48             mb.storeToArray(TypeDesc.OBJECT);
49         }
50         mb.invokeStatic("java/util/Arrays", "asList", Constants.LIST, 
51                 new TypeDesc[] {Constants.OBJECT_ARRAY});
52         return getReturnType();
53     }
54     
55     @Override
56     public void deconstruct(MethodBuilder mb, IVal parameter, Cont success,
57             Label failure) {
58         if(failure == null)
59             throw new InternalCompilerError("List deconstruction may always fail");
60         if(success.getArity() != arity)
61             throw new InternalCompilerError("Arity of the list constructor (" + arity +
62                     ") is different from the arity of the success continuation (" + success.getArity() + ").");
63         parameter.push(mb);
64         mb.invokeInterface(Constants.LIST, "size", TypeDesc.INT, Constants.EMPTY_TYPEDESC_ARRAY);
65         mb.loadConstant(arity);
66         mb.ifComparisonBranch(failure, "!=", TypeDesc.INT);
67         
68         JavaTypeTranslator translator = mb.getJavaTypeTranslator();
69         IVal[] parameters = new IVal[arity];
70         for(int i=0;i<arity;++i) {
71             parameter.push(mb);
72             mb.loadConstant(i);
73             mb.invokeInterface(Constants.LIST, "get", TypeDesc.OBJECT, new TypeDesc[] {TypeDesc.INT});
74             try {
75                 mb.unbox(Types.matchApply(Types.LIST,parameter.getType()));
76             } catch (MatchException e) {
77                 throw new InternalCompilerError("Expected list type.");
78             }
79             
80             Type pType = success.getParameterType(i);
81             TypeDesc pTypeDesc = translator.toTypeDesc(pType);
82             LocalVariable lv = mb.createLocalVariable("temp", pTypeDesc);
83             mb.storeLocal(lv);
84             
85             parameters[i] = new LocalVariableConstant(pType, lv);
86         }
87         
88         mb.jump(success, parameters);
89     }
90     
91     @Override
92     public int constructorTag() {
93         return arity;
94     }
95     
96     @Override
97     public String toString() {
98         return "[.." + arity + "..]";
99     }
100
101 }