source: branches/streams/abcl/src/org/armedbear/lisp/Extensions.java

Last change on this file was 14404, checked in by Mark Evenson, 12 years ago

Fix error on form redefition introduced with r14403.

Addresses #282 comment 5.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 10.7 KB
Line 
1/*
2 * Extensions.java
3 *
4 * Copyright (C) 2002-2007 Peter Graves
5 * $Id: Extensions.java 14404 2013-02-26 16:13:50Z mevenson $
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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 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
38import java.io.File;
39import java.io.IOException;
40import java.util.*;
41
42public final class Extensions
43{
44  // ### *ed-functions*
45  public static final Symbol _ED_FUNCTIONS_ =
46    exportSpecial("*ED-FUNCTIONS*", PACKAGE_EXT,
47                  list(intern("DEFAULT-ED-FUNCTION", PACKAGE_SYS)));
48
49  // ### truly-the value-type form => result*
50  private static final SpecialOperator TRULY_THE = new truly_the();
51  private static class truly_the extends SpecialOperator {
52    truly_the() {
53      super("truly-the", PACKAGE_EXT, true, "type value");
54    }
55    @Override
56    public LispObject execute(LispObject args, Environment env)
57    {
58      if (args.length() != 2)
59        return error(new WrongNumberOfArgumentsException(this, 2));
60      return eval(args.cadr(), env, LispThread.currentThread());
61    }
62  }
63
64  // ### neq
65  private static final Primitive NEQ = new neq();
66  private static class neq extends Primitive
67  {
68    neq() 
69    {
70      super(Symbol.NEQ, "obj1 obj2");
71    }
72    @Override
73    public LispObject execute(LispObject first, LispObject second)
74    {
75        return first != second ? T : NIL;
76    }
77  }
78
79  // ### memq item list => tail
80  private static final Primitive MEMQ = new memq();
81  private static class memq extends Primitive
82  {
83    memq() 
84    {
85      super(Symbol.MEMQ, "item list");
86    }
87    @Override
88    public LispObject execute(LispObject item, LispObject list)
89    {
90      while (list instanceof Cons)
91        {
92          if (item == ((Cons)list).car)
93            return list;
94          list = ((Cons)list).cdr;
95        }
96      if (list != NIL)
97        type_error(list, Symbol.LIST);
98      return NIL;
99    }
100  }
101
102  // ### memql item list => tail
103  private static final Primitive MEMQL = new memql();
104  private static class memql extends Primitive
105  {
106    memql() {
107      super(Symbol.MEMQL, "item list");
108    }
109    @Override
110    public LispObject execute(LispObject item, LispObject list)
111    {
112      while (list instanceof Cons)
113        {
114          if (item.eql(((Cons)list).car))
115            return list;
116          list = ((Cons)list).cdr;
117        }
118      if (list != NIL)
119        type_error(list, Symbol.LIST);
120      return NIL;
121    }
122  }
123
124  // ### adjoin-eql item list => new-list
125  private static final Primitive ADJOIN_EQL = new adjoin_eql();
126  private static class adjoin_eql extends Primitive {
127    adjoin_eql() {
128      super(Symbol.ADJOIN_EQL, "item list");
129    }
130    @Override
131    public LispObject execute(LispObject item, LispObject list)
132    {
133      return memql(item, list) ? list : new Cons(item, list);
134    }
135  }
136
137  // ### special-variable-p
138  private static final Primitive SPECIAL_VARIABLE_P = new special_variable_p();
139  private static class special_variable_p extends Primitive {
140    special_variable_p() {
141      super("special-variable-p", PACKAGE_EXT, true);
142    }
143    @Override
144    public LispObject execute(LispObject arg)
145    {
146      return arg.isSpecialVariable() ? T : NIL;
147    }
148  }
149
150  // ### source symbol
151  private static final Primitive SOURCE = new source();
152  private static class source extends Primitive {
153    source() {
154      super("source", PACKAGE_EXT, true);
155    }
156    @Override
157    public LispObject execute(LispObject arg)
158    {
159      return get(arg, Symbol._SOURCE, NIL);
160    }
161  }
162
163  // ### source-file-position symbol
164  private static final Primitive SOURCE_FILE_POSITION = new source_file_position();
165  private static class source_file_position extends Primitive {
166    source_file_position() {
167      super("source-file-position", PACKAGE_EXT, true);
168    }
169    @Override
170    public LispObject execute(LispObject arg)
171    {
172      LispObject obj = get(arg, Symbol._SOURCE, NIL);
173      if (obj instanceof Cons)
174        return obj.cdr();
175      return NIL;
176    }
177  }
178
179  // XXX rename to something else as it doesn't always refer to a pathname.
180  public static final Primitive SOURCE_PATHNAME = new pf_source_pathname();
181  @DocString(
182    name="source-pathname",
183    args="symbol",
184    doc="Returns either the pathname corresponding to the file from which this symbol was compiled,"
185    + "or the keyword :TOP-LEVEL."
186  )
187  private static class pf_source_pathname extends Primitive {
188    pf_source_pathname() {
189      super("source-pathname", PACKAGE_EXT, true);
190    }
191    @Override
192    public LispObject execute(LispObject arg)
193    {
194      LispObject obj = get(arg, Symbol._SOURCE, NIL);
195      if (obj instanceof Cons)
196        return obj.car();
197      return obj;
198    }
199  }
200
201  // ### exit
202  private static final Primitive EXIT = new exit();
203  private static class exit extends Primitive {
204    exit() {
205      super("exit", PACKAGE_EXT, true, "&key status");
206    }
207    @Override
208    public LispObject execute()
209    {
210      throw new ProcessingTerminated();
211    }
212    @Override
213    public LispObject execute(LispObject first, LispObject second)
214     
215    {
216      int status = 0;
217      if (first == Keyword.STATUS)
218        {
219          if (second instanceof Fixnum)
220            status = ((Fixnum)second).value;
221        }
222      throw new ProcessingTerminated(status);
223    }
224  }
225
226  // ### quit
227  private static final Primitive QUIT = new quit();
228  private static class quit extends Primitive {
229    quit() {
230      super("quit", PACKAGE_EXT, true, "&key status");
231    }
232    @Override
233    public LispObject execute()
234    {
235      ((Stream)Symbol.STANDARD_OUTPUT.getSymbolValue())._finishOutput();
236      ((Stream)Symbol.ERROR_OUTPUT.getSymbolValue())._finishOutput();
237      throw new ProcessingTerminated();
238    }
239    @Override
240    public LispObject execute(LispObject first, LispObject second)
241    {
242      int status = 0;
243      if (first == Keyword.STATUS)
244        {
245          if (second instanceof Fixnum)
246            status = ((Fixnum)second).value;
247        }
248      throw new ProcessingTerminated(status);
249    }
250  }
251
252  // ### dump-java-stack
253  private static final Primitive DUMP_JAVA_STACK = new dump_java_stack();
254  private static class dump_java_stack extends Primitive {
255    dump_java_stack() {
256      super("dump-java-stack", PACKAGE_EXT, true);
257    }
258    @Override
259    public LispObject execute()
260    {
261      Thread.dumpStack();
262      return LispThread.currentThread().nothing();
263    }
264  }
265
266  public static final Primitive MAKE_TEMP_FILE = new make_temp_file();
267  @DocString(name="make_temp_file",
268             doc="Create and return the pathname of a previously non-existent file.")
269  private static class make_temp_file extends Primitive { 
270    make_temp_file() {
271      super("make-temp-file", PACKAGE_EXT, true, "");
272    }
273    @Override
274    public LispObject execute()
275    {
276      try
277        {
278          File file = File.createTempFile("abcl", null, null);
279          if (file != null)
280            return new Pathname(file.getPath());
281        }
282      catch (IOException e)
283        {
284          Debug.trace(e);
285        }
286      return NIL;
287    }
288  }
289
290  public static final Primitive MAKE_TEMP_DIRECTORY = new make_temp_directory();
291  @DocString(name="make_temp_directory",
292             doc="Create and return the pathname of a previously non-existent directory.")
293  private static class make_temp_directory extends Primitive { 
294    make_temp_directory() {
295      super("make-temp-directory", PACKAGE_EXT, true, "");
296    }
297    @Override
298    public LispObject execute()
299    {
300      try {
301        File dir = File.createTempFile("abcl", null);
302        dir.delete();
303        if (dir.mkdirs()) {
304          return new Pathname(dir + "/");
305        }
306      } catch (Throwable t) {
307        Debug.trace(t);
308      }
309      return NIL;
310    }
311  }
312
313  // ### interrupt-lisp
314  private static final Primitive INTERRUPT_LISP = new interrupt_lisp();
315  private static class interrupt_lisp extends Primitive {
316    interrupt_lisp() {
317      super("interrupt-lisp", PACKAGE_EXT, true, "");
318    }
319    @Override
320    public LispObject execute()
321    {
322      setInterrupted(true);
323      return T;
324    }
325  }
326
327  // ### getenv variable => string
328  private static final Primitive GETENV = new getenv();
329  private static class getenv extends Primitive
330  {
331    getenv() 
332    {
333      super("getenv", PACKAGE_EXT, true, "variable",
334             "Return the value of the environment VARIABLE if it exists, otherwise return NIL.");
335    }
336    @Override
337    public LispObject execute(LispObject arg)
338    {
339      AbstractString string;
340      if (arg instanceof AbstractString) {
341        string = (AbstractString) arg;
342      } else
343        return type_error(arg, Symbol.STRING);
344      String result = System.getenv(string.getStringValue());
345      if (result != null)
346        return new SimpleString(result);
347      else
348        return NIL;
349    }
350  }
351
352  // ### getenv-all variable => string
353  private static final Primitive GETENV_ALL = new getenv_all();
354  private static class getenv_all extends Primitive
355  {
356    getenv_all() 
357    {
358      super("getenv-all", PACKAGE_EXT, true, "variable",
359             "Returns all environment variables as an alist containing (name . value)");
360    }
361    @Override
362    public LispObject execute()
363    {
364      Cons result = new Cons(NIL);
365      Map<String, String> env = System.getenv();
366      for (Map.Entry<String, String> entry : env.entrySet()) {
367          Cons entryPair = new Cons(new SimpleString(entry.getKey()), 
368                                    new SimpleString(entry.getValue()));
369          result = new Cons(entryPair, result);
370      }
371      return result;
372    }
373  }
374
375}
Note: See TracBrowser for help on using the repository browser.