HomeDigital EditionSys-Con RadioSearch Java Cd
Advanced Java AWT Book Reviews/Excerpts Client Server Corba Editorials Embedded Java Enterprise Java IDE's Industry Watch Integration Interviews Java Applet Java & Databases Java & Web Services Java Fundamentals Java Native Interface Java Servlets Java Beans J2ME Libraries .NET Object Orientation Observations/IMHO Product Reviews Scalability & Performance Security Server Side Source Code Straight Talking Swing Threads Using Java with others Wireless XML

"Design Patterns in a Java Interpreter"
Volume: 4 Issue: 1, p. 24


Listing 1: List.Eval()

public SchemeObject Eval(Environment env)
    throws SchemeException
    SchemeObject f = car.Eval(env);
// evaluate syntactical forms first:
    if(f instanceof SyntacticalForm)
        if(f == TraceOn)       trace_on = true;
        else if(f == TraceOff) trace_on = false;
// pass the args to syntactical forms without evaluating them!
        else return f.Apply(cdr, env); 

        throw new SpecialFormException(f.Print());
// else ordinary function application:
// we don't have to check whether f is a function --
//  f will throw an exception if it's not and its
//  apply method is called
        else return f.Apply(cdr.Evargs(env), env);

Listing 2: List.Print() 

public String Print()
// if the first item is null, simply print it
// Nullp (null predicate) returns true or false depending on whether
//  the object is or isn't null
    if(car.Nullp()) return car.Print();
    else            return "( " + aux_print() + " )";
protected String aux_print()
    StringBuffer s = new StringBuffer(car.Print());
        s.append(" ");
// Listp (list predicate) returns true or false depending on whether
//  the object is or isn't a list
        if(cdr.Listp()) s.append(cdr.aux_print());
        else            s.append(". " + cdr.Print());
    return s.toString();

Listing 3: SchemeObject.make()

// part of the source of this method:
public static final SchemeObject make(LispTerminal lisp_term, int
    context, Environment lenv)
    throws SchemeException
    int    c = 0;
    SchemeToken token = lisp_term.getToken();
        case START:
                case SchemeToken.QUOTE_MACRO:
// this case expands '(a b c) to (quote (a b c))
                    return new List(Quote,
                        new List(SchemeObject.make(lisp_term,
                            START, lenv), False));
                case SchemeToken.OPEN_PAREN:
                    SchemeToken next_token = lisp_term.getToken();
                    if(next_token.getType() == SchemeToken.CLOSE_PAREN)
                        return False;
                    else if((next_token.getText()).equals(
                        SchemeObject rep = new Lambda(lisp_term, lenv);
                        if((lisp_term.getToken()).getType() != 
                            throw new SchemeException
                        return rep;
                    else if((next_token.getText()).equals(
                        SchemeObject rep = new Let(lisp_term, lenv);
                        return rep;
// other syntactical forms are handled here with more
//  else-if constructs -- we've omitted them for brevity's sake
// the else case below means we have an ordinary list in hand:
// put the next token back, then ask a list to create itself
//  off of the input stream:
                        return new List(lisp_term, lenv);
                case SchemeToken.CHAR:
                    return new CharRep((token.getText()).charAt(0));
                case SchemeToken.INT:
                    return new IntRep(Long.parseLong(token.getText()));
                case SchemeToken.STRING:
                    return new StringRep(token.getText());

Listing 4: Append

// functor to append to a list
// our implementation of append uses the traditional Lisp
//  technique of auxilliary functions.
//  The code here is directly translated from R. Kent Dybvig's
//  Scheme implementation of append in
//  "The Scheme Programming Language."
//  Instead of an explicit loop, we use recursive function
//  calls to "straighten out" the lists of lists in args
//  into one list.
class Append extends BuiltIn
public SchemeObject Apply(SchemeObject args, Environment env)
       throws SchemeException
// SchemeObject.False is our null value
    return appaux1(SchemeObject.False, args);
private static final SchemeObject appaux1(SchemeObject ls,
    SchemeObject args)
    throws SchemeException
// if we have no more args, just return ls
    if(args.Nullp()) return ls;
// else we DO have args, so use appaux2 to append them
    else             return appaux2(ls, args);
private static final SchemeObject appaux2(SchemeObject ls,
    SchemeObject args)
    throws SchemeException
        return(appaux1(args.first(), args.restl()));
            ls.first(), appaux2(ls.restl(), args)));

Listing 5: LispTerminal

abstract public class LispTerminal
public LispTerminal();
abstract public void print(String s);
abstract public void print(Object obj);
abstract public void println(Object obj);
abstract public int read();
abstract public void unread(int c);
abstract public boolean eof();


All Rights Reserved
Copyright ©  2004 SYS-CON Media, Inc.
  E-mail: [email protected]

Java and Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. SYS-CON Publications, Inc. is independent of Sun Microsystems, Inc.