1 package org.simantics.scl.compiler.internal.codegen.references;
3 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
4 import org.simantics.scl.compiler.internal.codegen.types.BTypes;
5 import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
6 import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
7 import org.simantics.scl.compiler.types.TVar;
8 import org.simantics.scl.compiler.types.Type;
9 import org.simantics.scl.compiler.types.Types;
10 import org.simantics.scl.compiler.types.exceptions.MatchException;
12 import gnu.trove.map.hash.THashMap;
15 public abstract class Val implements IVal {
17 public static final Val[] EMPTY_ARRAY = new Val[0];
19 transient ValRef occurrence;
22 public final ValRef createOccurrence() {
23 return new ValRef(this, Type.EMPTY_ARRAY);
27 public final ValRef createOccurrence(Type ... parameters) {
28 return new ValRef(this, parameters);
32 public IVal createSpecialization(Type... parameters) {
33 return new ValSpecialization(this, parameters);
36 public final void replaceBy(ValRef other) {
37 if(other.parameters.length == 0)
38 replaceBy(other.binding);
40 replaceBy(other.binding, other.parameters);
43 public final ValRef getOccurrence() {
47 public void replaceBy(Val other) {
48 ValRef cur = occurrence;
51 //System.out.println("+ " + other + " - " + cur.binding);
52 if(SCLCompilerConfiguration.DEBUG) {
53 if(cur.binding != this)
54 throw new InternalCompilerError("Invalid ValRef encountered when replacing " + this + " by " + other + ".");
57 cur.updateParentEffect();
63 cur.next = other.occurrence;
64 if(other.occurrence != null)
65 other.occurrence.prev = cur;
66 other.occurrence = occurrence;
71 private void replaceBy(Val other, Type[] parameters) {
72 if(other == this || other == null)
73 throw new InternalCompilerError();
74 ValRef cur = occurrence;
77 //System.out.println("+ " + other + " - " + cur.binding);
78 if(SCLCompilerConfiguration.DEBUG) {
79 if(cur.binding != this)
80 throw new InternalCompilerError("Invalid ValRef encountered when replacing " + this + " by " + other + ".");
83 cur.parameters = Types.concat(parameters, cur.parameters);
84 cur.updateParentEffect();
90 cur.next = other.occurrence;
91 if(other.occurrence != null)
92 other.occurrence.prev = cur;
93 other.occurrence = occurrence;
98 public void replaceBy(Val other, TVar[] from, Type[] to) {
99 if(other == this || other == null)
100 throw new InternalCompilerError();
102 replaceBy(other, to);
104 ValRef cur = occurrence;
107 //System.out.println("+ " + other + " - " + cur.binding);
108 if(SCLCompilerConfiguration.DEBUG) {
109 if(cur.binding != this)
110 throw new InternalCompilerError("Invalid ValRef encountered when replacing " + this + " by " + other + ".");
113 cur.parameters = Types.replace(to, from, cur.parameters);
114 cur.updateParentEffect();
120 cur.next = other.occurrence;
121 if(other.occurrence != null)
122 other.occurrence.prev = cur;
123 other.occurrence = occurrence;
129 public abstract Type getType();
132 * Returns the number of ValRefs of this Val.
135 public final int occurrenceCount() {
137 for(ValRef ref = occurrence;ref != null;ref=ref.getNext())
143 public final boolean hasMoreThanOneOccurences() {
144 return occurrence != null && occurrence.getNext() != null;
147 public final boolean hasNoOccurences() {
148 return occurrence == null;
151 public abstract Val copy(THashMap<TVar, TVar> tvarMap);
153 public ValRef[] getOccurences() {
154 int count = occurrenceCount();
156 return ValRef.EMPTY_ARRAY;
157 ValRef[] result = new ValRef[count];
158 ValRef cur = occurrence;
159 for(int i=0;i<count;++i,cur=cur.getNext())
164 public abstract int getEffectiveArity();
167 * Applies given values to this constant. Pushes the result to stack and
168 * returns the type of the result value.
171 public Type apply(MethodBuilder mb, Type[] typeParameters, Val ... parameters) {
173 if(parameters.length == 0)
177 returnType = BTypes.matchFunction(getType(), parameters.length)[parameters.length];
178 } catch (MatchException e) {
179 throw new InternalCompilerError();
181 mb.pushBoxed(parameters);
182 mb.genericApply(parameters.length);
183 mb.unbox(returnType);
188 public void setLabel(String label) {
191 public void prepare(MethodBuilder mb) {