package jscheme; /** @author Peter Norvig, peter@norvig.com http://www.norvig.com * Copyright 1998 Peter Norvig, see http://www.norvig.com/license.html **/ public class Macro extends Closure { /** Make a macro from a parameter list, body, and environment. **/ public Macro (Object parms, Object body, Environment env) { super(parms, body, env); } /** Replace the old cons cell with the macro expansion, and return it. **/ public Pair expand(Scheme interpreter, Pair oldPair, Object args) { Object expansion = apply(interpreter, args); if (expansion instanceof Pair) { oldPair.first = ((Pair)expansion).first; oldPair.rest = ((Pair)expansion).rest; } else { oldPair.first = "begin"; oldPair.rest = cons(expansion, null); } return oldPair; } /** Macro expand an expression **/ public static Object macroExpand(Scheme interpreter, Object x) { if (!(x instanceof Pair)) return x; Object fn = interpreter.eval(first(x), interpreter.globalEnvironment); if (!(fn instanceof Macro)) return x; return ((Macro)fn).expand(interpreter, (Pair)x, rest(x)); } }