// File: Scheme.java
// Date: 7/4/2008
package org.bot.jscheme;
/**
* This class represents a Scheme interpreter.
* See http://www.norvig.com/jscheme.html for more documentation.
*
* @author Berlin Brown (refactoring modifications)
* @author Peter Norvig, peter@norvig.com http://www.norvig.com
* Copyright 1998 Peter Norvig, see http://www.norvig.com/license.html
*/
public class Scheme {
private Environment globalEnvironment = new Environment();
public static void main(final String [] args) {
System.out.println("Running Interpreter");
}
public Object eval(Object x) {
return eval(x, this.globalEnvironment);
}
public Object eval(Object x, Environment env) {
while (true) {
if (x instanceof String) {
// VARIABLE
System.out.println("trace: eval - instance of String: " + x);
// Look up a variable or a procedure (built in function).
return env.lookup((String) x);
} else if (!(x instanceof Pair)) {
// CONSTANT
System.out.println("trace: eval - instance of Pair =>" + x);
return x;
} else {
// Procedure Call
System.out.println("trace: eval[t1] - instance of procedure call");
Object fn = SchemeUtil.first(x);
Object args = SchemeUtil.rest(x);
System.out.println("trace: eval[t2] - fn => [" + fn + "] args => " + args);
fn = eval(fn, env);
// Coerce the object to a procedure (E.g. '+/add' procedure)
Procedure p = Procedure.proc(fn);
return p.apply(this, evalList(args, env));
} // End of if - else
} // End of While
} // End of Method
public Pair evalList(Object list, Environment env) {
if (list == null)
return null;
else if (!(list instanceof Pair)) {
final String msg = "Illegal arg list: " + list;
System.err.println(msg);
throw new RuntimeException(msg);
} else {
final Object first = eval(SchemeUtil.first(list), env);
final Object rest = evalList(SchemeUtil.rest(list), env);
return SchemeUtil.cons(first, rest);
}
}
}