All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.dragome.compiler.graph.transformation.Transformation Maven / Gradle / Ivy

There is a newer version: 0.96-beta4
Show newest version
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();
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy