package xtc.translator.representation; import java.util.List; import java.util.Map; import xtc.translator.translation.CppPrinter; import xtc.tree.GNode; import xtc.tree.Node; public class CallExpressionPiece extends BaseVisitor implements CppPrintable { public Map<String, List<Method>> methodMap; private Map<String, String> variableMap; public Node baseNode; public String representation; public CallExpressionPiece(Node baseNode) { this.baseNode = baseNode; this.methodMap = null; } public void processNode() { representation = ""; dispatch(baseNode); } public void visitCallExpression(GNode n) { boolean staticCall = false; // get caller Node caller = n.getNode(0); if (caller.getName().equals("PrimaryIdentifier")) { if (variableMap.containsKey(caller.getString(0))) representation += caller.getString(0); else { representation += "__" + caller.getString(0); staticCall = true; } } if (caller.getName().equals("CastExpression")) { System.out.println("CAST!!!!"); representation += " __rt::java_cast<"; representation += caller.getNode(0).getNode(0).getString(0); representation += ">("; representation += caller.getNode(1).getString(0); representation += ") "; } // recurse into caller for chained methods dispatch(caller); // get arguments here Node arguments = n.getNode(3); ArgumentVisitor argumentVisitor = new ArgumentVisitor(variableMap, methodMap); argumentVisitor.dispatch(arguments); // check methodMap String name = n.getString(2); // Special case for print and println if (name.equals("println") || name.equals("print")) { representation += "."; representation += name; if (argumentVisitor.getArguments().getArguments().size() == 0) { representation += "()"; } else { if (arguments.getNode(0).getName().equals("AdditiveExpression")) { representation += "("; for (Argument arg : argumentVisitor.getArguments() .getArguments()) { representation += arg.value; representation += ","; } representation = representation.substring(0, representation.length() - 1); representation += ")"; } else { representation += "(" + argumentVisitor.getArguments().getArguments() .get(0).value + ")"; } } } else { List<Method> methodList = null; // if caller is self, use current method map // otherwise, need to get methodmap for caller if (caller.getName().equals("PrimaryIdentifier")) { String className = variableMap.get(caller.getString(0)); Map<String, List<Method>> mm = null; if (staticCall) mm = MethodMaps.getMethodMapForClass(caller.getString(0)); else mm = MethodMaps.getMethodMapForClass(className); // no method map for this class, means it is something we don't // know what to do with if (mm == null && !staticCall) { representation += "-> __vptr ->"; representation += name; } else { methodList = mm.get(name); } } else { // get method list for name methodList = methodMap.get(name); } if (methodList == null) { // Print arguments representation += "("; if (caller.getName().equals("PrimaryIdentifier")) { representation += caller.getString(0); } else if (caller.getName().equals("CallExpression")) { Node currentNode = caller; String result = ""; while (currentNode != null && currentNode.getName().equals("CallExpression")) { if (currentNode.getNode(0) != null && currentNode.getNode(0).getName() .equals("PrimaryIdentifier")) { result = currentNode.getNode(0).getString(0); break; } representation += result; } } else { representation += "__this"; } for (Argument arg : argumentVisitor.getArguments() .getArguments()) { representation += ","; representation += arg.value; } representation += ")"; return; } else { boolean matchFound = false; for (Method method : methodList) { // check for method with matching arguments if (method.getArguments().compareTo( argumentVisitor.getArguments()) == 0) { matchFound = true; if (method.isStatic) { if (staticCall) { representation += "::" + method.getOverloadedIdentifier(); } else { representation += "->" + method.getOverloadedIdentifier(); } staticCall = true; } else { representation += "->__vptr ->" + method.getOverloadedIdentifier(); } } } if (!matchFound) { // try casting as int if short if (argumentVisitor.getArguments().getArguments().get(0).type .equals("short")) { argumentVisitor.getArguments().getArguments().get(0).type = "int"; for (Method method : methodList) { // check for method with matching arguments if (method.getArguments().compareTo( argumentVisitor.getArguments()) == 0) { matchFound = true; if (method.isStatic) { if (staticCall) { representation += "::" + method.getOverloadedIdentifier(); } else { representation += "->" + method.getOverloadedIdentifier(); } staticCall = true; } else { representation += "->__vptr ->" + method.getOverloadedIdentifier(); } } } } else { representation += "->__vptr ->" + name; } } } // Print arguments representation += "("; if (caller.getName().equals("PrimaryIdentifier")) { if (!staticCall) representation += caller.getString(0); } else if (caller.getName().equals("CallExpression")) { Node currentNode = caller; String result = ""; while (currentNode != null && currentNode.getName().equals("CallExpression")) { if (currentNode.getNode(0) != null && currentNode.getNode(0).getName() .equals("PrimaryIdentifier")) { result = currentNode.getNode(0).getString(0); break; } currentNode = currentNode.getNode(0); } representation += result; } else { if (!staticCall) representation += "__this"; } for (Argument arg : argumentVisitor.getArguments().getArguments()) { representation += ","; representation += arg.value; } representation += ")"; } } public void visitThisExpression(GNode n) { representation += "__this"; } public void visitSelectionExpression(GNode n) { String primaryId = n.getNode(0).getString(0); String selection = n.getString(1); representation += primaryId + "::" + selection; } @Override public void printCpp(CppPrinter cp) { cp.p(representation); } public Map<String, List<Method>> getMethodMap() { return methodMap; } public void setMethodMap(Map<String, List<Method>> methodMap) { this.methodMap = methodMap; } public Map<String, String> getVariableMap() { return variableMap; } public void setVariableMap(Map<String, String> variableMap) { this.variableMap = variableMap; } public Node getBaseNode() { return baseNode; } public void setBaseNode(Node baseNode) { this.baseNode = baseNode; } public String getRepresentation() { return representation; } public void setRepresentation(String representation) { this.representation = representation; } }