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