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));
}
}