source: branches/1.1.x/src/org/armedbear/lisp/Extensions.java

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

Use java.io.File routine to guarantee uniquely non-existing pathname for EXT:MAKE-TEMP-DIRECTORY.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 10.5 KB
Line 
1/*
2 * Extensions.java
3 *
4 * Copyright (C) 2002-2007 Peter Graves
5 * $Id: Extensions.java 13946 2012-05-24 11:26:06Z 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  // ### source-pathname
180  public static final Primitive SOURCE_PATHNAME = new source_pathname();
181  private static class source_pathname extends Primitive {
182    source_pathname() {
183      super("source-pathname", PACKAGE_EXT, true);
184    }
185    @Override
186    public LispObject execute(LispObject arg)
187    {
188      LispObject obj = get(arg, Symbol._SOURCE, NIL);
189      if (obj instanceof Cons)
190        return obj.car();
191      return obj;
192    }
193  }
194
195  // ### exit
196  private static final Primitive EXIT = new exit();
197  private static class exit extends Primitive {
198    exit() {
199      super("exit", PACKAGE_EXT, true, "&key status");
200    }
201    @Override
202    public LispObject execute()
203    {
204      throw new ProcessingTerminated();
205    }
206    @Override
207    public LispObject execute(LispObject first, LispObject second)
208     
209    {
210      int status = 0;
211      if (first == Keyword.STATUS)
212        {
213          if (second instanceof Fixnum)
214            status = ((Fixnum)second).value;
215        }
216      throw new ProcessingTerminated(status);
217    }
218  }
219
220  // ### quit
221  private static final Primitive QUIT = new quit();
222  private static class quit extends Primitive {
223    quit() {
224      super("quit", PACKAGE_EXT, true, "&key status");
225    }
226    @Override
227    public LispObject execute()
228    {
229      ((Stream)Symbol.STANDARD_OUTPUT.getSymbolValue())._finishOutput();
230      ((Stream)Symbol.ERROR_OUTPUT.getSymbolValue())._finishOutput();
231      throw new ProcessingTerminated();
232    }
233    @Override
234    public LispObject execute(LispObject first, LispObject second)
235    {
236      int status = 0;
237      if (first == Keyword.STATUS)
238        {
239          if (second instanceof Fixnum)
240            status = ((Fixnum)second).value;
241        }
242      throw new ProcessingTerminated(status);
243    }
244  }
245
246  // ### dump-java-stack
247  private static final Primitive DUMP_JAVA_STACK = new dump_java_stack();
248  private static class dump_java_stack extends Primitive {
249    dump_java_stack() {
250      super("dump-java-stack", PACKAGE_EXT, true);
251    }
252    @Override
253    public LispObject execute()
254    {
255      Thread.dumpStack();
256      return LispThread.currentThread().nothing();
257    }
258  }
259
260  public static final Primitive MAKE_TEMP_FILE = new make_temp_file();
261  @DocString(name="make_temp_file",
262             doc="Create and return the pathname of a previously non-existent file.")
263  private static class make_temp_file extends Primitive { 
264    make_temp_file() {
265      super("make-temp-file", PACKAGE_EXT, true, "");
266    }
267    @Override
268    public LispObject execute()
269    {
270      try
271        {
272          File file = File.createTempFile("abcl", null, null);
273          if (file != null)
274            return new Pathname(file.getPath());
275        }
276      catch (IOException e)
277        {
278          Debug.trace(e);
279        }
280      return NIL;
281    }
282  }
283
284  public static final Primitive MAKE_TEMP_DIRECTORY = new make_temp_directory();
285  @DocString(name="make_temp_directory",
286             doc="Create and return the pathname of a previously non-existent directory.")
287  private static class make_temp_directory extends Primitive { 
288    make_temp_directory() {
289      super("make-temp-directory", PACKAGE_EXT, true, "");
290    }
291    @Override
292    public LispObject execute()
293    {
294      try {
295        File dir = File.createTempFile("abcl", null);
296        dir.delete();
297        if (dir.mkdirs()) {
298          return new Pathname(dir + "/");
299        }
300      } catch (Throwable t) {
301        Debug.trace(t);
302      }
303      return NIL;
304    }
305  }
306
307  // ### interrupt-lisp
308  private static final Primitive INTERRUPT_LISP = new interrupt_lisp();
309  private static class interrupt_lisp extends Primitive {
310    interrupt_lisp() {
311      super("interrupt-lisp", PACKAGE_EXT, true, "");
312    }
313    @Override
314    public LispObject execute()
315    {
316      setInterrupted(true);
317      return T;
318    }
319  }
320
321  // ### getenv variable => string
322  private static final Primitive GETENV = new getenv();
323  private static class getenv extends Primitive
324  {
325    getenv() 
326    {
327      super("getenv", PACKAGE_EXT, true, "variable",
328             "Return the value of the environment VARIABLE if it exists, otherwise return NIL.");
329    }
330    @Override
331    public LispObject execute(LispObject arg)
332    {
333      AbstractString string;
334      if (arg instanceof AbstractString) {
335        string = (AbstractString) arg;
336      } else
337        return type_error(arg, Symbol.STRING);
338      String result = System.getenv(string.getStringValue());
339      if (result != null)
340        return new SimpleString(result);
341      else
342        return NIL;
343    }
344  }
345
346  // ### getenv-all variable => string
347  private static final Primitive GETENV_ALL = new getenv_all();
348  private static class getenv_all extends Primitive
349  {
350    getenv_all() 
351    {
352      super("getenv-all", PACKAGE_EXT, true, "variable",
353             "Returns all environment variables as an alist containing (name . value)");
354    }
355    @Override
356    public LispObject execute()
357    {
358      Cons result = new Cons(NIL);
359      Map<String, String> env = System.getenv();
360      for (Map.Entry<String, String> entry : env.entrySet()) {
361          Cons entryPair = new Cons(new SimpleString(entry.getKey()), 
362                                    new SimpleString(entry.getValue()));
363          result = new Cons(entryPair, result);
364      }
365      return result;
366    }
367  }
368
369}
Note: See TracBrowser for help on using the repository browser.