Newer
Older
AlgebraicDataflowArchitectureModel / AlgebraicDataflowArchitectureModel / src / algorithms / CodeGenerator.java
package algorithms;

import java.util.ArrayList;

import code.ast.*;
import models.*;
import models.algebra.*;
import models.dataConstraintModel.*;
import models.dataFlowModel.*;
import models.dataFlowModel.DataflowChannelGenerator.IResourceStateAccessor;

public class CodeGenerator {
	static public ArrayList<TypeDeclaration> doGenerate(ResourceDependencyGraph graph, DataFlowModel model) {
		ArrayList<TypeDeclaration> codes = new ArrayList<>();
		ArrayList<ResourceNode> resources = StoreResourceCheck(graph);

		codes.add(new TypeDeclaration("Main"));
		for (ResourceNode rn : resources) {
			String name = rn.getIdentifierTemplate().getResourceName().substring(0, 1).toUpperCase()
					+ rn.getIdentifierTemplate().getResourceName().substring(1);
			FieldDeclaration field = new FieldDeclaration(new Type(name, name),
					rn.getIdentifierTemplate().getResourceName());
			TypeDeclaration type = new TypeDeclaration(name);
			codes.get(0).addField(field);
			for (Edge e : rn.getOutEdges()) {
				ResourceDependency re = (ResourceDependency) e;
				String rename = ((ResourceNode) re.getDestination()).getIdentifierTemplate().getResourceName()
						.substring(0, 1).toUpperCase()
						+ ((ResourceNode) re.getDestination()).getIdentifierTemplate().getResourceName().substring(1);
				if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) == PushPullValue.PUSH) {
					type.addField(new FieldDeclaration(new Type(rename, rename),
							((ResourceNode) re.getDestination()).getIdentifierTemplate().getResourceName()));
					type.addConstructors(new VariableDeclaration(new Type(rename, rename),
							((ResourceNode) re.getDestination()).getIdentifierTemplate().getResourceName()));
				}
			}
			for (Edge e : rn.getInEdges()) {
				ResourceDependency re = (ResourceDependency) e;
				String rename = ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceName()
						.substring(0, 1).toUpperCase()
						+ ((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceName().substring(1);
				if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) != PushPullValue.PUSH) {
					type.addField(new FieldDeclaration(new Type(rename, rename),
							((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceName()));
					type.addConstructors(new VariableDeclaration(new Type(rename, rename),
							((ResourceNode) re.getSource()).getIdentifierTemplate().getResourceName()));
				}
			}
			if (((StoreAttribute) rn.getAttribute()).isStored())
				type.addField(new FieldDeclaration(DataConstraintModel.typeInt,
						rn.getIdentifierTemplate().getResourceName()));
			codes.add(type);
		}
		return codes;
	}

	static public ArrayList<String> getCodes(ArrayList<TypeDeclaration> codeTree) {
		ArrayList<String> codes = new ArrayList<>();
		for (TypeDeclaration type : codeTree) {
			codes.add("public class " + type.getTypeName() + "{");
			for (FieldDeclaration field : type.getFields()) {
				if (type.getTypeName() != "Main") {
					codes.add("\t" + "private " + field.getType().getImplementationTypeName() + " " + field.getName()
							+ ";");
				} else {
					String cons = "\t" + "private " + field.getType().getImplementationTypeName() + " "
							+ field.getName() + " = new " + field.getType().getTypeName() + "(";
					for (TypeDeclaration tree:codeTree) {
						if(field.getType().getTypeName() == tree.getTypeName()) {
							for(VariableDeclaration var:tree.getConstructors()) {
								cons += var.getType().getTypeName() + " " + var.getName() + ",";
							}
							if(!tree.getConstructors().isEmpty()) cons = cons.substring(0, cons.length() - 1);
							break;
						}
					}
					cons += ");";
					codes.add(cons);
				}
			}
			codes.add("");
			if (type.getTypeName() != "Main") {
				String cons = "\t" + "public " + type.getTypeName() + "(";
				for (VariableDeclaration constructor : type.getConstructors()) {
					cons += constructor.getType().getTypeName() + " " + constructor.getName() + ",";
				}
				if (!type.getConstructors().isEmpty())
					cons = cons.substring(0, cons.length() - 1);
				cons += ");";
				codes.add(cons);
				for (FieldDeclaration field : type.getFields()) {
					for (VariableDeclaration vari : type.getConstructors()) {
						if (field.getType().getTypeName().equals(vari.getType().getTypeName())) {
							codes.add("\t\t" + "this." + field.getName() + " = " + field.getName());
						}
					}
				}
				codes.add("\t" + "}");
			}
			for (MethodDeclaration method : type.getMethods()) {
				codes.add("\t" + "public " + method.getReturnType().getImplementationTypeName() + " " + method.getName()
						+ "{");
				for (VariableDeclaration value : method.getParameters()) {
					codes.add("\t\t" + value.getType().getImplementationTypeName() + " " + value.getName());
				}
				codes.add("\t" + "}");
				codes.add("");
			}
			codes.add("}");
			codes.add("");
		}
		return codes;
	}

