-package org.simantics.scl.compiler.internal.codegen.references;\r
-\r
-import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
-import org.simantics.scl.compiler.internal.codegen.types.BTypes;\r
-import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;\r
-import org.simantics.scl.compiler.top.SCLCompilerConfiguration;\r
-import org.simantics.scl.compiler.types.TVar;\r
-import org.simantics.scl.compiler.types.Type;\r
-import org.simantics.scl.compiler.types.Types;\r
-import org.simantics.scl.compiler.types.exceptions.MatchException;\r
-\r
-import gnu.trove.map.hash.THashMap;\r
-\r
-\r
-public abstract class Val implements IVal {\r
- \r
- public static final Val[] EMPTY_ARRAY = new Val[0];\r
- \r
- transient ValRef occurrence;\r
- \r
- @Override\r
- public final ValRef createOccurrence() {\r
- return new ValRef(this, Type.EMPTY_ARRAY);\r
- }\r
- \r
- @Override\r
- public final ValRef createOccurrence(Type ... parameters) {\r
- return new ValRef(this, parameters);\r
- }\r
- \r
- @Override\r
- public IVal createSpecialization(Type... parameters) {\r
- return new ValSpecialization(this, parameters);\r
- }\r
- \r
- public final void replaceBy(ValRef other) {\r
- if(other.parameters.length == 0)\r
- replaceBy(other.binding);\r
- else\r
- replaceBy(other.binding, other.parameters);\r
- }\r
- \r
- public final ValRef getOccurrence() {\r
- return occurrence;\r
- }\r
- \r
- private void replaceBy(Val other) {\r
- ValRef cur = occurrence;\r
- if(cur != null) {\r
- while(true) {\r
- //System.out.println("+ " + other + " - " + cur.binding);\r
- if(SCLCompilerConfiguration.DEBUG) {\r
- if(cur.binding != this)\r
- throw new InternalCompilerError("Invalid ValRef encountered when replacing " + this + " by " + other + ".");\r
- } \r
- cur.binding = other;\r
- cur.updateParentEffect();\r
- if(cur.next == null)\r
- break;\r
- else\r
- cur = cur.next;\r
- }\r
- cur.next = other.occurrence;\r
- if(other.occurrence != null)\r
- other.occurrence.prev = cur;\r
- other.occurrence = occurrence;\r
- occurrence = null;\r
- } \r
- }\r
- \r
- private void replaceBy(Val other, Type[] parameters) {\r
- if(other == this || other == null)\r
- throw new InternalCompilerError();\r
- ValRef cur = occurrence;\r
- if(cur != null) {\r
- while(true) {\r
- //System.out.println("+ " + other + " - " + cur.binding);\r
- if(SCLCompilerConfiguration.DEBUG) {\r
- if(cur.binding != this)\r
- throw new InternalCompilerError("Invalid ValRef encountered when replacing " + this + " by " + other + ".");\r
- }\r
- cur.binding = other;\r
- cur.parameters = Types.concat(parameters, cur.parameters);\r
- cur.updateParentEffect();\r
- if(cur.next == null)\r
- break;\r
- else\r
- cur = cur.next;\r
- }\r
- cur.next = other.occurrence;\r
- if(other.occurrence != null)\r
- other.occurrence.prev = cur;\r
- other.occurrence = occurrence;\r
- occurrence = null;\r
- }\r
- }\r
- \r
- public void replaceBy(Val other, TVar[] from, Type[] to) {\r
- if(other == this || other == null)\r
- throw new InternalCompilerError();\r
- if(from.length == 0)\r
- replaceBy(other, to);\r
- else {\r
- ValRef cur = occurrence;\r
- if(cur != null) {\r
- while(true) {\r
- //System.out.println("+ " + other + " - " + cur.binding);\r
- if(SCLCompilerConfiguration.DEBUG) {\r
- if(cur.binding != this)\r
- throw new InternalCompilerError("Invalid ValRef encountered when replacing " + this + " by " + other + ".");\r
- }\r
- cur.binding = other;\r
- cur.parameters = Types.replace(to, from, cur.parameters);\r
- cur.updateParentEffect();\r
- if(cur.next == null)\r
- break;\r
- else\r
- cur = cur.next;\r
- }\r
- cur.next = other.occurrence;\r
- if(other.occurrence != null)\r
- other.occurrence.prev = cur;\r
- other.occurrence = occurrence;\r
- occurrence = null;\r
- }\r
- } \r
- }\r
- \r
- public abstract Type getType();\r
-\r
- /**\r
- * Returns the number of ValRefs of this Val.\r
- * @return\r
- */\r
- public final int occurrenceCount() {\r
- int count = 0;\r
- for(ValRef ref = occurrence;ref != null;ref=ref.getNext())\r
- ++count;\r
- return count;\r
- }\r
- \r
-\r
- public final boolean hasMoreThanOneOccurences() {\r
- return occurrence != null && occurrence.getNext() != null;\r
- }\r
-\r
- public final boolean hasNoOccurences() {\r
- return occurrence == null;\r
- }\r
-\r
- public abstract Val copy(THashMap<TVar, TVar> tvarMap);\r
- \r
- public ValRef[] getOccurences() {\r
- int count = occurrenceCount();\r
- if(count == 0)\r
- return ValRef.EMPTY_ARRAY;\r
- ValRef[] result = new ValRef[count];\r
- ValRef cur = occurrence;\r
- for(int i=0;i<count;++i,cur=cur.getNext())\r
- result[i] = cur;\r
- return result;\r
- }\r
-\r
- public abstract int getEffectiveArity();\r
- \r
- /**\r
- * Applies given values to this constant. Pushes the result to stack and \r
- * returns the type of the result value.\r
- */\r
- @Override \r
- public Type apply(MethodBuilder mb, Type[] typeParameters, Val ... parameters) {\r
- push(mb);\r
- if(parameters.length == 0) \r
- return getType();\r
- Type returnType;\r
- try {\r
- returnType = BTypes.matchFunction(getType(), parameters.length)[parameters.length]; \r
- } catch (MatchException e) {\r
- throw new InternalCompilerError();\r
- }\r
- mb.pushBoxed(parameters);\r
- mb.genericApply(parameters.length); \r
- mb.unbox(returnType);\r
- return returnType;\r
- }\r
- \r
- @Override\r
- public void setLabel(String label) { \r
- }\r
- \r
- public void prepare(MethodBuilder mb) { \r
- }\r
-}\r
+package org.simantics.scl.compiler.internal.codegen.references;
+
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
+import org.simantics.scl.compiler.internal.codegen.types.BTypes;
+import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
+import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
+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.exceptions.MatchException;
+
+import gnu.trove.map.hash.THashMap;
+
+
+public abstract class Val implements IVal {
+
+ public static final Val[] EMPTY_ARRAY = new Val[0];
+
+ transient ValRef occurrence;
+
+ @Override
+ public final ValRef createOccurrence() {
+ return new ValRef(this, Type.EMPTY_ARRAY);
+ }
+
+ @Override
+ public final ValRef createOccurrence(Type ... parameters) {
+ return new ValRef(this, parameters);
+ }
+
+ @Override
+ public IVal createSpecialization(Type... parameters) {
+ return new ValSpecialization(this, parameters);
+ }
+
+ public final void replaceBy(ValRef other) {
+ if(other.parameters.length == 0)
+ replaceBy(other.binding);
+ else
+ replaceBy(other.binding, other.parameters);
+ }
+
+ public final ValRef getOccurrence() {
+ return occurrence;
+ }
+
+ public void replaceBy(Val other) {
+ ValRef cur = occurrence;
+ if(cur != null) {
+ while(true) {
+ //System.out.println("+ " + other + " - " + cur.binding);
+ if(SCLCompilerConfiguration.DEBUG) {
+ if(cur.binding != this)
+ throw new InternalCompilerError("Invalid ValRef encountered when replacing " + this + " by " + other + ".");
+ }
+ cur.binding = other;
+ cur.updateParentEffect();
+ if(cur.next == null)
+ break;
+ else
+ cur = cur.next;
+ }
+ cur.next = other.occurrence;
+ if(other.occurrence != null)
+ other.occurrence.prev = cur;
+ other.occurrence = occurrence;
+ occurrence = null;
+ }
+ }
+
+ private void replaceBy(Val other, Type[] parameters) {
+ if(other == this || other == null)
+ throw new InternalCompilerError();
+ ValRef cur = occurrence;
+ if(cur != null) {
+ while(true) {
+ //System.out.println("+ " + other + " - " + cur.binding);
+ if(SCLCompilerConfiguration.DEBUG) {
+ if(cur.binding != this)
+ throw new InternalCompilerError("Invalid ValRef encountered when replacing " + this + " by " + other + ".");
+ }
+ cur.binding = other;
+ cur.parameters = Types.concat(parameters, cur.parameters);
+ cur.updateParentEffect();
+ if(cur.next == null)
+ break;
+ else
+ cur = cur.next;
+ }
+ cur.next = other.occurrence;
+ if(other.occurrence != null)
+ other.occurrence.prev = cur;
+ other.occurrence = occurrence;
+ occurrence = null;
+ }
+ }
+
+ public void replaceBy(Val other, TVar[] from, Type[] to) {
+ if(other == this || other == null)
+ throw new InternalCompilerError();
+ if(from.length == 0)
+ replaceBy(other, to);
+ else {
+ ValRef cur = occurrence;
+ if(cur != null) {
+ while(true) {
+ //System.out.println("+ " + other + " - " + cur.binding);
+ if(SCLCompilerConfiguration.DEBUG) {
+ if(cur.binding != this)
+ throw new InternalCompilerError("Invalid ValRef encountered when replacing " + this + " by " + other + ".");
+ }
+ cur.binding = other;
+ cur.parameters = Types.replace(to, from, cur.parameters);
+ cur.updateParentEffect();
+ if(cur.next == null)
+ break;
+ else
+ cur = cur.next;
+ }
+ cur.next = other.occurrence;
+ if(other.occurrence != null)
+ other.occurrence.prev = cur;
+ other.occurrence = occurrence;
+ occurrence = null;
+ }
+ }
+ }
+
+ public abstract Type getType();
+
+ /**
+ * Returns the number of ValRefs of this Val.
+ * @return
+ */
+ public final int occurrenceCount() {
+ int count = 0;
+ for(ValRef ref = occurrence;ref != null;ref=ref.getNext())
+ ++count;
+ return count;
+ }
+
+
+ public final boolean hasMoreThanOneOccurences() {
+ return occurrence != null && occurrence.getNext() != null;
+ }
+
+ public final boolean hasNoOccurences() {
+ return occurrence == null;
+ }
+
+ public abstract Val copy(THashMap<TVar, TVar> tvarMap);
+
+ public ValRef[] getOccurences() {
+ int count = occurrenceCount();
+ if(count == 0)
+ return ValRef.EMPTY_ARRAY;
+ ValRef[] result = new ValRef[count];
+ ValRef cur = occurrence;
+ for(int i=0;i<count;++i,cur=cur.getNext())
+ result[i] = cur;
+ return result;
+ }
+
+ public abstract int getEffectiveArity();
+
+ /**
+ * Applies given values to this constant. Pushes the result to stack and
+ * returns the type of the result value.
+ */
+ @Override
+ public Type apply(MethodBuilder mb, Type[] typeParameters, Val ... parameters) {
+ push(mb);
+ if(parameters.length == 0)
+ return getType();
+ Type returnType;
+ try {
+ returnType = BTypes.matchFunction(getType(), parameters.length)[parameters.length];
+ } catch (MatchException e) {
+ throw new InternalCompilerError();
+ }
+ mb.pushBoxed(parameters);
+ mb.genericApply(parameters.length);
+ mb.unbox(returnType);
+ return returnType;
+ }
+
+ @Override
+ public void setLabel(String label) {
+ }
+
+ public void prepare(MethodBuilder mb) {
+ }
+}