/parser/branches/proteus_annotations/branches/expander-macros/test/edu/vub/at/parser/ATWalkerTest.java

http://ambienttalk.googlecode.com/ · Java · 226 lines · 193 code · 22 blank · 11 comment · 1 complexity · 3aa140eb0d25e5cd08dacd8649a469d4 MD5 · raw file

  1. package edu.vub.at.parser;
  2. import edu.vub.at.objects.natives.grammar.NATAbstractGrammar;
  3. import edu.vub.util.Matcher;
  4. import edu.vub.util.Pattern;
  5. import edu.vub.util.PatternSyntaxException;
  6. import java.io.ByteArrayInputStream;
  7. import junit.framework.TestCase;
  8. import antlr.CharStreamException;
  9. import antlr.CommonAST;
  10. import antlr.TokenStreamException;
  11. public class ATWalkerTest extends TestCase {
  12. public static void main(String[] args) {
  13. junit.swingui.TestRunner.run(ATWalkerTest.class);
  14. }
  15. /**
  16. * Replace all occurences of the regular expression match 'regex' in 'input' by 'replacement'.
  17. * @return the output string with all occurences replaced.
  18. */
  19. public static String replaceAll(String input, String regex, String replacement) throws PatternSyntaxException {
  20. try {
  21. Pattern p = Pattern.compile(regex);
  22. Matcher m = p.matcher(new StringBuffer(input));
  23. StringBuffer sb = new StringBuffer();
  24. while (m.find()) {
  25. m.appendReplacement(sb, replacement);
  26. }
  27. m.appendTail(sb);
  28. return sb.toString();
  29. } catch (PatternSyntaxException e) {
  30. e.printStackTrace();
  31. return null;
  32. }
  33. }
  34. private void testWalker(String walkerInput) {
  35. testWalker(walkerInput, walkerInput);
  36. }
  37. private void testWalker(String input, String output) {
  38. try {
  39. LexerImpl lexer = new LexerImpl(new ByteArrayInputStream(input.getBytes()));
  40. ParserImpl parser = new ParserImpl(lexer);
  41. // Parse the input expression
  42. parser.program();
  43. CommonAST t = (CommonAST)parser.getAST();
  44. // Print the resulting tree out in LISP notation
  45. System.out.println(t.toStringList());
  46. TreeWalkerImpl walker = new TreeWalkerImpl();
  47. // Traverse the tree created by the parser
  48. NATAbstractGrammar ag = walker.program(t);
  49. // Backport from JDK 1.4 to 1.3
  50. assertEquals(replaceAll(output, "\\s", ""), replaceAll(ag.meta_print().javaValue, "\\s", ""));
  51. //assertEquals(output.replaceAll("\\s",""), ag.meta_print().javaValue.replaceAll("\\s",""));
  52. } catch(Exception e) {
  53. e.printStackTrace();
  54. fail("exception: "+e);
  55. }
  56. }
  57. public void testStatementGrammar() {
  58. testWalker("a; b; c");
  59. testWalker("def x", "def x := nil");
  60. testWalker("def x := 5");
  61. testWalker("def o.x", "def o.x := nil");
  62. testWalker("def o.x := 5");
  63. testWalker("def self.x := 5");
  64. testWalker("def f(a,b)", "def f(a,b) { nil }");
  65. testWalker("def f(a,b) { 5 }");
  66. testWalker("def foo:=(a)", "def foo:=(a) { nil }");
  67. testWalker("def foo: x bar: y", "def foo:bar:(x,y) { nil }");
  68. testWalker("def foo: x bar: y { 5 }", "def foo:bar:(x,y) { 5 }");
  69. testWalker("def o.f(a,b)", "def o.f(a,b) { nil }");
  70. testWalker("def self.f(a,b)", "def self.f(a,b) { nil }");
  71. testWalker("def o.f(a,b) { 5 }");
  72. testWalker("def o.foo: x bar: y", "def o.foo:bar:(x,y) { nil }");
  73. testWalker("def o.foo: x bar: y { 5 }", "def o.foo:bar:(x,y) { 5 }");
  74. testWalker("def t[5]", "def t[5] { nil }");
  75. testWalker("def t[5] { a }");
  76. testWalker("def t[5] { i := i + 1 }", "def t[5] { i := i.+(1) }");
  77. testWalker("def [x, y]", "def [x, y] := [ nil, nil ]");
  78. testWalker("def [x, y] := [y, x]");
  79. testWalker("x := 7");
  80. testWalker("x[5] := 7");
  81. testWalker("o.m := x");
  82. testWalker("[x, y] := [y, x]");
  83. testWalker("[x, y := 1] := a");
  84. testWalker("deftype foo");
  85. testWalker("deftype foo <: bar");
  86. testWalker("deftype foo <: bar, x", "deftype foo <: bar, x");
  87. testWalker("import o alias a := b, c := d exclude e, f");
  88. testWalker("import o.m()");
  89. testWalker("import o alias a: := b:c:");
  90. testWalker("import o exclude e");
  91. }
  92. public void testExpressionGrammar() {
  93. testWalker("o.m(a,b)");
  94. testWalker("o<-m(a,b)");
  95. testWalker("o.foo: a bar: b", "o.foo:bar:(a,b)");
  96. testWalker("o<-foo: a bar: b", "o<-foo:bar:(a,b)");
  97. testWalker("super.m(a)");
  98. testWalker("m(a,b)");
  99. testWalker("f()");
  100. testWalker("o.m");
  101. testWalker("o.&m");
  102. testWalker("o.&m:=");
  103. testWalker(".m(a,b)");
  104. testWalker(".x");
  105. testWalker("<-m(a,b)");
  106. testWalker("^m(a,b)");
  107. testWalker("t[a]");
  108. testWalker("f()[a+b]", "f()[a.+(b)]");
  109. testWalker("a");
  110. testWalker("o<+.m()","o.m()");
  111. testWalker("o<+foo()","o<+foo()");
  112. testWalker("o<+^foo()","o^foo()");
  113. testWalker("obj^m(a)");
  114. testWalker("&x","&x");
  115. testWalker("&x:=","&x:=");
  116. }
  117. public void testQuasiquoting() {
  118. testWalker("`(x)");
  119. testWalker("`(t[a].+(1))");
  120. testWalker("#(t[a].+(1))");
  121. testWalker("#@(t[a].+(1))");
  122. testWalker("`t[a] + 1", "`(t)[a].+(1)");
  123. testWalker("`(t[a]) + 1", "`(t[a]).+(1)");
  124. testWalker("#t[a] + 1", "#(t)[a].+(1)");
  125. testWalker("#@t[a] + 1", "#@(t)[a].+(1)");
  126. testWalker("`{ def x := 5 }", "`( def x := 5 )");
  127. testWalker("`({ def x := 5 })");
  128. testWalker("`foo:","`(foo:)");
  129. testWalker("`foo:bar:","`(foo:bar:)");
  130. testWalker("`foo:=","`(foo:=)");
  131. testWalker("`{ def #(name) }", "`(def #(name) := nil)");
  132. testWalker("`{ def #(name) := value }", "`( def #(name) := value )");
  133. testWalker("`{ def #(name) ( @args ); }", "`( def #(name) ( @args ) { nil } )");
  134. testWalker("`{ def #(name) ( @args ) { system.println(args); }; }", "`( def #(name) ( @args ) { system.println(args) } )");
  135. testWalker("`{ def key: #(name) word: args; }", "`(def key:word: ( #(name), args ) { nil } )");
  136. testWalker("`{ def #(name) [ 5 ] }", "`( def #(name) [ 5 ] { nil } )");
  137. testWalker("`{ def #(name) [ 5 ] { random(); } }", "`( def #(name) [ 5 ] { random() } )");
  138. // testWalker("`{ def [ #(name), cancel ]; }", "`( def [ #(name), cancel ] := [ nil, nil ] )");
  139. // testWalker("`{ def [ #(name), cancel ] := [ true, false ]; }", "`( def [ #(name), cancel ] := [ true, false ]; )");
  140. testWalker("`{ def #(object) . #(name) }", "`(def #(object) . #(name) := nil )");
  141. testWalker("`{ def #(object) . #(name) ( @args ); }", "`(def #(object) . #(name) ( @args ) { nil } )");
  142. testWalker("`{ #(name) ( @args ); }", "`( #(name) ( @args ))");
  143. testWalker("`{ #(receiver) . #(name) ( @args ); }", "`( #(receiver) . #(name) ( @args ))");
  144. testWalker("`{ #(receiver) ^ #(name) ( @args ); }", "`( #(receiver) ^ #(name) ( @args ))");
  145. testWalker("`{ #(receiver) <- #(name) ( @args ); }", "`( #(receiver) <- #(name) ( @args ))");
  146. testWalker("`{ def foo(#@(`([a]))) { #@([1]) }}", "`(def foo (#@( `([a]) )) { #@([1]) })");
  147. }
  148. public void testOperatorGrammar() {
  149. testWalker("1 + 2 + 3", "1.+(2).+(3)");
  150. testWalker("a * b!3 + c < d / e - f", "a.*(b.!(3)).+(c).<(d./(e).-(f))");
  151. testWalker("+(1,2)");
  152. testWalker("a.+(2)");
  153. testWalker("+.m(1)");
  154. testWalker("+.m");
  155. testWalker("+.&m");
  156. testWalker("m.+");
  157. testWalker("m.&+");
  158. testWalker("-1", "-(1)");
  159. testWalker("-t[5]","-(t[5])");
  160. testWalker("-5 + a", "-(5).+(a)");
  161. testWalker("/");
  162. testWalker("/.at");
  163. testWalker("~.test");
  164. }
  165. public void testLiteralGrammar() {
  166. testWalker("-12345","-(12345)");
  167. testWalker("1.05");
  168. testWalker("-5.04e-10","-(5.04E-10)");
  169. testWalker("\"hello \\tworld\"", "\"hello \tworld\"");
  170. testWalker("[a,b,c]");
  171. testWalker("[]");
  172. testWalker("{ | x, y | x.+(y) }");
  173. testWalker("{ a := 2; b }");
  174. }
  175. public void testSplice() {
  176. testWalker("def f(x,@y) { 1 }");
  177. testWalker("def foo: x bar: @y { 1 }", "def foo:bar:(x, @y) { 1 }");
  178. testWalker("[x, @y] := t");
  179. testWalker("f(1,@[2,3])");
  180. testWalker("foo: 1 bar: @[2,3]", "foo:bar:(1, @[2,3])");
  181. testWalker("[x, @[y,z], u, @v]");
  182. testWalker("[x, @y] := [u, v, w]");
  183. }
  184. public void testCurriedInvocations() {
  185. testWalker("closures.at(closures.length)()");
  186. testWalker("closures[closures.length]()");
  187. }
  188. public void testOptionalArgs() {
  189. testWalker("def foo(x := 5) { 1 }");
  190. testWalker("def foo(x, y := 1+2, @z) { 1 }", "def foo(x, y := 1.+(2), @z) { 1 }");
  191. testWalker("def foo(x := #5) { 1 }", "def foo(x := #(5)) { 1 }");
  192. }
  193. public void testAnnotations() {
  194. testWalker("o.m(1)@[]", "o.m(1)");
  195. testWalker("o.m(1)@x");
  196. testWalker("o^m(1)@x");
  197. testWalker("o<-m(1)@x");
  198. testWalker("o.m(1)@[x,y]");
  199. }
  200. public void testMacro() throws TokenStreamException, CharStreamException {
  201. testWalker("defmacro expandThisSymbol := id(17)");
  202. testWalker("defmacro case: expression { case: { expression } }", "defmacro case:(expression) { case:({ expression }) }");
  203. }
  204. }