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

Last change on this file since 15798 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.