package org.simantics.scl.compiler.internal.codegen.ssa; import java.util.ArrayList; import org.simantics.scl.compiler.internal.codegen.references.BoundVar; import org.simantics.scl.compiler.internal.codegen.references.ValRef; import org.simantics.scl.compiler.internal.codegen.ssa.binders.ClosureBinder; import org.simantics.scl.compiler.internal.codegen.utils.CopyContext; import org.simantics.scl.compiler.internal.codegen.utils.PrintingContext; import org.simantics.scl.compiler.internal.codegen.utils.SSALambdaLiftingContext; import org.simantics.scl.compiler.internal.codegen.utils.SSASimplificationContext; import org.simantics.scl.compiler.internal.codegen.utils.SSAValidationContext; import org.simantics.scl.compiler.internal.codegen.utils.ValRefVisitor; import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter; import org.simantics.scl.compiler.internal.codegen.writer.ModuleWriter; import org.simantics.scl.compiler.types.TVar; import org.simantics.scl.compiler.types.Type; public class SSAObject extends SSAClosure implements ClosureBinder { Type type; SSAClosure firstClosure; public SSAObject(Type type) { this.type = type; } @Override public void toString(PrintingContext context) { for(SSAClosure closure = firstClosure; closure != null; closure = closure.getNext()) { context.indentation(); context.append(closure.getTarget()); context.append("(" + closure.getTarget().occurrenceCount() + ")"); context.append(" :: "); context.append(closure.getTarget().getType()); context.append(" = \n"); context.indent(); closure.toString(context); context.dedent(); } } @Override public SSAClosure getFirstClosure() { return firstClosure; } @Override public void setFirstClosure(SSAClosure function) { this.firstClosure = function; if(function == null) detach(); } @Override public void destroy() { for(SSAClosure closure = firstClosure; closure != null; closure = closure.getNext()) closure.destroy(); } @Override public SSAClosure copy(CopyContext context) { SSAObject result = new SSAObject(context.copyType(type)); for(SSAClosure closure = firstClosure; closure != null; closure = closure.getNext()) { SSAClosure newFunction = closure.copy(context); newFunction.setTarget(context.copy(closure.getTarget())); result.addClosure(newFunction); } return result; } public void addClosure(SSAClosure closure) { closure.setParent(this); closure.setNext(firstClosure); if(firstClosure != null) firstClosure.setPrev(closure); firstClosure = closure; } @Override public void markGenerateOnFly() { for(SSAClosure closure = firstClosure; closure != null; closure = closure.getNext()) closure.markGenerateOnFly(); } @Override public void replace(TVar[] vars, Type[] replacements) { for(SSAClosure closure = firstClosure; closure != null; closure = closure.getNext()) closure.replace(vars, replacements); } @Override public void collectFreeVariables(ArrayList freeVars) { for(SSAClosure closure = firstClosure; closure != null; closure = closure.getNext()) closure.collectFreeVariables(freeVars); } @Override public void simplify(SSASimplificationContext context) { for(SSAClosure closure = firstClosure; closure != null; closure = closure.getNext()) closure.simplify(context); } @Override public void validate(SSAValidationContext context) { for(SSAClosure closure = firstClosure; closure != null; closure = closure.getNext()) closure.validate(context); } @Override public void lambdaLift(SSALambdaLiftingContext context) { for(SSAClosure closure = firstClosure; closure != null; closure = closure.getNext()) closure.lambdaLift(context); } @Override public boolean isValue() { return false; } @Override public void parametrize(BoundVar[] parameters) { // TODO Auto-generated method stub } @Override public Type getType() { return type; } public CodeWriter createMethod(ModuleWriter moduleWriter, TVar[] typeParameters, Type effect, Type returnType, Type[] parameterTypes) { SSAFunction function = new SSAFunction(typeParameters, effect, returnType); SSABlock block = new SSABlock(parameterTypes); function.addBlock(block); BoundVar target = new BoundVar(function.getType()); function.setTarget(target); addClosure(function); return new CodeWriter(moduleWriter, block); } @Override public void forValRefs(ValRefVisitor visitor) { for(SSAClosure closure = firstClosure; closure != null; closure = closure.getNext()) closure.forValRefs(visitor); } }