PageRenderTime 49ms CodeModel.GetById 37ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

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

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