source: trunk/abcl/src/org/armedbear/lisp/AutoloadGeneralizedReference.java

Last change on this file was 14369, checked in by Mark Evenson, 11 years ago

Implementation of autoloader for SETF generalized references.

Fixes #296. Fixes #266. Fixes #228.

For forms which set the symbol properties of SETF-EXPANDER or
SETF-FUNCTION to function definitions, places stub of type
AutoloadGeneralizedReference? to be resolved when first invoked.

File size: 7.5 KB
Line 
1/*
2 * AutoloadGeneralizedReference.java
3 *
4 * Copyright (C) 2014 Mark Evenson
5 * $Id$
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 AutoloadGeneralizedReference extends Autoload
39{
40  Symbol indicator; 
41  private AutoloadGeneralizedReference(Symbol symbol, Symbol indicator, String filename) {
42    super(symbol, filename, null);
43    this.indicator = indicator; 
44  }
45
46  @Override
47  public void load()
48  {
49    Load.loadSystemFile(getFileName(), true);
50  }
51
52  static final Symbol SETF_EXPANDER  = PACKAGE_SYS.intern("SETF-EXPANDER");
53  public static final Primitive AUTOLOAD_SETF_EXPANDER = new pf_autoload_setf_expander();
54  @DocString(
55    name="autoload-setf-expander",
56    args="symbol-or-symbols filename",
57    doc="Setup the autoload for SYMBOL-OR-SYMBOLS on the setf-expander from FILENAME."
58  )
59  private static final class pf_autoload_setf_expander extends Primitive {
60    pf_autoload_setf_expander() {   
61      super("autoload-setf-expander", PACKAGE_EXT, true);
62    }
63    @Override
64    public LispObject execute(LispObject first, LispObject second) {
65      final String filename = second.getStringValue();
66      return installAutoloadGeneralizedReference(first, SETF_EXPANDER, filename);
67    }
68  };
69
70  static final Symbol SETF_FUNCTION  = PACKAGE_SYS.intern("SETF-FUNCTION");
71  public static final Primitive AUTOLOAD_SETF_FUNCTION = new pf_autoload_setf_function();
72  @DocString(
73    name="autoload-setf-function", 
74    args="symbol-or-symbols filename",
75    doc="Setup the autoload for SYMBOL-OR-SYMBOLS on the setf-function from FILENAME."
76  )
77  private static final class pf_autoload_setf_function extends Primitive {
78    pf_autoload_setf_function() {   
79      super("autoload-setf-function", PACKAGE_EXT, true);
80    }
81    @Override
82    public LispObject execute(LispObject first, LispObject second) {
83      final String filename = second.getStringValue();
84      return installAutoloadGeneralizedReference(first, SETF_FUNCTION, filename);
85    }
86  };
87
88  public static final Primitive AUTOLOAD_REF_P = new pf_autoload_ref_p();
89  @DocString(
90    name="autoload-ref-p",
91    args="symbol",
92    doc="Boolean predicate for whether SYMBOL has generalized reference functions which need to be resolved."
93  )
94  private static final class pf_autoload_ref_p extends Primitive {
95    pf_autoload_ref_p() {
96      super("autoload-ref-p", PACKAGE_EXT, true, "symbol");
97    }
98    @Override
99    public LispObject execute(LispObject arg) {
100      LispObject list = checkSymbol(arg).getPropertyList();
101      while (list != NIL) {
102        if (list.car() instanceof AutoloadGeneralizedReference) {
103          return T;
104        }
105
106        list = list.cdr();
107      }
108      return NIL;
109    }
110  };
111       
112
113  private static final LispObject installAutoloadGeneralizedReference(LispObject first, 
114                                                                      Symbol indicator, 
115                                                                      String filename) 
116  {
117    if (first instanceof Symbol) {
118      Symbol symbol = checkSymbol(first);
119      install(symbol, indicator, filename);
120      return T;
121    }
122    if (first instanceof Cons) {
123      for (LispObject list = first; list != NIL; list = list.cdr()) {
124        Symbol symbol = checkSymbol(list.car());
125        install(symbol, indicator, filename);
126      }
127      return T;
128    }
129    return error(new TypeError(first));
130  }
131
132  private static LispObject install(Symbol symbol, Symbol indicator, String filename) {
133    if (get(symbol, indicator) == NIL) {
134      return Primitives.PUT.execute(symbol, indicator,
135                                    new AutoloadGeneralizedReference(symbol, indicator, filename));
136    } else {
137      return NIL;
138    }
139   
140  }
141  @Override
142  public LispObject execute()
143  {
144    load();
145    return get(symbol, indicator, null).execute();
146  }
147
148  @Override
149  public LispObject execute(LispObject arg)
150  {
151    load();
152    return get(symbol, indicator, null).execute(arg);
153  }
154
155  @Override
156  public LispObject execute(LispObject first, LispObject second)
157
158  {
159    load();
160    return get(symbol, indicator, null).execute(first, second);
161  }
162
163  @Override
164  public LispObject execute(LispObject first, LispObject second,
165                            LispObject third)
166
167  {
168    load();
169    return get(symbol, indicator, null).execute(first, second, third);
170  }
171
172  @Override
173  public LispObject execute(LispObject first, LispObject second,
174                            LispObject third, LispObject fourth)
175
176  {
177    load();
178    return get(symbol, indicator, null).execute(first, second, third, fourth);
179  }
180
181  @Override
182  public LispObject execute(LispObject first, LispObject second,
183                            LispObject third, LispObject fourth,
184                            LispObject fifth)
185
186  {
187    load();
188    return get(symbol, indicator, null).execute(first, second, third, fourth, fifth);
189  }
190
191  @Override
192  public LispObject execute(LispObject first, LispObject second,
193                            LispObject third, LispObject fourth,
194                            LispObject fifth, LispObject sixth)
195
196  {
197    load();
198    return get(symbol, indicator, null).execute(first, second, third, fourth, fifth, sixth);
199  }
200
201  @Override
202  public LispObject execute(LispObject first, LispObject second,
203                            LispObject third, LispObject fourth,
204                            LispObject fifth, LispObject sixth,
205                            LispObject seventh)
206
207  {
208    load();
209    return symbol.execute(first, second, third, fourth, fifth, sixth,
210                          seventh);
211  }
212
213  @Override
214  public LispObject execute(LispObject first, LispObject second,
215                            LispObject third, LispObject fourth,
216                            LispObject fifth, LispObject sixth,
217                            LispObject seventh, LispObject eighth)
218
219  {
220    load();
221    return get(symbol, indicator, null).execute(first, second, third, fourth, fifth, sixth,
222                                                seventh, eighth);
223  }
224
225  @Override
226  public LispObject execute(LispObject[] args)
227  {
228    load();
229    return get(symbol, indicator, null).execute(args);
230  }
231
232 
233
234}
Note: See TracBrowser for help on using the repository browser.