X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Finternal%2Fcodegen%2Freferences%2FVal.java;fp=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Finternal%2Fcodegen%2Freferences%2FVal.java;h=392dfb2feb14234b4fc541fd6fd3e729638eeceb;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/references/Val.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/references/Val.java new file mode 100644 index 000000000..392dfb2fe --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/references/Val.java @@ -0,0 +1,193 @@ +package org.simantics.scl.compiler.internal.codegen.references; + +import gnu.trove.map.hash.THashMap; + +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; + + +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; + } + + private 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 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