Newer
Older
AlgebraicDataflowArchitectureModel / AlgebraicDataflowArchitectureModel / src / generators / JavaImplementationVisitor.java
@shohei-yamagiwa shohei-yamagiwa 24 days ago 7 KB Organize duplicated implementations
package generators;

import models.algebra.*;
import models.dataConstraintModel.DataConstraintModel;
import models.dataConstraintModel.JsonAccessor;
import models.dataConstraintModel.JsonTerm;

/**
 * This class is a Java implementation of {@link IExpressionVisitor}
 * which holds and manages the actual method of implementation code generation
 *
 * @author s-yamagiwa
 */
public class JavaImplementationVisitor implements IExpressionVisitor {
	private static int jsonCount = 0;
	
	@Override
	public String visit(Term term, String[] sideEffects) {
		int[] implParamOrder = term.getSymbol().getImplParamOrder();
		if (term.getSymbol().isImplLambda()) {
			String[] components = term.getSymbol().getImplName().split("->");
			String component0 = components[0].replace("(", "").replace(")", "");
			String[] params = component0.split(",");
			String exp = components[1];
			String receiver = "";
			if (implParamOrder == null) {
				receiver = term.getChildren().get(0).accept(this, sideEffects);
				exp = exp.replace(params[0], receiver);
				for (int i = 1; i < params.length; i++) {
					exp = exp.replace(params[i], term.getChildren().get(i).accept(this, sideEffects));
				}
			} else {
				receiver = term.getChildren().get(implParamOrder[0]).accept(this, sideEffects);
				exp = exp.replace(params[0], receiver);
				for (int i = 1; i < params.length; i++) {
					exp = exp.replace(params[i], term.getChildren().get(implParamOrder[i]).accept(this, sideEffects));
				}
			}
			if (term.getSymbol().isImplWithSideEffect()) {
				sideEffects[0] = sideEffects[0] + exp + ";\n";
				exp = receiver;
			}
			return exp;
		}
		if (term.getSymbol().isImplGenerative()) {
			Type[] childrenTypes = new Type[term.getChildren().size()];
			String[] childrenImpl = new String[term.getChildren().size()];
			String[] childrenSideEffects = new String[term.getChildren().size()];
			if (implParamOrder == null) {
				for (int i = 0; i < term.getChildren().size(); i++) {
					Expression child = term.getChildren().get(i);
					if (child instanceof Variable) {
						childrenTypes[i] = ((Variable) child).getType();
					} else if (child instanceof Term) {
						childrenTypes[i] = ((Term) child).getType();
					}
					String[] childSideEffect = new String[]{""};
					childrenImpl[i] = child.accept(this, childSideEffect);
					childrenSideEffects[i] = childSideEffect[0];
				}
				String exp = term.getSymbol().generate(term.getType(), childrenTypes, childrenImpl, childrenSideEffects, sideEffects);
				if (term.getSymbol().isImplWithSideEffect()) {
					sideEffects[0] = sideEffects[0] + exp;
					exp = childrenImpl[0];        // the value of this term
				}
				return exp;
			} else {
				for (int i = 0; i < term.getChildren().size(); i++) {
					Expression child = term.getChildren().get(implParamOrder[i]);
					if (child instanceof Variable) {
						childrenTypes[i] = ((Variable) child).getType();
					} else if (child instanceof Term) {
						childrenTypes[i] = ((Term) child).getType();
					}
					String[] childSideEffect = new String[]{""};
					childrenImpl[i] = child.accept(this, childSideEffect);
					childrenSideEffects[i] = childSideEffect[0];
				}
				String exp = term.getSymbol().generate(term.getType(), childrenTypes, childrenImpl, childrenSideEffects, sideEffects);
				if (term.getSymbol().isImplWithSideEffect()) {
					sideEffects[0] = sideEffects[0] + exp;
					exp = childrenImpl[0];        // the value of this term
				}
				return exp;
			}
		}
		if (term.getArity() == 2 && term.getSymbol().isImplInfix()) {
			if (implParamOrder == null) {
				return "(" + term.getChildren().get(0).accept(this, sideEffects) + term.getSymbol().toImplementation() + term.getChildren().get(1).accept(this, sideEffects) + ")";
			} else {
				return "(" + term.getChildren().get(implParamOrder[0]).accept(this, sideEffects) + term.getSymbol().toImplementation() + term.getChildren().get(implParamOrder[1]).accept(this, sideEffects) + ")";
			}
		}
		if ((term.getArity() >= 1 || term.getArity() == -1) && term.getSymbol().isImplMethod()) {
			if (implParamOrder == null) {
				String exp = null;
				String receiver = "";
				if (term.getChildren().size() > 0 && term.getChildren().get(0) != null) {
					receiver = term.getChildren().get(0).accept(this, sideEffects);
					exp = receiver + "." + term.getSymbol().toImplementation() + "(";
				} else {
					exp = term.getSymbol().toImplementation() + "(";
				}
				String delimiter = "";
				for (int i = 1; i < term.getChildren().size(); i++) {
					Expression e = term.getChildren().get(i);
					exp += (delimiter + e.accept(this, sideEffects));
					delimiter = ",";
				}
				exp += ")";
				if (term.getSymbol().isImplWithSideEffect()) {
					sideEffects[0] = sideEffects[0] + exp + ";\n";
					exp = receiver;
				}
				return exp;
			} else {
				String receiver = term.getChildren().get(implParamOrder[0]).accept(this, sideEffects);
				String exp = receiver + "." + term.getSymbol().toImplementation() + "(";
				String delimiter = "";
				for (int i = 1; i < term.getChildren().size(); i++) {
					Expression e = term.getChildren().get(implParamOrder[i]);
					exp += (delimiter + e.accept(this, sideEffects));
					delimiter = ",";
				}
				exp += ")";
				if (term.getSymbol().isImplWithSideEffect()) {
					sideEffects[0] = sideEffects[0] + exp + ";\n";
					exp = receiver;
				}
				return exp;
			}
		} else {
			if (implParamOrder == null) {
				String exp = term.getSymbol().toImplementation() + "(";
				String delimiter = "";
				for (Expression e : term.getChildren()) {
					exp += (delimiter + e.accept(this, sideEffects));
					delimiter = ",";
				}
				return exp + ")";
			} else {
				String exp = term.getSymbol().toImplementation() + "(";
				String delimiter = "";
				for (int i = 0; i < term.getChildren().size(); i++) {
					Expression e = term.getChildren().get(implParamOrder[i]);
					exp += (delimiter + e.accept(this, sideEffects));
					delimiter = ",";
				}
				return exp + ")";
			}
		}
	}
	
