PageRenderTime 35ms CodeModel.GetById 15ms app.highlight 16ms RepoModel.GetById 1ms app.codeStats 0ms

/interpreter/tags/at2-build270707/src/edu/vub/at/objects/natives/NATText.java

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