	static private ArrayList<ResourceNode> StoreResourceCheck(ResourceDependencyGraph graph) {
		ArrayList<ResourceNode> resources = new ArrayList<>();
		for (Node n : graph.getNodes()) {
			ResourceNode rn = (ResourceNode) n;
			boolean flag = true;
			for (Edge e : rn.getOutEdges()) {
				ResourceDependency re = (ResourceDependency) e;
				if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) == PushPullValue.PUSH) {
					flag = false;
				}
			}
			for (Edge e : rn.getInEdges()) {
				ResourceDependency re = (ResourceDependency) e;
				if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) != PushPullValue.PUSH) {
					flag = false;
				}
			}
			if (flag)
				resources.add(rn);
		}
		trackNode(resources.get(0), resources);
		return resources;
	}

	static private void trackNode(ResourceNode current, ArrayList<ResourceNode> resources) {
		if (!resources.contains(current))
			resources.add(current);
		for (Edge e : current.getOutEdges()) {
			ResourceDependency re = (ResourceDependency) e;
			if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) != PushPullValue.PUSH) {
				trackNode((ResourceNode) re.getDestination(), resources);
			}
		}
		for (Edge e : current.getInEdges()) {
			ResourceDependency re = (ResourceDependency) e;
			if (((PushPullAttribute) re.getAttribute()).getOptions().get(0) == PushPullValue.PUSH) {
				trackNode((ResourceNode) re.getSource(), resources);
			}
		}
	}

	static public IResourceStateAccessor pushAccessor = new IResourceStateAccessor() {
		@Override
		public Expression getCurrentStateAccessorFor(IdentifierTemplate target, IdentifierTemplate from) {
			if (target.equals(from)) {
				return new Field(target.getResourceName(),
						target.getResourceStateType() != null ? target.getResourceStateType()
								: DataConstraintModel.typeInt);
			}
			return null;
		}

		@Override
		public Expression getNextStateAccessorFor(IdentifierTemplate target, IdentifierTemplate from) {
			return new Parameter(target.getResourceName(),
					target.getResourceStateType() != null ? target.getResourceStateType()
							: DataConstraintModel.typeInt);
		}
	};
	static public IResourceStateAccessor pullAccessor = new IResourceStateAccessor() {
		@Override
		public Expression getCurrentStateAccessorFor(IdentifierTemplate target, IdentifierTemplate from) {
			if (target.equals(from)) {
				return new Field(target.getResourceName(),
						target.getResourceStateType() != null ? target.getResourceStateType()
								: DataConstraintModel.typeInt);
			}
			return null;
		}

		@Override
		public Expression getNextStateAccessorFor(IdentifierTemplate target, IdentifierTemplate from) {
			Term getter = new Term(new Symbol("get" + target.getResourceName(), 1, Symbol.Type.METHOD));
			getter.addChild(new Field(target.getResourceName(), target.getResourceStateType()));
			return getter;
		}
	};
}