X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Finternal%2Fcodegen%2Fwriter%2FCodeWriter.java;h=6bed9f0661fc854b86afa24738bc3eb6dc032f91;hp=f11babe06bd3ef8e110fc00d4a719cf72b424293;hb=9a175feb652b2b7bba7afa540831b9076be3c10e;hpb=0b72d3e4ec886838314ffeba0fa201e32c0aae3e diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/writer/CodeWriter.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/writer/CodeWriter.java index f11babe06..6bed9f066 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/writer/CodeWriter.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/writer/CodeWriter.java @@ -1,146 +1,147 @@ -package org.simantics.scl.compiler.internal.codegen.writer; - -import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; -import org.simantics.scl.compiler.internal.codegen.continuations.Branch; -import org.simantics.scl.compiler.internal.codegen.continuations.BranchRef; -import org.simantics.scl.compiler.internal.codegen.continuations.ICont; -import org.simantics.scl.compiler.internal.codegen.references.BoundVar; -import org.simantics.scl.compiler.internal.codegen.references.IVal; -import org.simantics.scl.compiler.internal.codegen.references.ValRef; -import org.simantics.scl.compiler.internal.codegen.ssa.SSABlock; -import org.simantics.scl.compiler.internal.codegen.ssa.SSAFunction; -import org.simantics.scl.compiler.internal.codegen.ssa.exits.If; -import org.simantics.scl.compiler.internal.codegen.ssa.exits.Jump; -import org.simantics.scl.compiler.internal.codegen.ssa.exits.Switch; -import org.simantics.scl.compiler.internal.codegen.ssa.exits.Throw; -import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetApply; -import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetFunctions; -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 org.simantics.scl.compiler.types.util.MultiFunction; - -public class CodeWriter { - - ModuleWriter moduleWriter; - SSABlock block; - - CodeWriter(ModuleWriter moduleWriter, SSABlock block) { - this.moduleWriter = moduleWriter; - this.block = block; - } - - public IVal apply(int lineNumber, IVal function, IVal ... parameters) { - try { - MultiFunction mfun = Types.matchFunction(function.getType(), parameters.length); - return applyWithEffect(lineNumber, - mfun.effect, - mfun.returnType, - function, parameters); - } catch (MatchException e) { - throw new InternalCompilerError(e); - } - } - - public IVal applyWithEffectChecked(int lineNumber, Type effect, Type returnType, IVal function, IVal ... parameters) { - try { - MultiFunction mfun = Types.matchFunction(function.getType(), parameters.length); - if(!Types.equals(effect, mfun.effect)) - throw new InternalCompilerError(); - if(!Types.equals(returnType, mfun.returnType)) - throw new InternalCompilerError(); - } catch (MatchException e) { - throw new InternalCompilerError(e); - } - return applyWithEffect(lineNumber, effect, returnType, function, parameters); - } - - public IVal applyWithEffect(long location, Type effect, Type returnType, IVal function, IVal ... parameters) { - BoundVar var = new BoundVar(returnType); - LetApply apply = new LetApply(var, - effect, - function.createOccurrence(), - ValRef.createOccurrences(parameters)); - apply.location = location; - block.addStatement(apply); - return var; - } - - public CodeWriter createBlock(Type ... parameterTypes) { - SSABlock newBlock = new SSABlock(parameterTypes); - block.getParent().addBlock(newBlock); - return new CodeWriter(moduleWriter, newBlock); - } - - public CodeWriter createFunction(TVar[] typeParameters, Type effect, Type returnType, Type[] parameterTypes) { - if(SCLCompilerConfiguration.DEBUG) - if(effect == null) - throw new InternalCompilerError(); - SSAFunction function = new SSAFunction(typeParameters, effect, returnType); - SSABlock block = new SSABlock(parameterTypes); - function.addBlock(block); - BoundVar target = new BoundVar(function.getType()); - function.setTarget(target); - - this.block.addStatement(new LetFunctions(function)); - return new CodeWriter(moduleWriter, block); - } - - public RecursiveDefinitionWriter createRecursiveDefinition() { - LetFunctions let = new LetFunctions(); - block.addStatement(let); - return new RecursiveDefinitionWriter(moduleWriter, let); - } - - public void continueAs(CodeWriter codeWriter) { - this.block = codeWriter.block; - codeWriter.block = null; - } - - public IVal[] getParameters() { - return block.getParameters(); - } - - public ICont getContinuation() { - return block; - } - - public void jump(ICont cont, IVal ... parameters) { - block.setExit(new Jump(cont.createOccurrence(), - ValRef.createOccurrences(parameters))); - block = null; - } - - public void if_(IVal condition, ICont thenTarget, ICont elseTarget) { - block.setExit(new If(condition.createOccurrence(), - thenTarget.createOccurrence(), - elseTarget.createOccurrence())); - block = null; - } - - public void return_(IVal val) { - jump(block.getParent().getReturnCont(), val); - } - - public void switch_(IVal val, Branch[] branches) { - block.setExit(new Switch(val.createOccurrence(), BranchRef.toBranchRefs(branches))); - block = null; - } - - public void throw_(long location, String description) { - Throw exit = new Throw(description); - exit.location = location; - block.setExit(exit); - block = null; - } - - public ModuleWriter getModuleWriter() { - return moduleWriter; - } - - public SSAFunction getFunction() { - return block.getParent(); - } -} +package org.simantics.scl.compiler.internal.codegen.writer; + +import org.cojen.classfile.TypeDesc; +import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; +import org.simantics.scl.compiler.internal.codegen.continuations.Branch; +import org.simantics.scl.compiler.internal.codegen.continuations.BranchRef; +import org.simantics.scl.compiler.internal.codegen.continuations.ICont; +import org.simantics.scl.compiler.internal.codegen.references.BoundVar; +import org.simantics.scl.compiler.internal.codegen.references.IVal; +import org.simantics.scl.compiler.internal.codegen.references.ValRef; +import org.simantics.scl.compiler.internal.codegen.ssa.SSABlock; +import org.simantics.scl.compiler.internal.codegen.ssa.SSAFunction; +import org.simantics.scl.compiler.internal.codegen.ssa.exits.If; +import org.simantics.scl.compiler.internal.codegen.ssa.exits.Jump; +import org.simantics.scl.compiler.internal.codegen.ssa.exits.Switch; +import org.simantics.scl.compiler.internal.codegen.ssa.exits.Throw; +import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetApply; +import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetFunctions; +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 org.simantics.scl.compiler.types.util.MultiFunction; + +public class CodeWriter { + + ModuleWriter moduleWriter; + SSABlock block; + + CodeWriter(ModuleWriter moduleWriter, SSABlock block) { + this.moduleWriter = moduleWriter; + this.block = block; + } + + public IVal apply(int lineNumber, IVal function, IVal ... parameters) { + try { + MultiFunction mfun = Types.matchFunction(function.getType(), parameters.length); + return applyWithEffect(lineNumber, + mfun.effect, + mfun.returnType, + function, parameters); + } catch (MatchException e) { + throw new InternalCompilerError(e); + } + } + + public IVal applyWithEffectChecked(int lineNumber, Type effect, Type returnType, IVal function, IVal ... parameters) { + try { + MultiFunction mfun = Types.matchFunction(function.getType(), parameters.length); + if(!Types.equals(effect, mfun.effect)) + throw new InternalCompilerError(); + if(!Types.equals(returnType, mfun.returnType)) + throw new InternalCompilerError(); + } catch (MatchException e) { + throw new InternalCompilerError(e); + } + return applyWithEffect(lineNumber, effect, returnType, function, parameters); + } + + public IVal applyWithEffect(long location, Type effect, Type returnType, IVal function, IVal ... parameters) { + BoundVar var = new BoundVar(returnType); + LetApply apply = new LetApply(var, + effect, + function.createOccurrence(), + ValRef.createOccurrences(parameters)); + apply.location = location; + block.addStatement(apply); + return var; + } + + public CodeWriter createBlock(Type ... parameterTypes) { + SSABlock newBlock = new SSABlock(parameterTypes); + block.getParent().addBlock(newBlock); + return new CodeWriter(moduleWriter, newBlock); + } + + public CodeWriter createFunction(TVar[] typeParameters, Type effect, Type returnType, Type[] parameterTypes) { + if(SCLCompilerConfiguration.DEBUG) + if(effect == null) + throw new InternalCompilerError(); + SSAFunction function = new SSAFunction(typeParameters, effect, returnType); + SSABlock block = new SSABlock(parameterTypes); + function.addBlock(block); + BoundVar target = new BoundVar(function.getType()); + function.setTarget(target); + + this.block.addStatement(new LetFunctions(function)); + return new CodeWriter(moduleWriter, block); + } + + public RecursiveDefinitionWriter createRecursiveDefinition() { + LetFunctions let = new LetFunctions(); + block.addStatement(let); + return new RecursiveDefinitionWriter(moduleWriter, let); + } + + public void continueAs(CodeWriter codeWriter) { + this.block = codeWriter.block; + codeWriter.block = null; + } + + public IVal[] getParameters() { + return block.getParameters(); + } + + public ICont getContinuation() { + return block; + } + + public void jump(ICont cont, IVal ... parameters) { + block.setExit(new Jump(cont.createOccurrence(), + ValRef.createOccurrences(parameters))); + block = null; + } + + public void if_(IVal condition, ICont thenTarget, ICont elseTarget) { + block.setExit(new If(condition.createOccurrence(), + thenTarget.createOccurrence(), + elseTarget.createOccurrence())); + block = null; + } + + public void return_(IVal val) { + jump(block.getParent().getReturnCont(), val); + } + + public void switch_(IVal val, Branch[] branches) { + block.setExit(new Switch(val.createOccurrence(), BranchRef.toBranchRefs(branches))); + block = null; + } + + public void throw_(long location, TypeDesc exceptionClass, String description) { + Throw exit = new Throw(exceptionClass, description); + exit.location = location; + block.setExit(exit); + block = null; + } + + public ModuleWriter getModuleWriter() { + return moduleWriter; + } + + public SSAFunction getFunction() { + return block.getParent(); + } +}