1 package org.simantics.scl.compiler.elaboration.java;
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;
21 public class ListConstructor extends FunctionValue {
23 private static final TVar A = Types.var(Kinds.STAR);
25 public final int arity;
27 public ListConstructor(int arity) {
28 super(new TVar[] {A}, Types.NO_EFFECTS, Types.list(A), parameterList(arity));
32 private static Type[] parameterList(int arity) {
33 Type[] parameters = new Type[arity];
34 for(int i=0;i<arity;++i)
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) {
47 mb.pushBoxed(parameters[i]);
48 mb.storeToArray(TypeDesc.OBJECT);
50 mb.invokeStatic("java/util/Arrays", "asList", Constants.LIST,
51 new TypeDesc[] {Constants.OBJECT_ARRAY});
52 return getReturnType();
56 public void deconstruct(MethodBuilder mb, IVal parameter, Cont success,
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() + ").");
64 mb.invokeInterface(Constants.LIST, "size", TypeDesc.INT, Constants.EMPTY_TYPEDESC_ARRAY);
65 mb.loadConstant(arity);
66 mb.ifComparisonBranch(failure, "!=", TypeDesc.INT);
68 JavaTypeTranslator translator = mb.getJavaTypeTranslator();
69 IVal[] parameters = new IVal[arity];
70 for(int i=0;i<arity;++i) {
73 mb.invokeInterface(Constants.LIST, "get", TypeDesc.OBJECT, new TypeDesc[] {TypeDesc.INT});
75 mb.unbox(Types.matchApply(Types.LIST,parameter.getType()));
76 } catch (MatchException e) {
77 throw new InternalCompilerError("Expected list type.");
80 Type pType = success.getParameterType(i);
81 TypeDesc pTypeDesc = translator.toTypeDesc(pType);
82 LocalVariable lv = mb.createLocalVariable("temp", pTypeDesc);
85 parameters[i] = new LocalVariableConstant(pType, lv);
88 mb.jump(success, parameters);
92 public int constructorTag() {
97 public String toString() {