	@Override
	public String visit(Field field, String[] sideEffects) {
		return "this." + visit((Constant) field, sideEffects);
	}
	
	@Override
	public String visit(Constant constant, String[] sideEffects) {
		if (constant.getSymbol().isImplGenerative()) {
			String exp = constant.getSymbol().generate(constant.getType(), new Type[]{}, new String[]{}, new String[]{}, sideEffects);
			return exp;
		}
		return constant.getSymbol().getImplName();
	}
	
	@Override
	public String visit(Variable variable, String[] sideEffects) {
		return variable.getName();
	}
	
	@Override
	public String visit(JsonTerm jsonTerm, String[] sideEffects) {
		String temp = "temp_json" + jsonCount;
		jsonCount++;
		String impl = "";
		impl += "Map<String, Object> " + temp + " = new HashMap<>();\n";
		for (String key : jsonTerm.keySet()) {
			impl += temp + ".put(\"" + key + "\", " + jsonTerm.get(key).accept(this, sideEffects) + ");\n";
		}
		sideEffects[0] += impl;
		return temp;
	}
	
	@Override
	public String visit(JsonAccessor jsonAccessor, String[] sideEffects) {
		if (jsonAccessor.getSymbol().equals(DataConstraintModel.dotParam)) {
			return jsonAccessor.getChildren().get(0).accept(this, sideEffects) + "." + jsonAccessor.getSymbol().toImplementation() + "(" + jsonAccessor.getChildren().get(1).accept(this, sideEffects) + ")";
		}
		return visit((Term) jsonAccessor, sideEffects);
	}
}