source: branches/0.20.x/abcl/src/org/armedbear/lisp/Lisp.java

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

Add (and use) more wrappers for the lisp ERROR function, using
different return types: ierror returns an int, etc.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 88.6 KB
Line 
1/*
2 * Lisp.java
3 *
4 * Copyright (C) 2002-2007 Peter Graves <peter@armedbear.org>
5 * $Id: Lisp.java 12648 2010-05-02 18:30:47Z 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., 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 java.io.File;
37import java.io.FileInputStream;
38import java.io.FileNotFoundException;
39import java.io.IOException;
40import java.io.InputStream;
41import java.math.BigInteger;
42import java.net.MalformedURLException;
43import java.net.URL;
44import java.net.URLDecoder;
45import java.util.Hashtable;
46import java.util.zip.ZipEntry;
47import java.util.zip.ZipFile;
48
49public final class Lisp
50{
51  public static final boolean debug = true;
52
53  public static boolean cold = true;
54
55  public static boolean initialized;
56
57  // Packages.
58  public static final Package PACKAGE_CL =
59    Packages.createPackage("COMMON-LISP", 1024);
60  public static final Package PACKAGE_CL_USER =
61    Packages.createPackage("COMMON-LISP-USER", 1024);
62  public static final Package PACKAGE_KEYWORD =
63    Packages.createPackage("KEYWORD", 1024);
64  public static final Package PACKAGE_SYS =
65    Packages.createPackage("SYSTEM");
66  public static final Package PACKAGE_MOP =
67    Packages.createPackage("MOP");
68  public static final Package PACKAGE_TPL =
69    Packages.createPackage("TOP-LEVEL");
70  public static final Package PACKAGE_EXT =
71    Packages.createPackage("EXTENSIONS");
72  public static final Package PACKAGE_JVM =
73    Packages.createPackage("JVM");
74  public static final Package PACKAGE_LOOP =
75    Packages.createPackage("LOOP");
76  public static final Package PACKAGE_PROF =
77    Packages.createPackage("PROFILER");
78  public static final Package PACKAGE_JAVA =
79    Packages.createPackage("JAVA");
80  public static final Package PACKAGE_LISP =
81    Packages.createPackage("LISP");
82  public static final Package PACKAGE_THREADS =
83    Packages.createPackage("THREADS");
84  public static final Package PACKAGE_FORMAT =
85    Packages.createPackage("FORMAT");
86  public static final Package PACKAGE_XP =
87    Packages.createPackage("XP");
88  public static final Package PACKAGE_PRECOMPILER =
89    Packages.createPackage("PRECOMPILER");
90  public static final Package PACKAGE_SEQUENCE =
91    Packages.createPackage("SEQUENCE");
92
93
94  // ### nil
95  public static final LispObject NIL = Nil.NIL;
96
97  // We need NIL before we can call usePackage().
98  static
99  {
100    PACKAGE_CL.addNickname("CL");
101    PACKAGE_CL_USER.addNickname("CL-USER");
102    PACKAGE_CL_USER.usePackage(PACKAGE_CL);
103    PACKAGE_CL_USER.usePackage(PACKAGE_EXT);
104    PACKAGE_CL_USER.usePackage(PACKAGE_JAVA);
105    PACKAGE_SYS.addNickname("SYS");
106    PACKAGE_SYS.usePackage(PACKAGE_CL);
107    PACKAGE_SYS.usePackage(PACKAGE_EXT);
108    PACKAGE_MOP.usePackage(PACKAGE_CL);
109    PACKAGE_MOP.usePackage(PACKAGE_EXT);
110    PACKAGE_MOP.usePackage(PACKAGE_SYS);
111    PACKAGE_TPL.addNickname("TPL");
112    PACKAGE_TPL.usePackage(PACKAGE_CL);
113    PACKAGE_TPL.usePackage(PACKAGE_EXT);
114    PACKAGE_EXT.addNickname("EXT");
115    PACKAGE_EXT.usePackage(PACKAGE_CL);
116    PACKAGE_EXT.usePackage(PACKAGE_THREADS);
117    PACKAGE_JVM.usePackage(PACKAGE_CL);
118    PACKAGE_JVM.usePackage(PACKAGE_EXT);
119    PACKAGE_JVM.usePackage(PACKAGE_SYS);
120    PACKAGE_LOOP.usePackage(PACKAGE_CL);
121    PACKAGE_PROF.addNickname("PROF");
122    PACKAGE_PROF.usePackage(PACKAGE_CL);
123    PACKAGE_PROF.usePackage(PACKAGE_EXT);
124    PACKAGE_JAVA.usePackage(PACKAGE_CL);
125    PACKAGE_JAVA.usePackage(PACKAGE_EXT);
126    PACKAGE_LISP.usePackage(PACKAGE_CL);
127    PACKAGE_LISP.usePackage(PACKAGE_EXT);
128    PACKAGE_LISP.usePackage(PACKAGE_SYS);
129    PACKAGE_THREADS.usePackage(PACKAGE_CL);
130    PACKAGE_THREADS.usePackage(PACKAGE_EXT);
131    PACKAGE_THREADS.usePackage(PACKAGE_SYS);
132    PACKAGE_FORMAT.usePackage(PACKAGE_CL);
133    PACKAGE_FORMAT.usePackage(PACKAGE_EXT);
134    PACKAGE_XP.usePackage(PACKAGE_CL);
135    PACKAGE_PRECOMPILER.addNickname("PRE");
136    PACKAGE_PRECOMPILER.usePackage(PACKAGE_CL);
137    PACKAGE_PRECOMPILER.usePackage(PACKAGE_EXT);
138    PACKAGE_PRECOMPILER.usePackage(PACKAGE_SYS);
139    PACKAGE_SEQUENCE.usePackage(PACKAGE_CL);
140  }
141
142  // End-of-file marker.
143  public static final LispObject EOF = new LispObject();
144
145  public static boolean profiling;
146
147  public static boolean sampling;
148
149  public static volatile boolean sampleNow;
150
151  // args must not be null!
152  public static final LispObject funcall(LispObject fun, LispObject[] args,
153                                         LispThread thread)
154
155  {
156    thread._values = null;
157
158    // 26-07-2009: For some reason we cannot "just" call the array version;
159    // it causes an error (Wrong number of arguments for LOOP-FOR-IN)
160    // which is probably a sign of an issue in our design?
161    switch (args.length)
162      {
163      case 0:
164        return thread.execute(fun);
165      case 1:
166        return thread.execute(fun, args[0]);
167      case 2:
168        return thread.execute(fun, args[0], args[1]);
169      case 3:
170        return thread.execute(fun, args[0], args[1], args[2]);
171      case 4:
172        return thread.execute(fun, args[0], args[1], args[2], args[3]);
173      case 5:
174        return thread.execute(fun, args[0], args[1], args[2], args[3],
175                              args[4]);
176      case 6:
177        return thread.execute(fun, args[0], args[1], args[2], args[3],
178                              args[4], args[5]);
179      case 7:
180        return thread.execute(fun, args[0], args[1], args[2], args[3],
181                              args[4], args[5], args[6]);
182      case 8:
183        return thread.execute(fun, args[0], args[1], args[2], args[3],
184                              args[4], args[5], args[6], args[7]);
185      default:
186        return thread.execute(fun, args);
187    }
188  }
189
190  public static final LispObject macroexpand(LispObject form,
191                                             final Environment env,
192                                             final LispThread thread)
193
194  {
195    LispObject expanded = NIL;
196    while (true)
197      {
198        form = macroexpand_1(form, env, thread);
199        LispObject[] values = thread._values;
200        if (values[1] == NIL)
201          {
202            values[1] = expanded;
203            return form;
204          }
205        expanded = T;
206      }
207  }
208
209  public static final LispObject macroexpand_1(final LispObject form,
210                                               final Environment env,
211                                               final LispThread thread)
212
213  {
214    if (form instanceof Cons)
215      {
216        LispObject car = ((Cons)form).car;
217        if (car instanceof Symbol)
218          {
219            LispObject obj = env.lookupFunction(car);
220            if (obj instanceof Autoload)
221              {
222                Autoload autoload = (Autoload) obj;
223                autoload.load();
224                obj = car.getSymbolFunction();
225              }
226            if (obj instanceof SpecialOperator)
227              {
228                obj = get(car, Symbol.MACROEXPAND_MACRO, null);
229                if (obj instanceof Autoload)
230                  {
231                    Autoload autoload = (Autoload) obj;
232                    autoload.load();
233                    obj = get(car, Symbol.MACROEXPAND_MACRO, null);
234                  }
235              }
236            if (obj instanceof MacroObject)
237              {
238                LispObject expander = ((MacroObject)obj).expander;
239                if (profiling)
240                  if (!sampling)
241                    expander.incrementCallCount();
242                LispObject hook =
243                  coerceToFunction(Symbol.MACROEXPAND_HOOK.symbolValue(thread));
244                return thread.setValues(hook.execute(expander, form, env),
245                                        T);
246              }
247          }
248      }
249    else if (form instanceof Symbol)
250      {
251        Symbol symbol = (Symbol) form;
252        LispObject obj = null;
253        if (symbol.isSpecialVariable())
254          obj = thread.lookupSpecial(symbol);
255        else
256          obj = env.lookup(symbol);
257        if (obj == null)
258          obj = symbol.getSymbolValue();
259        if (obj instanceof SymbolMacro)
260          return thread.setValues(((SymbolMacro)obj).getExpansion(), T);
261      }
262    // Not a macro.
263    return thread.setValues(form, NIL);
264  }
265
266  // ### interactive-eval
267  private static final Primitive INTERACTIVE_EVAL =
268    new Primitive("interactive-eval", PACKAGE_SYS, true)
269    {
270      @Override
271      public LispObject execute(LispObject object)
272      {
273        final LispThread thread = LispThread.currentThread();
274        thread.setSpecialVariable(Symbol.MINUS, object);
275        LispObject result;
276        try
277          {
278            result = thread.execute(Symbol.EVAL.getSymbolFunction(), object);
279          }
280        catch (OutOfMemoryError e)
281          {
282            return error(new LispError("Out of memory."));
283          }
284        catch (StackOverflowError e)
285          {
286            thread.setSpecialVariable(_SAVED_BACKTRACE_,
287                                      thread.backtrace(0));
288            return error(new StorageCondition("Stack overflow."));
289          }
290        catch (ControlTransfer c)
291          {
292            throw c;
293          }
294        catch (Throwable t) // ControlTransfer handled above
295          {
296            Debug.trace(t);
297            thread.setSpecialVariable(_SAVED_BACKTRACE_,
298                                      thread.backtrace(0));
299            return error(new LispError("Caught " + t + "."));
300          }
301        Debug.assertTrue(result != null);
302        thread.setSpecialVariable(Symbol.STAR_STAR_STAR,
303                                  thread.safeSymbolValue(Symbol.STAR_STAR));
304        thread.setSpecialVariable(Symbol.STAR_STAR,
305                                  thread.safeSymbolValue(Symbol.STAR));
306        thread.setSpecialVariable(Symbol.STAR, result);
307        thread.setSpecialVariable(Symbol.PLUS_PLUS_PLUS,
308                                  thread.safeSymbolValue(Symbol.PLUS_PLUS));
309        thread.setSpecialVariable(Symbol.PLUS_PLUS,
310                                  thread.safeSymbolValue(Symbol.PLUS));
311        thread.setSpecialVariable(Symbol.PLUS,
312                                  thread.safeSymbolValue(Symbol.MINUS));
313        LispObject[] values = thread._values;
314        thread.setSpecialVariable(Symbol.SLASH_SLASH_SLASH,
315                                  thread.safeSymbolValue(Symbol.SLASH_SLASH));
316        thread.setSpecialVariable(Symbol.SLASH_SLASH,
317                                  thread.safeSymbolValue(Symbol.SLASH));
318        if (values != null)
319          {
320            LispObject slash = NIL;
321            for (int i = values.length; i-- > 0;)
322              slash = new Cons(values[i], slash);
323            thread.setSpecialVariable(Symbol.SLASH, slash);
324          }
325        else
326          thread.setSpecialVariable(Symbol.SLASH, new Cons(result));
327        return result;
328      }
329    };
330
331  private static final void pushJavaStackFrames()
332  {
333      final LispThread thread = LispThread.currentThread();
334      final StackTraceElement[] frames = thread.getJavaStackTrace();
335
336      // Search for last Primitive in the StackTrace; that was the
337      // last entry point from Lisp.
338      int last = frames.length - 1;
339      for (int i = 0; i<= last; i++) {
340          if (frames[i].getClassName().startsWith("org.armedbear.lisp.Primitive"))
341            last = i;
342      }
343      // Do not include the first three frames:
344      //   Thread.getStackTrace, LispThread.getJavaStackTrace,
345      //   Lisp.pushJavaStackFrames.
346      while (last > 2) {
347        thread.pushStackFrame(new JavaStackFrame(frames[last]));
348        last--;
349      }
350  }
351
352
353  public static final LispObject error(LispObject condition)
354  {
355    pushJavaStackFrames();
356    return Symbol.ERROR.execute(condition);
357  }
358
359  public static final int ierror(LispObject condition)
360  {
361    error(condition);
362    return 0; // Not reached
363  }
364
365  public static final String serror(LispObject condition)
366  {
367    error(condition);
368    return ""; // Not reached
369  }
370
371
372  public static final LispObject error(LispObject condition, LispObject message)
373  {
374    pushJavaStackFrames();
375    return Symbol.ERROR.execute(condition, Keyword.FORMAT_CONTROL, message);
376  }
377
378  public static final int ierror(LispObject condition, LispObject message)
379  {
380    error(condition, message);
381    return 0; // Not reached
382  }
383
384  public static final String serror(LispObject condition, LispObject message)
385  {
386    error(condition, message);
387    return ""; // Not reached
388  }
389
390
391
392  public static final LispObject type_error(LispObject datum,
393                                            LispObject expectedType)
394
395  {
396    return error(new TypeError(datum, expectedType));
397  }
398
399  public static volatile boolean interrupted;
400
401  public static synchronized final void setInterrupted(boolean b)
402  {
403    interrupted = b;
404  }
405
406  public static final void handleInterrupt()
407  {
408    setInterrupted(false);
409    Symbol.BREAK.getSymbolFunction().execute();
410    setInterrupted(false);
411  }
412
413  // Used by the compiler.
414  public static final LispObject loadTimeValue(LispObject obj)
415
416  {
417    final LispThread thread = LispThread.currentThread();
418    if (Symbol.LOAD_TRUENAME.symbolValue(thread) != NIL)
419      return eval(obj, new Environment(), thread);
420    else
421      return NIL;
422  }
423
424  public static final LispObject eval(LispObject obj)
425
426  {
427    return eval(obj, new Environment(), LispThread.currentThread());
428  }
429
430  public static final LispObject eval(final LispObject obj,
431                                      final Environment env,
432                                      final LispThread thread)
433
434  {
435    thread._values = null;
436    if (interrupted)
437      handleInterrupt();
438    if (thread.isDestroyed())
439      throw new ThreadDestroyed();
440    if (obj instanceof Symbol)
441      {
442        Symbol symbol = (Symbol)obj;
443        LispObject result;
444        if (symbol.isSpecialVariable())
445          {
446            if (symbol.constantp())
447              return symbol.getSymbolValue();
448            else
449              result = thread.lookupSpecial(symbol);
450          }
451        else if (env.isDeclaredSpecial(symbol))
452          result = thread.lookupSpecial(symbol);
453        else
454          result = env.lookup(symbol);
455        if (result == null)
456          {
457            result = symbol.getSymbolValue();
458            if (result == null)
459              return error(new UnboundVariable(obj));
460          }
461        if (result instanceof SymbolMacro)
462          return eval(((SymbolMacro)result).getExpansion(), env, thread);
463        return result;
464      }
465    else if (obj instanceof Cons)
466      {
467        LispObject first = ((Cons)obj).car;
468        if (first instanceof Symbol)
469          {
470            LispObject fun = env.lookupFunction(first);
471            if (fun instanceof SpecialOperator)
472              {
473                if (profiling)
474                  if (!sampling)
475                    fun.incrementCallCount();
476                // Don't eval args!
477                return fun.execute(((Cons)obj).cdr, env);
478              }
479            if (fun instanceof MacroObject)
480              return eval(macroexpand(obj, env, thread), env, thread);
481            if (fun instanceof Autoload)
482              {
483                Autoload autoload = (Autoload) fun;
484                autoload.load();
485                return eval(obj, env, thread);
486              }
487            return evalCall(fun != null ? fun : first,
488                            ((Cons)obj).cdr, env, thread);
489          }
490        else
491          {
492            if (first.car() == Symbol.LAMBDA)
493              {
494                Closure closure = new Closure(first, env);
495                return evalCall(closure, ((Cons)obj).cdr, env, thread);
496              }
497            else
498              return error(new ProgramError("Illegal function object: " +
499                                             first.writeToString()));
500          }
501      }
502    else
503      return obj;
504  }
505
506  public static final int CALL_REGISTERS_MAX = 8;
507
508  // Also used in JProxy.java.
509  public static final LispObject evalCall(LispObject function,
510                                             LispObject args,
511                                             Environment env,
512                                             LispThread thread)
513
514  {
515    if (args == NIL)
516      return thread.execute(function);
517    LispObject first = eval(args.car(), env, thread);
518    args = ((Cons)args).cdr;
519    if (args == NIL)
520      {
521        thread._values = null;
522        return thread.execute(function, first);
523      }
524    LispObject second = eval(args.car(), env, thread);
525    args = ((Cons)args).cdr;
526    if (args == NIL)
527      {
528        thread._values = null;
529        return thread.execute(function, first, second);
530      }
531    LispObject third = eval(args.car(), env, thread);
532    args = ((Cons)args).cdr;
533    if (args == NIL)
534      {
535        thread._values = null;
536        return thread.execute(function, first, second, third);
537      }
538    LispObject fourth = eval(args.car(), env, thread);
539    args = ((Cons)args).cdr;
540    if (args == NIL)
541      {
542        thread._values = null;
543        return thread.execute(function, first, second, third, fourth);
544      }
545    LispObject fifth = eval(args.car(), env, thread);
546    args = ((Cons)args).cdr;
547    if (args == NIL)
548      {
549        thread._values = null;
550        return thread.execute(function, first, second, third, fourth, fifth);
551      }
552    LispObject sixth = eval(args.car(), env, thread);
553    args = ((Cons)args).cdr;
554    if (args == NIL)
555      {
556        thread._values = null;
557        return thread.execute(function, first, second, third, fourth, fifth,
558                              sixth);
559      }
560    LispObject seventh = eval(args.car(), env, thread);
561    args = ((Cons)args).cdr;
562    if (args == NIL)
563      {
564        thread._values = null;
565        return thread.execute(function, first, second, third, fourth, fifth,
566                              sixth, seventh);
567      }
568    LispObject eighth = eval(args.car(), env, thread);
569    args = ((Cons)args).cdr;
570    if (args == NIL)
571      {
572        thread._values = null;
573        return thread.execute(function, first, second, third, fourth, fifth,
574                              sixth, seventh, eighth);
575      }
576    // More than CALL_REGISTERS_MAX arguments.
577    final int length = args.length() + CALL_REGISTERS_MAX;
578    LispObject[] array = new LispObject[length];
579    array[0] = first;
580    array[1] = second;
581    array[2] = third;
582    array[3] = fourth;
583    array[4] = fifth;
584    array[5] = sixth;
585    array[6] = seventh;
586    array[7] = eighth;
587    for (int i = CALL_REGISTERS_MAX; i < length; i++)
588      {
589        array[i] = eval(args.car(), env, thread);
590        args = args.cdr();
591      }
592    thread._values = null;
593    return thread.execute(function, array);
594  }
595
596  public static final LispObject parseBody(LispObject body,
597                                           boolean documentationAllowed)
598
599  {
600      LispObject decls = NIL;
601      LispObject doc = NIL;
602
603      while (body != NIL) {
604        LispObject form = body.car();
605        if (documentationAllowed && form instanceof AbstractString
606            && body.cdr() != NIL) {
607          doc = body.car();
608          documentationAllowed = false;
609        } else if (form instanceof Cons && form.car() == Symbol.DECLARE)
610          decls = new Cons(form, decls);
611        else
612          break;
613
614        body = body.cdr();
615      }
616      return list(body, decls.nreverse(), doc);
617  }
618
619  public static final LispObject parseSpecials(LispObject forms)
620
621  {
622    LispObject specials = NIL;
623    while (forms != NIL) {
624      LispObject decls = forms.car();
625
626      Debug.assertTrue(decls instanceof Cons);
627      Debug.assertTrue(decls.car() == Symbol.DECLARE);
628      decls = decls.cdr();
629      while (decls != NIL) {
630        LispObject decl = decls.car();
631
632        if (decl instanceof Cons && decl.car() == Symbol.SPECIAL) {
633            decl = decl.cdr();
634            while (decl != NIL) {
635              specials = new Cons(checkSymbol(decl.car()), specials);
636              decl = decl.cdr();
637            }
638        }
639
640        decls = decls.cdr();
641      }
642
643      forms = forms.cdr();
644    }
645
646    return specials;
647  }
648
649  public static final LispObject progn(LispObject body, Environment env,
650                                       LispThread thread)
651
652  {
653    LispObject result = NIL;
654    while (body != NIL)
655      {
656        result = eval(body.car(), env, thread);
657        body = ((Cons)body).cdr;
658      }
659    return result;
660  }
661
662  public static final LispObject preprocessTagBody(LispObject body,
663                                                   Environment env)
664
665  {
666    LispObject localTags = NIL; // Tags that are local to this TAGBODY.
667    while (body != NIL)
668      {
669        LispObject current = body.car();
670        body = ((Cons)body).cdr;
671        if (current instanceof Cons)
672          continue;
673        // It's a tag.
674        env.addTagBinding(current, body);
675        localTags = new Cons(current, localTags);
676      }
677    return localTags;
678  }
679
680  /** Throws a Go exception to cause a non-local transfer
681   * of control event, after checking that the extent of
682   * the catching tagbody hasn't ended yet.
683   *
684   * This version is used by the compiler.
685   */
686  public static final LispObject nonLocalGo(LispObject tagbody,
687                                            LispObject tag)
688
689  {
690    if (tagbody == null)
691      return error(new ControlError("Unmatched tag "
692                                    + tag.writeToString() +
693                                    " for GO outside lexical extent."));
694
695    throw new Go(tagbody, tag);
696  }
697
698  /** Throws a Go exception to cause a non-local transfer
699   * of control event, after checking that the extent of
700   * the catching tagbody hasn't ended yet.
701   *
702   * This version is used by the interpreter.
703   */
704  public static final LispObject nonLocalGo(Binding binding,
705                                            LispObject tag)
706
707  {
708    if (binding.env.inactive)
709      return error(new ControlError("Unmatched tag "
710                                    + binding.symbol.writeToString() +
711                                    " for GO outside of lexical extent."));
712
713    throw new Go(binding.env, binding.symbol);
714  }
715
716  /** Throws a Return exception to cause a non-local transfer
717   * of control event, after checking that the extent of
718   * the catching block hasn't ended yet.
719   *
720   * This version is used by the compiler.
721   */
722  public static final LispObject nonLocalReturn(LispObject blockId,
723                                                LispObject blockName,
724                                                LispObject result)
725
726  {
727    if (blockId == null)
728      return error(new ControlError("Unmatched block "
729                                    + blockName.writeToString() + " for " +
730                                    "RETURN-FROM outside lexical extent."));
731
732    throw new Return(blockId, result);
733  }
734
735  /** Throws a Return exception to cause a non-local transfer
736   * of control event, after checking that the extent of
737   * the catching block hasn't ended yet.
738   *
739   * This version is used by the interpreter.
740   */
741  public static final LispObject nonLocalReturn(Binding binding,
742                                                Symbol block,
743                                                LispObject result)
744
745  {
746    if (binding == null)
747      {
748        return error(new LispError("No block named " + block.getName() +
749                                   " is currently visible."));
750      }
751
752    if (binding.env.inactive)
753      return error(new ControlError("Unmatched block "
754                                    + binding.symbol.writeToString() +
755                                    " for RETURN-FROM outside of" +
756                                    " lexical extent."));
757
758    throw new Return(binding.symbol, binding.value, result);
759  }
760
761  public static final LispObject processTagBody(LispObject body,
762                                                LispObject localTags,
763                                                Environment env)
764
765  {
766    LispObject remaining = body;
767    LispThread thread = LispThread.currentThread();
768    while (remaining != NIL)
769      {
770        LispObject current = remaining.car();
771        if (current instanceof Cons)
772          {
773            try {
774              // Handle GO inline if possible.
775              if (((Cons)current).car == Symbol.GO)
776                {
777                  if (interrupted)
778                    handleInterrupt();
779                  LispObject tag = current.cadr();
780                  Binding binding = env.getTagBinding(tag);
781                  if (binding == null)
782                    return error(new ControlError("No tag named " +
783                                                  tag.writeToString() +
784                                                  " is currently visible."));
785                  else if (memql(tag, localTags))
786                    {
787                      if (binding.value != null)
788                        {
789                          remaining = binding.value;
790                          continue;
791                        }
792                    }
793                  throw new Go(binding.env, tag);
794                }
795              eval(current, env, thread);
796            }
797            catch (Go go)
798              {
799                LispObject tag;
800                if (go.getTagBody() == env
801                    && memql(tag = go.getTag(), localTags))
802                  {
803                    Binding binding = env.getTagBinding(tag);
804                    if (binding != null && binding.value != null)
805                      {
806                        remaining = binding.value;
807                        continue;
808                      }
809                  }
810                throw go;
811              }
812          }
813        remaining = ((Cons)remaining).cdr;
814      }
815    thread._values = null;
816    return NIL;
817  }
818
819  // Environment wrappers.
820  private static final boolean isSpecial(Symbol sym, LispObject ownSpecials,
821                                         Environment env)
822
823  {
824    if (ownSpecials != null)
825      {
826        if (sym.isSpecialVariable())
827          return true;
828        for (; ownSpecials != NIL; ownSpecials = ownSpecials.cdr())
829          {
830            if (sym == ownSpecials.car())
831              return true;
832          }
833      }
834    return false;
835  }
836
837  public static final void bindArg(LispObject ownSpecials,
838                                      Symbol sym, LispObject value,
839                                      Environment env, LispThread thread)
840
841  {
842    if (isSpecial(sym, ownSpecials, env)) {
843      env.declareSpecial(sym);
844      thread.bindSpecial(sym, value);
845    }
846    else
847      env.bind(sym, value);
848  }
849
850
851  public static final Cons list(LispObject obj1, LispObject... remaining)
852  {
853    Cons theList = null;
854    if (remaining.length > 0) {
855      theList = new Cons(remaining[remaining.length-1]);
856      for (int i = remaining.length - 2; i >= 0; i--)
857        theList = new Cons(remaining[i], theList);
858    }
859    return (theList == null) ? new Cons(obj1) : new Cons(obj1, theList);
860  }
861
862  @Deprecated
863  public static final Cons list1(LispObject obj1)
864  {
865    return new Cons(obj1);
866  }
867
868  @Deprecated
869  public static final Cons list2(LispObject obj1, LispObject obj2)
870  {
871    return new Cons(obj1, new Cons(obj2));
872  }
873
874  @Deprecated
875  public static final Cons list3(LispObject obj1, LispObject obj2,
876                                 LispObject obj3)
877  {
878    return new Cons(obj1, new Cons(obj2, new Cons(obj3)));
879  }
880
881  @Deprecated
882  public static final Cons list4(LispObject obj1, LispObject obj2,
883                                 LispObject obj3, LispObject obj4)
884  {
885    return new Cons(obj1,
886                    new Cons(obj2,
887                             new Cons(obj3,
888                                      new Cons(obj4))));
889  }
890
891  @Deprecated
892  public static final Cons list5(LispObject obj1, LispObject obj2,
893                                 LispObject obj3, LispObject obj4,
894                                 LispObject obj5)
895  {
896    return new Cons(obj1,
897                    new Cons(obj2,
898                             new Cons(obj3,
899                                      new Cons(obj4,
900                                               new Cons(obj5)))));
901  }
902
903  @Deprecated
904  public static final Cons list6(LispObject obj1, LispObject obj2,
905                                 LispObject obj3, LispObject obj4,
906                                 LispObject obj5, LispObject obj6)
907  {
908    return new Cons(obj1,
909                    new Cons(obj2,
910                             new Cons(obj3,
911                                      new Cons(obj4,
912                                               new Cons(obj5,
913                                                        new Cons(obj6))))));
914  }
915
916  @Deprecated
917  public static final Cons list7(LispObject obj1, LispObject obj2,
918                                 LispObject obj3, LispObject obj4,
919                                 LispObject obj5, LispObject obj6,
920                                 LispObject obj7)
921  {
922    return new Cons(obj1,
923                    new Cons(obj2,
924                             new Cons(obj3,
925                                      new Cons(obj4,
926                                               new Cons(obj5,
927                                                        new Cons(obj6,
928                                                                 new Cons(obj7)))))));
929  }
930
931  @Deprecated
932  public static final Cons list8(LispObject obj1, LispObject obj2,
933                                 LispObject obj3, LispObject obj4,
934                                 LispObject obj5, LispObject obj6,
935                                 LispObject obj7, LispObject obj8)
936  {
937    return new Cons(obj1,
938                    new Cons(obj2,
939                             new Cons(obj3,
940                                      new Cons(obj4,
941                                               new Cons(obj5,
942                                                        new Cons(obj6,
943                                                                 new Cons(obj7,
944                                                                          new Cons(obj8))))))));
945  }
946
947  @Deprecated
948  public static final Cons list9(LispObject obj1, LispObject obj2,
949                                 LispObject obj3, LispObject obj4,
950                                 LispObject obj5, LispObject obj6,
951                                 LispObject obj7, LispObject obj8,
952                                 LispObject obj9)
953  {
954    return new Cons(obj1,
955                    new Cons(obj2,
956                             new Cons(obj3,
957                                      new Cons(obj4,
958                                               new Cons(obj5,
959                                                        new Cons(obj6,
960                                                                 new Cons(obj7,
961                                                                          new Cons(obj8,
962                                                                                   new Cons(obj9)))))))));
963  }
964
965  // Used by the compiler.
966  public static final LispObject multipleValueList(LispObject result)
967
968  {
969    LispThread thread = LispThread.currentThread();
970    LispObject[] values = thread._values;
971    if (values == null)
972      return new Cons(result);
973    thread._values = null;
974    LispObject list = NIL;
975    for (int i = values.length; i-- > 0;)
976      list = new Cons(values[i], list);
977    return list;
978  }
979
980  // Used by the compiler for MULTIPLE-VALUE-CALLs with a single values form.
981  public static final LispObject multipleValueCall1(LispObject result,
982                                                    LispObject function,
983                                                    LispThread thread)
984
985  {
986    LispObject[] values = thread._values;
987    thread._values = null;
988    if (values == null)
989      return thread.execute(coerceToFunction(function), result);
990    else
991      return funcall(coerceToFunction(function), values, thread);
992  }
993
994  public static final void progvBindVars(LispObject symbols,
995                                         LispObject values,
996                                         LispThread thread)
997
998  {
999    for (LispObject list = symbols; list != NIL; list = list.cdr())
1000      {
1001        Symbol symbol = checkSymbol(list.car());
1002        LispObject value;
1003        if (values != NIL)
1004          {
1005            value = values.car();
1006            values = values.cdr();
1007          }
1008        else
1009          {
1010            // "If too few values are supplied, the remaining symbols are
1011            // bound and then made to have no value."
1012            value = null;
1013          }
1014        thread.bindSpecial(symbol, value);
1015      }
1016  }
1017
1018  public static Symbol checkSymbol(LispObject obj)
1019  {             
1020          if (obj instanceof Symbol)     
1021                  return (Symbol) obj;         
1022          return (Symbol)// Not reached.       
1023              type_error(obj, Symbol.SYMBOL);
1024  }
1025
1026  public static final LispObject checkList(LispObject obj)
1027
1028  {
1029    if (obj.listp())
1030      return obj;
1031    return type_error(obj, Symbol.LIST);
1032  }
1033
1034  public static final AbstractArray checkArray(LispObject obj)
1035
1036  {
1037          if (obj instanceof AbstractArray)       
1038                  return (AbstractArray) obj;         
1039          return (AbstractArray)// Not reached.       
1040        type_error(obj, Symbol.ARRAY);
1041  }
1042
1043  public static final AbstractVector checkVector(LispObject obj)
1044
1045  {
1046          if (obj instanceof AbstractVector)     
1047                  return (AbstractVector) obj;         
1048          return (AbstractVector)// Not reached.       
1049        type_error(obj, Symbol.VECTOR);
1050  }
1051
1052  public static final DoubleFloat checkDoubleFloat(LispObject obj)
1053
1054  {
1055          if (obj instanceof DoubleFloat)
1056                  return (DoubleFloat) obj;
1057          return (DoubleFloat)// Not reached.
1058            type_error(obj, Symbol.DOUBLE_FLOAT);
1059  }
1060
1061  public static final SingleFloat checkSingleFloat(LispObject obj)
1062
1063  {
1064          if (obj instanceof SingleFloat)
1065                  return (SingleFloat) obj;
1066          return (SingleFloat)// Not reached.
1067            type_error(obj, Symbol.SINGLE_FLOAT);
1068  }
1069
1070  public static final StackFrame checkStackFrame(LispObject obj)
1071
1072  {
1073          if (obj instanceof StackFrame)     
1074                  return (StackFrame) obj;         
1075          return (StackFrame)// Not reached.       
1076            type_error(obj, Symbol.STACK_FRAME);
1077  }
1078
1079  static
1080  {
1081    // ### *gensym-counter*
1082    Symbol.GENSYM_COUNTER.initializeSpecial(Fixnum.ZERO);
1083  }
1084
1085  public static final Symbol gensym(LispThread thread)
1086
1087  {
1088    return gensym("G", thread);
1089  }
1090
1091  public static final Symbol gensym(String prefix, LispThread thread)
1092
1093  {
1094    StringBuilder sb = new StringBuilder(prefix);
1095    SpecialBinding binding = thread.getSpecialBinding(Symbol.GENSYM_COUNTER);
1096    final LispObject oldValue;
1097    if (binding != null) {
1098        oldValue = binding.value;
1099        if (oldValue instanceof Fixnum
1100                || oldValue instanceof Bignum)
1101          binding.value = oldValue.incr();
1102        else {
1103           Symbol.GENSYM_COUNTER.setSymbolValue(Fixnum.ZERO);
1104           error(new TypeError("The value of *GENSYM-COUNTER* was not a nonnegative integer. Old value: " +
1105                                oldValue.writeToString() + " New value: 0"));
1106        }
1107    } else {
1108        // we're manipulating a global resource
1109        // make sure we operate thread-safely
1110        synchronized (Symbol.GENSYM_COUNTER) {
1111            oldValue = Symbol.GENSYM_COUNTER.getSymbolValue();
1112            if (oldValue instanceof Fixnum
1113                    || oldValue instanceof Bignum)
1114                Symbol.GENSYM_COUNTER.setSymbolValue(oldValue.incr());
1115            else {
1116               Symbol.GENSYM_COUNTER.setSymbolValue(Fixnum.ZERO);
1117               error(new TypeError("The value of *GENSYM-COUNTER* was not a nonnegative integer. Old value: " +
1118                                    oldValue.writeToString() + " New value: 0"));
1119            }
1120        }
1121    }
1122     
1123    // Decimal representation.
1124    if (oldValue instanceof Fixnum)
1125      sb.append(((Fixnum)oldValue).value);
1126    else if (oldValue instanceof Bignum)
1127      sb.append(((Bignum)oldValue).value.toString());
1128
1129    return new Symbol(new SimpleString(sb));
1130  }
1131
1132  public static final String javaString(LispObject arg)
1133
1134  {
1135    if (arg instanceof AbstractString)
1136      return arg.getStringValue();
1137    if (arg instanceof Symbol)
1138      return ((Symbol)arg).getName();
1139    if (arg instanceof LispCharacter)
1140      return String.valueOf(new char[] {((LispCharacter)arg).value});
1141    type_error(arg, list(Symbol.OR, Symbol.STRING, Symbol.SYMBOL,
1142                               Symbol.CHARACTER));
1143    // Not reached.
1144    return null;
1145  }
1146
1147  public static final LispObject number(long n)
1148  {
1149    if (n >= Integer.MIN_VALUE && n <= Integer.MAX_VALUE)
1150      return Fixnum.getInstance((int)n);
1151    else
1152      return Bignum.getInstance(n);
1153  }
1154
1155  private static final BigInteger INT_MIN = BigInteger.valueOf(Integer.MIN_VALUE);
1156  private static final BigInteger INT_MAX = BigInteger.valueOf(Integer.MAX_VALUE);
1157
1158  public static final LispObject number(BigInteger numerator,
1159                                        BigInteger denominator)
1160
1161  {
1162    if (denominator.signum() == 0)
1163      error(new DivisionByZero());
1164    if (denominator.signum() < 0)
1165      {
1166        numerator = numerator.negate();
1167        denominator = denominator.negate();
1168      }
1169    BigInteger gcd = numerator.gcd(denominator);
1170    if (!gcd.equals(BigInteger.ONE))
1171      {
1172        numerator = numerator.divide(gcd);
1173        denominator = denominator.divide(gcd);
1174      }
1175    if (denominator.equals(BigInteger.ONE))
1176      return number(numerator);
1177    else
1178      return new Ratio(numerator, denominator);
1179  }
1180
1181  public static final LispObject number(BigInteger n)
1182  {
1183    if (n.compareTo(INT_MIN) >= 0 && n.compareTo(INT_MAX) <= 0)
1184      return Fixnum.getInstance(n.intValue());
1185    else
1186      return Bignum.getInstance(n);
1187  }
1188
1189  public static final int mod(int number, int divisor)
1190
1191  {
1192    final int r;
1193    try
1194      {
1195        r = number % divisor;
1196      }
1197    catch (ArithmeticException e)
1198      {
1199        error(new ArithmeticError("Division by zero."));
1200        // Not reached.
1201        return 0;
1202      }
1203    if (r == 0)
1204      return r;
1205    if (divisor < 0)
1206      {
1207        if (number > 0)
1208          return r + divisor;
1209      }
1210    else
1211      {
1212        if (number < 0)
1213          return r + divisor;
1214      }
1215    return r;
1216  }
1217
1218  // Adapted from SBCL.
1219  public static final int mix(long x, long y)
1220  {
1221    long xy = x * 3 + y;
1222    return (int) (536870911L & (441516657L ^ xy ^ (xy >> 5)));
1223  }
1224
1225  // Used by the compiler.
1226  public static final LispObject readObjectFromString(String s)
1227  {
1228    return new StringInputStream(s).read(true, NIL, false,
1229                                         LispThread.currentThread(),
1230                                         Stream.faslReadtable);
1231  }
1232
1233    @Deprecated
1234  public static final LispObject loadCompiledFunction(final String namestring)
1235  {
1236      Pathname name = new Pathname(namestring);
1237      byte[] bytes = readFunctionBytes(name);
1238      if (bytes != null)
1239        return loadClassBytes(bytes);
1240
1241      return null;
1242  }
1243
1244  public static final byte[] readFunctionBytes(final Pathname name) {
1245      final LispThread thread = LispThread.currentThread();
1246      Pathname load = null;
1247      LispObject truenameFasl = Symbol.LOAD_TRUENAME_FASL.symbolValue(thread);
1248      LispObject truename = Symbol.LOAD_TRUENAME.symbolValue(thread);
1249      Pathname fasl = null;
1250      if (truenameFasl instanceof Pathname) {
1251          load = Pathname.mergePathnames(name, (Pathname)truenameFasl, Keyword.NEWEST);
1252      } else if (truename instanceof Pathname) {
1253          load = Pathname.mergePathnames(name, (Pathname) truename, Keyword.NEWEST);
1254      } else {
1255          if (!Pathname.truename(name).equals(NIL)) {
1256              load = name;
1257          } else {
1258              load = null;
1259          }
1260      }
1261      InputStream input = null;
1262      if (load != null) {
1263          input = load.getInputStream();
1264      } else { 
1265          // Make a last-ditch attempt to load from the boot classpath XXX OSGi hack
1266          URL url = null;
1267          try {
1268              url = Lisp.class.getResource(name.getNamestring());
1269              input = url.openStream();
1270          } catch (IOException e) {
1271              error(new LispError("Failed to read class bytes from boot class " + url));
1272          }
1273      }
1274      byte[] bytes = new byte[4096];
1275      try {
1276          if (input == null) {
1277                  Debug.trace("Pathname: " + name);
1278                  Debug.trace("LOAD_TRUENAME_FASL: " + truenameFasl);
1279                  Debug.trace("LOAD_TRUENAME: " + truename);
1280                  Debug.assertTrue(input != null);
1281          }
1282
1283          int n = 0;
1284          java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
1285          try {
1286              while (n >= 0) {
1287                  n = input.read(bytes, 0, 4096);
1288                if (n >= 0) {
1289                    baos.write(bytes, 0, n);
1290                }
1291            }
1292          } catch (IOException e) {
1293              Debug.trace("Failed to read bytes from "
1294                          + "'" + name.getNamestring() + "'");
1295              return null;
1296          }
1297          bytes = baos.toByteArray();
1298      } finally {
1299          try {
1300              input.close();
1301          } catch (IOException e) {
1302              Debug.trace("Failed to close InputStream: " + e);
1303          }
1304      }
1305      return bytes;
1306  }
1307
1308    public static final Function makeCompiledFunctionFromClass(Class<?> c) {
1309      try {
1310  if (c != null) {
1311      Function obj = (Function)c.newInstance();
1312      return obj;
1313        } else {
1314            return null;
1315        }
1316      }
1317      catch (InstantiationException e) {} // ### FIXME
1318      catch (IllegalAccessException e) {} // ### FIXME
1319
1320      return null;
1321    }
1322
1323
1324  public static final LispObject loadCompiledFunction(InputStream in, int size)
1325  {
1326      byte[] bytes = readFunctionBytes(in, size);
1327      if (bytes != null)
1328        return loadClassBytes(bytes);
1329      else
1330        return error(new FileError("Can't read file off stream."));
1331  }
1332
1333
1334
1335  private static final byte[] readFunctionBytes(InputStream in, int size)
1336  {
1337    try
1338      {
1339        byte[] bytes = new byte[size];
1340        int bytesRemaining = size;
1341        int bytesRead = 0;
1342        while (bytesRemaining > 0)
1343          {
1344            int n = in.read(bytes, bytesRead, bytesRemaining);
1345            if (n < 0)
1346              break;
1347            bytesRead += n;
1348            bytesRemaining -= n;
1349          }
1350        in.close();
1351        if (bytesRemaining > 0)
1352          Debug.trace("bytesRemaining = " + bytesRemaining);
1353
1354        return bytes;
1355      }
1356    catch (IOException t)
1357      {
1358        Debug.trace(t); // FIXME: call error()?
1359      }
1360    return null;
1361  }
1362
1363    public static final Function loadClassBytes(byte[] bytes)
1364    {
1365      return loadClassBytes(bytes, new JavaClassLoader());
1366    }
1367
1368    public static final Function loadClassBytes(byte[] bytes,
1369                                                JavaClassLoader cl)
1370    {
1371        Class<?> c = cl.loadClassFromByteArray(null, bytes, 0, bytes.length);
1372  Function obj = makeCompiledFunctionFromClass(c);
1373  if (obj != null) {
1374      obj.setClassBytes(bytes);
1375  }
1376  return obj;
1377    }
1378
1379
1380  public static final LispObject makeCompiledClosure(LispObject template,
1381                                                     ClosureBinding[] context)
1382
1383  {
1384    return ((CompiledClosure)template).dup().setContext(context);
1385  }
1386
1387  public static final String safeWriteToString(LispObject obj)
1388  {
1389    try {
1390        return obj.writeToString();
1391      }
1392    catch (NullPointerException e)
1393      {
1394        Debug.trace(e);
1395        return "null";
1396      }
1397  }
1398
1399  public static final boolean isValidSetfFunctionName(LispObject obj)
1400  {
1401    if (obj instanceof Cons)
1402      {
1403        Cons cons = (Cons) obj;
1404        if (cons.car == Symbol.SETF && cons.cdr instanceof Cons)
1405          {
1406            Cons cdr = (Cons) cons.cdr;
1407            return (cdr.car instanceof Symbol && cdr.cdr == NIL);
1408          }
1409      }
1410    return false;
1411  }
1412
1413  public static final boolean isValidMacroFunctionName(LispObject obj)
1414  {
1415    if (obj instanceof Cons)
1416      {
1417        Cons cons = (Cons) obj;
1418        if (cons.car == Symbol.MACRO_FUNCTION && cons.cdr instanceof Cons)
1419          {
1420            Cons cdr = (Cons) cons.cdr;
1421            return (cdr.car instanceof Symbol && cdr.cdr == NIL);
1422          }
1423      }
1424    return false;
1425  }
1426
1427
1428  public static final LispObject FUNCTION_NAME =
1429    list(Symbol.OR,
1430          Symbol.SYMBOL,
1431          list(Symbol.CONS,
1432                list(Symbol.EQL, Symbol.SETF),
1433                list(Symbol.CONS, Symbol.SYMBOL, Symbol.NULL)));
1434
1435  public static final LispObject UNSIGNED_BYTE_8 =
1436    list(Symbol.UNSIGNED_BYTE, Fixnum.constants[8]);
1437
1438  public static final LispObject UNSIGNED_BYTE_16 =
1439    list(Symbol.UNSIGNED_BYTE, Fixnum.constants[16]);
1440
1441  public static final LispObject UNSIGNED_BYTE_32 =
1442    list(Symbol.UNSIGNED_BYTE, Fixnum.constants[32]);
1443
1444  public static final LispObject UNSIGNED_BYTE_32_MAX_VALUE =
1445    Bignum.getInstance(4294967296L);
1446
1447  public static final LispObject getUpgradedArrayElementType(LispObject type)
1448
1449  {
1450    if (type instanceof Symbol)
1451      {
1452        if (type == Symbol.CHARACTER || type == Symbol.BASE_CHAR ||
1453            type == Symbol.STANDARD_CHAR)
1454          return Symbol.CHARACTER;
1455        if (type == Symbol.BIT)
1456          return Symbol.BIT;
1457        if (type == NIL)
1458          return NIL;
1459      }
1460    if (type == BuiltInClass.CHARACTER)
1461      return Symbol.CHARACTER;
1462    if (type instanceof Cons)
1463      {
1464        if (type.equal(UNSIGNED_BYTE_8))
1465          return type;
1466        if (type.equal(UNSIGNED_BYTE_16))
1467          return type;
1468        if (type.equal(UNSIGNED_BYTE_32))
1469          return type;
1470        LispObject car = type.car();
1471        if (car == Symbol.INTEGER)
1472          {
1473            LispObject lower = type.cadr();
1474            LispObject upper = type.cdr().cadr();
1475            // Convert to inclusive bounds.
1476            if (lower instanceof Cons)
1477              lower = lower.car().incr();
1478            if (upper instanceof Cons)
1479              upper = upper.car().decr();
1480            if (lower.integerp() && upper.integerp())
1481              {
1482                if (lower instanceof Fixnum && upper instanceof Fixnum)
1483                  {
1484                    int l = ((Fixnum)lower).value;
1485                    if (l >= 0)
1486                      {
1487                        int u = ((Fixnum)upper).value;
1488                        if (u <= 1)
1489                          return Symbol.BIT;
1490                        if (u <= 255)
1491                          return UNSIGNED_BYTE_8;
1492                        if (u <= 65535)
1493                          return UNSIGNED_BYTE_16;
1494                        return UNSIGNED_BYTE_32;
1495                      }
1496                  }
1497                if (lower.isGreaterThanOrEqualTo(Fixnum.ZERO))
1498                  {
1499                    if (lower.isLessThan(UNSIGNED_BYTE_32_MAX_VALUE))
1500                      {
1501                        if (upper.isLessThan(UNSIGNED_BYTE_32_MAX_VALUE))
1502                          return UNSIGNED_BYTE_32;
1503                      }
1504                  }
1505              }
1506          }
1507        else if (car == Symbol.EQL)
1508          {
1509            LispObject obj = type.cadr();
1510            if (obj instanceof Fixnum)
1511              {
1512                int val = ((Fixnum)obj).value;
1513                if (val >= 0)
1514                  {
1515                    if (val <= 1)
1516                      return Symbol.BIT;
1517                    if (val <= 255)
1518                      return UNSIGNED_BYTE_8;
1519                    if (val <= 65535)
1520                      return UNSIGNED_BYTE_16;
1521                    return UNSIGNED_BYTE_32;
1522                  }
1523              }
1524            else if (obj instanceof Bignum)
1525              {
1526                if (obj.isGreaterThanOrEqualTo(Fixnum.ZERO))
1527                  {
1528                    if (obj.isLessThan(UNSIGNED_BYTE_32_MAX_VALUE))
1529                      return UNSIGNED_BYTE_32;
1530                  }
1531              }
1532          }
1533        else if (car == Symbol.MEMBER)
1534          {
1535            LispObject rest = type.cdr();
1536            while (rest != NIL)
1537              {
1538                LispObject obj = rest.car();
1539                if (obj instanceof LispCharacter)
1540                  rest = rest.cdr();
1541                else
1542                  return T;
1543              }
1544            return Symbol.CHARACTER;
1545          }
1546      }
1547    return T;
1548  }
1549
1550  public static final byte coerceLispObjectToJavaByte(LispObject obj)
1551
1552  {
1553          return (byte)Fixnum.getValue(obj);
1554  }
1555
1556  public static final LispObject coerceJavaByteToLispObject(byte b)
1557  {
1558    return Fixnum.constants[((int)b) & 0xff];
1559  }
1560
1561  public static final LispCharacter checkCharacter(LispObject obj)
1562
1563  {
1564          if (obj instanceof LispCharacter) 
1565                  return (LispCharacter) obj;         
1566          return (LispCharacter) // Not reached.       
1567        type_error(obj, Symbol.CHARACTER);
1568  }
1569
1570  public static final Package checkPackage(LispObject obj)
1571
1572  {
1573          if (obj instanceof Package)     
1574                  return (Package) obj;         
1575          return (Package) // Not reached.       
1576        type_error(obj, Symbol.PACKAGE);
1577  }
1578
1579  public static final Function checkFunction(LispObject obj)
1580
1581  {
1582          if (obj instanceof Function)   
1583                  return (Function) obj;         
1584          return (Function) // Not reached.       
1585        type_error(obj, Symbol.FUNCTION);
1586  }
1587
1588  public static final Stream checkStream(LispObject obj)
1589
1590  {
1591          if (obj instanceof Stream)     
1592                  return (Stream) obj;         
1593          return (Stream) // Not reached.       
1594        type_error(obj, Symbol.STREAM);
1595  }
1596
1597  public static final Stream checkCharacterInputStream(LispObject obj)
1598
1599  {
1600          final Stream stream = checkStream(obj);
1601          if (stream.isCharacterInputStream())     
1602                  return stream;                       
1603          return (Stream) // Not reached.                     
1604          error(new TypeError("The value " + obj.writeToString() +
1605                        " is not a character input stream."));
1606  }
1607
1608  public static final Stream checkCharacterOutputStream(LispObject obj)
1609
1610  {
1611          final Stream stream = checkStream(obj);
1612          if (stream.isCharacterOutputStream())     
1613                  return stream;                       
1614        return (Stream) // Not reached.
1615        error(new TypeError("The value " + obj.writeToString() +
1616                            " is not a character output stream."));
1617  }
1618
1619  public static final Stream checkBinaryInputStream(LispObject obj)
1620
1621  {
1622          final Stream stream = checkStream(obj);
1623          if (stream.isBinaryInputStream())     
1624                  return stream;                       
1625        return (Stream) // Not reached.
1626        error(new TypeError("The value " + obj.writeToString() +
1627                             " is not a binary input stream."));
1628  }
1629 
1630  public static final Stream outSynonymOf(LispObject obj)
1631
1632  {       
1633          if (obj instanceof Stream)
1634            return (Stream) obj;
1635          if (obj == T)
1636            return checkCharacterOutputStream(Symbol.TERMINAL_IO.symbolValue());
1637          if (obj == NIL)
1638            return checkCharacterOutputStream(Symbol.STANDARD_OUTPUT.symbolValue());
1639          return (Stream)         // Not reached.
1640          type_error(obj, Symbol.STREAM);
1641  }
1642
1643  public static final Stream inSynonymOf(LispObject obj)
1644
1645  {
1646    if (obj instanceof Stream)
1647      return (Stream) obj;
1648    if (obj == T)
1649      return checkCharacterInputStream(Symbol.TERMINAL_IO.symbolValue());
1650    if (obj == NIL)
1651      return checkCharacterInputStream(Symbol.STANDARD_INPUT.symbolValue());
1652          return (Stream)         // Not reached.
1653          type_error(obj, Symbol.STREAM);
1654  }
1655
1656  public static final void writeByte(int n, LispObject obj)
1657
1658  {
1659    if (n < 0 || n > 255)
1660      type_error(Fixnum.getInstance(n), UNSIGNED_BYTE_8);
1661    checkStream(obj)._writeByte(n);
1662  }
1663
1664  public static final Readtable checkReadtable(LispObject obj)
1665
1666  {
1667          if (obj instanceof Readtable)   
1668                  return (Readtable) obj;         
1669          return (Readtable)// Not reached.       
1670          type_error(obj, Symbol.READTABLE);
1671  }
1672 
1673  public final static AbstractString checkString(LispObject obj) 
1674
1675  {
1676          if (obj instanceof AbstractString)           
1677                  return (AbstractString) obj;                   
1678          return (AbstractString)// Not reached.               
1679              type_error(obj, Symbol.STRING);
1680  }
1681 
1682  public final static Layout checkLayout(LispObject obj) 
1683
1684  {
1685          if (obj instanceof Layout)           
1686                  return (Layout) obj;                   
1687          return (Layout)// Not reached.               
1688                type_error(obj, Symbol.LAYOUT);
1689  }
1690
1691  public static final Readtable designator_readtable(LispObject obj)
1692
1693  {
1694    if (obj == NIL)
1695      obj = STANDARD_READTABLE.symbolValue();
1696    if (obj == null)
1697        throw new NullPointerException();
1698    return checkReadtable(obj);
1699  }
1700
1701  public static final Environment checkEnvironment(LispObject obj)
1702
1703  {
1704          if (obj instanceof Environment)         
1705                  return (Environment) obj;         
1706          return (Environment)// Not reached.       
1707        type_error(obj, Symbol.ENVIRONMENT);
1708  }
1709
1710  public static final void checkBounds(int start, int end, int length)
1711
1712  {
1713    if (start < 0 || end < 0 || start > end || end > length)
1714      {
1715        StringBuilder sb = new StringBuilder("The bounding indices ");
1716        sb.append(start);
1717        sb.append(" and ");
1718        sb.append(end);
1719        sb.append(" are bad for a sequence of length ");
1720        sb.append(length);
1721        sb.append('.');
1722        error(new TypeError(sb.toString()));
1723      }
1724  }
1725
1726  public static final LispObject coerceToFunction(LispObject obj)
1727
1728  {
1729    if (obj instanceof Function)
1730      return obj;
1731    if (obj instanceof StandardGenericFunction)
1732      return obj;
1733    if (obj instanceof Symbol)
1734      {
1735        LispObject fun = obj.getSymbolFunction();
1736        if (fun instanceof Function)
1737          return (Function) fun;
1738      }
1739    else if (obj instanceof Cons && obj.car() == Symbol.LAMBDA)
1740      return new Closure(obj, new Environment());
1741    error(new UndefinedFunction(obj));
1742    // Not reached.
1743    return null;
1744  }
1745
1746  // Returns package or throws exception.
1747  public static final Package coerceToPackage(LispObject obj)
1748
1749  {
1750    if (obj instanceof Package)
1751      return (Package) obj;
1752    Package pkg = Packages.findPackage(javaString(obj));
1753    if (pkg != null)
1754      return pkg;
1755    error(new PackageError(obj.writeToString() + " is not the name of a package."));
1756    // Not reached.
1757    return null;
1758  }
1759
1760  public static Pathname coerceToPathname(LispObject arg)
1761
1762  {
1763    if (arg instanceof Pathname)
1764      return (Pathname) arg;
1765    if (arg instanceof AbstractString)
1766      return Pathname.parseNamestring((AbstractString)arg);
1767    if (arg instanceof FileStream)
1768      return ((FileStream)arg).getPathname();
1769    if (arg instanceof JarStream)
1770      return ((JarStream)arg).getPathname();
1771    if (arg instanceof URLStream)
1772      return ((URLStream)arg).getPathname();
1773    type_error(arg, list(Symbol.OR, Symbol.PATHNAME,
1774                         Symbol.STRING, Symbol.FILE_STREAM,
1775                         Symbol.JAR_STREAM, Symbol.URL_STREAM));
1776    // Not reached.
1777    return null;
1778  }
1779
1780  public static LispObject assq(LispObject item, LispObject alist)
1781
1782  {
1783    while (alist instanceof Cons)
1784      {
1785        LispObject entry = ((Cons)alist).car;
1786        if (entry instanceof Cons)
1787          {
1788            if (((Cons)entry).car == item)
1789              return entry;
1790          }
1791        else if (entry != NIL)
1792          return type_error(entry, Symbol.LIST);
1793        alist = ((Cons)alist).cdr;
1794      }
1795    if (alist != NIL)
1796      return type_error(alist, Symbol.LIST);
1797    return NIL;
1798  }
1799
1800  public static final boolean memq(LispObject item, LispObject list)
1801
1802  {
1803    while (list instanceof Cons)
1804      {
1805        if (item == ((Cons)list).car)
1806          return true;
1807        list = ((Cons)list).cdr;
1808      }
1809    if (list != NIL)
1810      type_error(list, Symbol.LIST);
1811    return false;
1812  }
1813
1814  public static final boolean memql(LispObject item, LispObject list)
1815
1816  {
1817    while (list instanceof Cons)
1818      {
1819        if (item.eql(((Cons)list).car))
1820          return true;
1821        list = ((Cons)list).cdr;
1822      }
1823    if (list != NIL)
1824      type_error(list, Symbol.LIST);
1825    return false;
1826  }
1827
1828  // Property lists.
1829  public static final LispObject getf(LispObject plist, LispObject indicator,
1830                                      LispObject defaultValue)
1831
1832  {
1833    LispObject list = plist;
1834    while (list != NIL)
1835      {
1836        if (list.car() == indicator)
1837          return list.cadr();
1838        if (list.cdr() instanceof Cons)
1839          list = list.cddr();
1840        else
1841          return error(new TypeError("Malformed property list: " +
1842                                      plist.writeToString()));
1843      }
1844    return defaultValue;
1845  }
1846
1847  public static final LispObject get(LispObject symbol, LispObject indicator)
1848
1849  {
1850    LispObject list = checkSymbol(symbol).getPropertyList();
1851    while (list != NIL)
1852      {
1853        if (list.car() == indicator)
1854          return list.cadr();
1855        list = list.cddr();
1856      }
1857    return NIL;
1858  }
1859
1860  public static final LispObject get(LispObject symbol, LispObject indicator,
1861                                     LispObject defaultValue)
1862
1863  {
1864    LispObject list = checkSymbol(symbol).getPropertyList();
1865    while (list != NIL)
1866      {
1867        if (list.car() == indicator)
1868          return list.cadr();
1869        list = list.cddr();
1870      }
1871    return defaultValue;
1872  }
1873
1874  public static final LispObject put(Symbol symbol, LispObject indicator,
1875                                     LispObject value)
1876
1877  {
1878    LispObject list = symbol.getPropertyList();
1879    while (list != NIL)
1880      {
1881        if (list.car() == indicator)
1882          {
1883            // Found it!
1884            LispObject rest = list.cdr();
1885            rest.setCar(value);
1886            return value;
1887          }
1888        list = list.cddr();
1889      }
1890    // Not found.
1891    symbol.setPropertyList(new Cons(indicator,
1892                                    new Cons(value,
1893                                             symbol.getPropertyList())));
1894    return value;
1895  }
1896
1897  public static final LispObject putf(LispObject plist, LispObject indicator,
1898                                      LispObject value)
1899
1900  {
1901    LispObject list = plist;
1902    while (list != NIL)
1903      {
1904        if (list.car() == indicator)
1905          {
1906            // Found it!
1907            LispObject rest = list.cdr();
1908            rest.setCar(value);
1909            return plist;
1910          }
1911        list = list.cddr();
1912      }
1913    // Not found.
1914    return new Cons(indicator, new Cons(value, plist));
1915  }
1916
1917  public static final LispObject remprop(Symbol symbol, LispObject indicator)
1918
1919  {
1920    LispObject list = checkList(symbol.getPropertyList());
1921    LispObject prev = null;
1922    while (list != NIL)
1923      {
1924        if (!(list.cdr() instanceof Cons))
1925          error(new ProgramError("The symbol " + symbol.writeToString() +
1926                                  " has an odd number of items in its property list."));
1927        if (list.car() == indicator)
1928          {
1929            // Found it!
1930            if (prev != null)
1931              prev.setCdr(list.cddr());
1932            else
1933              symbol.setPropertyList(list.cddr());
1934            return T;
1935          }
1936        prev = list.cdr();
1937        list = list.cddr();
1938      }
1939    // Not found.
1940    return NIL;
1941  }
1942
1943  public static final String format(LispObject formatControl,
1944                                    LispObject formatArguments)
1945
1946  {
1947    final LispThread thread = LispThread.currentThread();
1948    String control = formatControl.getStringValue();
1949    LispObject[] args = formatArguments.copyToArray();
1950    StringBuffer sb = new StringBuffer();
1951    if (control != null)
1952      {
1953        final int limit = control.length();
1954        int j = 0;
1955        final int NEUTRAL = 0;
1956        final int TILDE = 1;
1957        int state = NEUTRAL;
1958        for (int i = 0; i < limit; i++)
1959          {
1960            char c = control.charAt(i);
1961            if (state == NEUTRAL)
1962              {
1963                if (c == '~')
1964                  state = TILDE;
1965                else
1966                  sb.append(c);
1967              }
1968            else if (state == TILDE)
1969              {
1970                if (c == 'A' || c == 'a')
1971                  {
1972                    if (j < args.length)
1973                      {
1974                        LispObject obj = args[j++];
1975                        final SpecialBindingsMark mark = thread.markSpecialBindings();
1976                        thread.bindSpecial(Symbol.PRINT_ESCAPE, NIL);
1977                        thread.bindSpecial(Symbol.PRINT_READABLY, NIL);
1978                        try {
1979                            sb.append(obj.writeToString());
1980                        }
1981                        finally {
1982                            thread.resetSpecialBindings(mark);
1983                        }
1984                      }
1985                  }
1986                else if (c == 'S' || c == 's')
1987                  {
1988                    if (j < args.length)
1989                      {
1990                        LispObject obj = args[j++];
1991                        final SpecialBindingsMark mark = thread.markSpecialBindings();
1992                        thread.bindSpecial(Symbol.PRINT_ESCAPE, T);
1993                        try {
1994                            sb.append(obj.writeToString());
1995                        }
1996                        finally {
1997                            thread.resetSpecialBindings(mark);
1998                        }
1999                      }
2000                  }
2001                else if (c == 'D' || c == 'd')
2002                  {
2003                    if (j < args.length)
2004                      {
2005                        LispObject obj = args[j++];
2006                        final SpecialBindingsMark mark = thread.markSpecialBindings();
2007                        thread.bindSpecial(Symbol.PRINT_ESCAPE, NIL);
2008                        thread.bindSpecial(Symbol.PRINT_RADIX, NIL);
2009                        thread.bindSpecial(Symbol.PRINT_BASE, Fixnum.constants[10]);
2010                        try {
2011                            sb.append(obj.writeToString());
2012                        }
2013                        finally {
2014                            thread.resetSpecialBindings(mark);
2015                        }
2016                      }
2017                  }
2018                else if (c == 'X' || c == 'x')
2019                  {
2020                    if (j < args.length)
2021                      {
2022                        LispObject obj = args[j++];
2023                        final SpecialBindingsMark mark = thread.markSpecialBindings();
2024                        thread.bindSpecial(Symbol.PRINT_ESCAPE, NIL);
2025                        thread.bindSpecial(Symbol.PRINT_RADIX, NIL);
2026                        thread.bindSpecial(Symbol.PRINT_BASE, Fixnum.constants[16]);
2027                        try {
2028                            sb.append(obj.writeToString());
2029                        }
2030                        finally {
2031                            thread.resetSpecialBindings(mark);
2032                        }
2033                      }
2034                  }
2035                else if (c == '%')
2036                  {
2037                    sb.append('\n');
2038                  }
2039                state = NEUTRAL;
2040              }
2041            else
2042              {
2043                // There are no other valid states.
2044                Debug.assertTrue(false);
2045              }
2046          }
2047      }
2048    return sb.toString();
2049  }
2050
2051  public static final Symbol intern(String name, Package pkg)
2052  {
2053    return pkg.intern(name);
2054  }
2055
2056  // Used by the compiler.
2057  public static final Symbol internInPackage(String name, String packageName)
2058
2059  {
2060    Package pkg = Packages.findPackage(packageName);
2061    if (pkg == null)
2062      error(new LispError(packageName + " is not the name of a package."));
2063    return pkg.intern(name);
2064  }
2065
2066  public static final Symbol internKeyword(String s)
2067  {
2068    return PACKAGE_KEYWORD.intern(s);
2069  }
2070
2071  // The compiler's object table.
2072  static final Hashtable<String,LispObject> objectTable =
2073          new Hashtable<String,LispObject>();
2074
2075  public static final LispObject recall(String key)
2076  {
2077    return objectTable.remove(key);
2078  }
2079
2080  public static final LispObject recall(SimpleString key)
2081  {
2082    return objectTable.remove(key.getStringValue());
2083  }
2084
2085  // ### remember
2086  public static final Primitive REMEMBER =
2087    new Primitive("remember", PACKAGE_SYS, true)
2088    {
2089      @Override
2090      public LispObject execute(LispObject key, LispObject value)
2091
2092      {
2093        objectTable.put(key.getStringValue(), value);
2094        return NIL;
2095      }
2096    };
2097
2098  public static final Symbol internSpecial(String name, Package pkg,
2099                                           LispObject value)
2100  {
2101    Symbol symbol = pkg.intern(name);
2102    symbol.setSpecial(true);
2103    symbol.setSymbolValue(value);
2104    return symbol;
2105  }
2106
2107  public static final Symbol internConstant(String name, Package pkg,
2108                                            LispObject value)
2109  {
2110    Symbol symbol = pkg.intern(name);
2111    symbol.initializeConstant(value);
2112    return symbol;
2113  }
2114
2115  public static final Symbol exportSpecial(String name, Package pkg,
2116                                           LispObject value)
2117  {
2118    Symbol symbol = pkg.intern(name);
2119    pkg.export(symbol); // FIXME Inefficient!
2120    symbol.setSpecial(true);
2121    symbol.setSymbolValue(value);
2122    return symbol;
2123  }
2124
2125  public static final Symbol exportConstant(String name, Package pkg,
2126                                            LispObject value)
2127  {
2128    Symbol symbol = pkg.intern(name);
2129    pkg.export(symbol); // FIXME Inefficient!
2130    symbol.initializeConstant(value);
2131    return symbol;
2132  }
2133
2134  static
2135  {
2136    String userDir = System.getProperty("user.dir");
2137    if (userDir != null && userDir.length() > 0)
2138      {
2139        if (userDir.charAt(userDir.length() - 1) != File.separatorChar)
2140          userDir = userDir.concat(File.separator);
2141      }
2142    // This string will be converted to a pathname when Pathname.java is loaded.
2143    Symbol.DEFAULT_PATHNAME_DEFAULTS.initializeSpecial(new SimpleString(userDir));
2144  }
2145
2146  static
2147  {
2148    Symbol._PACKAGE_.initializeSpecial(PACKAGE_CL_USER);
2149  }
2150
2151  public static final Package getCurrentPackage()
2152  {
2153    return (Package) Symbol._PACKAGE_.symbolValueNoThrow();
2154  }
2155
2156
2157
2158  public static final void resetIO(Stream in, Stream out)
2159  {
2160    stdin = in;
2161    stdout = out;
2162    Symbol.STANDARD_INPUT.setSymbolValue(stdin);
2163    Symbol.STANDARD_OUTPUT.setSymbolValue(stdout);
2164    Symbol.ERROR_OUTPUT.setSymbolValue(stdout);
2165    Symbol.TRACE_OUTPUT.setSymbolValue(stdout);
2166    Symbol.TERMINAL_IO.setSymbolValue(new TwoWayStream(stdin, stdout, true));
2167    Symbol.QUERY_IO.setSymbolValue(new TwoWayStream(stdin, stdout, true));
2168    Symbol.DEBUG_IO.setSymbolValue(new TwoWayStream(stdin, stdout, true));
2169  }
2170
2171  // Used in org/armedbear/j/JLisp.java.
2172  public static final void resetIO()
2173  {
2174    resetIO(new Stream(Symbol.SYSTEM_STREAM, System.in, Symbol.CHARACTER, true),
2175            new Stream(Symbol.SYSTEM_STREAM, System.out, Symbol.CHARACTER, true));
2176  }
2177
2178  public static final TwoWayStream getTerminalIO()
2179  {
2180    return (TwoWayStream) Symbol.TERMINAL_IO.symbolValueNoThrow();
2181  }
2182
2183  public static final Stream getStandardInput()
2184  {
2185    return (Stream) Symbol.STANDARD_INPUT.symbolValueNoThrow();
2186  }
2187
2188  public static final Stream getStandardOutput()
2189  {
2190    return checkCharacterOutputStream(Symbol.STANDARD_OUTPUT.symbolValue());
2191  }
2192
2193  static
2194  {
2195    Symbol.CURRENT_READTABLE.initializeSpecial(new Readtable());
2196  }
2197
2198  // ### +standard-readtable+
2199  // internal symbol
2200  public static final Symbol STANDARD_READTABLE =
2201    internConstant("+STANDARD-READTABLE+", PACKAGE_SYS, new Readtable());
2202
2203  public static final Readtable currentReadtable()
2204  {
2205    return (Readtable) Symbol.CURRENT_READTABLE.symbolValue();
2206  }
2207
2208  static
2209  {
2210    Symbol.READ_SUPPRESS.initializeSpecial(NIL);
2211    Symbol.DEBUGGER_HOOK.initializeSpecial(NIL);
2212  }
2213
2214  static
2215  {
2216    Symbol.MOST_POSITIVE_FIXNUM.initializeConstant(Fixnum.getInstance(Integer.MAX_VALUE));
2217    Symbol.MOST_NEGATIVE_FIXNUM.initializeConstant(Fixnum.getInstance(Integer.MIN_VALUE));
2218    Symbol.MOST_POSITIVE_JAVA_LONG.initializeConstant(Bignum.getInstance(Long.MAX_VALUE));
2219    Symbol.MOST_NEGATIVE_JAVA_LONG.initializeConstant(Bignum.getInstance(Long.MIN_VALUE));
2220  }
2221
2222  public static void exit(int status)
2223  {
2224    Interpreter interpreter = Interpreter.getInstance();
2225    if (interpreter != null)
2226      interpreter.kill(status);
2227  }
2228
2229  // ### t
2230  public static final Symbol T = Symbol.T;
2231  static
2232  {
2233    T.initializeConstant(T);
2234  }
2235
2236  static
2237  {
2238    Symbol.READ_EVAL.initializeSpecial(T);
2239  }
2240
2241  // ### *features*
2242  static
2243  {
2244    Symbol.FEATURES.initializeSpecial(NIL);
2245    String osName = System.getProperty("os.name");
2246    if (osName.startsWith("Linux"))
2247      {
2248        Symbol.FEATURES.setSymbolValue(list(Keyword.ARMEDBEAR,
2249                                             Keyword.ABCL,
2250                                             Keyword.COMMON_LISP,
2251                                             Keyword.ANSI_CL,
2252                                             Keyword.UNIX,
2253                                             Keyword.LINUX,
2254                                             Keyword.CDR6));
2255      }
2256    else if (osName.startsWith("SunOS"))
2257      {
2258        Symbol.FEATURES.setSymbolValue(list(Keyword.ARMEDBEAR,
2259                                             Keyword.ABCL,
2260                                             Keyword.COMMON_LISP,
2261                                             Keyword.ANSI_CL,
2262                                             Keyword.UNIX,
2263                                             Keyword.SUNOS,
2264                                             Keyword.CDR6));
2265      }
2266    else if (osName.startsWith("Mac OS X") ||
2267             osName.startsWith("Darwin"))
2268      {
2269        Symbol.FEATURES.setSymbolValue(list(Keyword.ARMEDBEAR,
2270                                             Keyword.ABCL,
2271                                             Keyword.COMMON_LISP,
2272                                             Keyword.ANSI_CL,
2273                                             Keyword.UNIX,
2274                                             Keyword.DARWIN,
2275                                             Keyword.CDR6));
2276      }
2277    else if (osName.startsWith("FreeBSD"))
2278      {
2279        Symbol.FEATURES.setSymbolValue(list(Keyword.ARMEDBEAR,
2280                                             Keyword.ABCL,
2281                                             Keyword.COMMON_LISP,
2282                                             Keyword.ANSI_CL,
2283                                             Keyword.UNIX,
2284                                             Keyword.FREEBSD,
2285                                             Keyword.CDR6));
2286      }
2287    else if (osName.startsWith("OpenBSD"))
2288      {
2289        Symbol.FEATURES.setSymbolValue(list(Keyword.ARMEDBEAR,
2290                                             Keyword.ABCL,
2291                                             Keyword.COMMON_LISP,
2292                                             Keyword.ANSI_CL,
2293                                             Keyword.UNIX,
2294                                             Keyword.OPENBSD,
2295                                             Keyword.CDR6));
2296      }
2297    else if (osName.startsWith("NetBSD"))
2298      {
2299        Symbol.FEATURES.setSymbolValue(list(Keyword.ARMEDBEAR,
2300                                             Keyword.ABCL,
2301                                             Keyword.COMMON_LISP,
2302                                             Keyword.ANSI_CL,
2303                                             Keyword.UNIX,
2304                                             Keyword.NETBSD,
2305                                             Keyword.CDR6));
2306      }
2307    else if (osName.startsWith("Windows"))
2308      {
2309        Symbol.FEATURES.setSymbolValue(list(Keyword.ARMEDBEAR,
2310                                             Keyword.ABCL,
2311                                             Keyword.COMMON_LISP,
2312                                             Keyword.ANSI_CL,
2313                                             Keyword.WINDOWS,
2314                                             Keyword.CDR6));
2315      }
2316    else
2317      {
2318        Symbol.FEATURES.setSymbolValue(list(Keyword.ARMEDBEAR,
2319                                             Keyword.ABCL,
2320                                             Keyword.COMMON_LISP,
2321                                             Keyword.ANSI_CL,
2322                                             Keyword.CDR6));
2323      }
2324  }
2325  static
2326  {
2327    final String version = System.getProperty("java.version");
2328    if (version.startsWith("1.5"))
2329      {
2330        Symbol.FEATURES.setSymbolValue(new Cons(Keyword.JAVA_1_5,
2331                                                Symbol.FEATURES.getSymbolValue()));
2332      }
2333    else if (version.startsWith("1.6"))
2334      {
2335        Symbol.FEATURES.setSymbolValue(new Cons(Keyword.JAVA_1_6,
2336                                                Symbol.FEATURES.getSymbolValue()));
2337      }
2338    else if (version.startsWith("1.7"))
2339      {
2340        Symbol.FEATURES.setSymbolValue(new Cons(Keyword.JAVA_1_7,
2341                                                Symbol.FEATURES.getSymbolValue()));
2342      }
2343  }
2344  static
2345  {
2346    String os_arch = System.getProperty("os.arch");
2347    if(os_arch != null) {
2348      if (os_arch.equals("amd64"))
2349        Symbol.FEATURES.setSymbolValue(new Cons(Keyword.X86_64,
2350                                                Symbol.FEATURES.getSymbolValue()));
2351      else if (os_arch.equals("x86"))
2352        Symbol.FEATURES.setSymbolValue(new Cons(Keyword.X86,
2353                                                Symbol.FEATURES.getSymbolValue()));
2354    }
2355  }
2356
2357  static
2358  {
2359    Symbol.MODULES.initializeSpecial(NIL);
2360  }
2361
2362  static
2363  {
2364    Symbol.LOAD_VERBOSE.initializeSpecial(NIL);
2365    Symbol.LOAD_PRINT.initializeSpecial(NIL);
2366    Symbol.LOAD_PATHNAME.initializeSpecial(NIL);
2367    Symbol.LOAD_TRUENAME.initializeSpecial(NIL);
2368    Symbol.LOAD_TRUENAME_FASL.initializeSpecial(NIL);
2369    Symbol.COMPILE_VERBOSE.initializeSpecial(T);
2370    Symbol.COMPILE_PRINT.initializeSpecial(T);
2371    Symbol._COMPILE_FILE_PATHNAME_.initializeSpecial(NIL);
2372    Symbol.COMPILE_FILE_TRUENAME.initializeSpecial(NIL);
2373  }
2374
2375  // ### *double-colon-package-separators*
2376  // internal symbol
2377  public static final Symbol DOUBLE_COLON_PACKAGE_SEPARATORS =
2378    internSpecial("*DOUBLE-COLON-PACKAGE-SEPARATORS*", PACKAGE_SYS, NIL);
2379
2380  // ### *load-depth*
2381  // internal symbol
2382  public static final Symbol _LOAD_DEPTH_ =
2383    internSpecial("*LOAD-DEPTH*", PACKAGE_SYS, Fixnum.ZERO);
2384
2385  // ### *load-stream*
2386  // internal symbol
2387  public static final Symbol _LOAD_STREAM_ =
2388    internSpecial("*LOAD-STREAM*", PACKAGE_SYS, NIL);
2389
2390  // ### *source*
2391  // internal symbol
2392  public static final Symbol _SOURCE_ =
2393    exportSpecial("*SOURCE*", PACKAGE_SYS, NIL);
2394
2395  // ### *source-position*
2396  // internal symbol
2397  public static final Symbol _SOURCE_POSITION_ =
2398    exportSpecial("*SOURCE-POSITION*", PACKAGE_SYS, NIL);
2399
2400  // ### *autoload-verbose*
2401  // internal symbol
2402  public static final Symbol _AUTOLOAD_VERBOSE_ =
2403    exportSpecial("*AUTOLOAD-VERBOSE*", PACKAGE_EXT, NIL);
2404
2405  // ### *preloading-cache*
2406 public static final Symbol AUTOLOADING_CACHE =
2407   internSpecial("*AUTOLOADING-CACHE*", PACKAGE_SYS, NIL);
2408
2409  // ### *compile-file-type*
2410  public static final String COMPILE_FILE_TYPE = "abcl";
2411  public static final Symbol _COMPILE_FILE_TYPE_ =
2412    internConstant("*COMPILE-FILE-TYPE*", PACKAGE_SYS,
2413                   new SimpleString(COMPILE_FILE_TYPE));
2414
2415  // ### *compile-file-zip*
2416  public static final Symbol _COMPILE_FILE_ZIP_ =
2417    exportSpecial("*COMPILE-FILE-ZIP*", PACKAGE_SYS, T);
2418
2419  static
2420  {
2421    Symbol.MACROEXPAND_HOOK.initializeSpecial(Symbol.FUNCALL);
2422  }
2423
2424  public static final int ARRAY_DIMENSION_MAX = Integer.MAX_VALUE;
2425  static
2426  {
2427    // ### array-dimension-limit
2428    Symbol.ARRAY_DIMENSION_LIMIT.initializeConstant(Fixnum.getInstance(ARRAY_DIMENSION_MAX));
2429  }
2430
2431  // ### char-code-limit
2432  // "The upper exclusive bound on the value returned by the function CHAR-CODE."
2433  public static final int CHAR_MAX = Character.MAX_VALUE;
2434  static
2435  {
2436    Symbol.CHAR_CODE_LIMIT.initializeConstant(Fixnum.getInstance(CHAR_MAX + 1));
2437  }
2438
2439  static
2440  {
2441    Symbol.READ_BASE.initializeSpecial(Fixnum.constants[10]);
2442  }
2443
2444  static
2445  {
2446    Symbol.READ_DEFAULT_FLOAT_FORMAT.initializeSpecial(Symbol.SINGLE_FLOAT);
2447  }
2448
2449  // Printer control variables.
2450  static
2451  {
2452    Symbol.PRINT_ARRAY.initializeSpecial(T);
2453    Symbol.PRINT_BASE.initializeSpecial(Fixnum.constants[10]);
2454    Symbol.PRINT_CASE.initializeSpecial(Keyword.UPCASE);
2455    Symbol.PRINT_CIRCLE.initializeSpecial(NIL);
2456    Symbol.PRINT_ESCAPE.initializeSpecial(T);
2457    Symbol.PRINT_GENSYM.initializeSpecial(T);
2458    Symbol.PRINT_LENGTH.initializeSpecial(NIL);
2459    Symbol.PRINT_LEVEL.initializeSpecial(NIL);
2460    Symbol.PRINT_LINES.initializeSpecial(NIL);
2461    Symbol.PRINT_MISER_WIDTH.initializeSpecial(NIL);
2462    Symbol.PRINT_PPRINT_DISPATCH.initializeSpecial(NIL);
2463    Symbol.PRINT_PRETTY.initializeSpecial(NIL);
2464    Symbol.PRINT_RADIX.initializeSpecial(NIL);
2465    Symbol.PRINT_READABLY.initializeSpecial(NIL);
2466    Symbol.PRINT_RIGHT_MARGIN.initializeSpecial(NIL);
2467  }
2468
2469  public static final Symbol _PRINT_STRUCTURE_ =
2470    exportSpecial("*PRINT-STRUCTURE*", PACKAGE_EXT, T);
2471
2472  // ### *current-print-length*
2473  public static final Symbol _CURRENT_PRINT_LENGTH_ =
2474    exportSpecial("*CURRENT-PRINT-LENGTH*", PACKAGE_SYS, Fixnum.ZERO);
2475
2476  // ### *current-print-level*
2477  public static final Symbol _CURRENT_PRINT_LEVEL_ =
2478    exportSpecial("*CURRENT-PRINT-LEVEL*", PACKAGE_SYS, Fixnum.ZERO);
2479
2480  public static final Symbol _PRINT_FASL_ =
2481    internSpecial("*PRINT-FASL*", PACKAGE_SYS, NIL);
2482
2483  static
2484  {
2485    Symbol._RANDOM_STATE_.initializeSpecial(new RandomState());
2486  }
2487
2488  static
2489  {
2490    Symbol.STAR.initializeSpecial(NIL);
2491    Symbol.STAR_STAR.initializeSpecial(NIL);
2492    Symbol.STAR_STAR_STAR.initializeSpecial(NIL);
2493    Symbol.MINUS.initializeSpecial(NIL);
2494    Symbol.PLUS.initializeSpecial(NIL);
2495    Symbol.PLUS_PLUS.initializeSpecial(NIL);
2496    Symbol.PLUS_PLUS_PLUS.initializeSpecial(NIL);
2497    Symbol.SLASH.initializeSpecial(NIL);
2498    Symbol.SLASH_SLASH.initializeSpecial(NIL);
2499    Symbol.SLASH_SLASH_SLASH.initializeSpecial(NIL);
2500  }
2501
2502  // Floating point constants.
2503  static
2504  {
2505    Symbol.PI.initializeConstant(new DoubleFloat(Math.PI));
2506    Symbol.SHORT_FLOAT_EPSILON.initializeConstant(new SingleFloat((float)5.960465E-8));
2507    Symbol.SINGLE_FLOAT_EPSILON.initializeConstant(new SingleFloat((float)5.960465E-8));
2508    Symbol.DOUBLE_FLOAT_EPSILON.initializeConstant(new DoubleFloat((double)1.1102230246251568E-16));
2509    Symbol.LONG_FLOAT_EPSILON.initializeConstant(new DoubleFloat((double)1.1102230246251568E-16));
2510    Symbol.SHORT_FLOAT_NEGATIVE_EPSILON.initializeConstant(new SingleFloat(2.9802326e-8f));
2511    Symbol.SINGLE_FLOAT_NEGATIVE_EPSILON.initializeConstant(new SingleFloat(2.9802326e-8f));
2512    Symbol.DOUBLE_FLOAT_NEGATIVE_EPSILON.initializeConstant(new DoubleFloat((double)5.551115123125784E-17));
2513    Symbol.LONG_FLOAT_NEGATIVE_EPSILON.initializeConstant(new DoubleFloat((double)5.551115123125784E-17));
2514    Symbol.MOST_POSITIVE_SHORT_FLOAT.initializeConstant(new SingleFloat(Float.MAX_VALUE));
2515    Symbol.MOST_POSITIVE_SINGLE_FLOAT.initializeConstant(new SingleFloat(Float.MAX_VALUE));
2516    Symbol.MOST_POSITIVE_DOUBLE_FLOAT.initializeConstant(new DoubleFloat(Double.MAX_VALUE));
2517    Symbol.MOST_POSITIVE_LONG_FLOAT.initializeConstant(new DoubleFloat(Double.MAX_VALUE));
2518    Symbol.LEAST_POSITIVE_SHORT_FLOAT.initializeConstant(new SingleFloat(Float.MIN_VALUE));
2519    Symbol.LEAST_POSITIVE_SINGLE_FLOAT.initializeConstant(new SingleFloat(Float.MIN_VALUE));
2520    Symbol.LEAST_POSITIVE_DOUBLE_FLOAT.initializeConstant(new DoubleFloat(Double.MIN_VALUE));
2521    Symbol.LEAST_POSITIVE_LONG_FLOAT.initializeConstant(new DoubleFloat(Double.MIN_VALUE));
2522    Symbol.LEAST_POSITIVE_NORMALIZED_SHORT_FLOAT.initializeConstant(new SingleFloat(1.17549435e-38f));
2523    Symbol.LEAST_POSITIVE_NORMALIZED_SINGLE_FLOAT.initializeConstant(new SingleFloat(1.17549435e-38f));
2524    Symbol.LEAST_POSITIVE_NORMALIZED_DOUBLE_FLOAT.initializeConstant(new DoubleFloat(2.2250738585072014e-308d));
2525    Symbol.LEAST_POSITIVE_NORMALIZED_LONG_FLOAT.initializeConstant(new DoubleFloat(2.2250738585072014e-308d));
2526    Symbol.MOST_NEGATIVE_SHORT_FLOAT.initializeConstant(new SingleFloat(- Float.MAX_VALUE));
2527    Symbol.MOST_NEGATIVE_SINGLE_FLOAT.initializeConstant(new SingleFloat(- Float.MAX_VALUE));
2528    Symbol.MOST_NEGATIVE_DOUBLE_FLOAT.initializeConstant(new DoubleFloat(- Double.MAX_VALUE));
2529    Symbol.MOST_NEGATIVE_LONG_FLOAT.initializeConstant(new DoubleFloat(- Double.MAX_VALUE));
2530    Symbol.LEAST_NEGATIVE_SHORT_FLOAT.initializeConstant(new SingleFloat(- Float.MIN_VALUE));
2531    Symbol.LEAST_NEGATIVE_SINGLE_FLOAT.initializeConstant(new SingleFloat(- Float.MIN_VALUE));
2532    Symbol.LEAST_NEGATIVE_DOUBLE_FLOAT.initializeConstant(new DoubleFloat(- Double.MIN_VALUE));
2533    Symbol.LEAST_NEGATIVE_LONG_FLOAT.initializeConstant(new DoubleFloat(- Double.MIN_VALUE));
2534    Symbol.LEAST_NEGATIVE_NORMALIZED_SHORT_FLOAT.initializeConstant(new SingleFloat(-1.17549435e-38f));
2535    Symbol.LEAST_NEGATIVE_NORMALIZED_SINGLE_FLOAT.initializeConstant(new SingleFloat(-1.17549435e-38f));
2536    Symbol.LEAST_NEGATIVE_NORMALIZED_DOUBLE_FLOAT.initializeConstant(new DoubleFloat(-2.2250738585072014e-308d));
2537    Symbol.LEAST_NEGATIVE_NORMALIZED_LONG_FLOAT.initializeConstant(new DoubleFloat(-2.2250738585072014e-308d));
2538  }
2539
2540  static
2541  {
2542    Symbol.BOOLE_CLR.initializeConstant(Fixnum.ZERO);
2543    Symbol.BOOLE_SET.initializeConstant(Fixnum.ONE);
2544    Symbol.BOOLE_1.initializeConstant(Fixnum.TWO);
2545    Symbol.BOOLE_2.initializeConstant(Fixnum.constants[3]);
2546    Symbol.BOOLE_C1.initializeConstant(Fixnum.constants[4]);
2547    Symbol.BOOLE_C2.initializeConstant(Fixnum.constants[5]);
2548    Symbol.BOOLE_AND.initializeConstant(Fixnum.constants[6]);
2549    Symbol.BOOLE_IOR.initializeConstant(Fixnum.constants[7]);
2550    Symbol.BOOLE_XOR.initializeConstant(Fixnum.constants[8]);
2551    Symbol.BOOLE_EQV.initializeConstant(Fixnum.constants[9]);
2552    Symbol.BOOLE_NAND.initializeConstant(Fixnum.constants[10]);
2553    Symbol.BOOLE_NOR.initializeConstant(Fixnum.constants[11]);
2554    Symbol.BOOLE_ANDC1.initializeConstant(Fixnum.constants[12]);
2555    Symbol.BOOLE_ANDC2.initializeConstant(Fixnum.constants[13]);
2556    Symbol.BOOLE_ORC1.initializeConstant(Fixnum.constants[14]);
2557    Symbol.BOOLE_ORC2.initializeConstant(Fixnum.constants[15]);
2558  }
2559
2560  static
2561  {
2562    // ### call-arguments-limit
2563    Symbol.CALL_ARGUMENTS_LIMIT.initializeConstant(Fixnum.constants[50]);
2564  }
2565
2566  static
2567  {
2568    // ### lambda-parameters-limit
2569    Symbol.LAMBDA_PARAMETERS_LIMIT.initializeConstant(Fixnum.constants[50]);
2570  }
2571
2572  static
2573  {
2574    // ### multiple-values-limit
2575    Symbol.MULTIPLE_VALUES_LIMIT.initializeConstant(Fixnum.constants[20]);
2576  }
2577
2578  static
2579  {
2580    // ### internal-time-units-per-second
2581    Symbol.INTERNAL_TIME_UNITS_PER_SECOND.initializeConstant(Fixnum.getInstance(1000));
2582  }
2583
2584  static
2585  {
2586    Symbol.LAMBDA_LIST_KEYWORDS
2587      .initializeConstant(list(Symbol.AND_OPTIONAL,
2588                               Symbol.AND_REST,
2589                               Symbol.AND_KEY,
2590                               Symbol.AND_AUX,
2591                               Symbol.AND_BODY,
2592                               Symbol.AND_WHOLE,
2593                               Symbol.AND_ALLOW_OTHER_KEYS,
2594                               Symbol.AND_ENVIRONMENT));
2595  }
2596
2597  // ### call-registers-limit
2598  public static final Symbol CALL_REGISTERS_LIMIT =
2599    exportConstant("CALL-REGISTERS-LIMIT", PACKAGE_SYS,
2600                   Fixnum.constants[CALL_REGISTERS_MAX]);
2601
2602  // ### *warn-on-redefinition*
2603  public static final Symbol _WARN_ON_REDEFINITION_ =
2604    exportSpecial("*WARN-ON-REDEFINITION*", PACKAGE_EXT, T);
2605
2606  // ### *saved-backtrace*
2607  public static final Symbol _SAVED_BACKTRACE_ =
2608    exportSpecial("*SAVED-BACKTRACE*", PACKAGE_EXT, NIL);
2609
2610  // ### *command-line-argument-list*
2611  public static final Symbol _COMMAND_LINE_ARGUMENT_LIST_ =
2612    exportSpecial("*COMMAND-LINE-ARGUMENT-LIST*", PACKAGE_EXT, NIL);
2613
2614  // ### *batch-mode*
2615  public static final Symbol _BATCH_MODE_ =
2616    exportSpecial("*BATCH-MODE*", PACKAGE_EXT, NIL);
2617
2618  // ### *noinform*
2619  public static final Symbol _NOINFORM_ =
2620    exportSpecial("*NOINFORM*", PACKAGE_SYS, NIL);
2621
2622  // ### *disassembler*
2623  public static final Symbol _DISASSEMBLER_ =
2624    exportSpecial("*DISASSEMBLER*", PACKAGE_EXT,
2625                  new SimpleString("jad -a -p")); // or "jad -dis -p"
2626
2627  // ### *speed* compiler policy
2628  public static final Symbol _SPEED_ =
2629    exportSpecial("*SPEED*", PACKAGE_SYS, Fixnum.ONE);
2630
2631  // ### *space* compiler policy
2632  public static final Symbol _SPACE_ =
2633    exportSpecial("*SPACE*", PACKAGE_SYS, Fixnum.ONE);
2634
2635  // ### *safety* compiler policy
2636  public static final Symbol _SAFETY_ =
2637    exportSpecial("*SAFETY*", PACKAGE_SYS, Fixnum.ONE);
2638
2639  // ### *debug* compiler policy
2640  public static final Symbol _DEBUG_ =
2641    exportSpecial("*DEBUG*", PACKAGE_SYS, Fixnum.ONE);
2642
2643  // ### *explain* compiler policy
2644  public static final Symbol _EXPLAIN_ =
2645    exportSpecial("*EXPLAIN*", PACKAGE_SYS, NIL);
2646
2647  // ### *enable-inline-expansion*
2648  public static final Symbol _ENABLE_INLINE_EXPANSION_ =
2649    exportSpecial("*ENABLE-INLINE-EXPANSION*", PACKAGE_EXT, T);
2650
2651  // ### *require-stack-frame*
2652  public static final Symbol _REQUIRE_STACK_FRAME_ =
2653    exportSpecial("*REQUIRE-STACK-FRAME*", PACKAGE_EXT, NIL);
2654
2655  static
2656  {
2657    Symbol.SUPPRESS_COMPILER_WARNINGS.initializeSpecial(NIL);
2658  }
2659
2660  public static final Symbol _COMPILE_FILE_ENVIRONMENT_ =
2661    exportSpecial("*COMPILE-FILE-ENVIRONMENT*", PACKAGE_SYS, NIL);
2662
2663  public static final LispObject UNBOUND_VALUE = new unboundValue();
2664  static class unboundValue extends LispObject
2665  {
2666    @Override
2667    public String writeToString()
2668    {
2669      return "#<UNBOUND>";
2670    }
2671  }
2672
2673  public static final LispObject NULL_VALUE = new nullValue();
2674  static class nullValue extends LispObject
2675  {
2676    @Override
2677    public String writeToString()
2678    {
2679      return "null";
2680    }
2681  }
2682
2683  public static final Symbol _SLOT_UNBOUND_ =
2684    exportConstant("+SLOT-UNBOUND+", PACKAGE_SYS, UNBOUND_VALUE);
2685
2686  public static final Symbol _CL_PACKAGE_ =
2687    exportConstant("+CL-PACKAGE+", PACKAGE_SYS, PACKAGE_CL);
2688
2689  public static final Symbol _KEYWORD_PACKAGE_ =
2690    exportConstant("+KEYWORD-PACKAGE+", PACKAGE_SYS, PACKAGE_KEYWORD);
2691
2692  // ### *backquote-count*
2693  public static final Symbol _BACKQUOTE_COUNT_ =
2694    internSpecial("*BACKQUOTE-COUNT*", PACKAGE_SYS, Fixnum.ZERO);
2695
2696  // ### *bq-vector-flag*
2697  public static final Symbol _BQ_VECTOR_FLAG_ =
2698    internSpecial("*BQ-VECTOR-FLAG*", PACKAGE_SYS, list(new Symbol("bqv")));
2699
2700  // ### *traced-names*
2701  public static final Symbol _TRACED_NAMES_ =
2702    exportSpecial("*TRACED-NAMES*", PACKAGE_SYS, NIL);
2703
2704  // Floating point traps.
2705  protected static boolean TRAP_OVERFLOW  = true;
2706  protected static boolean TRAP_UNDERFLOW = true;
2707
2708
2709  // Extentions
2710  static {
2711    Symbol._INSPECTOR_HOOK_.initializeSpecial(NIL);
2712  }
2713
2714  private static final void loadClass(String className)
2715  {
2716    try
2717      {
2718        Class.forName(className);
2719      }
2720    catch (ClassNotFoundException e)
2721      {
2722        Debug.trace(e);
2723      }
2724  }
2725
2726  static
2727  {
2728    loadClass("org.armedbear.lisp.Primitives");
2729    loadClass("org.armedbear.lisp.SpecialOperators");
2730    loadClass("org.armedbear.lisp.Extensions");
2731    loadClass("org.armedbear.lisp.CompiledClosure");
2732    loadClass("org.armedbear.lisp.Autoload");
2733    loadClass("org.armedbear.lisp.AutoloadMacro");
2734    loadClass("org.armedbear.lisp.cxr");
2735    loadClass("org.armedbear.lisp.Do");
2736    loadClass("org.armedbear.lisp.dolist");
2737    loadClass("org.armedbear.lisp.dotimes");
2738    loadClass("org.armedbear.lisp.Pathname");
2739    loadClass("org.armedbear.lisp.LispClass");
2740    loadClass("org.armedbear.lisp.BuiltInClass");
2741    loadClass("org.armedbear.lisp.StructureObject");
2742    loadClass("org.armedbear.lisp.ash");
2743    loadClass("org.armedbear.lisp.Java");
2744    loadClass("org.armedbear.lisp.PackageFunctions");
2745    cold = false;
2746  }
2747
2748    private static Stream stdin = new Stream(Symbol.SYSTEM_STREAM, System.in, Symbol.CHARACTER, true);
2749
2750    private static Stream stdout = new Stream(Symbol.SYSTEM_STREAM,System.out, Symbol.CHARACTER, true);
2751
2752  static
2753  {
2754    Symbol.STANDARD_INPUT.initializeSpecial(stdin);
2755    Symbol.STANDARD_OUTPUT.initializeSpecial(stdout);
2756    Symbol.ERROR_OUTPUT.initializeSpecial(stdout);
2757    Symbol.TRACE_OUTPUT.initializeSpecial(stdout);
2758    Symbol.TERMINAL_IO.initializeSpecial(new TwoWayStream(stdin, stdout, true));
2759    Symbol.QUERY_IO.initializeSpecial(new TwoWayStream(stdin, stdout, true));
2760    Symbol.DEBUG_IO.initializeSpecial(new TwoWayStream(stdin, stdout, true));
2761  }
2762
2763}
Note: See TracBrowser for help on using the repository browser.