PageRenderTime 54ms CodeModel.GetById 12ms app.highlight 37ms RepoModel.GetById 1ms app.codeStats 0ms

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

http://ambienttalk.googlecode.com/
Java | 237 lines | 153 code | 31 blank | 53 comment | 13 complexity | 64e6a75d9dc86a78dd739f84b70cf358 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 java.util.HashMap;
 31
 32import edu.vub.at.eval.Evaluator;
 33import edu.vub.at.exceptions.InterpreterException;
 34import edu.vub.at.exceptions.XIllegalArgument;
 35import edu.vub.at.exceptions.XTypeMismatch;
 36import edu.vub.at.objects.ATBoolean;
 37import edu.vub.at.objects.ATClosure;
 38import edu.vub.at.objects.ATNil;
 39import edu.vub.at.objects.ATNumber;
 40import edu.vub.at.objects.ATNumeric;
 41import edu.vub.at.objects.ATObject;
 42import edu.vub.at.objects.ATTable;
 43import edu.vub.at.objects.ATText;
 44import edu.vub.at.objects.coercion.NativeTypeTags;
 45import edu.vub.at.objects.natives.grammar.AGExpression;
 46import edu.vub.util.Regexp;
 47import edu.vub.util.TempFieldGenerator;
 48
 49import org.apache.regexp.RE;
 50import org.apache.regexp.RESyntaxException;
 51
 52/*
 53import java.util.regex.Matcher;
 54import java.util.regex.Pattern;
 55import java.util.regex.PatternSyntaxException;
 56*/
 57
 58/**
 59 * The native implementation of an AmbientTalk text string.
 60 * A text string is implemented by a Java String.
 61 * 
 62 * @author tvcutsem
 63 */
 64public final class NATText extends AGExpression implements ATText {
 65		
 66	    /** Text is represented as Java String */
 67		public final String javaValue;
 68		
 69		/**
 70		 * This method currently serves as a hook for text creation.
 71		 * Currently text objects are not reused, but this might change in the future.
 72		 */
 73		public static final NATText atValue(String javaString) {
 74			return new NATText(javaString);
 75		}
 76		
 77		private NATText(String javaString) {
 78			javaValue = javaString;
 79		}
 80
 81		public boolean isNativeText() { return true; }
 82		public NATText asNativeText() throws XTypeMismatch { return this; }
 83		
 84		public NATText meta_print() throws InterpreterException {
 85	        return NATText.atValue("\"" + javaValue + "\"");
 86		}
 87		
 88		public NATText impl_asCode(TempFieldGenerator objectMap) throws InterpreterException {
 89	        return NATText.atValue("\"" + javaValue + "\"");
 90		}
 91		
 92		public ATObject meta_clone() throws InterpreterException {
 93			return this;
 94		}
 95		
 96	    public ATTable meta_typeTags() throws InterpreterException {
 97	    	return NATTable.of(NativeTypeTags._TEXT_, NativeTypeTags._ISOLATE_);
 98	    }
 99		
100		// comparison and identity operations
101		
102	    public ATBoolean base__opeql__opeql_(ATObject comparand) throws InterpreterException {
103	    	if (comparand.isNativeText()) {
104	    		return NATBoolean.atValue(javaValue.equals(comparand.asNativeText().javaValue));
105	    	} else {
106	    		return NATBoolean._FALSE_;
107	    	}
108	    }
109		
110		public int hashCode() {
111			return javaValue.hashCode();
112		}
113		
114		// base-level interface
115		
116		/**
117		 * Explodes a text string into a table of constinuent characters
118		 */
119		public ATTable base_explode() throws InterpreterException {
120			ATObject[] chars = new ATObject[javaValue.length()];
121			char[] rawchars = javaValue.toCharArray();
122			for (int i = 0; i < chars.length; i++) {
123				chars[i] = NATText.atValue(new Character(rawchars[i]).toString());
124			}
125			return NATTable.atValue(chars);
126		}
127		
128		/**
129		 * Split the string according to the given regular expression.
130		 * For regular expression syntax, see the Apache Regexp API of class {@link RE}.
131		 */
132		public ATTable base_split(ATText regexp) throws InterpreterException {
133			 try {
134				 String[] elements = new RE(Regexp.compile(regexp.asNativeText().javaValue)).split(javaValue);
135				 ATObject[] tbl = new ATObject[elements.length];
136				 for (int i = 0; i < elements.length; i++) {
137					 tbl[i] = NATText.atValue(elements[i]);
138				 }
139				 return NATTable.atValue(tbl);
140			 } catch (RESyntaxException e) {
141				throw new XIllegalArgument("Illegal argument to split: " + e.getMessage());
142			 }
143		}
144		
145		public ATNil base_find_do_(ATText regexp, final ATClosure consumer) throws InterpreterException {
146			 try {
147				 RE pattern = new RE(Regexp.compile(regexp.asNativeText().javaValue));
148				 Regexp.findAll(pattern, javaValue, new Regexp.StringRunnable() {
149					 public void run(String match) throws InterpreterException {
150						 consumer.base_apply(NATTable.atValue(new ATObject[] { NATText.atValue(match) }));
151					 }
152				 });
153				 return Evaluator.getNil();
154			 } catch (RESyntaxException e) {
155				throw new XIllegalArgument("Illegal argument to find:do: " + e.getMessage());
156			 }
157		}
158		
159		public ATText base_replace_by_(ATText regexp, final ATClosure transformer) throws InterpreterException {
160			 try {
161				 RE pattern = new RE(Regexp.compile(regexp.asNativeText().javaValue));
162				 return NATText.atValue(Regexp.replaceAll(pattern, javaValue, new Regexp.StringCallable() {
163					 public String call(String match) throws InterpreterException {
164						 ATObject replacement = transformer.base_apply(NATTable.atValue(new ATObject[] { NATText.atValue(match) }));
165						 return replacement.asNativeText().javaValue;
166					 }
167				 }));
168			 } catch (RESyntaxException e) {
169				throw new XIllegalArgument("Illegal argument to replace:by: " + e.getMessage());
170			 }
171		}
172		
173		public ATText base_toUpperCase() {
174			return NATText.atValue(javaValue.toUpperCase());
175		}
176		
177		public ATText base_toLowerCase() {
178			return NATText.atValue(javaValue.toLowerCase());
179		}
180		
181		public ATNumber base_length() {
182			return NATNumber.atValue(javaValue.length());
183		}
184		
185		public ATText base__oppls_(ATObject other) throws InterpreterException {
186			return NATText.atValue(javaValue +
187					(other.isNativeText() ? other.asNativeText().javaValue : other.meta_print().javaValue));
188		}
189		
190		public ATNumber base__opltx__opeql__opgtx_(ATText other) throws InterpreterException {
191			int cmp = javaValue.compareTo(other.asNativeText().javaValue);
192			if (cmp > 0)
193			    return NATNumber.ONE;
194			else if (cmp < 0)
195				return NATNumber.MONE;
196			else
197				return NATNumber.ZERO;
198		}
199		
200		public ATBoolean base__optil__opeql_(ATText regexp) throws InterpreterException {
201			try {
202				return NATBoolean.atValue(new RE(Regexp.compile(regexp.asNativeText().javaValue)).match(javaValue));
203			} catch (RESyntaxException e) {
204				throw new XIllegalArgument("Illegal regular expression for ~=: " + e.getMessage());
205			}
206		}
207		
208		public ATNumeric base_parseNumeric() throws InterpreterException {
209			try {
210				return NATNumber.atValue(Integer.parseInt(javaValue));
211			} catch(NumberFormatException e) {
212				try {
213					return NATFraction.atValue(Double.parseDouble(javaValue));
214				} catch(NumberFormatException e2) {
215					throw new XIllegalArgument("Cannot convert "+javaValue+" into a numeric object");
216				}
217			}
218		}
219		
220		public ATNumber base_toNumber() throws InterpreterException {
221			if (javaValue.length() == 1) {
222				return NATNumber.atValue(Character.getNumericValue(javaValue.charAt(0)));
223			} else {
224				throw new XTypeMismatch(Character.class, this);
225			}
226		}
227		
228		/** Convert this text into a Java character */
229		public char asChar() throws XTypeMismatch {
230			if (javaValue.length() == 1) {
231				return javaValue.charAt(0);
232			} else {
233				throw new XTypeMismatch(Character.class, this);
234			}
235		}
236
237}