source: branches/0.22.x/abcl/src/org/armedbear/lisp/Do.java

Last change on this file was 12513, checked in by ehuelsmann, 15 years ago

Remove 'private' keyword to eliminate the Java requirement

for the compiler to generate synthetic accessors: functions that
don't appear in the source but do appear in the class file.

Patch by: Douglas Miles <dmiles _at_ users.sf.net>

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 7.1 KB
Line 
1/*
2 * Do.java
3 *
4 * Copyright (C) 2003-2006 Peter Graves
5 * $Id: Do.java 12513 2010-03-02 22:35:36Z ehuelsmann $
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20 *
21 * As a special exception, the copyright holders of this library give you
22 * permission to link this library with independent modules to produce an
23 * executable, regardless of the license terms of these independent
24 * modules, and to copy and distribute the resulting executable under
25 * terms of your choice, provided that you also meet, for each linked
26 * independent module, the terms and conditions of the license of that
27 * module.  An independent module is a module which is not derived from
28 * or based on this library.  If you modify this library, you may extend
29 * this exception to your version of the library, but you are not
30 * obligated to do so.  If you do not wish to do so, delete this
31 * exception statement from your version.
32 */
33
34package org.armedbear.lisp;
35
36import static org.armedbear.lisp.Lisp.*;
37
38public final class Do {
39    // ### do
40    private static final SpecialOperator DO = new sf_do();
41    private static final class sf_do extends SpecialOperator {
42        sf_do() {
43            super(Symbol.DO, "varlist endlist &body body");
44        }
45
46        @Override
47        public LispObject execute(LispObject args, Environment env)
48
49        {
50            return _do(args, env, false);
51        }
52    };
53
54    // ### do*
55    private static final SpecialOperator DO_STAR = new sf_do_star();
56    private static final class sf_do_star extends SpecialOperator {
57        sf_do_star() {
58            super(Symbol.DO_STAR, "varlist endlist &body body");
59        }
60
61        @Override
62        public LispObject execute(LispObject args, Environment env)
63
64        {
65            return _do(args, env, true);
66        }
67    };
68
69    static final LispObject _do(LispObject args, Environment env,
70                                        boolean sequential)
71
72    {
73        LispObject varlist = args.car();
74        LispObject second = args.cadr();
75        LispObject end_test_form = second.car();
76        LispObject result_forms = second.cdr();
77        LispObject body = args.cddr();
78        // Process variable specifications.
79        final int numvars = varlist.length();
80        Symbol[] vars = new Symbol[numvars];
81        LispObject[] initforms = new LispObject[numvars];
82        LispObject[] stepforms = new LispObject[numvars];
83        for (int i = 0; i < numvars; i++) {
84            final LispObject varspec = varlist.car();
85            if (varspec instanceof Cons) {
86                vars[i] = checkSymbol(varspec.car());
87                initforms[i] = varspec.cadr();
88                // Is there a step form?
89                if (varspec.cddr() != NIL)
90                    stepforms[i] = varspec.caddr();
91            } else {
92                // Not a cons, must be a symbol.
93                vars[i] = checkSymbol(varspec);
94                initforms[i] = NIL;
95            }
96            varlist = varlist.cdr();
97        }
98        final LispThread thread = LispThread.currentThread();
99        final SpecialBindingsMark mark = thread.markSpecialBindings();
100        // Process declarations.
101
102        final LispObject bodyAndDecls = parseBody(body, false);
103        LispObject specials = parseSpecials(bodyAndDecls.NTH(1));
104        body = bodyAndDecls.car();
105
106        Environment ext = new Environment(env);
107        for (int i = 0; i < numvars; i++) {
108            Symbol var = vars[i];
109            LispObject value = eval(initforms[i], (sequential ? ext : env), thread);
110            ext = new Environment(ext);
111            if (specials != NIL && memq(var, specials))
112                thread.bindSpecial(var, value);
113            else if (var.isSpecialVariable())
114                thread.bindSpecial(var, value);
115            else
116                ext.bind(var, value);
117        }
118        LispObject list = specials;
119        while (list != NIL) {
120            ext.declareSpecial(checkSymbol(list.car()));
121            list = list.cdr();
122        }
123        // Look for tags.
124        LispObject localTags = preprocessTagBody(body, ext);
125        LispObject blockId = new LispObject();
126        try {
127            // Implicit block.
128            ext.addBlock(NIL, blockId);
129            while (true) {
130                // Execute body.
131                // Test for termination.
132                if (eval(end_test_form, ext, thread) != NIL)
133                    break;
134
135                processTagBody(body, localTags, ext);
136
137                // Update variables.
138                if (sequential) {
139                    for (int i = 0; i < numvars; i++) {
140                        LispObject step = stepforms[i];
141                        if (step != null) {
142                            Symbol symbol = vars[i];
143                            LispObject value = eval(step, ext, thread);
144                            if (symbol.isSpecialVariable()
145                                    || ext.isDeclaredSpecial(symbol))
146                                thread.rebindSpecial(symbol, value);
147                            else
148                                ext.rebind(symbol, value);
149                        }
150                    }
151                } else {
152                    // Evaluate step forms.
153                    LispObject results[] = new LispObject[numvars];
154                    for (int i = 0; i < numvars; i++) {
155                        LispObject step = stepforms[i];
156                        if (step != null) {
157                            LispObject result = eval(step, ext, thread);
158                            results[i] = result;
159                        }
160                    }
161                    // Update variables.
162                    for (int i = 0; i < numvars; i++) {
163                        if (results[i] != null) {
164                            Symbol symbol = vars[i];
165                            LispObject value = results[i];
166                            if (symbol.isSpecialVariable()
167                                    || ext.isDeclaredSpecial(symbol))
168                                thread.rebindSpecial(symbol, value);
169                            else
170                                ext.rebind(symbol, value);
171                        }
172                    }
173                }
174                if (interrupted)
175                    handleInterrupt();
176            }
177            LispObject result = progn(result_forms, ext, thread);
178            return result;
179        } catch (Return ret) {
180            if (ret.getBlock() == blockId) {
181                return ret.getResult();
182            }
183            throw ret;
184        }
185        finally {
186            thread.resetSpecialBindings(mark);
187            ext.inactive = true;
188        }
189    }
190}
Note: See TracBrowser for help on using the repository browser.