PageRenderTime 18ms CodeModel.GetById 1ms app.highlight 12ms RepoModel.GetById 2ms app.codeStats 0ms

/interpreter/tags/at2dist041108/src/edu/vub/at/objects/natives/NATText.java

http://ambienttalk.googlecode.com/
Java | 222 lines | 141 code | 28 blank | 53 comment | 10 complexity | 463df07424be2721da307bb7e7c34fd7 MD5 | raw file
  1/**
  2 * AmbientTalk/2 Project
  3 * NATText.java created on 26-jul-2006 at 16:45:43
  4 * (c) Programming Technology Lab, 2006 - 2007
  5 * Authors: Tom Van Cutsem & Stijn Mostinckx
  6 * 
  7 * Permission is hereby granted, free of charge, to any person
  8 * obtaining a copy of this software and associated documentation
  9 * files (the "Software"), to deal in the Software without
 10 * restriction, including without limitation the rights to use,
 11 * copy, modify, merge, publish, distribute, sublicense, and/or
 12 * sell copies of the Software, and to permit persons to whom the
 13 * Software is furnished to do so, subject to the following
 14 * conditions:
 15 *
 16 * The above copyright notice and this permission notice shall be
 17 * included in all copies or substantial portions of the Software.
 18 *
 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 21 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 22 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 23 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 24 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 26 * OTHER DEALINGS IN THE SOFTWARE.
 27 */
 28package edu.vub.at.objects.natives;
 29
 30import edu.vub.at.eval.Evaluator;
 31import edu.vub.at.exceptions.InterpreterException;
 32import edu.vub.at.exceptions.XIllegalArgument;
 33import edu.vub.at.exceptions.XTypeMismatch;
 34import edu.vub.at.objects.ATBoolean;
 35import edu.vub.at.objects.ATClosure;
 36import edu.vub.at.objects.ATNil;
 37import edu.vub.at.objects.ATNumber;
 38import edu.vub.at.objects.ATNumeric;
 39import edu.vub.at.objects.ATObject;
 40import edu.vub.at.objects.ATTable;
 41import edu.vub.at.objects.ATText;
 42import edu.vub.at.objects.coercion.NativeTypeTags;
 43import edu.vub.at.objects.natives.grammar.AGExpression;
 44import edu.vub.util.Regexp;
 45
 46import org.apache.regexp.RE;
 47import org.apache.regexp.RESyntaxException;
 48
 49/*
 50import java.util.regex.Matcher;
 51import java.util.regex.Pattern;
 52import java.util.regex.PatternSyntaxException;
 53*/
 54
 55/**
 56 * The native implementation of an AmbientTalk text string.
 57 * A text string is implemented by a Java String.
 58 * 
 59 * @author tvcutsem
 60 */
 61public final class NATText extends AGExpression implements ATText {
 62		
 63	    /** Text is represented as Java String */
 64		public final String javaValue;
 65		
 66		/**
 67		 * This method currently serves as a hook for text creation.
 68		 * Currently text objects are not reused, but this might change in the future.
 69		 */
 70		public static final NATText atValue(String javaString) {
 71			return new NATText(javaString);
 72		}
 73		
 74		private NATText(String javaString) {
 75			javaValue = javaString;
 76		}
 77
 78		public boolean isNativeText() { return true; }
 79		public NATText asNativeText() throws XTypeMismatch { return this; }
 80		
 81		public NATText meta_print() throws InterpreterException {
 82	        return NATText.atValue("\"" + javaValue + "\"");
 83		}
 84		
 85		public ATObject meta_clone() throws InterpreterException {
 86			return this;
 87		}
 88		
 89	    public ATTable meta_typeTags() throws InterpreterException {
 90	    	return NATTable.of(NativeTypeTags._TEXT_, NativeTypeTags._ISOLATE_);
 91	    }
 92		
 93		// comparison and identity operations
 94		
 95	    public ATBoolean base__opeql__opeql_(ATObject comparand) throws InterpreterException {
 96	    	if (comparand.isNativeText()) {
 97	    		return NATBoolean.atValue(javaValue.equals(comparand.asNativeText().javaValue));
 98	    	} else {
 99	    		return NATBoolean._FALSE_;
100	    	}
101	    }
102		
103		public int hashCode() {
104			return javaValue.hashCode();
105		}
106		
107		// base-level interface
108		
109		/**
110		 * Explodes a text string into a table of constinuent characters
111		 */
112		public ATTable base_explode() throws InterpreterException {
113			ATObject[] chars = new ATObject[javaValue.length()];
114			char[] rawchars = javaValue.toCharArray();
115			for (int i = 0; i < chars.length; i++) {
116				chars[i] = NATText.atValue(new Character(rawchars[i]).toString());
117			}
118			return NATTable.atValue(chars);
119		}
120		
121		/**
122		 * Split the string according to the given regular expression.
123		 * For regular expression syntax, see the Apache Regexp API of class {@link RE}.
124		 */
125		public ATTable base_split(ATText regexp) throws InterpreterException {
126			 try {
127				 String[] elements = new RE(Regexp.compile(regexp.asNativeText().javaValue)).split(javaValue);
128				 ATObject[] tbl = new ATObject[elements.length];
129				 for (int i = 0; i < elements.length; i++) {
130					 tbl[i] = NATText.atValue(elements[i]);
131				 }
132				 return NATTable.atValue(tbl);
133			 } catch (RESyntaxException e) {
134				throw new XIllegalArgument("Illegal argument to split: " + e.getMessage());
135			 }
136		}
137		
138		public ATNil base_find_do_(ATText regexp, final ATClosure consumer) throws InterpreterException {
139			 try {
140				 RE pattern = new RE(Regexp.compile(regexp.asNativeText().javaValue));
141				 Regexp.findAll(pattern, javaValue, new Regexp.StringRunnable() {
142					 public void run(String match) throws InterpreterException {
143						 consumer.base_apply(NATTable.atValue(new ATObject[] { NATText.atValue(match) }));
144					 }
145				 });
146				 return Evaluator.getNil();
147			 } catch (RESyntaxException e) {
148				throw new XIllegalArgument("Illegal argument to find:do: " + e.getMessage());
149			 }
150		}
151		
152		public ATText base_replace_by_(ATText regexp, final ATClosure transformer) throws InterpreterException {
153			 try {
154				 RE pattern = new RE(Regexp.compile(regexp.asNativeText().javaValue));
155				 return NATText.atValue(Regexp.replaceAll(pattern, javaValue, new Regexp.StringCallable() {
156					 public String call(String match) throws InterpreterException {
157						 ATObject replacement = transformer.base_apply(NATTable.atValue(new ATObject[] { NATText.atValue(match) }));
158						 return replacement.asNativeText().javaValue;
159					 }
160				 }));
161			 } catch (RESyntaxException e) {
162				throw new XIllegalArgument("Illegal argument to replace:by: " + e.getMessage());
163			 }
164		}
165		
166		public ATText base_toUpperCase() {
167			return NATText.atValue(javaValue.toUpperCase());
168		}
169		
170		public ATText base_toLowerCase() {
171			return NATText.atValue(javaValue.toLowerCase());
172		}
173		
174		public ATNumber base_length() {
175			return NATNumber.atValue(javaValue.length());
176		}
177		
178		public ATText base__oppls_(ATObject other) throws InterpreterException {
179			return NATText.atValue(javaValue +
180					(other.isNativeText() ? other.asNativeText().javaValue : other.meta_print().javaValue));
181		}
182		
183		public ATNumber base__opltx__opeql__opgtx_(ATText other) throws InterpreterException {
184			int cmp = javaValue.compareTo(other.asNativeText().javaValue);
185			if (cmp > 0)
186			    return NATNumber.ONE;
187			else if (cmp < 0)
188				return NATNumber.MONE;
189			else
190				return NATNumber.ZERO;
191		}
192		
193		public ATBoolean base__optil__opeql_(ATText regexp) throws InterpreterException {
194			try {
195				return NATBoolean.atValue(new RE(Regexp.compile(regexp.asNativeText().javaValue)).match(javaValue));
196			} catch (RESyntaxException e) {
197				throw new XIllegalArgument("Illegal regular expression for ~=: " + e.getMessage());
198			}
199		}
200		
201		public ATNumeric base_parseNumeric() throws InterpreterException {
202			try {
203				return NATNumber.atValue(Integer.parseInt(javaValue));
204			} catch(NumberFormatException e) {
205				try {
206					return NATFraction.atValue(Double.parseDouble(javaValue));
207				} catch(NumberFormatException e2) {
208					throw new XIllegalArgument("Cannot convert "+javaValue+" into a numeric object");
209				}
210			}
211		}
212		
213		/** Convert this text into a Java character */
214		public char asChar() throws XTypeMismatch {
215			if (javaValue.length() == 1) {
216				return javaValue.charAt(0);
217			} else {
218				throw new XTypeMismatch(Character.class, this);
219			}
220		}
221
222}