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

Last change on this file was 12516, checked in by astalla, 15 years ago

Support for user-extensible sequences, adapted from SBCL.

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