package de.skuzzle.polly.core.parser.util;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
import de.skuzzle.polly.core.parser.ast.declarations.Declaration;
import de.skuzzle.polly.core.parser.ast.declarations.Namespace;
import de.skuzzle.polly.core.parser.ast.declarations.types.ProductType;
import de.skuzzle.polly.core.parser.ast.declarations.types.Substitution;
import de.skuzzle.polly.core.parser.ast.declarations.types.Type;
import de.skuzzle.polly.core.parser.ast.expressions.Expression;
import de.skuzzle.polly.core.parser.ast.expressions.VarAccess;
import de.skuzzle.polly.core.parser.ast.expressions.literals.FunctionLiteral;
public class ASTDotBuilder extends DotBuilder {
public ASTDotBuilder(PrintStream out) {
super(out);
}
public void printNameSpace(Namespace ns) {
this.out.println("subgraph namespace {");
this.out.println("label=\"Declarations\";");
this.out.println("style=filled;");
this.out.println("bgcolor=lightgrey;");
this.out.println("rank=sink;");
this.out.println("rankdir=LR;");
this.out.println("concentrate=true;");
this.out.println("node [style=filled, shape=Mrecord, bgcolor=white];");
this.out.print("structNS [fontname=\"Consolas\", label=\"");
int level = 0;
for (Namespace space = ns; space != null; space = space.getParent()) {
this.out.print("Level: ");
this.out.print(level++);
this.out.print("|");
for (final List<Declaration> decls : space.getDeclarations().values()) {
for (final Declaration decl : decls) {
Integer i = this.nodes.get(decl);
if (i != null) {
continue;
}
i = this.nodeIdx++;
this.nodes.put(decl, i);
this.out.print("{<n");
this.out.print(i);
this.out.print("> ");
this.out.print(this.escape(decl.getName().getId()));
this.out.print("|");
this.out.print(this.escape(decl.getType().getName().getId()));
this.out.print("}|");
}
}
}
this.out.println("\"];");
this.out.println("}");
}
private String escape(String s) {
s = s.replace("\\", "\\\\");
s = s.replace("|", "\\|");
s = s.replace("<", "\\<");
s = s.replace(">", "\\>");
s = s.replace("{", "\\{");
s = s.replace("}", "\\}");
s = s.replace("[", "\\[");
s = s.replace("]", "\\]");
return s;
}
public void printUsage(VarAccess start, Declaration target) {
final Integer startIdx = this.nodes.get(start);
final Integer targetIdx = this.nodes.get(target);
if (startIdx == null) {
return;
} else if (targetIdx == null) {
return;
}
this.out.print("n");
this.out.print(startIdx);
this.out.print("--");
this.out.print("n");
this.out.print(targetIdx);
this.out.print(" [fontname=\"Consolas\", constraint=false,dir=forward, arrowHead=\"open\", label=\"");
this.out.print("");
this.out.print("\", style=\"");
this.out.print("dotted");
this.out.println("\"];");
}
public void printFunction(FunctionLiteral fun) {
final StringBuilder typesBuilder = new StringBuilder();
final List<Type> types = new ArrayList<Type>(fun.getFormal().size());
for (final Declaration decl : fun.getFormal()) {
types.add(decl.getType());
}
final Type signature = new ProductType(types);
for (final Type t : fun.getTypes()) {
typesBuilder.append(t);
if (fun.hasConstraint(t)) {
final Substitution constraint = fun.getConstraint(t);
typesBuilder.append(" ");
typesBuilder.append(constraint.map().entrySet().toString());
}
typesBuilder.append("\\n");
}
this.printNode(fun,
"Function",
"Unique: " + fun.getUnique(),
"Formal: " + signature.getName(),
"Types:\\n" + typesBuilder.toString(),
fun.getPosition().toString());
}
public void printExpression(String label, Expression exp) {
final StringBuilder typesBuilder = new StringBuilder();
for (final Type t : exp.getTypes()) {
typesBuilder.append(t);
if (exp.hasConstraint(t)) {
final Substitution constraint = exp.getConstraint(t);
typesBuilder.append(" ");
typesBuilder.append(constraint.map().entrySet().toString());
}
typesBuilder.append("\\n");
}
this.printNode(exp,
label,
"Unique: " + exp.getUnique(),
"Types:\\n" + typesBuilder.toString(),
exp.getPosition().toString());
}
}