/* * Copyright (c) 2007 BUSINESS OBJECTS SOFTWARE LIMITED * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Business Objects nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * NInd.java * Created: Sep 23, 2002 at 2:59:58 PM * By: Raymond Cypher */ package org.openquark.cal.internal.machine.g; import java.util.Collection; import org.openquark.cal.runtime.CALExecutorException; import org.openquark.cal.runtime.CalValue; /** * This is the NInd class * * Used to represent an indirection node in the * program graph. * Creation: Sep 23, 2002 at 2:59:57 PM * @author Raymond Cypher */ class NInd extends Node { private Node indirectionNode; private Node parent; NInd () { super (); //the Node.indirection has the default of null upon construction. //In fact, the NInd node type is a placeholder where we know we //need a Node, but don't know what kind yet. } @Override public String toString (int indent) { StringBuilder sp = new StringBuilder (); for (int i = 0; i < indent; ++i) { sp.append (" "); } if (indirectionNode == null) { return sp.toString() + ": NInd <null>"; // return sp.toString() + "#" + nodeOrd + ": NInd <null>"; } return indString (indent); } /** * {@inheritDoc} */ @Override public int debug_getNChildren() { if (indirectionNode == null) { throw new IllegalStateException("should call the overidden version if indirectionNode == null"); } return 1; } /** * {@inheritDoc} */ @Override public CalValue debug_getChild(int childN) { if (indirectionNode == null) { throw new IllegalStateException("should call the overidden version if indirectionNode == null"); } if (childN == 0) { return indirectionNode; } throw new IndexOutOfBoundsException(); } /** * {@inheritDoc} */ @Override public String debug_getNodeStartText() { if (indirectionNode == null) { throw new IllegalStateException("should call the overidden version if indirectionNode == null"); } return ""; } /** * {@inheritDoc} */ @Override public String debug_getNodeEndText() { if (indirectionNode == null) { throw new IllegalStateException("should call the overidden version if indirectionNode == null"); } return ""; } /** * {@inheritDoc} */ @Override public String debug_getChildPrefixText(int childN) { if (indirectionNode == null) { throw new IllegalStateException("should call the overidden version if indirectionNode == null"); } if (childN == 0) { return ""; } throw new IndexOutOfBoundsException(); } @Override Node getIndirectionNode() { return indirectionNode; } @Override protected void setIndirectionNode(Node n) { n = n.getLeafNode(); if (n != this) { if (this.parent == null) { (indirectionNode = n).setParent(this); } else { this.parent.setIndirectionNode(indirectionNode = n); } } } @Override protected void setParent(Node n) { this.parent = n; } protected void clearIndirectionNode() { indirectionNode = null; } @Override public Node getLeafNode () { if (indirectionNode == null) { return this; } Node temp = indirectionNode; while (temp.hasIndirection()) { temp = temp.getIndirectionNode(); } return (indirectionNode = temp); } @Override protected void addChildren(Collection<Node> c) { if (indirectionNode != null) { if (!c.contains(indirectionNode)) { c.add(indirectionNode); indirectionNode.addChildren(c); } } } protected String indString(int indent) { StringBuilder sp = new StringBuilder(); for (int i = 0; i < indent; ++i) { sp.append(" "); } return sp.toString() // + "#" // + nodeOrd + ": NInd <\n" + indirectionNode.idString(indent + 12) + "\n" + sp.toString() + " >"; } /** * Generate a string of the form '#<ordinal value>: <type name> */ @Override protected String idString (int indent) { if (indirectionNode == null) { return super.idString (indent); } else { return indirectionNode.idString (indent); } } /* * Functions to perform state transisions. */ /** * Do the Eval state transition. */ @Override protected void i_eval (Executor e) throws CALExecutorException { if (getIndirectionNode() != null) { e.stack.pop (); e.stack.push (getIndirectionNode().getLeafNode()); getIndirectionNode().getLeafNode().i_eval(e); return; } throw new CALExecutorException.InternalException ("Null indirection in NInd node.", null); } @Override protected void i_unwind (Executor e) throws CALExecutorException { Executor.GStack stack = e.stack; stack.pop (); stack.push (indirectionNode.getLeafNode()); indirectionNode.getLeafNode().i_unwind (e); } @Override protected boolean hasIndirection () { return indirectionNode != null; } /** * Build an application of deepSeq */ @Override protected Node buildDeepSeqInternal(Node rhs) { throw new UnsupportedOperationException("buildDeepSeq() should only be called on a WHNF."); } /** * {@inheritDoc} */ @Override public DataType getDataType() { if (indirectionNode != null) { return indirectionNode.getDataType(); } else { return DataType.OTHER; } } }