Aspect-oriented programming (AOP) such as AspectJ, were proposed to support modularization of crosscutting concerns. Recently, there have been many research efforts on adopting aspect-oriented programming to product line implementation. The main idea is to implement variations as separate aspects and to obtain each product by weaving base code and aspect code.
Base Code
interface Exp {
public int eval (Env env) throws Exception;
public Exp check (Env env) throws Exception;
}
class Num implements Exp {
protected final int num;
Num (int n) { num = n; }
public int eval(Env env) { return num; }
public Exp check(Env env) { return this; }
}
class Var implements Exp {
protected final String var;
Var (String v) { var = v; }
public int eval(Env env) throws Exception {
return env.find(var);
}
public Exp check(Env env) throws Exception {
env.find(var);
return this;
}
}
class Plus implements Exp {
protected Exp left, right;
Plus (Exp l, Exp r) { left = l; right = r; }
public int eval(Env env) throws Exception {
return (left.eval(env) + right.eval(env));
}
public Exp check(Env env) throws Exception {
left.check(env);
right.check(env);
return this;
}
}
class Let implements Exp {
protected final String var;
protected Exp let;
protected Exp body;
Let(String v, Exp l, Exp b) { var = v; let = l; body = b; }
public int eval(Env env) throws Exception {
return body.eval(env.bind(var, let.eval(env)));
}
public Exp check(Env env) throws Exception {
let.check(env);
body.check(env.bind (var, 0));
return this;
}
// Test
public class Base {
public void eval(Exp e) {
try {
System.out.println((e.check(new Env())).eval (new Env()));
} catch (Exception ex) {
System.out.println("unbounded variable:"+ex);
}
}
public static void main(String[] args) {
Base interp = new Base ();
interp.eval(new Plus (new Num (1), new Num (2)));
interp.eval(new Let ("x", new Num (1), new Var ("x")));
interp.eval(new Let ("x", new Num (1), new Plus (new Var ("x"), new Num (5))));
}
}
Aspect Code
The base code gives basic interpreter while aspect code woven with base code gives an optimized interpter.
/*
* ajc Base.java BaseOpt.aj
* java Base
*/
public aspect BaseOpt {
// inteface
public abstract Exp Exp.opt () throws Exception;
// class
public Exp Num.opt() { return this; }
public Exp Var.opt() { return this; }
public Exp Plus.opt() throws Exception {
left = left.opt();
right = right.opt();
if (left instanceof Num && right instanceof Num) {
return new Num(left.eval(new Env()) + right.eval(new Env()));
}
return this;
}
public Exp Let.opt() throws Exception {
let = let.opt();
body = body.opt();
return this;
}
// add test
pointcut main() :
execution(public static void main(String[]));
after() returning : main() {
System.out.println("Hello from Aspect");
}
// add Opt
pointcut Opt(Base b):
execution (public void Base.eval(Exp))
&& target (b);
void around(Base b, Exp e) : Opt(b) && args(e) {
try {
System.out.println(((e.check(new Env())).opt()).eval (new Env()));
} catch (Exception ex) {
System.out.println("unbounded variable:"+ex);
}
}
}
Compilation
ajc Base.java BaseOpt.aj
Go to home
