/* Copyright 2004-2006 David N. Welton Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package org.hecl; import java.util.Vector; import java.util.Hashtable; import java.util.Enumeration; /** * Thereturns a string representation of a * ListThing. * * @return aListThingclass implements lists, storing them internally * as a Vector. * * @author David N. Welton * @version 1.0 */ public class ListThing implements RealThing { protected Vector val = null; private int depth = 0; /** * Creates a new, emptyListThinginstance. * */ public ListThing() { val = new Vector(); } /** * Creates a newListThinginstance from a vector. * * @param v aVectorvalue */ public ListThing(Vector v) { val = v; } /** * Attempts to create a newListThinginstance from a string. * May fail if the string can't be parsed into a list. * * @param s aStringvalue * @exception HeclException if an error occurs */ public ListThing(String s) throws HeclException { ParseList parseList = new ParseList(s); /* FIXME - this probably doesn't handle newlines. */ val = parseList.parse(); if (val == null) { val = new Vector(); } } /** *createallocates and returns a new ListThing typed Thing. * * @param v aVectorvalue. Note that the Vector * must contain Things, rather than, say, int's or Strings or * something else! * @return aThingvalue */ public static Thing create(Vector v) { return new Thing(new ListThing(v)); } @Override public String thingclass() { return "list"; } /** *setListFromAnyattempts to transform the given Thing into * a ListThing typed Thing. * * @param thing aThingvalue * @exception HeclException if an error occurs */ private static void setListFromAny(Thing thing) throws HeclException { RealThing realthing = thing.getVal(); if (realthing instanceof ListThing) { /* Nothing to be done. */ return; } RealThing newthing = null; Vector newval = new Vector(); if (realthing instanceof HashThing) { Hashtable h = HashThing.get(thing); for (Enumeration e = h.keys(); e.hasMoreElements();) { String key = (String) e.nextElement(); newval.addElement(new Thing(key)); newval.addElement(h.get(key)); } newthing = new ListThing(newval); } else { newthing = new ListThing(realthing.getStringRep()); } thing.setVal(newthing); } /** *getattempts to transform the given Thing into a List, and * return its Vector value. * * @param thing aThingvalue * @return aVectorvalue * @exception HeclException if an error occurs */ public static Vector get(Thing thing) throws HeclException { setListFromAny(thing); ListThing getlist = (ListThing) thing.getVal(); /* If the thing is slated for copying, it's elements should be * as well. */ if (thing.copy) { for (Enumeration e = getlist.val.elements(); e.hasMoreElements();) { Thing te = (Thing) e.nextElement(); te.copy = true; } } return getlist.val; } /** *getArrayattempts to transform the given Thing * into a List, and return it as an array of Things. * * @param thing aThingvalue * @return aThing[]value * @exception HeclException if an error occurs */ public static Thing[] getArray(Thing thing) throws HeclException { Vector v = ListThing.get(thing); Thing[] res = new Thing[v.size()]; int i = 0; for (Enumeration e = v.elements(); e.hasMoreElements();) { res[i] = (Thing)e.nextElement(); i ++; } return res; } /** *deepcopycopies a list and all of its elements. * * @return aRealThingvalue * @throws HeclException */ @Override public RealThing deepcopy() throws HeclException { Vector newv = new Vector(); for (Enumeration e = val.elements(); e.hasMoreElements();) { newv.addElement(((Thing) e.nextElement()).deepcopy()); } return new ListThing(newv); } /** *toListStringtransforms list elements into the * string form {foo bar} if the element contains a space. * * @param thing aThingvalue * @return aStringvalue */ public static String toListString(Thing thing) { String elementstring = thing.toString(); if (elementstring.indexOf(' ') >= 0 || elementstring.indexOf('\t') >= 0) { StringBuffer resbuf = new StringBuffer(); resbuf.append('{').append(elementstring).append('}'); // System.err.println("toListString: >"+elementstring+"< --> " + resbuf.toString()); return resbuf.toString(); } return elementstring; } public static StringBuffer appendListItem(StringBuffer buf,Thing thing) { String elementstring = thing.toString(); if (elementstring.indexOf(' ') >= 0 || elementstring.indexOf('\t') >= 0) { buf.append('{').append(elementstring).append('}'); } else { buf.append(elementstring); } return buf; } //#ifdef notdef static final int USE_BRACES = 1; static final int DONT_USE_BRACES = 2; static final int BRACES_UNMATCHED = 4; static int scanElement(Thing t) { String s = t.toString(); int flags = 0; int n = s.length(); char ch; if(n == 0 || (((ch = s.charAt(0)) == '{') || ch == '}')) flags |= USE_BRACES; int nestinglevel = 0; for(int i=0; igetStringRep Stringvalue */ @Override public String getStringRep() { int sz = val.size(); if(sz == 0) { return ""; //return "{}"; } /* if(depth > 1) { //throw new HeclException("Can't print circular references"); return "CIRCULAR REF! BANG!"; } else { depth ++; } */ int i = 0; //#ifdef notdef int[] flags = new int[sz]; for(i=0; i0) resbuf.append(' '); //resbuf.append(toListString((Thing)val.elementAt(i))); appendListItem(resbuf,(Thing)val.elementAt(i)); } return resbuf.toString(); } /** * The stringSplitmethod takes a string and splits * it according to another string, * * @param str aStringvalue * @param splitstr aStringvalue * @return aThingvalue */ public static Thing stringSplit(String str, String splitstr) { int idx = 0; int last = 0; Vector result = new Vector(); if (splitstr == null) { /* By default, we split on spaces. */ splitstr = " "; } int splitstringlen = splitstr.length(); if (splitstringlen > 0) { idx = str.indexOf(splitstr); while (idx >= 0) { result.addElement(new Thing(str.substring(last, idx))); last = idx + splitstringlen; idx = str.indexOf(splitstr, last); } result.addElement(new Thing(str.substring(last, str.length()))); } else { /* This is a special case: when the splitstring is an * empty string "". */ for(int i = 0; i < str.length(); i++) { char[] c = new char[1]; c[0] = str.charAt(i); result.addElement(new Thing(new String(c))); } } return ListThing.create(result); } /** * ThebuildCmdListmethod takes a Thing, treats it as a * list, and adds arguments to it from the args array. The whole * thing is returned and is ready to be executed by interp.eval(). * This is a convenience function utilized in various callbacks * throughout the code. * * @param cmd aThingvalue * @param args an array ofThingvalues * @return aThingvalue * @exception HeclException if an error occurs */ public static Thing buildCmdList(Thing cmd, Thing[] args) throws HeclException { Vector v = ListThing.get(cmd.deepcopy()); for(int i = 0; i < args.length; i++) { v.addElement(args[i]); } return ListThing.create(v); } }
Ads help maintain this website.