Changeset 4078


Ignore:
Timestamp:
09/26/03 18:48:00 (20 years ago)
Author:
piso
Message:

eval(): catch ConditionThrowable? and save backtrace.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/j/src/org/armedbear/lisp/Lisp.java

    r4059 r4078  
    33 *
    44 * Copyright (C) 2002-2003 Peter Graves
    5  * $Id: Lisp.java,v 1.151 2003-09-25 18:20:57 piso Exp $
     5 * $Id: Lisp.java,v 1.152 2003-09-26 18:48:00 piso Exp $
    66 *
    77 * This program is free software; you can redistribute it and/or
     
    269269        throws ConditionThrowable
    270270    {
    271         thread.clearValues();
    272         if (thread.isDestroyed())
    273             throw new ThreadDestroyed();
    274         if (obj instanceof Symbol) {
    275             LispObject result = null;
    276             if (obj.isSpecialVariable()) {
    277                 result = thread.lookupSpecial(obj);
     271        try {
     272            thread.clearValues();
     273            if (thread.isDestroyed())
     274                throw new ThreadDestroyed();
     275            if (obj instanceof Symbol) {
     276                LispObject result = null;
     277                if (obj.isSpecialVariable()) {
     278                    result = thread.lookupSpecial(obj);
     279                } else
     280                    result = env.lookup(obj);
     281                if (result == null) {
     282                    result = obj.getSymbolValue();
     283                    if (result == null)
     284                        throw new ConditionThrowable(new UnboundVariable(obj));
     285                }
     286                return result;
     287            } else if (obj instanceof Cons) {
     288                LispObject first = obj.car();
     289                if (first instanceof Symbol) {
     290                    LispObject fun = env.lookupFunctional(first);
     291                    if (fun == null)
     292                        throw new ConditionThrowable(new UndefinedFunction(first));
     293                    switch (fun.getFunctionalType()) {
     294                        case FTYPE_SPECIAL_OPERATOR: {
     295                            if (profiling)
     296                                fun.incrementCallCount();
     297                            // Don't eval args!
     298                            return fun.execute(obj.cdr(), env);
     299                        }
     300                        case FTYPE_MACRO:
     301                            return eval(macroexpand(obj, env, thread), env, thread);
     302                        case FTYPE_AUTOLOAD: {
     303                            Autoload autoload = (Autoload) fun;
     304                            autoload.load();
     305                            return eval(obj, env, thread);
     306                        }
     307                        default: {
     308                            if (debug)
     309                                return funcall(fun,
     310                                               evalList(obj.cdr(), env, thread),
     311                                               thread);
     312                            if (profiling)
     313                                fun.incrementCallCount();
     314                            LispObject args = obj.cdr();
     315                            if (args == NIL)
     316                                return fun.execute();
     317                            LispObject arg1 = args.car();
     318                            args = args.cdr();
     319                            if (args == NIL)
     320                                return fun.execute(thread.value(eval(arg1, env, thread)));
     321                            LispObject arg2 = args.car();
     322                            args = args.cdr();
     323                            if (args == NIL)
     324                                return fun.execute(eval(arg1, env, thread),
     325                                                   thread.value(eval(arg2, env, thread)));
     326                            LispObject arg3 = args.car();
     327                            args = args.cdr();
     328                            if (args == NIL)
     329                                return fun.execute(eval(arg1, env, thread),
     330                                                   eval(arg2, env, thread),
     331                                                   thread.value(eval(arg3, env, thread)));
     332                            // More than 3 arguments.
     333                            final int length = args.length() + 3;
     334                            LispObject[] results = new LispObject[length];
     335                            results[0] = eval(arg1, env, thread);
     336                            results[1] = eval(arg2, env, thread);
     337                            results[2] = eval(arg3, env, thread);
     338                            for (int i = 3; i < length; i++) {
     339                                results[i] = eval(args.car(), env, thread);
     340                                args = args.cdr();
     341                            }
     342                            thread.clearValues();
     343                            return fun.execute(results);
     344                        }
     345                    }
     346                } else {
     347                    LispObject args = obj.cdr();
     348                    if (!args.listp())
     349                        throw new ConditionThrowable(new TypeError(args, "list"));
     350                    LispObject funcar = first.car();
     351                    LispObject rest = first.cdr();
     352                    Symbol symbol = checkSymbol(funcar);
     353                    if (symbol == Symbol.LAMBDA) {
     354                        Closure closure = new Closure(rest.car(), rest.cdr(), env);
     355                        return closure.execute(evalList(args, env, thread));
     356                    } else
     357                        throw new ConditionThrowable(new ProgramError("illegal function object: " + first));
     358                }
    278359            } else
    279                 result = env.lookup(obj);
    280             if (result == null) {
    281                 result = obj.getSymbolValue();
    282                 if (result == null)
    283                     throw new ConditionThrowable(new UnboundVariable(obj));
     360                return obj;
     361        }
     362        catch (ConditionThrowable t) {
     363            if (debug) {
     364                Symbol savedBacktrace = intern("*SAVED-BACKTRACE*", PACKAGE_EXT);
     365                savedBacktrace.setSymbolValue(thread.backtraceAsList(0));
    284366            }
    285             return result;
    286         } else if (obj instanceof Cons) {
    287             LispObject first = obj.car();
    288             if (first instanceof Symbol) {
    289                 LispObject fun = env.lookupFunctional(first);
    290                 if (fun == null)
    291                     throw new ConditionThrowable(new UndefinedFunction(first));
    292                 switch (fun.getFunctionalType()) {
    293                     case FTYPE_SPECIAL_OPERATOR: {
    294                         if (profiling)
    295                             fun.incrementCallCount();
    296                         // Don't eval args!
    297                         return fun.execute(obj.cdr(), env);
    298                     }
    299                     case FTYPE_MACRO:
    300                         return eval(macroexpand(obj, env, thread), env, thread);
    301                     case FTYPE_AUTOLOAD: {
    302                         Autoload autoload = (Autoload) fun;
    303                         autoload.load();
    304                         return eval(obj, env, thread);
    305                     }
    306                     default: {
    307                         if (debug)
    308                             return funcall(fun,
    309                                            evalList(obj.cdr(), env, thread),
    310                                            thread);
    311                         if (profiling)
    312                             fun.incrementCallCount();
    313                         LispObject args = obj.cdr();
    314                         if (args == NIL)
    315                             return fun.execute();
    316                         LispObject arg1 = args.car();
    317                         args = args.cdr();
    318                         if (args == NIL)
    319                             return fun.execute(thread.value(eval(arg1, env, thread)));
    320                         LispObject arg2 = args.car();
    321                         args = args.cdr();
    322                         if (args == NIL)
    323                             return fun.execute(eval(arg1, env, thread),
    324                                                thread.value(eval(arg2, env, thread)));
    325                         LispObject arg3 = args.car();
    326                         args = args.cdr();
    327                         if (args == NIL)
    328                             return fun.execute(eval(arg1, env, thread),
    329                                                eval(arg2, env, thread),
    330                                                thread.value(eval(arg3, env, thread)));
    331                         // More than 3 arguments.
    332                         final int length = args.length() + 3;
    333                         LispObject[] results = new LispObject[length];
    334                         results[0] = eval(arg1, env, thread);
    335                         results[1] = eval(arg2, env, thread);
    336                         results[2] = eval(arg3, env, thread);
    337                         for (int i = 3; i < length; i++) {
    338                             results[i] = eval(args.car(), env, thread);
    339                             args = args.cdr();
    340                         }
    341                         thread.clearValues();
    342                         return fun.execute(results);
    343                     }
    344                 }
    345             } else {
    346                 LispObject args = obj.cdr();
    347                 if (!args.listp())
    348                     throw new ConditionThrowable(new TypeError(args, "list"));
    349                 LispObject funcar = first.car();
    350                 LispObject rest = first.cdr();
    351                 Symbol symbol = checkSymbol(funcar);
    352                 if (symbol == Symbol.LAMBDA) {
    353                     Closure closure = new Closure(rest.car(), rest.cdr(), env);
    354                     return closure.execute(evalList(args, env, thread));
    355                 } else
    356                     throw new ConditionThrowable(new ProgramError("illegal function object: " + first));
    357             }
    358         } else
    359             return obj;
     367            throw t;
     368        }
    360369    }
    361370
Note: See TracChangeset for help on using the changeset viewer.