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