com.dragome.compiler.graph.transformation.Transformation Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dragome-bytecode-js-compiler Show documentation
Show all versions of dragome-bytecode-js-compiler Show documentation
Dragome SDK module: bytecode to javascript compiler
package com.dragome.compiler.graph.transformation;
import com.dragome.compiler.ast.Block;
import com.dragome.compiler.ast.BooleanExpression;
import com.dragome.compiler.ast.BreakStatement;
import com.dragome.compiler.ast.ContinueStatement;
import com.dragome.compiler.ast.Expression;
import com.dragome.compiler.ast.IfStatement;
import com.dragome.compiler.graph.ConditionalEdge;
import com.dragome.compiler.graph.ControlFlowGraph;
import com.dragome.compiler.graph.Edge;
import com.dragome.compiler.graph.Graph;
import com.dragome.compiler.graph.Node;
import com.dragome.compiler.parser.Optimizer;
import com.dragome.compiler.utils.Log;
public abstract class Transformation
{
static Class[] transformations= new Class[] { Switch.class, Try.class, Loop.class, Merge.class };
public static Transformation select(Graph graph, Node node)
{
for (int i= 0; i < transformations.length; i++)
{
Transformation t= fetch(i);
if (t.applies(node))
{
return t;
}
}
return null;
}
static Transformation fetch(int index)
{
Transformation t= null;
try
{
t= (Transformation) transformations[index].newInstance();
}
catch (InstantiationException e)
{
throw new RuntimeException(e);
}
catch (IllegalAccessException e)
{
throw new RuntimeException(e);
}
return t;
}
ControlFlowGraph graph;
public Node header;
Node newNode;
public Transformation()
{
}
public Node apply()
{
newNode= graph.createNode(Node.class);
newNode.setInitialPc(header.getInitialPc());
newNode.trans= this;
apply_();
graph.replaceNode(header, newNode);
Log.getLogger().debug(toString() + " -> " + newNode);
return newNode;
}
public boolean applies(Node node)
{
graph= (ControlFlowGraph) node.getGraph();
header= node;
return applies_();
}
abstract boolean applies_();
abstract void apply_();
abstract void rollOut_(Block block);
public void rollOut(Block block)
{
rollOut_(block);
block.appendChildren(newNode.block);
}
void produceJump(Edge edge, Block labeledBlock)
{
Node referer= edge.getOrgSource();
Block breakBlock;
if (edge instanceof ConditionalEdge)
{
ConditionalEdge condEdge= (ConditionalEdge) edge;
BooleanExpression condExpr= condEdge.getBooleanExpression();
Expression expr= Optimizer.simplifyBooleanExpression(condExpr.getExpression(), condEdge.isNegate());
IfStatement ifStmt= new IfStatement();
ifStmt.setExpression(expr);
referer.block.appendChild(ifStmt);
Block ifBlock= new Block();
ifStmt.setIfBlock(ifBlock);
breakBlock= ifBlock;
}
else
{
breakBlock= referer.block;
}
if (edge.isBackEdge())
{
breakBlock.appendChild(new ContinueStatement(labeledBlock));
}
else
{
breakBlock.appendChild(new BreakStatement(labeledBlock));
}
}
public String toString()
{
return getClass().getName();
}
}