/* * Basic class for the "Concreate Data Structure" datatype. * * Copyright 2000 Andy Gill * * $Revision: 1.1 $ * $Date: 2000/09/15 16:14:17 $ */ import java.util.*; /** * * @author Andy Gill * @version 0.1 */ public class CDSCons extends CDS { protected int enterId; // The time this node was entered protected String consName; // The name of this constructor protected CDS children[]; // The children, null == not entered /** * Construct a basic CDS object. */ public CDSCons(int nodeId,String consName,int childCount) { this.nodeId = nodeId; this.consName = consName; children = new CDS[childCount]; for(int i = 0;i < children.length;i++) { children[i] = CDSUnknown.unknown; } enterId = -1; } /* Adding a child to a specific node. */ public void addChild(CDS child,int portNo) { if (portNo < 0 || portNo >= children.length) { Message.abort("connecting to non-existent port"); } children[portNo] = children[portNo].adding(child); } protected CDS adding(CDS newChild) { Message.abort("Can not update WHNF with another WHNF"); return null; } protected void addEnterId(int enterId) { this.enterId = enterId; } public void visitNodes(HoodVector nodes) { _visitNodes(nodes); } protected void _visitNodes(HoodVector nodes) { if (enterId != -1) { nodes.setElementAt(this,enterId); } nodes.setElementAt(this,nodeId); for(int i = 0;i < children.length;i++) { if (children[i] != null) { children[i].visitNodes(nodes); } } } private Pretty addEval(PrettyStep parent,Pretty p) { PrettyMany pm = Pretty.nil(); int pi = -1; if (parent != null) { pi = parent.getBirthId(); } if (enterId != -1) { pm._shadow(pi,enterId,"_",Pretty.UNEVAL); pm._shadow(enterId,nodeId,"?",Pretty.UNEVAL); } else { pm._shadow(pi,nodeId,"_",Pretty.UNEVAL); } pm.add(p); return pm; } public Pretty render(PrettyStep parent,int prec,boolean par) { Pretty ret = null; PrettyMany pm = Pretty.nil(); if ((consName == ":" && children.length == 2) || (consName == "(:)" && children.length == 2)) { boolean needParen = prec > 4; PrettyMany elem = Pretty.nil(); elem._brk(); addEval(parent,elem); elem.add(children[0].render(this,5,false)); elem._text(this," : ",Pretty.CONS); pm._group(this,elem); pm.add(children[1].render(this,4,true)); if (par && !needParen) { ret = pm; } else { ret = Pretty.paren(this,needParen,Pretty.nest(this,0,pm)); } } else if (consName.length() > 1 && consName.charAt(0) == ':' && children.length == 2) { pm.add(children[0].render(this,10,false)); addEval(parent,pm); pm._text(this," " + consName + " ",Pretty.CONS); pm.add(children[1].render(this,10,true)); ret = Pretty.paren(this,true,Pretty.nest(this,0,pm)); } else if (consName == "," || consName == "(,)" || consName == "(,,)" || consName == "(,,,)" || consName == "(,,,,)") { boolean first = true; for(int i = 0;i < children.length;i++) { if (first) { addEval(parent,pm); pm._text(this,"(",Pretty.CONS); first = false; } else { pm._text(this,",",Pretty.CONS); } pm.add(children[i].render(this,0,false)); } pm._text(this,")",Pretty.CONS); ret = Pretty.nest(this,2,pm); } else { boolean needParen = children.length > 0 && prec != 0; addEval(parent,pm); if (children.length == 0) { pm._text(this,consName,Pretty.PRIM); } else { pm._text(this,consName,Pretty.CONS); } for(int i = 0;i < children.length;i++) { pm._sep(this); pm.add(children[i].render(this,10,false)); } Pretty p = Pretty.nest(this,2,pm); ret = Pretty.paren(this,needParen,p); } return addEval(parent,ret); } /** * Basic debugging support; accurately dump out the structure. */ public String toString() { if (children.length == 0) { return consName; } String txt = "(" + consName; for(int i = 0;i < children.length;i++) { txt += " "; txt += toString(children[i]); } txt += ")"; return txt; } protected String toString(CDS cds) { if (cds == null) { return "_"; } else { return cds.toString(); } } }