package de.fuberlin.projecta.analysis.ast; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import de.fuberlin.commons.parser.ISyntaxTree; import de.fuberlin.projecta.analysis.SymbolTableStack; /** * Record type * * Declarations are the children, there may be an arbitrary amount of them */ public class Record extends Type { @Override public String genCode() { String ret = ""; if (!(getParent().getParent() instanceof FuncDef)) ret = "%struct." + getFuncId().getValue(); if (getParent() instanceof Params) ret = "%struct." + getFuncId().getValue() + "* byval"; return ret; } @Override public String toTypeString() { ArrayList<Declaration> decls = new ArrayList<Declaration>(); for (ISyntaxTree child : this.getChildren()) { decls.add((Declaration) child); } Collections.sort(decls, new Comparator<Declaration>() { @Override public int compare(Declaration child1, Declaration child2) { String id1, id2; id1 = ((Id) child1.getChild(1)).getValue(); id2 = ((Id) child2.getChild(1)).getValue(); return id1.compareTo(id2); } }); String typeString = "record("; ArrayList<String> subStrings = new ArrayList<String>(); for (Declaration decl : decls) { Type t = (Type) decl.getChild(0); Id id = (Id) decl.getChild(1); subStrings.add("(" + id.getValue() + "," + t.toTypeString() + ")"); } for (String subStr : subStrings) { typeString += subStr + ";"; } typeString += ")"; return typeString; } @Override protected String genStruct() { String ret = ""; List<String> recordTypes = new ArrayList<String>(); if (!(getParent() instanceof Params)) { if (getFuncId() != null) { ret = "%struct." + getFuncId().getValue() + " = type { "; boolean tmp = false; for (int i = 0; i < getChildrenCount(); i++) { if (getChild(i).getChild(0) instanceof Record) { recordTypes.add(((Record) (getChild(i).getChild(0))) .genStruct()); String t = ((Type) (getChild(i).getChild(0))).genCode(); if (!t.equals("")) { t += ", "; tmp = true; } ret += t; } else { String t = ((Type) (getChild(i).getChild(0))).genCode(); if (!t.equals("")) { t += ", "; tmp = true; } ret += t; } } if (tmp) { ret = ret.substring(0, ret.length() - 2); } ret += " }\n"; for (String struct : recordTypes) { ret += struct + "\n"; } return ret; } } return ret; } /** * This is hopefully working all the time, since no checking on * classCastException is done. * * @return */ private Id getFuncId() { return (Id) getParent().getChild(1); } @Override public void buildSymbolTable(SymbolTableStack tables) { tables.push(); for (int i = 0; i < getChildrenCount(); i++) { ((Declaration) getChild(i)).buildSymbolTable(tables); } table = tables.pop(); } }