Changeset 4838


Ignore:
Timestamp:
11/19/03 16:16:48 (18 years ago)
Author:
piso
Message:

Added support for SPECIAL declarations.

File:
1 edited

Legend:

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

    r4038 r4838  
    33 *
    44 * Copyright (C) 2003 Peter Graves
    5  * $Id: Do.java,v 1.3 2003-09-24 00:06:42 piso Exp $
     5 * $Id: Do.java,v 1.4 2003-11-19 16:16:48 piso Exp $
    66 *
    77 * This program is free software; you can redistribute it and/or
     
    2525{
    2626    // ### do
    27     private static final SpecialOperator DO = new SpecialOperator("do") {
     27    private static final SpecialOperator DO = new SpecialOperator("do")
     28    {
    2829        public LispObject execute(LispObject args, Environment env)
    2930            throws ConditionThrowable
     
    3435
    3536    // ### do*
    36     private static final SpecialOperator DO_ = new SpecialOperator("do*") {
     37    private static final SpecialOperator DO_ = new SpecialOperator("do*")
     38    {
    3739        public LispObject execute(LispObject args, Environment env)
    3840            throws ConditionThrowable
     
    4648        throws ConditionThrowable
    4749    {
     50        LispObject varList = args.car();
     51        LispObject second = args.cadr();
     52        LispObject endTestForm = second.car();
     53        LispObject resultForms = second.cdr();
     54        LispObject body = args.cddr();
    4855        // Process variable specifications.
    49         LispObject first = args.car();
    50         args = args.cdr();
    51         int length = first.length();
     56        int length = varList.length();
    5257        Symbol[] variables = new Symbol[length];
    5358        LispObject[] initials = new LispObject[length];
    5459        LispObject[] updates = new LispObject[length];
    5560        for (int i = 0; i < length; i++) {
    56             LispObject obj = first.car();
     61            LispObject obj = varList.car();
    5762            if (obj instanceof Cons) {
    5863                variables[i] = checkSymbol(obj.car());
     
    6671                initials[i] = NIL;
    6772            }
    68             first = first.cdr();
     73            varList = varList.cdr();
    6974        }
    7075        final LispThread thread = LispThread.currentThread();
    7176        Environment oldDynEnv = thread.getDynamicEnvironment();
     77        // Process declarations.
     78        LispObject specials = NIL;
     79        while (body != NIL) {
     80            LispObject obj = body.car();
     81            if (obj instanceof Cons && obj.car() == Symbol.DECLARE) {
     82                LispObject decls = obj.cdr();
     83                while (decls != NIL) {
     84                    LispObject decl = decls.car();
     85                    if (decl instanceof Cons && decl.car() == Symbol.SPECIAL) {
     86                        LispObject vars = decl.cdr();
     87                        while (vars != NIL) {
     88                            specials = new Cons(vars.car(), specials);
     89                            vars = vars.cdr();
     90                        }
     91                    }
     92                    decls = decls.cdr();
     93                }
     94                body = body.cdr();
     95            } else
     96                break;
     97        }
    7298        Environment ext = new Environment(env);
    7399        for (int i = 0; i < length; i++) {
     
    75101            LispObject value =
    76102                eval(initials[i], (sequential ? ext : env), thread);
    77             bind(symbol, value, ext);
    78         }
    79         LispObject second = args.car();
    80         LispObject test = second.car();
    81         LispObject resultForms = second.cdr();
    82         LispObject body = args.cdr();
     103            if (specials != NIL && memq(symbol, specials)) {
     104                thread.bindSpecial(symbol, value);
     105                ext.declareSpecial(symbol);
     106            } else if (symbol.isSpecialVariable()) {
     107                thread.bindSpecial(symbol, value);
     108            } else
     109                ext.bind(symbol, value);
     110        }
    83111        final int depth = thread.getStackDepth();
    84112        // Look for tags.
     
    98126                // Execute body.
    99127                // Test for termination.
    100                 if (eval(test, ext, thread) != NIL)
     128                if (eval(endTestForm, ext, thread) != NIL)
    101129                    break;
    102130                remaining = body;
     
    146174                    for (int i = 0; i < length; i++) {
    147175                        LispObject update = updates[i];
    148                         if (update != null)
    149                             rebind(variables[i], eval(update, ext, thread), ext);
     176                        if (update != null) {
     177                            Symbol symbol = variables[i];
     178                            LispObject value = eval(update, ext, thread);
     179                            if (specials != NIL && memq(symbol, specials)) {
     180                                thread.getDynamicEnvironment().rebind(symbol, value);
     181                            } else if (symbol.isSpecialVariable()) {
     182                                thread.getDynamicEnvironment().rebind(symbol, value);
     183                            } else
     184                                ext.rebind(symbol, value);
     185                        }
    150186                    }
    151187                } else {
     
    163199                        if (results[i] != null) {
    164200                            Symbol symbol = variables[i];
    165                             rebind(symbol, results[i], ext);
     201                            LispObject value = results[i];
     202                            if (specials != NIL && memq(symbol, specials)) {
     203                                thread.getDynamicEnvironment().rebind(symbol, value);
     204                            } else if (symbol.isSpecialVariable()) {
     205                                thread.getDynamicEnvironment().rebind(symbol, value);
     206                            } else
     207                                ext.rebind(symbol, value);
    166208                        }
    167209                    }
Note: See TracChangeset for help on using the changeset viewer.