package edu.neu.ccs.demeterf.examples; import edu.neu.ccs.demeterf.*; /** Type unification test. We can unify an arbitrary recursive object * structure. We use TUCombiner to fund the count/sum/product of nested * arithmetic expressions. */ public class TUTest{ static void print(String s){ System.out.println(s); } static public void main(String[] args){ Exp p = new Bin(new Div(), new Bin(new Plus(), new Bin(new Plus(), new Bin(new Times(),new Num(9),new Num(6)),new Num(8)), new Bin(new Minus(),new Num(5),new Num(7))),new Num(4)); print(" Before: "+p); print(" Sum[39]: "+new Add().traverse(p)); print(" Mult[60480]: "+new Mult().traverse(p)); print(" Count[6]: "+new Count().traverse(p)); } // Count the number of Leafs static class Count extends TU{ public Integer fold(Integer i, Integer j){ return i+j; } public Integer combine(){ return 0; } int combine(Num i){ return 1; } } // Adds all the Leafs (SUM) static class Add extends Count{ int combine(Num i){ return i.num; } } // Multiply all the Leafs static class Mult extends Add{ public Integer fold(Integer i, Integer j){ return i*j; } public Integer combine(){ return 1; } } // Simple Arithmetic Expressions static abstract class Exp{ public String toString(){ return new Traversal(new ID(){ String combine(Num n, int i){ return ""+i; } String combine(Bin b, String op, String l, String r){ return "("+l+" "+op+" "+r+")"; } String combine(Plus p){ return "+"; } String combine(Minus p){ return "-"; } String combine(Times p){ return "*"; } String combine(Div p){ return "/"; } }).traverse(this); } } // Integer Literals static class Num extends Exp{ int num; Num(int i){ num = i; } public String toString(){ return ""+num; } } // The usual operators for Binary Expressions... static class Bin extends Exp{ Op op; Exp left, right; Bin(Op o, Exp l, Exp r){ op = o; left = l; right = r; } } static abstract class Op{} static class Plus extends Op{} static class Minus extends Op{} static class Times extends Op{} static class Div extends Op{} }