/* * xtc - The eXTensible Compiler * Copyright (C) 2004 Robert Grimm * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package xtc.tree; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.NoSuchElementException; /** * A node in an abstract syntax tree or DAG. * * @author Robert Grimm * @version $Revision: 1.1 $ */ public abstract class Node { /** The properties. */ private Map properties; /** The optional source location. */ public Location location; /** Create a new node. */ public Node() { } /** * Create a new node. * * @param location The source location for the new node. */ public Node(Location location) { this.location = location; } /** * Accept the specified visitor. * * <p />Optionally, a visitor may return a value, thus making it * possible, for example, to replace nodes or to construct entirely * new trees. If the specified visitor does not return a value, this * method returns <code>null</code>. * * @param v The visitor. * @return The (optional) return value. * @throws VisitorException * Signals that the specified visitor does not have a matching * <code>visit()</code> method. * @throws VisitingException * Signals an exceptional condition while applying the specified * visitor on this node. */ public Object accept(Visitor v) { return v.dispatch(this); } /** * Set the value of a property. * * @param name The property name. * @param value The new property value. * @return The property's old value or <code>null</code> if the * property didn't have a value. */ public Object setProperty(String name, Object value) { if (null == properties) { properties = new HashMap(); } return properties.put(name, value); } /** * Test if this node has a property. * * @param name The property name. * @return <code>true</code> if this node has a property with the * specified name. */ public boolean hasProperty(String name) { if (null == properties) { return false; } else { return properties.containsKey(name); } } /** * Get a property value. * * @param name The property name. * @return The property's value or <code>null</code> if the * property doesn't have a value. */ public Object getProperty(String name) { if (null == properties) { return null; } else { return properties.get(name); } } /** * Remove a property. * * @param name The property name. * @return The property's old value or <code>null</code> if the * property didn't have a value. */ public Object removeProperty(String name) { if (null == properties) { return null; } else { return properties.remove(name); } } /** * Get an iterator over this node's property names. * * @return An iterator over this node's property names. */ public Iterator properties() { if (null == properties) { return new Iterator() { public boolean hasNext() { return false; } public Object next() { throw new NoSuchElementException(); } public void remove() { throw new IllegalStateException(); } }; } else { return properties.keySet().iterator(); } } /** * Set the location of this node to the specified values, * <code>iff</code> the location has not been set before. * * @param file The file. * @param line The line number. * @param column The column number. */ public void setLocation(String file, int line, int column) { if (null == location) { location = new Location(file, line, column); } } }