source: branches/0.17.x/abcl/src/org/armedbear/lisp/Primitives.java

Last change on this file was 12254, checked in by ehuelsmann, 16 years ago

Remove 'throws ConditionThrowable?' method annotations:

it's an unchecked exception now, so no need to declare it thrown.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 154.6 KB
Line 
1/*
2 * Primitives.java
3 *
4 * Copyright (C) 2002-2007 Peter Graves
5 * $Id: Primitives.java 12254 2009-11-06 20:07:54Z ehuelsmann $
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 *
21 * As a special exception, the copyright holders of this library give you
22 * permission to link this library with independent modules to produce an
23 * executable, regardless of the license terms of these independent
24 * modules, and to copy and distribute the resulting executable under
25 * terms of your choice, provided that you also meet, for each linked
26 * independent module, the terms and conditions of the license of that
27 * module.  An independent module is a module which is not derived from
28 * or based on this library.  If you modify this library, you may extend
29 * this exception to your version of the library, but you are not
30 * obligated to do so.  If you do not wish to do so, delete this
31 * exception statement from your version.
32 */
33
34package org.armedbear.lisp;
35
36import java.math.BigInteger;
37import java.util.ArrayList;
38
39public final class Primitives extends Lisp
40{
41  // ### *
42  public static final Primitive MULTIPLY =
43    new Primitive(Symbol.STAR, "&rest numbers")
44    {
45      @Override
46      public LispObject execute()
47      {
48        return Fixnum.ONE;
49      }
50      @Override
51      public LispObject execute(LispObject arg)
52      {
53        if (arg.numberp())
54          return arg;
55        return type_error(arg, Symbol.NUMBER);
56      }
57      @Override
58      public LispObject execute(LispObject first, LispObject second)
59
60      {
61        return first.multiplyBy(second);
62      }
63      @Override
64      public LispObject execute(LispObject[] args)
65      {
66        LispObject result = Fixnum.ONE;
67        for (int i = 0; i < args.length; i++)
68          result = result.multiplyBy(args[i]);
69        return result;
70      }
71    };
72
73  // ### /
74  public static final Primitive DIVIDE =
75    new Primitive(Symbol.SLASH, "numerator &rest denominators")
76    {
77      @Override
78      public LispObject execute()
79      {
80        return error(new WrongNumberOfArgumentsException(this));
81      }
82      @Override
83      public LispObject execute(LispObject arg)
84      {
85        return Fixnum.ONE.divideBy(arg);
86      }
87      @Override
88      public LispObject execute(LispObject first, LispObject second)
89
90      {
91        return first.divideBy(second);
92      }
93      @Override
94      public LispObject execute(LispObject[] args)
95      {
96        LispObject result = args[0];
97        for (int i = 1; i < args.length; i++)
98          result = result.divideBy(args[i]);
99        return result;
100      }
101    };
102
103  // ### min
104  public static final Primitive MIN =
105    new Primitive(Symbol.MIN, "&rest reals")
106    {
107      @Override
108      public LispObject execute()
109      {
110        return error(new WrongNumberOfArgumentsException(this));
111      }
112      @Override
113      public LispObject execute(LispObject arg)
114      {
115        if (arg.realp())
116          return arg;
117        return type_error(arg, Symbol.REAL);
118      }
119      @Override
120      public LispObject execute(LispObject first, LispObject second)
121
122      {
123        return first.isLessThan(second) ? first : second;
124      }
125      @Override
126      public LispObject execute(LispObject[] args)
127      {
128        LispObject result = args[0];
129        if (!result.realp())
130          type_error(result, Symbol.REAL);
131        for (int i = 1; i < args.length; i++)
132          {
133            if (args[i].isLessThan(result))
134              result = args[i];
135          }
136        return result;
137      }
138    };
139
140  // ### max
141  public static final Primitive MAX =
142    new Primitive(Symbol.MAX, "&rest reals")
143    {
144      @Override
145      public LispObject execute()
146      {
147        return error(new WrongNumberOfArgumentsException(this));
148      }
149      @Override
150      public LispObject execute(LispObject arg)
151      {
152        if (arg.realp())
153          return arg;
154        return type_error(arg, Symbol.REAL);
155      }
156      @Override
157      public LispObject execute(LispObject first, LispObject second)
158
159      {
160        return first.isGreaterThan(second) ? first : second;
161      }
162      @Override
163      public LispObject execute(LispObject[] args)
164      {
165        LispObject result = args[0];
166        if (!result.realp())
167          type_error(result, Symbol.REAL);
168        for (int i = 1; i < args.length; i++)
169          {
170            if (args[i].isGreaterThan(result))
171              result = args[i];
172          }
173        return result;
174      }
175    };
176
177  // ### identity
178  private static final Primitive IDENTITY =
179    new Primitive(Symbol.IDENTITY, "object")
180    {
181      @Override
182      public LispObject execute(LispObject arg)
183      {
184        return arg;
185      }
186    };
187
188  // ### compiled-function-p
189  private static final Primitive COMPILED_FUNCTION_P =
190    new Primitive(Symbol.COMPILED_FUNCTION_P, "object")
191    {
192      @Override
193      public LispObject execute(LispObject arg)
194      {
195        return arg.typep(Symbol.COMPILED_FUNCTION);
196      }
197    };
198
199  // ### consp
200  private static final Primitive CONSP =
201    new Primitive(Symbol.CONSP, "object")
202    {
203      @Override
204      public LispObject execute(LispObject arg)
205      {
206        return arg instanceof Cons ? T : NIL;
207      }
208    };
209
210  // ### listp
211  private static final Primitive LISTP =
212    new Primitive(Symbol.LISTP, "object")
213    {
214      @Override
215      public LispObject execute(LispObject arg)
216      {
217        return arg.LISTP();
218      }
219    };
220
221  // ### abs
222  private static final Primitive ABS =
223    new Primitive(Symbol.ABS, "number")
224    {
225      @Override
226      public LispObject execute(LispObject arg)
227      {
228        return arg.ABS();
229      }
230    };
231
232  // ### arrayp
233  private static final Primitive ARRAYP =
234    new Primitive(Symbol.ARRAYP, "object")
235    {
236      @Override
237      public LispObject execute(LispObject arg)
238      {
239        return arg instanceof AbstractArray ? T : NIL;
240      }
241    };
242
243  // ### array-has-fill-pointer-p
244  private static final Primitive ARRAY_HAS_FILL_POINTER_P =
245    new Primitive(Symbol.ARRAY_HAS_FILL_POINTER_P, "array")
246    {
247      @Override
248      public LispObject execute(LispObject arg)
249      {
250            return checkArray(arg).hasFillPointer() ? T : NIL;
251          }
252    };
253
254  // ### vectorp
255  private static final Primitive VECTORP =
256    new Primitive(Symbol.VECTORP, "object")
257    {
258      @Override
259      public LispObject execute(LispObject arg)
260      {
261        return arg.VECTORP();
262      }
263    };
264
265  // ### simple-vector-p
266  private static final Primitive SIMPLE_VECTOR_P =
267    new Primitive(Symbol.SIMPLE_VECTOR_P, "object")
268    {
269      @Override
270      public LispObject execute(LispObject arg)
271      {
272        return arg instanceof SimpleVector ? T : NIL;
273      }
274    };
275
276  // ### bit-vector-p
277  private static final Primitive BIT_VECTOR_P =
278    new Primitive(Symbol.BIT_VECTOR_P, "object")
279    {
280      @Override
281      public LispObject execute(LispObject arg)
282      {
283        return arg instanceof AbstractBitVector ? T : NIL;
284      }
285    };
286
287  // ### simple-bit-vector-p
288  private static final Primitive SIMPLE_BIT_VECTOR_P =
289    new Primitive(Symbol.SIMPLE_BIT_VECTOR_P, "object")
290    {
291      @Override
292      public LispObject execute(LispObject arg)
293      {
294        return arg.typep(Symbol.SIMPLE_BIT_VECTOR);
295      }
296    };
297
298  // ### %eval
299  private static final Primitive _EVAL =
300    new Primitive("%eval", PACKAGE_SYS, false, "form")
301    {
302      @Override
303      public LispObject execute(LispObject arg)
304      {
305        return eval(arg, new Environment(), LispThread.currentThread());
306      }
307    };
308
309  // ### eq
310  private static final Primitive EQ = new Primitive(Symbol.EQ, "x y")
311    {
312      @Override
313      public LispObject execute(LispObject first, LispObject second)
314
315      {
316        return first == second ? T : NIL;
317      }
318    };
319
320  // ### eql
321  private static final Primitive EQL = new Primitive(Symbol.EQL, "x y")
322    {
323      @Override
324      public LispObject execute(LispObject first, LispObject second)
325
326      {
327        return first.eql(second) ? T : NIL;
328      }
329    };
330
331  // ### equal
332  private static final Primitive EQUAL = new Primitive(Symbol.EQUAL, "x y")
333    {
334      @Override
335      public LispObject execute(LispObject first, LispObject second)
336
337      {
338        return first.equal(second) ? T : NIL;
339      }
340    };
341
342  // ### equalp
343  private static final Primitive EQUALP = new Primitive(Symbol.EQUALP, "x y")
344    {
345      @Override
346      public LispObject execute(LispObject first, LispObject second)
347
348      {
349        return first.equalp(second) ? T : NIL;
350      }
351    };
352
353  // ### values
354  private static final Primitive VALUES =
355    new Primitive(Symbol.VALUES, "&rest object")
356    {
357      @Override
358      public LispObject execute()
359      {
360        return LispThread.currentThread().setValues();
361      }
362      @Override
363      public LispObject execute(LispObject arg)
364      {
365        return LispThread.currentThread().setValues(arg);
366      }
367      @Override
368      public LispObject execute(LispObject first, LispObject second)
369      {
370        return LispThread.currentThread().setValues(first, second);
371      }
372      @Override
373      public LispObject execute(LispObject first, LispObject second,
374                                LispObject third)
375      {
376        return LispThread.currentThread().setValues(first, second, third);
377      }
378      @Override
379      public LispObject execute(LispObject first, LispObject second,
380                                LispObject third, LispObject fourth)
381      {
382        return LispThread.currentThread().setValues(first, second, third,
383                                                    fourth);
384      }
385      @Override
386      public LispObject execute(LispObject[] args)
387      {
388        return LispThread.currentThread().setValues(args);
389      }
390    };
391
392  // ### values-list list => element*
393  // Returns the elements of the list as multiple values.
394  private static final Primitive VALUES_LIST =
395    new Primitive(Symbol.VALUES_LIST, "list")
396    {
397      @Override
398      public LispObject execute(LispObject arg)
399      {
400        if (arg == NIL)
401          return LispThread.currentThread().setValues();
402        if (arg.cdr() == NIL)
403          return arg.car();
404        return LispThread.currentThread().setValues(arg.copyToArray());
405      }
406    };
407
408  // ### cons
409  private static final Primitive CONS =
410    new Primitive(Symbol.CONS, "object-1 object-2")
411    {
412      @Override
413      public LispObject execute(LispObject first, LispObject second)
414
415      {
416        return new Cons(first, second);
417      }
418    };
419
420  // ### length
421  private static final Primitive LENGTH =
422    new Primitive(Symbol.LENGTH, "sequence")
423    {
424      @Override
425      public LispObject execute(LispObject arg)
426      {
427        return arg.LENGTH();
428      }
429    };
430
431  // ### elt
432  private static final Primitive ELT =
433    new Primitive(Symbol.ELT, "sequence index")
434    {
435      @Override
436      public LispObject execute(LispObject first, LispObject second)
437
438      {
439            return first.elt(Fixnum.getValue(second));
440      }
441    };
442
443  // ### atom
444  private static final Primitive ATOM = new Primitive(Symbol.ATOM, "object")
445    {
446      @Override
447      public LispObject execute(LispObject arg)
448      {
449        return arg instanceof Cons ? NIL : T;
450      }
451    };
452
453  // ### constantp
454  private static final Primitive CONSTANTP =
455    new Primitive(Symbol.CONSTANTP, "form &optional environment")
456    {
457      @Override
458      public LispObject execute(LispObject arg)
459      {
460        return arg.constantp() ? T : NIL;
461      }
462      @Override
463      public LispObject execute(LispObject first, LispObject second)
464
465      {
466        return first.constantp() ? T : NIL;
467      }
468    };
469
470  // ### functionp
471  private static final Primitive FUNCTIONP =
472    new Primitive(Symbol.FUNCTIONP, "object")
473    {
474      @Override
475      public LispObject execute(LispObject arg)
476      {
477        return (arg instanceof Function || arg instanceof StandardGenericFunction) ? T : NIL;
478      }
479    };
480
481  // ### special-operator-p
482  private static final Primitive SPECIAL_OPERATOR_P =
483    new Primitive(Symbol.SPECIAL_OPERATOR_P, "symbol")
484    {
485      @Override
486      public LispObject execute(LispObject arg)
487      {
488        return arg.isSpecialOperator() ? T : NIL;
489      }
490    };
491
492  // ### symbolp
493  private static final Primitive SYMBOLP =
494    new Primitive(Symbol.SYMBOLP, "object")
495    {
496      @Override
497      public LispObject execute(LispObject arg)
498      {
499        return arg instanceof Symbol ? T : NIL;
500      }
501    };
502
503  // ### endp
504  private static final Primitive ENDP = new Primitive(Symbol.ENDP, "list")
505    {
506      @Override
507      public LispObject execute(LispObject arg)
508      {
509        return arg.endp() ? T : NIL;
510      }
511    };
512
513  // ### null
514  private static final Primitive NULL = new Primitive(Symbol.NULL, "object")
515    {
516      @Override
517      public LispObject execute(LispObject arg)
518      {
519        return arg == NIL ? T : NIL;
520      }
521    };
522
523  // ### not
524  private static final Primitive NOT = new Primitive(Symbol.NOT, "x")
525    {
526      @Override
527      public LispObject execute(LispObject arg)
528      {
529        return arg == NIL ? T : NIL;
530      }
531    };
532
533  // ### plusp
534  private static final Primitive PLUSP = new Primitive(Symbol.PLUSP, "real")
535    {
536      @Override
537      public LispObject execute(LispObject arg)
538      {
539        return arg.PLUSP();
540      }
541    };
542
543  // ### minusp
544  private static final Primitive MINUSP =
545    new Primitive(Symbol.MINUSP, "real")
546    {
547      @Override
548      public LispObject execute(LispObject arg)
549      {
550        return arg.MINUSP();
551      }
552    };
553
554  // ### zerop
555  private static final Primitive ZEROP =
556    new Primitive(Symbol.ZEROP, "number")
557    {
558      @Override
559      public LispObject execute(LispObject arg)
560      {
561        return arg.ZEROP();
562      }
563    };
564
565  // ### fixnump
566  private static final Primitive FIXNUMP =
567    new Primitive("fixnump", PACKAGE_EXT, true)
568    {
569      @Override
570      public LispObject execute(LispObject arg)
571      {
572        return arg instanceof Fixnum ? T : NIL;
573      }
574    };
575
576  // ### symbol-value
577  private static final Primitive SYMBOL_VALUE =
578    new Primitive(Symbol.SYMBOL_VALUE, "symbol")
579    {
580      @Override
581      public LispObject execute(LispObject arg)
582      {
583        final LispObject value;
584        value = checkSymbol(arg).symbolValue();
585        if (value instanceof SymbolMacro)
586          return error(new LispError(arg.writeToString() +
587                                      " has no dynamic value."));
588        return value;
589      }
590    };
591
592  // ### set symbol value => value
593  private static final Primitive SET =
594    new Primitive(Symbol.SET, "symbol value")
595    {
596      @Override
597      public LispObject execute(LispObject first, LispObject second)
598
599      {
600            return LispThread.currentThread().setSpecialVariable(checkSymbol(first),
601                                                                 second);
602      }
603    };
604
605  // ### rplaca
606  private static final Primitive RPLACA =
607    new Primitive(Symbol.RPLACA, "cons object")
608    {
609      @Override
610      public LispObject execute(LispObject first, LispObject second)
611
612      {
613        first.setCar(second);
614        return first;
615      }
616    };
617
618  // ### rplacd
619  private static final Primitive RPLACD =
620    new Primitive(Symbol.RPLACD, "cons object")
621    {
622      @Override
623      public LispObject execute(LispObject first, LispObject second)
624
625      {
626        first.setCdr(second);
627        return first;
628      }
629    };
630
631  // ### +
632  private static final Primitive ADD =
633    new Primitive(Symbol.PLUS, "&rest numbers")
634    {
635      @Override
636      public LispObject execute()
637      {
638        return Fixnum.ZERO;
639      }
640      @Override
641      public LispObject execute(LispObject arg)
642      {
643        if (arg.numberp())
644          return arg;
645        return type_error(arg, Symbol.NUMBER);
646      }
647      @Override
648      public LispObject execute(LispObject first, LispObject second)
649
650      {
651        return first.add(second);
652      }
653      @Override
654      public LispObject execute(LispObject first, LispObject second,
655                                LispObject third)
656
657      {
658        return first.add(second).add(third);
659      }
660      @Override
661      public LispObject execute(LispObject[] args)
662      {
663        LispObject result = Fixnum.ZERO;
664        final int length = args.length;
665        for (int i = 0; i < length; i++)
666          result = result.add(args[i]);
667        return result;
668      }
669    };
670
671  // ### 1+
672  private static final Primitive ONE_PLUS =
673    new Primitive(Symbol.ONE_PLUS, "number")
674    {
675      @Override
676      public LispObject execute(LispObject arg)
677      {
678        return arg.incr();
679      }
680    };
681
682  // ### -
683  private static final Primitive SUBTRACT =
684    new Primitive(Symbol.MINUS, "minuend &rest subtrahends")
685    {
686      @Override
687      public LispObject execute()
688      {
689        return error(new WrongNumberOfArgumentsException(this));
690      }
691      @Override
692      public LispObject execute(LispObject arg)
693      {
694        return arg.negate();
695      }
696      @Override
697      public LispObject execute(LispObject first, LispObject second)
698
699      {
700        return first.subtract(second);
701      }
702      @Override
703      public LispObject execute(LispObject[] args)
704      {
705        LispObject result = args[0];
706        for (int i = 1; i < args.length; i++)
707          result = result.subtract(args[i]);
708        return result;
709      }
710    };
711
712  // ### 1-
713  private static final Primitive ONE_MINUS =
714    new Primitive(Symbol.ONE_MINUS, "number")
715    {
716      @Override
717      public LispObject execute(LispObject arg)
718      {
719        return arg.decr();
720      }
721    };
722
723  // ### when
724  private static final SpecialOperator WHEN =
725    new SpecialOperator(Symbol.WHEN)
726    {
727      @Override
728      public LispObject execute(LispObject args, Environment env)
729
730      {
731        if (args == NIL)
732          return error(new WrongNumberOfArgumentsException(this));
733        final LispThread thread = LispThread.currentThread();
734        if (eval(args.car(), env, thread) != NIL)
735          {
736            args = args.cdr();
737            thread.clearValues();
738            return progn(args, env, thread);
739          }
740        return thread.setValues(NIL);
741      }
742    };
743
744  // ### unless
745  private static final SpecialOperator UNLESS =
746    new SpecialOperator(Symbol.UNLESS)
747    {
748      @Override
749      public LispObject execute(LispObject args, Environment env)
750
751      {
752        if (args == NIL)
753          return error(new WrongNumberOfArgumentsException(this));
754        final LispThread thread = LispThread.currentThread();
755        if (eval(args.car(), env, thread) == NIL)
756          {
757            args = args.cdr();
758            thread.clearValues();
759            return progn(args, env, thread);
760          }
761        return thread.setValues(NIL);
762      }
763    };
764
765  // ### %stream-output-object object stream => object
766  private static final Primitive _STREAM_OUTPUT_OBJECT =
767    new Primitive("%stream-output-object", PACKAGE_SYS, true)
768    {
769      @Override
770      public LispObject execute(LispObject first, LispObject second)
771
772      {
773            checkStream(second)._writeString(first.writeToString());
774            return first;
775      }
776    };
777
778  // ### %output-object object stream => object
779  private static final Primitive _OUTPUT_OBJECT =
780    new Primitive("%output-object", PACKAGE_SYS, true)
781    {
782      @Override
783      public LispObject execute(LispObject first, LispObject second)
784
785      {
786        final LispObject out;
787            if (second == T)
788              out = Symbol.TERMINAL_IO.symbolValue();
789            else if (second == NIL)
790              out = Symbol.STANDARD_OUTPUT.symbolValue();
791            else
792              out = second;
793        checkStream(out)._writeString(first.writeToString());
794        return first;
795      }
796    };
797
798  // ### %write-to-string object => string
799  private static final Primitive _WRITE_TO_STRING =
800    new Primitive("%write-to-string", PACKAGE_SYS, false)
801    {
802      @Override
803      public LispObject execute(LispObject arg)
804      {
805        return new SimpleString(arg.writeToString());
806      }
807    };
808
809  // ### %stream-terpri output-stream => nil
810  private static final Primitive _STREAM_TERPRI =
811    new Primitive("%stream-terpri", PACKAGE_SYS, true, "output-stream")
812    {
813      @Override
814      public LispObject execute(LispObject arg)
815      {
816            checkStream(arg)._writeChar('\n');
817            return NIL;
818      }
819    };
820
821  // ### %terpri output-stream => nil
822  private static final Primitive _TERPRI =
823    new Primitive("%terpri", PACKAGE_SYS, false, "output-stream")
824    {
825      @Override
826      public LispObject execute(LispObject arg)
827      {
828        if (arg == T)
829          arg = Symbol.TERMINAL_IO.symbolValue();
830        else if (arg == NIL)
831          arg = Symbol.STANDARD_OUTPUT.symbolValue();
832        final Stream stream;
833        stream = checkStream(arg);
834        return stream.terpri();
835      }
836    };
837
838  // ### %fresh-line
839  // %fresh-line &optional output-stream => generalized-boolean
840  private static final Primitive _FRESH_LINE =
841    new Primitive("%fresh-line", PACKAGE_SYS, false, "output-stream")
842    {
843      @Override
844      public LispObject execute(LispObject arg)
845      {
846        if (arg == T)
847          arg = Symbol.TERMINAL_IO.symbolValue();
848        else if (arg == NIL)
849          arg = Symbol.STANDARD_OUTPUT.symbolValue();
850        final Stream stream;
851        stream = checkStream(arg);
852        return stream.freshLine();
853      }
854    };
855
856  // ### boundp
857  // Determines only whether a symbol has a value in the global environment;
858  // any lexical bindings are ignored.
859  private static final Primitive BOUNDP =
860    new Primitive(Symbol.BOUNDP, "symbol")
861    {
862      @Override
863      public LispObject execute(LispObject arg)
864      {
865        final Symbol symbol;
866        symbol = checkSymbol(arg);
867        // PROGV: "If too few values are supplied, the remaining symbols
868        // are bound and then made to have no value." So BOUNDP must
869        // explicitly check for a binding with no value.
870        SpecialBinding binding =
871          LispThread.currentThread().getSpecialBinding(symbol);
872        if (binding != null)
873          return binding.value != null ? T : NIL;
874        // No binding.
875        return symbol.getSymbolValue() != null ? T : NIL;
876      }
877    };
878
879  // ### fboundp
880  private static final Primitive FBOUNDP =
881    new Primitive(Symbol.FBOUNDP, "name")
882    {
883      @Override
884      public LispObject execute(LispObject arg)
885      {
886        if (arg instanceof Symbol)
887          return arg.getSymbolFunction() != null ? T : NIL;
888        if (isValidSetfFunctionName(arg))
889          {
890            LispObject f = get(arg.cadr(), Symbol.SETF_FUNCTION, null);
891            return f != null ? T : NIL;
892          }
893        return type_error(arg, FUNCTION_NAME);
894      }
895    };
896
897  // ### fmakunbound name => name
898  private static final Primitive FMAKUNBOUND =
899    new Primitive(Symbol.FMAKUNBOUND, "name")
900    {
901      @Override
902      public LispObject execute(LispObject arg)
903      {
904        if (arg instanceof Symbol)
905          {
906            checkSymbol(arg).setSymbolFunction(null);
907            return arg;
908          }
909        if (isValidSetfFunctionName(arg))
910          {
911            remprop((Symbol)arg.cadr(), Symbol.SETF_FUNCTION);
912            return arg;
913          }
914        return type_error(arg, FUNCTION_NAME);
915      }
916    };
917
918  // ### setf-function-name-p
919  private static final Primitive SETF_FUNCTION_NAME_P =
920    new Primitive("setf-function-name-p", PACKAGE_SYS, true, "thing")
921    {
922      @Override
923      public LispObject execute(LispObject arg)
924      {
925        return isValidSetfFunctionName(arg) ? T : NIL;
926      }
927    };
928
929  // ### remprop
930  private static final Primitive REMPROP =
931    new Primitive(Symbol.REMPROP, "symbol indicator")
932    {
933      @Override
934      public LispObject execute(LispObject first, LispObject second)
935
936      {
937        return remprop(checkSymbol(first), second);
938      }
939    };
940
941  // ### append
942  public static final Primitive APPEND =
943    new Primitive(Symbol.APPEND, "&rest lists")
944    {
945      @Override
946      public LispObject execute()
947      {
948        return NIL;
949      }
950      @Override
951      public LispObject execute(LispObject arg)
952      {
953        return arg;
954      }
955      @Override
956      public LispObject execute(LispObject first, LispObject second)
957
958      {
959        if (first == NIL)
960          return second;
961        // APPEND is required to copy its first argument.
962        Cons result = new Cons(first.car());
963        Cons splice = result;
964        first = first.cdr();
965        while (first != NIL)
966          {
967            Cons temp = new Cons(first.car());
968            splice.cdr = temp;
969            splice = temp;
970            first = first.cdr();
971          }
972        splice.cdr = second;
973        return result;
974      }
975      @Override
976      public LispObject execute(LispObject first, LispObject second,
977                                LispObject third)
978
979      {
980        if (first == NIL)
981          return execute(second, third);
982        Cons result = new Cons(first.car());
983        Cons splice = result;
984        first = first.cdr();
985        while (first != NIL)
986          {
987            Cons temp = new Cons(first.car());
988            splice.cdr = temp;
989            splice = temp;
990            first = first.cdr();
991          }
992        while (second != NIL)
993          {
994            Cons temp = new Cons(second.car());
995            splice.cdr = temp;
996            splice = temp;
997            second = second.cdr();
998          }
999        splice.cdr = third;
1000        return result;
1001      }
1002      @Override
1003      public LispObject execute(LispObject[] args)
1004      {
1005        Cons result = null;
1006        Cons splice = null;
1007        final int limit = args.length - 1;
1008        int i;
1009        for (i = 0; i < limit; i++)
1010          {
1011            LispObject top = args[i];
1012            if (top == NIL)
1013              continue;
1014            result = new Cons(top.car());
1015            splice = result;
1016            top = top.cdr();
1017            while (top != NIL)
1018              {
1019                Cons temp = new Cons(top.car());
1020                splice.cdr = temp;
1021                splice = temp;
1022                top = top.cdr();
1023              }
1024            break;
1025          }
1026        if (result == null)
1027          return args[i];
1028        for (++i; i < limit; i++)
1029          {
1030            LispObject top = args[i];
1031            while (top != NIL)
1032              {
1033                Cons temp = new Cons(top.car());
1034                splice.cdr = temp;
1035                splice = temp;
1036                top = top.cdr();
1037              }
1038          }
1039        splice.cdr = args[i];
1040        return result;
1041      }
1042    };
1043
1044  // ### nconc
1045  private static final Primitive NCONC =
1046    new Primitive(Symbol.NCONC, "&rest lists")
1047    {
1048      @Override
1049      public LispObject execute()
1050      {
1051        return NIL;
1052      }
1053      @Override
1054      public LispObject execute(LispObject arg)
1055      {
1056        return arg;
1057      }
1058      @Override
1059      public LispObject execute(LispObject first, LispObject second)
1060
1061      {
1062        if (first == NIL)
1063          return second;
1064        if (first instanceof Cons)
1065          {
1066            LispObject result = first;
1067            Cons splice = null;
1068            while (first instanceof Cons)
1069              {
1070                splice = (Cons) first;
1071                first = splice.cdr;
1072              }
1073            splice.cdr = second;
1074            return result;
1075          }
1076        return type_error(first, Symbol.LIST);
1077      }
1078      @Override
1079      public LispObject execute(LispObject[] array)
1080      {
1081        LispObject result = null;
1082        Cons splice = null;
1083        final int limit = array.length - 1;
1084        int i;
1085        for (i = 0; i < limit; i++)
1086          {
1087            LispObject list = array[i];
1088            if (list == NIL)
1089              continue;
1090            if (list instanceof Cons)
1091              {
1092                if (splice != null)
1093                  {
1094                    splice.cdr = list;
1095                    splice = (Cons) list;
1096                  }
1097                while (list instanceof Cons)
1098                  {
1099                    if (result == null)
1100                      {
1101                        result = list;
1102                        splice = (Cons) result;
1103                      }
1104                    else
1105                      splice = (Cons) list;
1106                    list = splice.cdr;
1107                  }
1108              }
1109            else
1110              type_error(list, Symbol.LIST);
1111          }
1112        if (result == null)
1113          return array[i];
1114        splice.cdr = array[i];
1115        return result;
1116      }
1117    };
1118
1119  // ### =
1120  // Numeric equality.
1121  private static final Primitive EQUALS =
1122    new Primitive(Symbol.EQUALS, "&rest numbers")
1123    {
1124      @Override
1125      public LispObject execute()
1126      {
1127        return error(new WrongNumberOfArgumentsException(this));
1128      }
1129      @Override
1130      public LispObject execute(LispObject arg)
1131      {
1132        return T;
1133      }
1134      @Override
1135      public LispObject execute(LispObject first, LispObject second)
1136
1137      {
1138        return first.isEqualTo(second) ? T : NIL;
1139      }
1140      @Override
1141      public LispObject execute(LispObject first, LispObject second,
1142                                LispObject third)
1143
1144      {
1145        if (first.isEqualTo(second) && second.isEqualTo(third))
1146          return T;
1147        else
1148          return NIL;
1149      }
1150      @Override
1151      public LispObject execute(LispObject[] array)
1152      {
1153        final int length = array.length;
1154        final LispObject obj = array[0];
1155        for (int i = 1; i < length; i++)
1156          {
1157            if (array[i].isNotEqualTo(obj))
1158              return NIL;
1159          }
1160        return T;
1161      }
1162    };
1163
1164  // ### /=
1165  // Returns true if no two numbers are the same; otherwise returns false.
1166  private static final Primitive NOT_EQUALS =
1167    new Primitive(Symbol.NOT_EQUALS, "&rest numbers")
1168    {
1169      @Override
1170      public LispObject execute()
1171      {
1172        return error(new WrongNumberOfArgumentsException(this));
1173      }
1174      @Override
1175      public LispObject execute(LispObject arg)
1176      {
1177        return T;
1178      }
1179      @Override
1180      public LispObject execute(LispObject first, LispObject second)
1181
1182      {
1183        return first.isNotEqualTo(second) ? T : NIL;
1184      }
1185      @Override
1186      public LispObject execute(LispObject first, LispObject second,
1187                                LispObject third)
1188
1189      {
1190        if (first.isEqualTo(second))
1191          return NIL;
1192        if (first.isEqualTo(third))
1193          return NIL;
1194        if (second.isEqualTo(third))
1195          return NIL;
1196        return T;
1197      }
1198      @Override
1199      public LispObject execute(LispObject[] array)
1200      {
1201        final int length = array.length;
1202        for (int i = 0; i < length; i++)
1203          {
1204            final LispObject obj = array[i];
1205            for (int j = i+1; j < length; j++)
1206              {
1207                if (array[j].isEqualTo(obj))
1208                  return NIL;
1209              }
1210          }
1211        return T;
1212      }
1213    };
1214
1215  // ### <
1216  // Numeric comparison.
1217  private static final Primitive LT =
1218    new Primitive(Symbol.LT, "&rest numbers")
1219    {
1220      @Override
1221      public LispObject execute()
1222      {
1223        return error(new WrongNumberOfArgumentsException(this));
1224      }
1225      @Override
1226      public LispObject execute(LispObject arg)
1227      {
1228        return T;
1229      }
1230      @Override
1231      public LispObject execute(LispObject first, LispObject second)
1232
1233      {
1234        return first.isLessThan(second) ? T : NIL;
1235      }
1236      @Override
1237      public LispObject execute(LispObject first, LispObject second,
1238                                LispObject third)
1239
1240      {
1241        if (first.isLessThan(second) && second.isLessThan(third))
1242          return T;
1243        else
1244          return NIL;
1245      }
1246      @Override
1247      public LispObject execute(LispObject[] array)
1248      {
1249        final int length = array.length;
1250        for (int i = 1; i < length; i++)
1251          {
1252            if (array[i].isLessThanOrEqualTo(array[i-1]))
1253              return NIL;
1254          }
1255        return T;
1256      }
1257    };
1258
1259  // ### <=
1260  private static final Primitive LE =
1261    new Primitive(Symbol.LE, "&rest numbers")
1262    {
1263      @Override
1264      public LispObject execute()
1265      {
1266        return error(new WrongNumberOfArgumentsException(this));
1267      }
1268      @Override
1269      public LispObject execute(LispObject arg)
1270      {
1271        return T;
1272      }
1273      @Override
1274      public LispObject execute(LispObject first, LispObject second)
1275
1276      {
1277        return first.isLessThanOrEqualTo(second) ? T : NIL;
1278      }
1279      @Override
1280      public LispObject execute(LispObject first, LispObject second,
1281                                LispObject third)
1282
1283      {
1284        if (first.isLessThanOrEqualTo(second) && second.isLessThanOrEqualTo(third))
1285          return T;
1286        else
1287          return NIL;
1288      }
1289      @Override
1290      public LispObject execute(LispObject[] array)
1291      {
1292        final int length = array.length;
1293        for (int i = 1; i < length; i++)
1294          {
1295            if (array[i].isLessThan(array[i-1]))
1296              return NIL;
1297          }
1298        return T;
1299      }
1300    };
1301
1302  // ### >
1303  private static final Primitive GT =
1304    new Primitive(Symbol.GT, "&rest numbers")
1305    {
1306      @Override
1307      public LispObject execute()
1308      {
1309        return error(new WrongNumberOfArgumentsException(this));
1310      }
1311      @Override
1312      public LispObject execute(LispObject arg)
1313      {
1314        return T;
1315      }
1316      @Override
1317      public LispObject execute(LispObject first, LispObject second)
1318
1319      {
1320        return first.isGreaterThan(second) ? T : NIL;
1321      }
1322      @Override
1323      public LispObject execute(LispObject first, LispObject second,
1324                                LispObject third)
1325
1326      {
1327        if (first.isGreaterThan(second) && second.isGreaterThan(third))
1328          return T;
1329        else
1330          return NIL;
1331      }
1332      @Override
1333      public LispObject execute(LispObject[] array)
1334      {
1335        final int length = array.length;
1336        for (int i = 1; i < length; i++)
1337          {
1338            if (array[i].isGreaterThanOrEqualTo(array[i-1]))
1339              return NIL;
1340          }
1341        return T;
1342      }
1343    };
1344
1345  // ### >=
1346  private static final Primitive GE =
1347    new Primitive(Symbol.GE, "&rest numbers")
1348    {
1349      @Override
1350      public LispObject execute()
1351      {
1352        return error(new WrongNumberOfArgumentsException(this));
1353      }
1354      @Override
1355      public LispObject execute(LispObject arg)
1356      {
1357        return T;
1358      }
1359      @Override
1360      public LispObject execute(LispObject first, LispObject second)
1361
1362      {
1363        return first.isGreaterThanOrEqualTo(second) ? T : NIL;
1364      }
1365      @Override
1366      public LispObject execute(LispObject first, LispObject second,
1367                                LispObject third)
1368
1369      {
1370        if (first.isGreaterThanOrEqualTo(second) && second.isGreaterThanOrEqualTo(third))
1371          return T;
1372        else
1373          return NIL;
1374      }
1375      @Override
1376      public LispObject execute(LispObject[] array)
1377      {
1378        final int length = array.length;
1379        for (int i = 1; i < length; i++)
1380          {
1381            if (array[i].isGreaterThan(array[i-1]))
1382              return NIL;
1383          }
1384        return T;
1385      }
1386    };
1387
1388  // ### nth n list => object
1389  private static final Primitive NTH = new Primitive(Symbol.NTH, "n list")
1390    {
1391      @Override
1392      public LispObject execute(LispObject first, LispObject second)
1393
1394      {
1395        return second.NTH(first);
1396      }
1397    };
1398
1399  // ### %set-nth n list new-object => new-object
1400  private static final Primitive _SET_NTH =
1401    new Primitive("%set-nth", PACKAGE_SYS, false)
1402    {
1403      @Override
1404      public LispObject execute(LispObject first, LispObject second,
1405                                LispObject third)
1406
1407      {
1408        int index = Fixnum.getValue(first);
1409        if (index < 0)
1410          error(new TypeError("(SETF NTH): invalid index " + index + "."));
1411        int i = 0;
1412        while (true)
1413          {
1414            if (i == index)
1415              {
1416                second.setCar(third);
1417                return third;
1418              }
1419            second = second.cdr();
1420            if (second == NIL)
1421              {
1422                return error(new LispError("(SETF NTH): the index " +
1423                                            index + "is too large."));
1424              }
1425            ++i;
1426          }
1427      }
1428    };
1429
1430  // ### nthcdr
1431  private static final Primitive NTHCDR =
1432    new Primitive(Symbol.NTHCDR, "n list")
1433    {
1434      @Override
1435      public LispObject execute(LispObject first, LispObject second)
1436
1437      {
1438        final int index = Fixnum.getValue(first);
1439        if (index < 0)
1440          return type_error(first,
1441                                 list(Symbol.INTEGER, Fixnum.ZERO));
1442        for (int i = 0; i < index; i++)
1443          {
1444            second = second.cdr();
1445            if (second == NIL)
1446              return NIL;
1447          }
1448        return second;
1449      }
1450    };
1451
1452  /** Stub to be replaced later when signal.lisp has been loaded. */
1453  // ### error
1454  private static final Primitive ERROR =
1455    new Primitive(Symbol.ERROR, "datum &rest arguments")
1456    {
1457      @Override
1458      public LispObject execute(LispObject[] args)
1459      {
1460        Error e = new Error();
1461
1462        e.printStackTrace();
1463
1464        System.out.println("ERROR placeholder called with arguments:");
1465
1466        if (args.length == 1 && args[0] instanceof Condition) {
1467            System.out.println(args[0].writeToString());
1468            System.out.println(((Condition)args[0]).getConditionReport());
1469        }
1470        else
1471            for (LispObject a : args)
1472                System.out.println(a.writeToString());
1473
1474        //###FIXME: Bail out, but do it nicer...
1475        System.exit(1);
1476        return NIL;
1477      }
1478    };
1479
1480  /** Stub replaced when compiler-pass2.lisp has been loaded */
1481  // ### autocompile
1482  private static final Primitive AUTOCOMPILE =
1483    new Primitive(Symbol.AUTOCOMPILE, "function")
1484    {
1485      @Override
1486      public LispObject execute(LispObject function)
1487      {
1488        return NIL;
1489      }
1490    };
1491
1492  // ### signal
1493  /** Placeholder function, to be replaced by the function
1494   * defined in signal.lisp
1495   *
1496   * Calling this function is an error: we're not set up for
1497   * signalling yet.
1498   */
1499  private static final Primitive SIGNAL =
1500    new Primitive(Symbol.SIGNAL, "datum &rest arguments")
1501    {
1502      @Override
1503      public LispObject execute(LispObject[] args)
1504      {
1505        if (args.length < 1)
1506          return error(new WrongNumberOfArgumentsException(this));
1507        if (args[0] instanceof Condition)
1508          return error((Condition)args[0]);
1509        return error(new SimpleCondition());
1510      }
1511    };
1512
1513  // ### undefined-function-called
1514  // Redefined in restart.lisp.
1515  private static final Primitive UNDEFINED_FUNCTION_CALLED =
1516    new Primitive(Symbol.UNDEFINED_FUNCTION_CALLED, "name arguments")
1517    {
1518      @Override
1519      public LispObject execute(LispObject first, LispObject second)
1520
1521      {
1522        return error(new UndefinedFunction(first));
1523      }
1524    };
1525
1526  // ### %format
1527  private static final Primitive _FORMAT =
1528    new Primitive("%format", PACKAGE_SYS, false,
1529                  "destination control-string &rest args")
1530    {
1531      @Override
1532      public LispObject execute(LispObject first, LispObject second,
1533                                LispObject third)
1534
1535      {
1536        LispObject destination = first;
1537        // Copy remaining arguments.
1538        LispObject[] _args = new LispObject[2];
1539        _args[0] = second;
1540        _args[1] = third;
1541        String s = _format(_args);
1542        return outputFormattedString(s, destination);
1543      }
1544      @Override
1545      public LispObject execute(LispObject first, LispObject second,
1546                                LispObject third, LispObject fourth)
1547
1548      {
1549        LispObject destination = first;
1550        // Copy remaining arguments.
1551        LispObject[] _args = new LispObject[3];
1552        _args[0] = second;
1553        _args[1] = third;
1554        _args[2] = fourth;
1555        String s = _format(_args);
1556        return outputFormattedString(s, destination);
1557      }
1558      @Override
1559      public LispObject execute(LispObject[] args)
1560      {
1561        if (args.length < 2)
1562          return error(new WrongNumberOfArgumentsException(this));
1563        LispObject destination = args[0];
1564        // Copy remaining arguments.
1565        LispObject[] _args = new LispObject[args.length - 1];
1566        for (int i = 0; i < _args.length; i++)
1567          _args[i] = args[i+1];
1568        String s = _format(_args);
1569        return outputFormattedString(s, destination);
1570      }
1571      private final String _format(LispObject[] args)
1572
1573      {
1574        LispObject formatControl = args[0];
1575        LispObject formatArguments = NIL;
1576        for (int i = 1; i < args.length; i++)
1577          formatArguments = new Cons(args[i], formatArguments);
1578        formatArguments = formatArguments.nreverse();
1579        return format(formatControl, formatArguments);
1580      }
1581      private final LispObject outputFormattedString(String s,
1582                                                     LispObject destination)
1583
1584      {
1585        if (destination == T)
1586          {
1587            checkCharacterOutputStream(Symbol.STANDARD_OUTPUT.symbolValue())._writeString(s);
1588            return NIL;
1589          }
1590        if (destination == NIL)
1591          return new SimpleString(s);
1592        if (destination instanceof TwoWayStream)
1593          {
1594            Stream out = ((TwoWayStream)destination).getOutputStream();
1595            if (out instanceof Stream)
1596              {
1597                (out)._writeString(s);
1598                return NIL;
1599              }
1600            error(new TypeError("The value " +
1601                                 destination.writeToString() +
1602                                 " is not a character output stream."));
1603          }
1604        if (destination instanceof Stream)
1605          {
1606            ((Stream)destination)._writeString(s);
1607            return NIL;
1608          }
1609        return NIL;
1610      }
1611    };
1612
1613  private static final Symbol _SIMPLE_FORMAT_FUNCTION_ =
1614    internSpecial("*SIMPLE-FORMAT-FUNCTION*", PACKAGE_SYS, _FORMAT);
1615
1616  private static void checkRedefinition(LispObject arg)
1617
1618  {
1619    final LispThread thread = LispThread.currentThread();
1620    if (_WARN_ON_REDEFINITION_.symbolValue(thread) != NIL)
1621      {
1622        if (arg instanceof Symbol)
1623          {
1624            LispObject oldDefinition = arg.getSymbolFunction();
1625            if (oldDefinition != null && !(oldDefinition instanceof Autoload))
1626              {
1627                LispObject oldSource =
1628                  Extensions.SOURCE_PATHNAME.execute(arg);
1629                LispObject currentSource = _SOURCE_.symbolValue(thread);
1630                if (currentSource == NIL)
1631                  currentSource = Keyword.TOP_LEVEL;
1632                if (oldSource != NIL)
1633                  {
1634                    if (currentSource.equal(oldSource))
1635                      return; // OK
1636                  }
1637                if (currentSource == Keyword.TOP_LEVEL)
1638                  {
1639                    Symbol.STYLE_WARN.execute(new SimpleString("redefining ~S at top level"),
1640                                              arg);
1641
1642                  }
1643                else
1644                  {
1645                    SpecialBinding lastSpecialBinding = thread.lastSpecialBinding;
1646                    thread.bindSpecial(Symbol._PACKAGE_, PACKAGE_CL);
1647                    try
1648                      {
1649                        Symbol.STYLE_WARN.execute(new SimpleString("redefining ~S in ~S"),
1650                                                  arg, currentSource);
1651                      }
1652                    finally
1653                      {
1654                        thread.lastSpecialBinding = lastSpecialBinding;
1655                      }
1656                  }
1657              }
1658          }
1659      }
1660  }
1661
1662  // ### %defun name definition => name
1663  private static final Primitive _DEFUN =
1664    new Primitive("%defun", PACKAGE_SYS, true, "name definition")
1665    {
1666      @Override
1667      public LispObject execute(LispObject name, LispObject definition)
1668
1669      {
1670        if (name instanceof Symbol)
1671          {
1672            Symbol symbol = (Symbol) name;
1673            if (symbol.getSymbolFunction() instanceof SpecialOperator)
1674              {
1675                String message =
1676                  symbol.getName() + " is a special operator and may not be redefined.";
1677                return error(new ProgramError(message));
1678              }
1679          }
1680        else if (!isValidSetfFunctionName(name))
1681          return type_error(name, FUNCTION_NAME);
1682        if (definition instanceof Function)
1683          {
1684            Symbol.FSET.execute(name, definition, NIL,
1685                                ((Function)definition).getLambdaList());
1686            return name;
1687          }
1688        return type_error(definition, Symbol.FUNCTION);
1689      }
1690    };
1691
1692  // ### fdefinition-block-name
1693  private static final Primitive FDEFINITION_BLOCK_NAME =
1694    new Primitive("fdefinition-block-name", PACKAGE_SYS, true, "function-name")
1695    {
1696      @Override
1697      public LispObject execute(LispObject arg)
1698      {
1699        if (arg instanceof Symbol)
1700          return arg;
1701        if (isValidSetfFunctionName(arg))
1702          return arg.cadr();
1703        return type_error(arg, FUNCTION_NAME);
1704      }
1705    };
1706
1707  // ### macro-function
1708  private static final Primitive MACRO_FUNCTION =
1709    new Primitive(Symbol.MACRO_FUNCTION, "symbol &optional environment")
1710    {
1711      @Override
1712      public LispObject execute(LispObject arg)
1713      {
1714        LispObject obj = arg.getSymbolFunction();
1715        if (obj instanceof AutoloadMacro)
1716          {
1717            ((AutoloadMacro)obj).load();
1718            obj = arg.getSymbolFunction();
1719          }
1720        if (obj instanceof MacroObject)
1721          return ((MacroObject)obj).expander;
1722        if (obj instanceof SpecialOperator)
1723          {
1724            obj = get(arg, Symbol.MACROEXPAND_MACRO, NIL);
1725            if (obj instanceof AutoloadMacro)
1726              {
1727                ((AutoloadMacro)obj).load();
1728                obj = get(arg, Symbol.MACROEXPAND_MACRO, NIL);
1729              }
1730            if (obj instanceof MacroObject)
1731              return ((MacroObject)obj).expander;
1732          }
1733        return NIL;
1734      }
1735      @Override
1736      public LispObject execute(LispObject first, LispObject second)
1737
1738      {
1739        LispObject obj;
1740        if (second != NIL)
1741          {
1742            Environment env = checkEnvironment(second);
1743            obj = env.lookupFunction(first);
1744          }
1745        else
1746          obj = first.getSymbolFunction();
1747        if (obj instanceof AutoloadMacro)
1748          {
1749            ((AutoloadMacro)obj).load();
1750            obj = first.getSymbolFunction();
1751          }
1752        if (obj instanceof MacroObject)
1753          return ((MacroObject)obj).expander;
1754        if (obj instanceof SpecialOperator)
1755          {
1756            obj = get(first, Symbol.MACROEXPAND_MACRO, NIL);
1757            if (obj instanceof AutoloadMacro)
1758              {
1759                ((AutoloadMacro)obj).load();
1760                obj = get(first, Symbol.MACROEXPAND_MACRO, NIL);
1761              }
1762            if (obj instanceof MacroObject)
1763              return ((MacroObject)obj).expander;
1764          }
1765        return NIL;
1766      }
1767    };
1768
1769  // ### defmacro
1770  private static final SpecialOperator DEFMACRO =
1771    new SpecialOperator(Symbol.DEFMACRO)
1772    {
1773      @Override
1774      public LispObject execute(LispObject args, Environment env)
1775
1776      {
1777        Symbol symbol = checkSymbol(args.car());
1778        LispObject lambdaList = checkList(args.cadr());
1779        LispObject body = args.cddr();
1780        LispObject block = new Cons(Symbol.BLOCK, new Cons(symbol, body));
1781        LispObject toBeApplied =
1782          list(Symbol.FUNCTION, list(Symbol.LAMBDA, lambdaList, block));
1783        final LispThread thread = LispThread.currentThread();
1784        LispObject formArg = gensym("FORM-", thread);
1785        LispObject envArg = gensym("ENV-", thread); // Ignored.
1786        LispObject expander =
1787          list(Symbol.LAMBDA, list(formArg, envArg),
1788                list(Symbol.APPLY, toBeApplied,
1789                      list(Symbol.CDR, formArg)));
1790        Closure expansionFunction = new Closure(expander, env);
1791        MacroObject macroObject =
1792          new MacroObject(symbol, expansionFunction);
1793        if (symbol.getSymbolFunction() instanceof SpecialOperator)
1794          put(symbol, Symbol.MACROEXPAND_MACRO, macroObject);
1795        else
1796          symbol.setSymbolFunction(macroObject);
1797        macroObject.setLambdaList(lambdaList);
1798        thread._values = null;
1799        return symbol;
1800      }
1801    };
1802
1803  // ### make-macro
1804  private static final Primitive MAKE_MACRO =
1805    new Primitive("make-macro", PACKAGE_SYS, true, "name expansion-function")
1806    {
1807      @Override
1808      public LispObject execute(LispObject first, LispObject second)
1809
1810      {
1811        return new MacroObject(first, second);
1812      }
1813    };
1814
1815  // ### macro-function-p
1816  private static final Primitive MACRO_FUNCTION_P =
1817      new Primitive("macro-function-p", PACKAGE_SYS, true, "value")
1818  {
1819      @Override
1820      public LispObject execute(LispObject arg)
1821      {
1822          return (arg instanceof MacroObject) ? T : NIL;
1823      }
1824  };
1825
1826
1827  // ### make-symbol-macro
1828  private static final Primitive MAKE_SYMBOL_MACRO =
1829      new Primitive("make-symbol-macro", PACKAGE_SYS, true, "expansion")
1830  {
1831      @Override
1832      public LispObject execute(LispObject arg)
1833      {
1834          return new SymbolMacro(arg);
1835      }
1836  };
1837
1838  // ### symbol-macro-p
1839  private static final Primitive SYMBOL_MACRO_P =
1840      new Primitive("symbol-macro-p", PACKAGE_SYS, true, "value")
1841  {
1842      @Override
1843      public LispObject execute(LispObject arg)
1844      {
1845          return (arg instanceof SymbolMacro) ? T : NIL;
1846      }
1847  };
1848
1849  // ### %defparameter
1850  private static final Primitive _DEFPARAMETER =
1851    new Primitive("%defparameter", PACKAGE_SYS, false)
1852    {
1853      @Override
1854      public LispObject execute(LispObject first, LispObject second,
1855                                LispObject third)
1856
1857      {
1858        final Symbol symbol;
1859            symbol = checkSymbol(first);
1860        if (third instanceof AbstractString)
1861          symbol.setDocumentation(Symbol.VARIABLE, third);
1862        else if (third != NIL)
1863          type_error(third, Symbol.STRING);
1864        symbol.initializeSpecial(second);
1865        return symbol;
1866      }
1867    };
1868
1869  // ### %defvar
1870  private static final Primitive _DEFVAR =
1871    new Primitive("%defvar", PACKAGE_SYS, false)
1872    {
1873      @Override
1874      public LispObject execute(LispObject arg)
1875      {
1876        final Symbol symbol;
1877            symbol = checkSymbol(arg);
1878        symbol.setSpecial(true);
1879        return symbol;
1880      }
1881      @Override
1882      public LispObject execute(LispObject first, LispObject second)
1883
1884      {
1885        final Symbol symbol;
1886            symbol = checkSymbol(first);
1887        symbol.initializeSpecial(second);
1888        return symbol;
1889      }
1890    };
1891
1892  // ### %defconstant name initial-value documentation => name
1893  private static final Primitive _DEFCONSTANT =
1894    new Primitive("%defconstant", PACKAGE_SYS, false)
1895    {
1896      @Override
1897      public LispObject execute(LispObject first, LispObject second,
1898                                LispObject third)
1899
1900      {
1901        final Symbol symbol;
1902            symbol = checkSymbol(first);
1903        if (third != NIL)
1904          {
1905            if (third instanceof AbstractString)
1906              symbol.setDocumentation(Symbol.VARIABLE, third);
1907            else
1908              return type_error(third, Symbol.STRING);
1909          }
1910        symbol.initializeConstant(second);
1911        return symbol;
1912      }
1913    };
1914
1915  // ### cond
1916  private static final SpecialOperator COND =
1917    new SpecialOperator(Symbol.COND, "&rest clauses")
1918    {
1919      @Override
1920      public LispObject execute(LispObject args, Environment env)
1921
1922      {
1923        final LispThread thread = LispThread.currentThread();
1924        LispObject result = NIL;
1925        while (args != NIL)
1926          {
1927            LispObject clause = args.car();
1928            result = eval(clause.car(), env, thread);
1929            thread._values = null;
1930            if (result != NIL)
1931              {
1932                LispObject body = clause.cdr();
1933                while (body != NIL)
1934                  {
1935                    result = eval(body.car(), env, thread);
1936                    body = ((Cons)body).cdr;
1937                  }
1938                return result;
1939              }
1940            args = ((Cons)args).cdr;
1941          }
1942        return result;
1943      }
1944    };
1945
1946  // ### case
1947  private static final SpecialOperator CASE =
1948    new SpecialOperator(Symbol.CASE, "keyform &body cases")
1949    {
1950      @Override
1951      public LispObject execute(LispObject args, Environment env)
1952
1953      {
1954        final LispThread thread = LispThread.currentThread();
1955        LispObject key = eval(args.car(), env, thread);
1956        args = args.cdr();
1957        while (args != NIL)
1958          {
1959            LispObject clause = args.car();
1960            LispObject keys = clause.car();
1961            boolean match = false;
1962            if (keys.listp())
1963              {
1964                while (keys != NIL)
1965                  {
1966                    LispObject candidate = keys.car();
1967                    if (key.eql(candidate))
1968                      {
1969                        match = true;
1970                        break;
1971                      }
1972                    keys = keys.cdr();
1973                  }
1974              }
1975            else
1976              {
1977                LispObject candidate = keys;
1978                if (candidate == T || candidate == Symbol.OTHERWISE)
1979                  match = true;
1980                else if (key.eql(candidate))
1981                  match = true;
1982              }
1983            if (match)
1984              {
1985                return progn(clause.cdr(), env, thread);
1986              }
1987            args = args.cdr();
1988          }
1989        return NIL;
1990      }
1991    };
1992
1993  // ### ecase
1994  private static final SpecialOperator ECASE =
1995    new SpecialOperator(Symbol.ECASE, "keyform &body cases")
1996    {
1997      @Override
1998      public LispObject execute(LispObject args, Environment env)
1999
2000      {
2001        final LispThread thread = LispThread.currentThread();
2002        LispObject key = eval(args.car(), env, thread);
2003        LispObject clauses = args.cdr();
2004        while (clauses != NIL)
2005          {
2006            LispObject clause = clauses.car();
2007            LispObject keys = clause.car();
2008            boolean match = false;
2009            if (keys.listp())
2010              {
2011                while (keys != NIL)
2012                  {
2013                    LispObject candidate = keys.car();
2014                    if (key.eql(candidate))
2015                      {
2016                        match = true;
2017                        break;
2018                      }
2019                    keys = keys.cdr();
2020                  }
2021              }
2022            else
2023              {
2024                LispObject candidate = keys;
2025                if (key.eql(candidate))
2026                  match = true;
2027              }
2028            if (match)
2029              {
2030                return progn(clause.cdr(), env, thread);
2031              }
2032            clauses = clauses.cdr();
2033          }
2034        LispObject expectedType = NIL;
2035        clauses = args.cdr();
2036        while (clauses != NIL)
2037          {
2038            LispObject clause = clauses.car();
2039            LispObject keys = clause.car();
2040            if (keys.listp())
2041              {
2042                while (keys != NIL)
2043                  {
2044                    expectedType = expectedType.push(keys.car());
2045                    keys = keys.cdr();
2046                  }
2047              }
2048            else
2049              expectedType = expectedType.push(keys);
2050            clauses = clauses.cdr();
2051          }
2052        expectedType = expectedType.nreverse();
2053        expectedType = expectedType.push(Symbol.MEMBER);
2054        return type_error(key, expectedType);
2055      }
2056    };
2057
2058  // ### upgraded-array-element-type typespec &optional environment
2059  // => upgraded-typespec
2060  private static final Primitive UPGRADED_ARRAY_ELEMENT_TYPE =
2061    new Primitive(Symbol.UPGRADED_ARRAY_ELEMENT_TYPE,
2062                  "typespec &optional environment")
2063    {
2064      @Override
2065      public LispObject execute(LispObject arg)
2066      {
2067        return getUpgradedArrayElementType(arg);
2068      }
2069      @Override
2070      public LispObject execute(LispObject first, LispObject second)
2071
2072      {
2073        // Ignore environment.
2074        return getUpgradedArrayElementType(first);
2075      }
2076    };
2077
2078  // ### array-rank array => rank
2079  private static final Primitive ARRAY_RANK =
2080    new Primitive(Symbol.ARRAY_RANK, "array")
2081    {
2082      @Override
2083      public LispObject execute(LispObject arg)
2084      {
2085          return Fixnum.getInstance(checkArray(arg).getRank());
2086
2087      }
2088    };
2089
2090  // ### array-dimensions array => dimensions
2091  // Returns a list of integers. Fill pointer (if any) is ignored.
2092  private static final Primitive ARRAY_DIMENSIONS =
2093    new Primitive(Symbol.ARRAY_DIMENSIONS, "array")
2094    {
2095      @Override
2096      public LispObject execute(LispObject arg)
2097      {
2098            return checkArray(arg).getDimensions();
2099      }
2100    };
2101
2102  // ### array-dimension array axis-number => dimension
2103  private static final Primitive ARRAY_DIMENSION =
2104    new Primitive(Symbol.ARRAY_DIMENSION, "array axis-number")
2105    {
2106      @Override
2107      public LispObject execute(LispObject first, LispObject second)
2108
2109      {
2110        final AbstractArray array = checkArray(first);
2111        return Fixnum.getInstance(array.getDimension(Fixnum.getValue(second)));
2112      }
2113    };
2114
2115  // ### array-total-size array => size
2116  private static final Primitive ARRAY_TOTAL_SIZE =
2117    new Primitive(Symbol.ARRAY_TOTAL_SIZE, "array")
2118    {
2119      @Override
2120      public LispObject execute(LispObject arg)
2121      {
2122          return Fixnum.getInstance(checkArray(arg).getTotalSize());
2123      }
2124    };
2125
2126
2127  // ### array-element-type
2128  // array-element-type array => typespec
2129  private static final Primitive ARRAY_ELEMENT_TYPE =
2130    new Primitive(Symbol.ARRAY_ELEMENT_TYPE, "array")
2131    {
2132      @Override
2133      public LispObject execute(LispObject arg)
2134      {
2135            return checkArray(arg).getElementType();
2136      }
2137    };
2138
2139  // ### adjustable-array-p
2140  private static final Primitive ADJUSTABLE_ARRAY_P =
2141    new Primitive(Symbol.ADJUSTABLE_ARRAY_P, "array")
2142    {
2143      @Override
2144      public LispObject execute(LispObject arg)
2145      {
2146            return checkArray(arg).isAdjustable() ? T : NIL;
2147      }
2148    };
2149
2150  // ### array-displacement array => displaced-to, displaced-index-offset
2151  private static final Primitive ARRAY_DISPLACEMENT =
2152    new Primitive(Symbol.ARRAY_DISPLACEMENT, "array")
2153    {
2154      @Override
2155      public LispObject execute(LispObject arg)
2156      {
2157            return checkArray(arg).arrayDisplacement();
2158
2159      }
2160    };
2161
2162  // ### array-in-bounds-p array &rest subscripts => generalized-boolean
2163  private static final Primitive ARRAY_IN_BOUNDS_P =
2164    new Primitive(Symbol.ARRAY_IN_BOUNDS_P, "array &rest subscripts")
2165    {
2166      @Override
2167      public LispObject execute(LispObject[] args)
2168      {
2169        if (args.length < 1)
2170          return error(new WrongNumberOfArgumentsException(this));
2171        final AbstractArray array;
2172                LispObject r = args[0];
2173            array = checkArray(r);
2174        int rank = array.getRank();
2175        if (rank != args.length - 1)
2176          {
2177            FastStringBuffer sb =
2178              new FastStringBuffer("ARRAY-IN-BOUNDS-P: ");
2179            sb.append("wrong number of subscripts (");
2180            sb.append(args.length - 1);
2181            sb.append(") for array of rank ");
2182            sb.append(rank);
2183            error(new ProgramError(sb.toString()));
2184          }
2185        for (int i = 0; i < rank; i++)
2186          {
2187            LispObject arg = args[i+1];
2188            if (arg instanceof Fixnum)
2189              {
2190                int subscript = ((Fixnum)arg).value;
2191                if (subscript < 0 || subscript >= array.getDimension(i))
2192                  return NIL;
2193              }
2194            else if (arg instanceof Bignum)
2195              return NIL;
2196            else
2197              type_error(arg, Symbol.INTEGER);
2198          }
2199        return T;
2200      }
2201    };
2202
2203  // ### %array-row-major-index array subscripts => index
2204  private static final Primitive _ARRAY_ROW_MAJOR_INDEX =
2205    new Primitive("%array-row-major-index", PACKAGE_SYS, false)
2206    {
2207      @Override
2208      public LispObject execute(LispObject first, LispObject second)
2209
2210      {
2211        final AbstractArray array;
2212        array = checkArray(first);
2213        LispObject[] subscripts = second.copyToArray();
2214        return number(array.getRowMajorIndex(subscripts));
2215      }
2216    };
2217
2218  // ### aref array &rest subscripts => element
2219  private static final Primitive AREF =
2220    new Primitive(Symbol.AREF, "array &rest subscripts")
2221    {
2222      @Override
2223      public LispObject execute()
2224      {
2225        return error(new WrongNumberOfArgumentsException(this));
2226      }
2227      @Override
2228      public LispObject execute(LispObject arg)
2229      {
2230        final AbstractArray array;
2231        array = checkArray( arg);
2232        if (array.getRank() == 0)
2233          return array.AREF(0);
2234        FastStringBuffer sb =
2235          new FastStringBuffer("Wrong number of subscripts (0) for array of rank ");
2236        sb.append(array.getRank());
2237        sb.append('.');
2238        return error(new ProgramError(sb.toString()));
2239      }
2240      @Override
2241      public LispObject execute(LispObject first, LispObject second)
2242
2243      {
2244        return first.AREF(second);
2245      }
2246      @Override
2247      public LispObject execute(LispObject first, LispObject second,
2248                                LispObject third)
2249
2250      {
2251        return checkArray(first).get(new int[]{Fixnum.getValue(second),Fixnum.getValue(third)} );
2252      }
2253      @Override
2254      public LispObject execute(LispObject[] args)
2255      {
2256        final AbstractArray array = checkArray(args[0]);
2257        final int[] subs = new int[args.length - 1];
2258        for (int i = subs.length; i-- > 0;)
2259          {
2260            subs[i] = Fixnum.getValue(args[i+1]);
2261          }
2262        return array.get(subs);
2263      }
2264    };
2265
2266  // ### aset array subscripts new-element => new-element
2267  private static final Primitive ASET =
2268    new Primitive("aset", PACKAGE_SYS, true,
2269                  "array subscripts new-element")
2270    {
2271      @Override
2272      public LispObject execute(LispObject first, LispObject second)
2273
2274      {
2275        // Rank zero array.
2276        final ZeroRankArray array;
2277          if (first instanceof ZeroRankArray){
2278            array = (ZeroRankArray) first;
2279          }
2280          else
2281          {
2282            return error(new TypeError("The value " +
2283                                        first.writeToString() +
2284                                        " is not an array of rank 0."));
2285          }
2286        array.aset(0, second);
2287        return second;
2288      }
2289      @Override
2290      public LispObject execute(LispObject first, LispObject second,
2291                                LispObject third)
2292
2293      {
2294        first.aset(second, third);
2295        return third;
2296      }
2297      @Override
2298      public LispObject execute(LispObject[] args)
2299      {
2300        final AbstractArray array = checkArray(args[0]);
2301        final int nsubs = args.length - 2;
2302        final int[] subs = new int[nsubs];
2303        for (int i = nsubs; i-- > 0;)
2304            subs[i] = Fixnum.getValue(args[i+1]);
2305        final LispObject newValue = args[args.length - 1];
2306        array.set(subs, newValue);
2307        return newValue;
2308      }
2309    };
2310
2311  // ### row-major-aref array index => element
2312  private static final Primitive ROW_MAJOR_AREF =
2313    new Primitive(Symbol.ROW_MAJOR_AREF, "array index")
2314    {
2315      @Override
2316      public LispObject execute(LispObject first, LispObject second)
2317
2318      {         
2319            return checkArray(first).AREF(Fixnum.getValue(second));
2320      }
2321    };
2322
2323  // ### vector
2324  private static final Primitive VECTOR =
2325    new Primitive(Symbol.VECTOR, "&rest objects")
2326    {
2327      @Override
2328      public LispObject execute(LispObject[] args)
2329      {
2330        return new SimpleVector(args);
2331      }
2332    };
2333
2334  // ### fill-pointer
2335  private static final Primitive FILL_POINTER =
2336    new Primitive(Symbol.FILL_POINTER, "vector")
2337    {
2338      @Override
2339      public LispObject execute(LispObject arg)
2340
2341      {
2342          if (arg instanceof AbstractArray) {
2343                  AbstractArray aa = (AbstractArray)arg;
2344                  if (aa.hasFillPointer())           
2345                          return Fixnum.getInstance(aa.getFillPointer());
2346          }
2347            return type_error(arg, list(Symbol.AND, Symbol.VECTOR,
2348                                              list(Symbol.SATISFIES,
2349                                                    Symbol.ARRAY_HAS_FILL_POINTER_P)));
2350      }
2351    };
2352
2353  // ### %set-fill-pointer vector new-fill-pointer
2354  private static final Primitive _SET_FILL_POINTER =
2355    new Primitive("%set-fill-pointer", PACKAGE_SYS, true)
2356    {
2357      @Override
2358      public LispObject execute(LispObject first, LispObject second)
2359
2360      {
2361
2362          if (first instanceof AbstractVector) {
2363            AbstractVector v = (AbstractVector) first;
2364            if (v.hasFillPointer())
2365              v.setFillPointer(second);
2366            else
2367              v.noFillPointer();
2368            return second;
2369          }
2370
2371            return type_error(first, list(Symbol.AND, Symbol.VECTOR,
2372                                                list(Symbol.SATISFIES,
2373                                                      Symbol.ARRAY_HAS_FILL_POINTER_P)));         
2374      }
2375    };
2376
2377  // ### vector-push new-element vector => index-of-new-element
2378  private static final Primitive VECTOR_PUSH =
2379    new Primitive(Symbol.VECTOR_PUSH, "new-element vector")
2380    {
2381      @Override
2382      public LispObject execute(LispObject first, LispObject second)
2383
2384      {
2385        final AbstractVector v = checkVector(second);
2386        int fillPointer = v.getFillPointer();
2387        if (fillPointer < 0)
2388          v.noFillPointer();
2389        if (fillPointer >= v.capacity())
2390          return NIL;
2391        v.aset(fillPointer, first);
2392        v.setFillPointer(fillPointer + 1);
2393        return Fixnum.getInstance(fillPointer);
2394      }
2395    };
2396
2397  // ### vector-push-extend new-element vector &optional extension
2398  // => index-of-new-element
2399  private static final Primitive VECTOR_PUSH_EXTEND =
2400    new Primitive(Symbol.VECTOR_PUSH_EXTEND,
2401                  "new-element vector &optional extension")
2402    {
2403      @Override
2404      public LispObject execute(LispObject first, LispObject second)
2405
2406      {
2407        return second.VECTOR_PUSH_EXTEND(first);
2408      }
2409
2410      @Override
2411      public LispObject execute(LispObject first, LispObject second,
2412                                LispObject third)
2413
2414      {
2415        return second.VECTOR_PUSH_EXTEND(first, third);
2416      }
2417    };
2418
2419  // ### vector-pop vector => element
2420  private static final Primitive VECTOR_POP =
2421    new Primitive(Symbol.VECTOR_POP, "vector")
2422    {
2423      @Override
2424      public LispObject execute(LispObject arg)
2425      {
2426        final AbstractVector v = checkVector( arg);
2427        int fillPointer = v.getFillPointer();
2428        if (fillPointer < 0)
2429          v.noFillPointer();
2430        if (fillPointer == 0)
2431          error(new LispError("nothing left to pop"));
2432        int newFillPointer = v.checkIndex(fillPointer - 1);
2433        LispObject element = v.AREF(newFillPointer);
2434        v.setFillPointer(newFillPointer);
2435        return element;
2436      }
2437    };
2438
2439  // ### type-of
2440  private static final Primitive TYPE_OF =
2441    new Primitive(Symbol.TYPE_OF, "object")
2442    {
2443      @Override
2444      public LispObject execute(LispObject arg)
2445      {
2446        return arg.typeOf();
2447      }
2448    };
2449
2450  // ### class-of
2451  private static final Primitive CLASS_OF =
2452    new Primitive(Symbol.CLASS_OF, "object")
2453    {
2454      @Override
2455      public LispObject execute(LispObject arg)
2456      {
2457        return arg.classOf();
2458      }
2459    };
2460
2461  // ### simple-typep
2462  private static final Primitive SIMPLE_TYPEP =
2463    new Primitive("simple-typep", PACKAGE_SYS, true)
2464    {
2465      @Override
2466      public LispObject execute(LispObject first, LispObject second)
2467
2468      {
2469        return first.typep(second);
2470      }
2471    };
2472
2473  // ### function-lambda-expression function =>
2474  // lambda-expression, closure-p, name
2475  private static final Primitive FUNCTION_LAMBDA_EXPRESSION =
2476    new Primitive(Symbol.FUNCTION_LAMBDA_EXPRESSION, "function")
2477    {
2478      @Override
2479      public LispObject execute(LispObject arg)
2480      {
2481        final LispObject value1, value2, value3;
2482        if (arg instanceof CompiledClosure)
2483          {
2484            value1 = NIL;
2485            value2 = T;
2486            LispObject name = ((CompiledClosure)arg).getLambdaName();
2487            value3 = name != null ? name : NIL;
2488          }
2489        else if (arg instanceof Closure)
2490          {
2491            Closure closure = (Closure) arg;
2492            LispObject expr = closure.getBody();
2493            expr = new Cons(closure.getLambdaList(), expr);
2494            expr = new Cons(Symbol.LAMBDA, expr);
2495            value1 = expr;
2496            Environment env = closure.getEnvironment();
2497            if (env == null || env.isEmpty())
2498              value2 = NIL;
2499            else
2500              value2 = env; // Return environment as closure-p.
2501            LispObject name = ((Closure)arg).getLambdaName();
2502            value3 = name != null ? name : NIL;
2503          }
2504        else if (arg instanceof Function)
2505          {
2506            value1 = NIL;
2507            value2 = T;
2508            value3 = ((Function)arg).getLambdaName();
2509          }
2510        else if (arg instanceof StandardGenericFunction)
2511          {
2512            value1 = NIL;
2513            value2 = T;
2514            value3 = ((StandardGenericFunction)arg).getGenericFunctionName();
2515          }
2516        else
2517          return type_error(arg, Symbol.FUNCTION);
2518        return LispThread.currentThread().setValues(value1, value2, value3);
2519      }
2520    };
2521
2522  // ### funcall
2523  // This needs to be public for LispAPI.java.
2524  public static final Primitive FUNCALL =
2525    new Primitive(Symbol.FUNCALL, "function &rest args")
2526    {
2527      @Override
2528      public LispObject execute()
2529      {
2530        return error(new WrongNumberOfArgumentsException(this));
2531      }
2532      @Override
2533      public LispObject execute(LispObject arg)
2534      {
2535        return LispThread.currentThread().execute(arg);
2536      }
2537      @Override
2538      public LispObject execute(LispObject first, LispObject second)
2539
2540      {
2541        return LispThread.currentThread().execute(first, second);
2542      }
2543      @Override
2544      public LispObject execute(LispObject first, LispObject second,
2545                                LispObject third)
2546
2547      {
2548        return LispThread.currentThread().execute(first, second, third);
2549      }
2550      @Override
2551      public LispObject execute(LispObject first, LispObject second,
2552                                LispObject third, LispObject fourth)
2553
2554      {
2555        return LispThread.currentThread().execute(first, second, third,
2556                                                  fourth);
2557      }
2558      @Override
2559      public LispObject execute(LispObject first, LispObject second,
2560                                LispObject third, LispObject fourth,
2561                                LispObject fifth)
2562
2563      {
2564        return LispThread.currentThread().execute(first, second, third,
2565                                                  fourth, fifth);
2566      }
2567      @Override
2568      public LispObject execute(LispObject first, LispObject second,
2569                                LispObject third, LispObject fourth,
2570                                LispObject fifth, LispObject sixth)
2571
2572      {
2573        return LispThread.currentThread().execute(first, second, third,
2574                                                  fourth, fifth, sixth);
2575      }
2576      @Override
2577      public LispObject execute(LispObject first, LispObject second,
2578                                LispObject third, LispObject fourth,
2579                                LispObject fifth, LispObject sixth,
2580                                LispObject seventh)
2581
2582      {
2583        return LispThread.currentThread().execute(first, second, third,
2584                                                  fourth, fifth, sixth,
2585                                                  seventh);
2586      }
2587      @Override
2588      public LispObject execute(LispObject first, LispObject second,
2589                                LispObject third, LispObject fourth,
2590                                LispObject fifth, LispObject sixth,
2591                                LispObject seventh, LispObject eigth)
2592
2593      {
2594        return LispThread.currentThread().execute(first, second, third,
2595                                                  fourth, fifth, sixth,
2596                                                  seventh, eigth);
2597      }
2598      @Override
2599      public LispObject execute(LispObject[] args)
2600      {
2601        final int length = args.length - 1; // Number of arguments.
2602        if (length == 8)
2603          {
2604            return LispThread.currentThread().execute(args[0], args[1],
2605                                                      args[2], args[3],
2606                                                      args[4], args[5],
2607                                                      args[6], args[7],
2608                                                      args[8]);
2609          }
2610        else
2611          {
2612            LispObject[] newArgs = new LispObject[length];
2613            System.arraycopy(args, 1, newArgs, 0, length);
2614            return LispThread.currentThread().execute(args[0], newArgs);
2615          }
2616      }
2617    };
2618
2619  // ### apply
2620  public static final Primitive APPLY =
2621    new Primitive(Symbol.APPLY, "function &rest args")
2622    {
2623      @Override
2624      public LispObject execute()
2625      {
2626        return error(new WrongNumberOfArgumentsException(this));
2627      }
2628      @Override
2629      public LispObject execute(LispObject arg)
2630      {
2631        return error(new WrongNumberOfArgumentsException(this));
2632      }
2633      @Override
2634      public LispObject execute(LispObject fun, LispObject args)
2635
2636      {
2637        final LispThread thread = LispThread.currentThread();
2638        final int length = args.length();
2639        switch (length)
2640          {
2641          case 0:
2642            return thread.execute(fun);
2643          case 1:
2644            return thread.execute(fun, ((Cons)args).car);
2645          case 2:
2646            {
2647              Cons cons = (Cons) args;
2648              return thread.execute(fun, cons.car, ((Cons)cons.cdr).car);
2649            }
2650          case 3:
2651            return thread.execute(fun, args.car(), args.cadr(),
2652                                  args.cdr().cdr().car());
2653          default:
2654            {
2655              final LispObject[] funArgs = new LispObject[length];
2656              int j = 0;
2657              while (args != NIL)
2658                {
2659                  funArgs[j++] = args.car();
2660                  args = args.cdr();
2661                }
2662              return funcall(fun, funArgs, thread);
2663            }
2664          }
2665      }
2666      @Override
2667      public LispObject execute(LispObject first, LispObject second,
2668                                LispObject third)
2669
2670      {
2671        if (third.listp())
2672          {
2673            final int numFunArgs = 1 + third.length();
2674            final LispObject[] funArgs = new LispObject[numFunArgs];
2675            funArgs[0] = second;
2676            int j = 1;
2677            while (third != NIL)
2678              {
2679                funArgs[j++] = third.car();
2680                third = third.cdr();
2681              }
2682            return funcall(first, funArgs, LispThread.currentThread());
2683          }
2684        return type_error(third, Symbol.LIST);
2685      }
2686      @Override
2687      public LispObject execute(final LispObject[] args)
2688      {
2689        final int numArgs = args.length;
2690        LispObject spread = args[numArgs - 1];
2691        if (spread.listp())
2692          {
2693            final int numFunArgs = numArgs - 2 + spread.length();
2694            final LispObject[] funArgs = new LispObject[numFunArgs];
2695            int j = 0;
2696            for (int i = 1; i < numArgs - 1; i++)
2697              funArgs[j++] = args[i];
2698            while (spread != NIL)
2699              {
2700                funArgs[j++] = spread.car();
2701                spread = spread.cdr();
2702              }
2703            return funcall(args[0], funArgs, LispThread.currentThread());
2704          }
2705        return type_error(spread, Symbol.LIST);
2706      }
2707    };
2708
2709  // ### mapcar
2710  private static final Primitive MAPCAR =
2711    new Primitive(Symbol.MAPCAR, "function &rest lists")
2712    {
2713      @Override
2714      public LispObject execute(LispObject fun, LispObject list)
2715
2716      {
2717        final LispThread thread = LispThread.currentThread();
2718        LispObject result = NIL;
2719        Cons splice = null;
2720        while (list != NIL)
2721          {
2722            Cons cons;
2723            if (list instanceof Cons)
2724                cons = (Cons) list;
2725            else
2726                return type_error(list, Symbol.LIST);
2727            LispObject obj = thread.execute(fun, cons.car);
2728            if (splice == null)
2729              {
2730                splice = new Cons(obj, result);
2731                result = splice;
2732              }
2733            else
2734              {
2735                Cons c = new Cons(obj);
2736                splice.cdr = c;
2737                splice = c;
2738              }
2739            list = cons.cdr;
2740          }
2741        thread._values = null;
2742        return result;
2743      }
2744      @Override
2745      public LispObject execute(LispObject fun, LispObject list1,
2746                                LispObject list2)
2747
2748      {
2749        final LispThread thread = LispThread.currentThread();
2750        LispObject result = NIL;
2751        Cons splice = null;
2752        while (list1 != NIL && list2 != NIL)
2753          {
2754            LispObject obj =
2755              thread.execute(fun, list1.car(), list2.car());
2756            if (splice == null)
2757              {
2758                splice = new Cons(obj, result);
2759                result = splice;
2760              }
2761            else
2762              {
2763                Cons cons = new Cons(obj);
2764                splice.cdr = cons;
2765                splice = cons;
2766              }
2767            list1 = list1.cdr();
2768            list2 = list2.cdr();
2769          }
2770        thread._values = null;
2771        return result;
2772      }
2773      @Override
2774      public LispObject execute(final LispObject[] args)
2775
2776      {
2777        final int numArgs = args.length;
2778        if (numArgs < 2)
2779          return error(new WrongNumberOfArgumentsException(this));
2780        int commonLength = -1;
2781        for (int i = 1; i < numArgs; i++)
2782          {
2783            if (!args[i].listp())
2784              type_error(args[i], Symbol.LIST);
2785            int len = args[i].length();
2786            if (commonLength < 0)
2787              commonLength = len;
2788            else if (commonLength > len)
2789              commonLength = len;
2790          }
2791        final LispThread thread = LispThread.currentThread();
2792        LispObject[] results = new LispObject[commonLength];
2793        final int numFunArgs = numArgs - 1;
2794        final LispObject[] funArgs = new LispObject[numFunArgs];
2795        for (int i = 0; i < commonLength; i++)
2796          {
2797            for (int j = 0; j < numFunArgs; j++)
2798              funArgs[j] = args[j+1].car();
2799            results[i] = funcall(args[0], funArgs, thread);
2800            for (int j = 1; j < numArgs; j++)
2801              args[j] = args[j].cdr();
2802          }
2803        thread._values = null;
2804        LispObject result = NIL;
2805        for (int i = commonLength; i-- > 0;)
2806          result = new Cons(results[i], result);
2807        return result;
2808      }
2809    };
2810
2811  // ### mapc
2812  private static final Primitive MAPC =
2813    new Primitive(Symbol.MAPC, "function &rest lists")
2814    {
2815      @Override
2816      public LispObject execute(LispObject fun, LispObject list)
2817
2818      {
2819        final LispThread thread = LispThread.currentThread();
2820        LispObject result = list;
2821        while (list != NIL)
2822          {
2823            Cons cons;
2824            if (list instanceof Cons)
2825                cons = (Cons) list;
2826            else
2827                return type_error(list, Symbol.LIST);
2828            thread.execute(fun, cons.car);
2829            list = cons.cdr;
2830          }
2831        thread._values = null;
2832        return result;
2833      }
2834      @Override
2835      public LispObject execute(LispObject fun, LispObject list1,
2836                                LispObject list2)
2837
2838      {
2839        final LispThread thread = LispThread.currentThread();
2840        LispObject result = list1;
2841        while (list1 != NIL && list2 != NIL)
2842          {
2843            thread.execute(fun, list1.car(), list2.car());
2844            list1 = ((Cons)list1).cdr;
2845            list2 = ((Cons)list2).cdr;
2846          }
2847        thread._values = null;
2848        return result;
2849      }
2850      @Override
2851      public LispObject execute(final LispObject[] args)
2852
2853      {
2854        final int numArgs = args.length;
2855        if (numArgs < 2)
2856          return error(new WrongNumberOfArgumentsException(this));
2857        int commonLength = -1;
2858        for (int i = 1; i < numArgs; i++)
2859          {
2860            if (!args[i].listp())
2861              type_error(args[i], Symbol.LIST);
2862            int len = args[i].length();
2863            if (commonLength < 0)
2864              commonLength = len;
2865            else if (commonLength > len)
2866              commonLength = len;
2867          }
2868        final LispThread thread = LispThread.currentThread();
2869        LispObject result = args[1];
2870        final int numFunArgs = numArgs - 1;
2871        final LispObject[] funArgs = new LispObject[numFunArgs];
2872        for (int i = 0; i < commonLength; i++)
2873          {
2874            for (int j = 0; j < numFunArgs; j++)
2875              funArgs[j] = args[j+1].car();
2876            funcall(args[0], funArgs, thread);
2877            for (int j = 1; j < numArgs; j++)
2878              args[j] = args[j].cdr();
2879          }
2880        thread._values = null;
2881        return result;
2882      }
2883    };
2884
2885  // ### macroexpand
2886  private static final Primitive MACROEXPAND =
2887    new Primitive(Symbol.MACROEXPAND, "form &optional env")
2888    {
2889      @Override
2890      public LispObject execute(LispObject form)
2891      {
2892        return macroexpand(form,
2893                           new Environment(),
2894                           LispThread.currentThread());
2895      }
2896      @Override
2897      public LispObject execute(LispObject form, LispObject env)
2898
2899      {
2900        return macroexpand(form,
2901                           env != NIL ? checkEnvironment(env) : new Environment(),
2902                           LispThread.currentThread());
2903      }
2904    };
2905
2906  // ### macroexpand-1
2907  private static final Primitive MACROEXPAND_1 =
2908    new Primitive(Symbol.MACROEXPAND_1, "form &optional env")
2909    {
2910      @Override
2911      public LispObject execute(LispObject form)
2912      {
2913        return macroexpand_1(form,
2914                             new Environment(),
2915                             LispThread.currentThread());
2916      }
2917      @Override
2918      public LispObject execute(LispObject form, LispObject env)
2919
2920      {
2921        return macroexpand_1(form,
2922                             env != NIL ? checkEnvironment(env) : new Environment(),
2923                             LispThread.currentThread());
2924      }
2925    };
2926
2927  // ### gensym
2928  private static final Primitive GENSYM =
2929    new Primitive(Symbol.GENSYM, "&optional x")
2930    {
2931      @Override
2932      public LispObject execute()
2933      {
2934        return gensym("G", LispThread.currentThread());
2935      }
2936      @Override
2937      public LispObject execute(LispObject arg)
2938      {
2939        if (arg instanceof Fixnum)
2940          {
2941            int n = ((Fixnum)arg).value;
2942            if (n >= 0)
2943              {
2944                FastStringBuffer sb = new FastStringBuffer('G');
2945                sb.append(n); // Decimal representation.
2946                return new Symbol(new SimpleString(sb));
2947              }
2948          }
2949        else if (arg instanceof Bignum)
2950          {
2951            BigInteger n = ((Bignum)arg).value;
2952            if (n.signum() >= 0)
2953              {
2954                FastStringBuffer sb = new FastStringBuffer('G');
2955                sb.append(n.toString()); // Decimal representation.
2956                return new Symbol(new SimpleString(sb));
2957              }
2958          }
2959        else if (arg instanceof AbstractString)
2960          return gensym(arg.getStringValue(), LispThread.currentThread());
2961        return type_error(arg,
2962                               list(Symbol.OR,
2963                                     Symbol.STRING,
2964                                     Symbol.UNSIGNED_BYTE));
2965      }
2966    };
2967
2968  // ### string
2969  private static final Primitive STRING = new Primitive(Symbol.STRING, "x")
2970    {
2971      @Override
2972      public LispObject execute(LispObject arg)
2973      {
2974        return arg.STRING();
2975      }
2976    };
2977
2978  // ### intern string &optional package => symbol, status
2979  // STATUS is one of :INHERITED, :EXTERNAL, :INTERNAL or NIL.
2980  // "It is implementation-dependent whether the string that becomes the new
2981  // symbol's name is the given string or a copy of it."
2982  private static final Primitive INTERN =
2983    new Primitive(Symbol.INTERN, "string &optional package")
2984    {
2985      @Override
2986      public LispObject execute(LispObject arg)
2987      {
2988        final SimpleString s;
2989        if (arg instanceof SimpleString)
2990          s = (SimpleString) arg;
2991        else
2992          s = new SimpleString(arg.getStringValue());
2993        final LispThread thread = LispThread.currentThread();
2994        Package pkg = (Package) Symbol._PACKAGE_.symbolValue(thread);
2995        return pkg.intern(s, thread);
2996      }
2997      @Override
2998      public LispObject execute(LispObject first, LispObject second)
2999
3000      {
3001        final SimpleString s;
3002        if (first instanceof SimpleString)
3003          s = (SimpleString) first;
3004        else
3005          s = new SimpleString(first.getStringValue());
3006        Package pkg = coerceToPackage(second);
3007        return pkg.intern(s, LispThread.currentThread());
3008      }
3009    };
3010
3011  // ### unintern
3012  // unintern symbol &optional package => generalized-boolean
3013  private static final Primitive UNINTERN =
3014    new Primitive(Symbol.UNINTERN, "symbol &optional package")
3015    {
3016      @Override
3017      public LispObject execute(LispObject[] args)
3018      {
3019        if (args.length == 0 || args.length > 2)
3020          return error(new WrongNumberOfArgumentsException(this));
3021        Symbol symbol = checkSymbol(args[0]);
3022        Package pkg;
3023        if (args.length == 2)
3024          pkg = coerceToPackage(args[1]);
3025        else
3026          pkg = getCurrentPackage();
3027        return pkg.unintern(symbol);
3028      }
3029    };
3030
3031  // ### find-package
3032  private static final Primitive FIND_PACKAGE =
3033    new Primitive(Symbol.FIND_PACKAGE, "name")
3034    {
3035      @Override
3036      public LispObject execute(LispObject arg)
3037      {
3038        if (arg instanceof Package)
3039          return arg;
3040        if (arg instanceof AbstractString)
3041          {
3042            Package pkg =
3043              Packages.findPackage(arg.getStringValue());
3044            return pkg != null ? pkg : NIL;
3045          }
3046        if (arg instanceof Symbol)
3047          {
3048            Package pkg = Packages.findPackage(checkSymbol(arg).getName());
3049            return pkg != null ? pkg : NIL;
3050          }
3051        if (arg instanceof LispCharacter)
3052          {
3053            String packageName =
3054              String.valueOf(new char[] {((LispCharacter)arg).getValue()});
3055            Package pkg = Packages.findPackage(packageName);
3056            return pkg != null ? pkg : NIL;
3057          }
3058        return NIL;
3059      }
3060    };
3061
3062  // ### %make-package
3063  // %make-package package-name nicknames use => package
3064  private static final Primitive _MAKE_PACKAGE =
3065    new Primitive("%make-package", PACKAGE_SYS, false)
3066    {
3067      /**
3068       * This invocation is solely used to be able to create
3069       * a package to bind to *FASL-ANONYMOUS-PACKAGE*
3070       */
3071      @Override
3072      public LispObject execute()
3073
3074      {
3075        return new Package();
3076      }
3077
3078      /**
3079       * This invocation is used by MAKE-PACKAGE to create a package
3080       */
3081      @Override
3082      public LispObject execute(LispObject first, LispObject second,
3083                                LispObject third)
3084
3085      {
3086        String packageName = javaString(first);
3087        Package pkg = Packages.findPackage(packageName);
3088        if (pkg != null)
3089          error(new LispError("Package " + packageName +
3090                               " already exists."));
3091        LispObject nicknames = checkList(second);
3092        if (nicknames != NIL)
3093          {
3094            LispObject list = nicknames;
3095            while (list != NIL)
3096              {
3097                String nick = javaString(list.car());
3098                if (Packages.findPackage(nick) != null)
3099                  {
3100                    error(new PackageError("A package named " + nick +
3101                                            " already exists."));
3102                  }
3103                list = list.cdr();
3104              }
3105          }
3106        LispObject use = checkList(third);
3107        if (use != NIL)
3108          {
3109            LispObject list = use;
3110            while (list != NIL)
3111              {
3112                LispObject obj = list.car();
3113                if (obj instanceof Package) {
3114                  // OK.
3115                } else
3116                  {
3117                    String s = javaString(obj);
3118                    Package p = Packages.findPackage(s);
3119                    if (p == null)
3120                      {
3121                        error(new LispError(obj.writeToString() +
3122                                             " is not the name of a package."));
3123                        return NIL;
3124                      }
3125                  }
3126                list = list.cdr();
3127              }
3128          }
3129        // Now create the package.
3130        pkg = Packages.createPackage(packageName);
3131        // Add the nicknames.
3132        while (nicknames != NIL)
3133          {
3134            String nick = javaString(nicknames.car());
3135            pkg.addNickname(nick);
3136            nicknames = nicknames.cdr();
3137          }
3138        // Create the use list.
3139        while (use != NIL)
3140          {
3141            LispObject obj = use.car();
3142            if (obj instanceof Package)
3143              pkg.usePackage((Package)obj);
3144            else
3145              {
3146                String s = javaString(obj);
3147                Package p = Packages.findPackage(s);
3148                if (p == null)
3149                  {
3150                    error(new LispError(obj.writeToString() +
3151                                         " is not the name of a package."));
3152                    return NIL;
3153                  }
3154                pkg.usePackage(p);
3155              }
3156            use = use.cdr();
3157          }
3158        return pkg;
3159      }
3160    };
3161
3162  // ### %in-package
3163  private static final Primitive _IN_PACKAGE =
3164    new Primitive("%in-package", PACKAGE_SYS, true)
3165    {
3166      @Override
3167      public LispObject execute(LispObject arg)
3168      {
3169        final String packageName = javaString(arg);
3170        final Package pkg = Packages.findPackage(packageName);
3171        if (pkg == null)
3172          return error(new PackageError("The name " + packageName +
3173                                         " does not designate any package."));
3174        SpecialBinding binding =
3175          LispThread.currentThread().getSpecialBinding(Symbol._PACKAGE_);
3176        if (binding != null)
3177          binding.value = pkg;
3178        else
3179          // No dynamic binding.
3180          Symbol._PACKAGE_.setSymbolValue(pkg);
3181        return pkg;
3182      }
3183    };
3184
3185  // ### use-package packages-to-use &optional package => t
3186  private static final Primitive USE_PACKAGE =
3187    new Primitive(Symbol.USE_PACKAGE, "packages-to-use &optional package")
3188    {
3189      @Override
3190      public LispObject execute(LispObject[] args)
3191      {
3192        if (args.length < 1 || args.length > 2)
3193          return error(new WrongNumberOfArgumentsException(this));
3194        Package pkg;
3195        if (args.length == 2)
3196          pkg = coerceToPackage(args[1]);
3197        else
3198          pkg = getCurrentPackage();
3199        if (args[0].listp())
3200          {
3201            LispObject list = args[0];
3202            while (list != NIL)
3203              {
3204                pkg.usePackage(coerceToPackage(list.car()));
3205                list = list.cdr();
3206              }
3207          }
3208        else
3209          pkg.usePackage(coerceToPackage(args[0]));
3210        return T;
3211      }
3212    };
3213
3214  // ### package-symbols
3215  private static final Primitive PACKAGE_SYMBOLS =
3216    new Primitive("package-symbols", PACKAGE_SYS, true)
3217    {
3218      @Override
3219      public LispObject execute(LispObject arg)
3220      {
3221        return coerceToPackage(arg).getSymbols();
3222      }
3223    };
3224
3225  // ### package-internal-symbols
3226  private static final Primitive PACKAGE_INTERNAL_SYMBOLS =
3227    new Primitive("package-internal-symbols", PACKAGE_SYS, true)
3228    {
3229      @Override
3230      public LispObject execute(LispObject arg)
3231      {
3232        return coerceToPackage(arg).PACKAGE_INTERNAL_SYMBOLS();
3233      }
3234    };
3235
3236  // ### package-external-symbols
3237  private static final Primitive PACKAGE_EXTERNAL_SYMBOLS =
3238    new Primitive("package-external-symbols", PACKAGE_SYS, true)
3239    {
3240      @Override
3241      public LispObject execute(LispObject arg)
3242      {
3243        return coerceToPackage(arg).PACKAGE_EXTERNAL_SYMBOLS();
3244      }
3245    };
3246
3247  // ### package-inherited-symbols
3248  private static final Primitive PACKAGE_INHERITED_SYMBOLS =
3249    new Primitive("package-inherited-symbols", PACKAGE_SYS, true)
3250    {
3251      @Override
3252      public LispObject execute(LispObject arg)
3253      {
3254        return coerceToPackage(arg).PACKAGE_INHERITED_SYMBOLS();
3255      }
3256    };
3257
3258  // ### export symbols &optional package
3259  private static final Primitive EXPORT =
3260    new Primitive(Symbol.EXPORT, "symbols &optional package")
3261    {
3262      @Override
3263      public LispObject execute(LispObject arg)
3264      {
3265        final Package pkg = (Package) Symbol._PACKAGE_.symbolValue();
3266        if (arg instanceof Cons)
3267          {
3268            for (LispObject list = arg; list != NIL; list = list.cdr())
3269              pkg.export(checkSymbol(list.car()));
3270          }
3271        else
3272          pkg.export(checkSymbol(arg));
3273        return T;
3274      }
3275
3276      @Override
3277      public LispObject execute(LispObject first, LispObject second)
3278
3279      {
3280        if (first instanceof Cons)
3281          {
3282            Package pkg = coerceToPackage(second);
3283            for (LispObject list = first; list != NIL; list = list.cdr())
3284              pkg.export(checkSymbol(list.car()));
3285          }
3286        else
3287          coerceToPackage(second).export(checkSymbol(first));
3288        return T;
3289      }
3290    };
3291
3292  // ### find-symbol string &optional package => symbol, status
3293  private static final Primitive FIND_SYMBOL =
3294    new Primitive(Symbol.FIND_SYMBOL, "string &optional package")
3295    {
3296      @Override
3297      public LispObject execute(LispObject arg)
3298      {
3299        return getCurrentPackage().findSymbol(arg.getStringValue());
3300      }
3301
3302      @Override
3303      public LispObject execute(LispObject first, LispObject second)
3304
3305      {
3306        return coerceToPackage(second).findSymbol(first.getStringValue());
3307      }
3308    };
3309
3310  // ### fset name function &optional source-position arglist documentation
3311  // => function
3312  private static final Primitive FSET =
3313    new Primitive("fset", PACKAGE_SYS, true)
3314    {
3315      @Override
3316      public LispObject execute(LispObject first, LispObject second)
3317
3318      {
3319        return execute(first, second, NIL, NIL, NIL);
3320      }
3321      @Override
3322      public LispObject execute(LispObject first, LispObject second,
3323                                LispObject third)
3324
3325      {
3326        return execute(first, second, third, NIL, NIL);
3327      }
3328      @Override
3329      public LispObject execute(LispObject first, LispObject second,
3330                                LispObject third, LispObject fourth)
3331
3332      {
3333        return execute(first, second, third, fourth, NIL);
3334      }
3335      @Override
3336      public LispObject execute(LispObject first, LispObject second,
3337                                LispObject third, LispObject fourth,
3338                                LispObject fifth)
3339
3340      {
3341        if (first instanceof Symbol)
3342          {
3343            checkRedefinition(first);
3344            Symbol symbol = checkSymbol(first);
3345            symbol.setSymbolFunction(second);
3346            final LispThread thread = LispThread.currentThread();
3347            LispObject sourcePathname = _SOURCE_.symbolValue(thread);
3348            LispObject sourcePosition = third;
3349            if (sourcePathname != NIL)
3350              sourcePosition = _SOURCE_POSITION_.symbolValue(thread);
3351            if (sourcePathname == NIL)
3352              sourcePathname = Keyword.TOP_LEVEL;
3353            if (sourcePathname != Keyword.TOP_LEVEL)
3354              put(symbol, Symbol._SOURCE, new Cons(sourcePathname, third));
3355            else
3356              put(symbol, Symbol._SOURCE, sourcePathname);
3357          }
3358        else if (isValidSetfFunctionName(first))
3359          {
3360            // SETF function
3361            checkRedefinition(first);
3362            Symbol symbol = checkSymbol(first.cadr());
3363            put(symbol, Symbol.SETF_FUNCTION, second);
3364          }
3365        else
3366          return type_error(first, FUNCTION_NAME);
3367        if (second instanceof Operator)
3368          {
3369            Operator op = (Operator) second;
3370            op.setLambdaName(first);
3371            if (fourth != NIL)
3372              op.setLambdaList(fourth);
3373            if (fifth != NIL)
3374              op.setDocumentation(Symbol.FUNCTION, fifth);
3375          }
3376        return second;
3377      }
3378    };
3379
3380  // ### %set-symbol-plist
3381  private static final Primitive _SET_SYMBOL_PLIST =
3382    new Primitive("%set-symbol-plist", PACKAGE_SYS, false)
3383    {
3384      @Override
3385      public LispObject execute(LispObject first, LispObject second)
3386
3387      {
3388        checkSymbol(first).setPropertyList(checkList(second));
3389        return second;
3390      }
3391    };
3392
3393  // ### getf plist indicator &optional default => value
3394  private static final Primitive GETF =
3395    new Primitive(Symbol.GETF, "plist indicator &optional default")
3396    {
3397      @Override
3398      public LispObject execute(LispObject plist, LispObject indicator)
3399
3400      {
3401        return getf(plist, indicator, NIL);
3402      }
3403      @Override
3404      public LispObject execute(LispObject plist, LispObject indicator,
3405                                LispObject defaultValue)
3406
3407      {
3408        return getf(plist, indicator, defaultValue);
3409      }
3410    };
3411
3412  // ### get symbol indicator &optional default => value
3413  private static final Primitive GET =
3414    new Primitive(Symbol.GET, "symbol indicator &optional default")
3415    {
3416      @Override
3417      public LispObject execute(LispObject symbol, LispObject indicator)
3418
3419      {
3420        return get(symbol, indicator, NIL);
3421      }
3422      @Override
3423      public LispObject execute(LispObject symbol, LispObject indicator,
3424                                LispObject defaultValue)
3425
3426      {
3427        return get(symbol, indicator, defaultValue);
3428      }
3429    };
3430
3431  // ### put symbol indicator value => value
3432  private static final Primitive PUT =
3433    new Primitive("put", PACKAGE_SYS, true)
3434    {
3435      @Override
3436      public LispObject execute(LispObject symbol, LispObject indicator,
3437                                LispObject value)
3438
3439      {
3440            return put(checkSymbol(symbol), indicator, value);
3441      }
3442      @Override
3443      public LispObject execute(LispObject symbol, LispObject indicator,
3444                                LispObject defaultValue, LispObject value)
3445
3446      {
3447          return put(checkSymbol(symbol), indicator, value);
3448      }
3449    };
3450
3451  // ### macrolet
3452  private static final SpecialOperator MACROLET =
3453    new SpecialOperator(Symbol.MACROLET, "definitions &rest body")
3454    {
3455      @Override
3456      public LispObject execute(LispObject args, Environment env)
3457
3458      {
3459        LispObject defs = checkList(args.car());
3460        final LispThread thread = LispThread.currentThread();
3461        final SpecialBinding lastSpecialBinding = thread.lastSpecialBinding;
3462
3463        try
3464          {
3465            Environment ext = new Environment(env);
3466            while (defs != NIL)
3467              {
3468                LispObject def = checkList(defs.car());
3469                Symbol symbol = checkSymbol(def.car());
3470                Symbol make_expander_for_macrolet =
3471                  PACKAGE_SYS.intern("MAKE-EXPANDER-FOR-MACROLET");
3472                LispObject expander =
3473                  make_expander_for_macrolet.execute(def);
3474                Closure expansionFunction = new Closure(expander, env);
3475                MacroObject macroObject =
3476                  new MacroObject(symbol, expansionFunction);
3477                ext.addFunctionBinding(symbol, macroObject);
3478                defs = defs.cdr();
3479              }
3480            return progn(ext.processDeclarations(args.cdr()), ext, thread);
3481          }
3482        finally
3483          {
3484            thread.lastSpecialBinding = lastSpecialBinding;
3485          }
3486      }
3487    };
3488
3489  private static final Primitive MAKE_EXPANDER_FOR_MACROLET =
3490    new Primitive("make-expander-for-macrolet", PACKAGE_SYS, true,
3491                  "definition")
3492    {
3493      @Override
3494      public LispObject execute(LispObject definition)
3495
3496      {
3497        Symbol symbol = checkSymbol(definition.car());
3498        LispObject lambdaList = definition.cadr();
3499        LispObject body = definition.cddr();
3500        LispObject block =
3501          new Cons(Symbol.BLOCK, new Cons(symbol, body));
3502        LispObject toBeApplied =
3503          list(Symbol.LAMBDA, lambdaList, block);
3504        final LispThread thread = LispThread.currentThread();
3505        LispObject formArg = gensym("WHOLE-", thread);
3506        LispObject envArg = gensym("ENVIRONMENT-", thread); // Ignored.
3507        LispObject expander =
3508          list(Symbol.LAMBDA, list(formArg, envArg),
3509                list(Symbol.APPLY, toBeApplied,
3510                      list(Symbol.CDR, formArg)));
3511        return expander;
3512      }
3513    };
3514
3515  // ### tagbody
3516  private static final SpecialOperator TAGBODY =
3517    new SpecialOperator(Symbol.TAGBODY, "&rest statements")
3518    {
3519      @Override
3520      public LispObject execute(LispObject args, Environment env)
3521
3522      {
3523        Environment ext = new Environment(env);
3524        try {
3525          return processTagBody(args, preprocessTagBody(args, ext), ext);
3526        }
3527        finally {
3528          ext.inactive = true;
3529        }
3530      }
3531    };
3532
3533  // ### go
3534  private static final SpecialOperator GO =
3535    new SpecialOperator(Symbol.GO, "tag")
3536    {
3537      @Override
3538      public LispObject execute(LispObject args, Environment env)
3539
3540      {
3541        if (args.length() != 1)
3542          return error(new WrongNumberOfArgumentsException(this));
3543        Binding binding = env.getTagBinding(args.car());
3544        if (binding == null)
3545          return error(new ControlError("No tag named " +
3546                                         args.car().writeToString() +
3547                                         " is currently visible."));
3548
3549        return nonLocalGo(binding, args.car());
3550      }
3551    };
3552
3553  // ### block
3554  private static final SpecialOperator BLOCK =
3555    new SpecialOperator(Symbol.BLOCK, "name &rest forms")
3556    {
3557      @Override
3558      public LispObject execute(LispObject args, Environment env)
3559
3560      {
3561        if (args == NIL)
3562          return error(new WrongNumberOfArgumentsException(this));
3563        LispObject tag;
3564            tag = checkSymbol(args.car());
3565        LispObject body = ((Cons)args).cdr();
3566        Environment ext = new Environment(env);
3567        final LispObject block = new LispObject();
3568        ext.addBlock(tag, block);
3569        LispObject result = NIL;
3570        final LispThread thread = LispThread.currentThread();
3571        try
3572          {
3573            return progn(body, ext, thread);
3574          }
3575        catch (Return ret)
3576          {
3577            if (ret.getBlock() == block)
3578              {
3579                return ret.getResult();
3580              }
3581            throw ret;
3582          }
3583        finally
3584          {
3585              ext.inactive = true;
3586          }
3587      }
3588    };
3589
3590  // ### return-from
3591  private static final SpecialOperator RETURN_FROM =
3592    new SpecialOperator(Symbol.RETURN_FROM, "name &optional value")
3593    {
3594      @Override
3595      public LispObject execute(LispObject args, Environment env)
3596
3597      {
3598        final int length = args.length();
3599        if (length < 1 || length > 2)
3600          return error(new WrongNumberOfArgumentsException(this));
3601        Symbol symbol;
3602            symbol = checkSymbol(args.car());
3603
3604        return nonLocalReturn(env.getBlockBinding(symbol), symbol,
3605                              (length == 2) ? eval(args.cadr(), env,
3606                                                   LispThread.currentThread())
3607                                            : NIL);
3608      }
3609    };
3610
3611  // ### catch
3612  private static final SpecialOperator CATCH =
3613    new SpecialOperator(Symbol.CATCH, "tag &body body")
3614    {
3615      @Override
3616      public LispObject execute(LispObject args, Environment env)
3617
3618      {
3619        if (args.length() < 1)
3620          return error(new WrongNumberOfArgumentsException(this));
3621        final LispThread thread = LispThread.currentThread();
3622        LispObject tag = eval(args.car(), env, thread);
3623        thread.pushCatchTag(tag);
3624        LispObject body = args.cdr();
3625        LispObject result = NIL;
3626        try
3627          {
3628            return progn(body, env, thread);
3629          }
3630        catch (Throw t)
3631          {
3632            if (t.tag == tag)
3633              {
3634                return t.getResult(thread);
3635              }
3636            throw t;
3637          }
3638        catch (Return ret)
3639          {
3640            throw ret;
3641          }
3642        finally
3643          {
3644            thread.popCatchTag();
3645          }
3646      }
3647    };
3648
3649  // ### throw
3650  private static final SpecialOperator THROW =
3651    new SpecialOperator(Symbol.THROW, "tag result")
3652    {
3653      @Override
3654      public LispObject execute(LispObject args, Environment env)
3655
3656      {
3657        if (args.length() != 2)
3658          return error(new WrongNumberOfArgumentsException(this));
3659        final LispThread thread = LispThread.currentThread();
3660        thread.throwToTag(eval(args.car(), env, thread),
3661                          eval(args.cadr(), env, thread));
3662        // Not reached.
3663        return NIL;
3664      }
3665    };
3666
3667  // ### unwind-protect
3668  private static final SpecialOperator UNWIND_PROTECT =
3669    new SpecialOperator(Symbol.UNWIND_PROTECT, "protected &body cleanup")
3670    {
3671      @Override
3672      public LispObject execute(LispObject args, Environment env)
3673
3674      {
3675        final LispThread thread = LispThread.currentThread();
3676        LispObject result;
3677        LispObject[] values;
3678        try
3679          {
3680            result = eval(args.car(), env, thread);
3681          }
3682        finally
3683          {
3684            values = thread._values;
3685            LispObject body = args.cdr();
3686            while (body != NIL)
3687              {
3688                eval(body.car(), env, thread);
3689                body = ((Cons)body).cdr;
3690              }
3691            thread._values = values;
3692          }
3693        if (values != null)
3694          thread.setValues(values);
3695        else
3696          thread._values = null;
3697        return result;
3698      }
3699    };
3700
3701  // ### eval-when
3702  private static final SpecialOperator EVAL_WHEN =
3703    new SpecialOperator(Symbol.EVAL_WHEN, "situations &rest forms")
3704    {
3705      @Override
3706      public LispObject execute(LispObject args, Environment env)
3707
3708      {
3709        LispObject situations = args.car();
3710        if (situations != NIL)
3711          {
3712            if (memq(Keyword.EXECUTE, situations) ||
3713                memq(Symbol.EVAL, situations))
3714              {
3715                return progn(args.cdr(), env, LispThread.currentThread());
3716              }
3717          }
3718        return NIL;
3719      }
3720    };
3721
3722  // ### multiple-value-bind
3723  // multiple-value-bind (var*) values-form declaration* form*
3724  // Should be a macro.
3725  private static final SpecialOperator MULTIPLE_VALUE_BIND =
3726    new SpecialOperator(Symbol.MULTIPLE_VALUE_BIND,
3727                        "vars value-form &body body")
3728    {
3729      @Override
3730      public LispObject execute(LispObject args, Environment env)
3731
3732      {
3733        LispObject vars = args.car();
3734        args = args.cdr();
3735        LispObject valuesForm = args.car();
3736        LispObject body = args.cdr();
3737        final LispThread thread = LispThread.currentThread();
3738        LispObject value = eval(valuesForm, env, thread);
3739        LispObject[] values = thread._values;
3740        if (values == null)
3741          {
3742            // eval() did not return multiple values.
3743            values = new LispObject[1];
3744            values[0] = value;
3745          }
3746        // Process declarations.
3747        LispObject bodyAndDecls = parseBody(body, false);
3748        LispObject specials = parseSpecials(bodyAndDecls.NTH(1));
3749        body = bodyAndDecls.car();
3750
3751        final SpecialBinding lastSpecialBinding = thread.lastSpecialBinding;
3752        final Environment ext = new Environment(env);
3753        int i = 0;
3754        LispObject var = vars.car();
3755        while (var != NIL)
3756          {
3757            final Symbol sym;
3758
3759            sym =  checkSymbol(var);
3760
3761            LispObject val = i < values.length ? values[i] : NIL;
3762            if (specials != NIL && memq(sym, specials))
3763              {
3764                thread.bindSpecial(sym, val);
3765                ext.declareSpecial(sym);
3766              }
3767            else if (sym.isSpecialVariable())
3768              {
3769                thread.bindSpecial(sym, val);
3770              }
3771            else
3772              ext.bind(sym, val);
3773            vars = vars.cdr();
3774            var = vars.car();
3775            ++i;
3776          }
3777        // Make sure free special declarations are visible in the body.
3778        // "The scope of free declarations specifically does not include
3779        // initialization forms for bindings established by the form
3780        // containing the declarations." (3.3.4)
3781        while (specials != NIL)
3782          {
3783            Symbol symbol = (Symbol) specials.car();
3784            ext.declareSpecial(symbol);
3785            specials = ((Cons)specials).cdr;
3786          }
3787        thread._values = null;
3788        LispObject result = NIL;
3789        try
3790          {
3791            result  = progn(body, ext, thread);
3792          }
3793        finally
3794          {
3795            thread.lastSpecialBinding = lastSpecialBinding;
3796          }
3797        return result;
3798      }
3799    };
3800
3801  // ### multiple-value-prog1
3802  private static final SpecialOperator MULTIPLE_VALUE_PROG1 =
3803    new SpecialOperator(Symbol.MULTIPLE_VALUE_PROG1,
3804                        "values-form &rest forms")
3805    {
3806      @Override
3807      public LispObject execute(LispObject args, Environment env)
3808
3809      {
3810        if (args.length() == 0)
3811          return error(new WrongNumberOfArgumentsException(this));
3812        final LispThread thread = LispThread.currentThread();
3813        LispObject result = eval(args.car(), env, thread);
3814        LispObject[] values = thread._values;
3815        while ((args = args.cdr()) != NIL)
3816          eval(args.car(), env, thread);
3817        if (values != null)
3818          thread.setValues(values);
3819        else
3820          thread._values = null;
3821        return result;
3822      }
3823    };
3824
3825  // ### multiple-value-call
3826  private static final SpecialOperator MULTIPLE_VALUE_CALL =
3827    new SpecialOperator(Symbol.MULTIPLE_VALUE_CALL, "fun &rest args")
3828    {
3829      @Override
3830      public LispObject execute(LispObject args, Environment env)
3831
3832      {
3833        if (args.length() == 0)
3834          return error(new WrongNumberOfArgumentsException(this));
3835        final LispThread thread = LispThread.currentThread();
3836        LispObject function;
3837        LispObject obj = eval(args.car(), env, thread);
3838        args = args.cdr();
3839        if (obj instanceof Symbol)
3840          {
3841            function = obj.getSymbolFunction();
3842            if (function == null)
3843              error(new UndefinedFunction(obj));
3844          }
3845        else if (obj instanceof Function)
3846          {
3847            function = obj;
3848          }
3849        else
3850          {
3851            error(new LispError(obj.writeToString() +
3852                                 " is not a function name."));
3853            return NIL;
3854          }
3855        ArrayList<LispObject> arrayList = new ArrayList<LispObject>();
3856        while (args != NIL)
3857          {
3858            LispObject form = args.car();
3859            LispObject result = eval(form, env, thread);
3860            LispObject[] values = thread._values;
3861            if (values != null)
3862              {
3863                for (int i = 0; i < values.length; i++)
3864                  arrayList.add(values[i]);
3865              }
3866            else
3867              arrayList.add(result);
3868            args = ((Cons)args).cdr;
3869          }
3870        LispObject[] argv = new LispObject[arrayList.size()];
3871        arrayList.toArray(argv);
3872        return funcall(function, argv, thread);
3873      }
3874    };
3875
3876  // ### and
3877  // Should be a macro.
3878  private static final SpecialOperator AND =
3879    new SpecialOperator(Symbol.AND, "&rest forms")
3880    {
3881      @Override
3882      public LispObject execute(LispObject args, Environment env)
3883
3884      {
3885        final LispThread thread = LispThread.currentThread();
3886        LispObject result = T;
3887        while (args != NIL)
3888          {
3889            result = eval(args.car(), env, thread);
3890            if (result == NIL)
3891              {
3892                if (((Cons)args).cdr != NIL)
3893                  {
3894                    // Not the last form.
3895                    thread._values = null;
3896                  }
3897                break;
3898              }
3899            args = ((Cons)args).cdr;
3900          }
3901        return result;
3902      }
3903    };
3904
3905  // ### or
3906  // Should be a macro.
3907  private static final SpecialOperator OR =
3908    new SpecialOperator(Symbol.OR, "&rest forms")
3909    {
3910      @Override
3911      public LispObject execute(LispObject args, Environment env)
3912
3913      {
3914        final LispThread thread = LispThread.currentThread();
3915        LispObject result = NIL;
3916        while (args != NIL)
3917          {
3918            result = eval(args.car(), env, thread);
3919            if (result != NIL)
3920              {
3921                if (((Cons)args).cdr != NIL)
3922                  {
3923                    // Not the last form.
3924                    thread._values = null;
3925                  }
3926                break;
3927              }
3928            args = ((Cons)args).cdr;
3929          }
3930        return result;
3931      }
3932    };
3933
3934  // ### multiple-value-list form => list
3935  // Evaluates form and creates a list of the multiple values it returns.
3936  // Should be a macro.
3937  private static final SpecialOperator MULTIPLE_VALUE_LIST =
3938    new SpecialOperator(Symbol.MULTIPLE_VALUE_LIST, "value-form")
3939    {
3940      @Override
3941      public LispObject execute(LispObject args, Environment env)
3942
3943      {
3944        if (args.length() != 1)
3945          return error(new WrongNumberOfArgumentsException(this));
3946        final LispThread thread = LispThread.currentThread();
3947        LispObject result = eval(((Cons)args).car, env, thread);
3948        LispObject[] values = thread._values;
3949        if (values == null)
3950          return new Cons(result);
3951        thread._values = null;
3952        LispObject list = NIL;
3953        for (int i = values.length; i-- > 0;)
3954          list = new Cons(values[i], list);
3955        return list;
3956      }
3957    };
3958
3959  // ### nth-value n form => object
3960  // Evaluates n and then form and returns the nth value returned by form, or
3961  // NIL if n >= number of values returned.
3962  // Should be a macro.
3963  private static final SpecialOperator NTH_VALUE =
3964    new SpecialOperator(Symbol.NTH_VALUE, "n form")
3965    {
3966      @Override
3967      public LispObject execute(LispObject args, Environment env)
3968
3969      {
3970        if (args.length() != 2)
3971          return error(new WrongNumberOfArgumentsException(this));
3972        final LispThread thread = LispThread.currentThread();
3973        int n = Fixnum.getValue(eval(args.car(), env, thread));
3974        if (n < 0)
3975          n = 0;
3976        LispObject result = eval(args.cadr(), env, thread);
3977        LispObject[] values = thread._values;
3978        thread._values = null;
3979        if (values == null)
3980          {
3981            // A single value was returned.
3982            return n == 0 ? result : NIL;
3983          }
3984        if (n < values.length)
3985          return values[n];
3986        return NIL;
3987      }
3988    };
3989
3990  // ### call-count
3991  private static final Primitive CALL_COUNT =
3992    new Primitive("call-count", PACKAGE_SYS, true)
3993    {
3994      @Override
3995      public LispObject execute(LispObject arg)
3996      {
3997        return Fixnum.getInstance(arg.getCallCount());
3998      }
3999    };
4000
4001  // ### set-call-count
4002  private static final Primitive SET_CALL_COUNT =
4003    new Primitive("set-call-count", PACKAGE_SYS, true)
4004    {
4005      @Override
4006      public LispObject execute(LispObject first, LispObject second)
4007
4008      {
4009        first.setCallCount(Fixnum.getValue(second));
4010        return second;
4011      }
4012    };
4013
4014  // ### call-count
4015  private static final Primitive HOT_COUNT =
4016    new Primitive("hot-count", PACKAGE_SYS, true)
4017    {
4018      @Override
4019      public LispObject execute(LispObject arg)
4020      {
4021        return Fixnum.getInstance(arg.getHotCount());
4022      }
4023    };
4024
4025  // ### set-call-count
4026  private static final Primitive SET_HOT_COUNT =
4027    new Primitive("set-hot-count", PACKAGE_SYS, true)
4028    {
4029      @Override
4030      public LispObject execute(LispObject first, LispObject second)
4031
4032      {
4033        first.setHotCount(Fixnum.getValue(second));
4034        return second;
4035      }
4036    };
4037
4038    // ### lambda-name
4039  private static final Primitive LAMBDA_NAME =
4040    new Primitive("lambda-name", PACKAGE_SYS, true)
4041    {
4042      @Override
4043      public LispObject execute(LispObject arg)
4044      {
4045        if (arg instanceof Operator)
4046          {
4047            return ((Operator)arg).getLambdaName();
4048          }
4049        if (arg instanceof StandardGenericFunction)
4050          {
4051            return ((StandardGenericFunction)arg).getGenericFunctionName();
4052          }
4053        return type_error(arg, Symbol.FUNCTION);
4054      }
4055    };
4056
4057  // ### %set-lambda-name
4058  private static final Primitive _SET_LAMBDA_NAME =
4059    new Primitive("%set-lambda-name", PACKAGE_SYS, false)
4060    {
4061      @Override
4062      public LispObject execute(LispObject first, LispObject second)
4063
4064      {
4065        if (first instanceof Operator)
4066          {
4067            ((Operator)first).setLambdaName(second);
4068            return second;
4069          }
4070        if (first instanceof StandardGenericFunction)
4071          {
4072            ((StandardGenericFunction)first).setGenericFunctionName(second);
4073            return second;
4074          }
4075        return type_error(first, Symbol.FUNCTION);
4076      }
4077    };
4078
4079  // ### shrink-vector vector new-size => vector
4080  // Destructively alters the vector, changing its length to NEW-SIZE, which
4081  // must be less than or equal to its current length.
4082  // shrink-vector vector new-size => vector
4083  private static final Primitive SHRINK_VECTOR =
4084    new Primitive("shrink-vector", PACKAGE_SYS, true, "vector new-size")
4085    {
4086      @Override
4087      public LispObject execute(LispObject first, LispObject second)
4088
4089      {
4090        checkVector(first).shrink(Fixnum.getValue(second));
4091        return first;
4092      }
4093    };
4094
4095  // ### subseq sequence start &optional end
4096  private static final Primitive SUBSEQ =
4097    new Primitive(Symbol.SUBSEQ, "sequence start &optional end")
4098    {
4099      @Override
4100      public LispObject execute(LispObject first, LispObject second)
4101
4102      {
4103        final int start = Fixnum.getValue(second);
4104        if (start < 0)
4105          {
4106            FastStringBuffer sb = new FastStringBuffer("Bad start index (");
4107            sb.append(start);
4108            sb.append(") for SUBSEQ.");
4109            error(new TypeError(sb.toString()));
4110          }
4111        if (first.listp())
4112          return list_subseq(first, start, -1);
4113        if (first instanceof AbstractVector)
4114          {
4115            final AbstractVector v = (AbstractVector) first;
4116            return v.subseq(start, v.length());
4117          }
4118        return type_error(first, Symbol.SEQUENCE);
4119      }
4120      @Override
4121      public LispObject execute(LispObject first, LispObject second,
4122                                LispObject third)
4123
4124      {
4125        final int start = Fixnum.getValue(second);
4126        if (start < 0)
4127          {
4128            FastStringBuffer sb = new FastStringBuffer("Bad start index (");
4129            sb.append(start);
4130            sb.append(").");
4131            error(new TypeError(sb.toString()));
4132          }
4133        int end;
4134        if (third != NIL)
4135          {
4136            end = Fixnum.getValue(third);
4137            if (start > end)
4138              {
4139                FastStringBuffer sb = new FastStringBuffer("Start index (");
4140                sb.append(start);
4141                sb.append(") is greater than end index (");
4142                sb.append(end);
4143                sb.append(") for SUBSEQ.");
4144                error(new TypeError(sb.toString()));
4145              }
4146          }
4147        else
4148          end = -1;
4149        if (first.listp())
4150          return list_subseq(first, start, end);
4151        if (first instanceof AbstractVector)
4152          {
4153            final AbstractVector v = (AbstractVector) first;
4154            if (end < 0)
4155              end = v.length();
4156            return v.subseq(start, end);
4157          }
4158        return type_error(first, Symbol.SEQUENCE);
4159      }
4160    };
4161
4162  private static final LispObject list_subseq(LispObject list, int start,
4163                                              int end)
4164
4165  {
4166    int index = 0;
4167    LispObject result = NIL;
4168    while (list != NIL)
4169      {
4170        if (end >= 0 && index == end)
4171          return result.nreverse();
4172        if (index++ >= start)
4173          result = new Cons(list.car(), result);
4174        list = list.cdr();
4175      }
4176    return result.nreverse();
4177  }
4178
4179  // ### list
4180  private static final Primitive LIST =
4181    new Primitive(Symbol.LIST, "&rest objects")
4182    {
4183      @Override
4184      public LispObject execute()
4185      {
4186        return NIL;
4187      }
4188      @Override
4189      public LispObject execute(LispObject arg)
4190      {
4191        return new Cons(arg);
4192      }
4193      @Override
4194      public LispObject execute(LispObject first, LispObject second)
4195      {
4196        return new Cons(first, new Cons(second));
4197      }
4198      @Override
4199      public LispObject execute(LispObject first, LispObject second,
4200                                LispObject third)
4201      {
4202        return new Cons(first, new Cons(second, new Cons(third)));
4203      }
4204      @Override
4205      public LispObject execute(LispObject first, LispObject second,
4206                                LispObject third, LispObject fourth)
4207      {
4208        return new Cons(first,
4209                        new Cons(second,
4210                                 new Cons(third,
4211                                          new Cons(fourth))));
4212      }
4213      @Override
4214      public LispObject execute(LispObject[] args)
4215      {
4216        LispObject result = NIL;
4217        for (int i = args.length; i-- > 0;)
4218          result = new Cons(args[i], result);
4219        return result;
4220      }
4221    };
4222
4223  // ### list*
4224  private static final Primitive LIST_STAR =
4225    new Primitive(Symbol.LIST_STAR, "&rest objects")
4226    {
4227      @Override
4228      public LispObject execute()
4229      {
4230        return error(new WrongNumberOfArgumentsException(this));
4231      }
4232      @Override
4233      public LispObject execute(LispObject arg)
4234      {
4235        return arg;
4236      }
4237      @Override
4238      public LispObject execute(LispObject first, LispObject second)
4239
4240      {
4241        return new Cons(first, second);
4242      }
4243      @Override
4244      public LispObject execute(LispObject first, LispObject second,
4245                                LispObject third)
4246
4247      {
4248        return new Cons(first, new Cons(second, third));
4249      }
4250      @Override
4251      public LispObject execute(LispObject first, LispObject second,
4252                                LispObject third, LispObject fourth)
4253
4254      {
4255        return new Cons(first,
4256                        new Cons(second,
4257                                 new Cons(third, fourth)));
4258      }
4259      @Override
4260      public LispObject execute(LispObject[] args)
4261      {
4262        int i = args.length - 1;
4263        LispObject result = args[i];
4264        while (i-- > 0)
4265          result = new Cons(args[i], result);
4266        return result;
4267      }
4268    };
4269
4270  // ### nreverse
4271  public static final Primitive NREVERSE =
4272    new Primitive(Symbol.NREVERSE, "sequence")
4273    {
4274      @Override
4275      public LispObject execute (LispObject arg)
4276      {
4277        return arg.nreverse();
4278      }
4279    };
4280
4281  // ### nreconc
4282  private static final Primitive NRECONC =
4283    new Primitive(Symbol.NRECONC, "list tail")
4284    {
4285      @Override
4286      public LispObject execute(LispObject list, LispObject obj)
4287
4288      {
4289        if (list instanceof Cons)
4290          {
4291            LispObject list3 = list.cdr();
4292            if (list3 instanceof Cons)
4293              {
4294                if (list3.cdr() instanceof Cons)
4295                  {
4296                    LispObject list1 = list3;
4297                    LispObject list2 = NIL;
4298                    do
4299                      {
4300                        LispObject h = list3.cdr();
4301                        list3.setCdr(list2);
4302                        list2 = list3;
4303                        list3 = h;
4304                      } while (list3.cdr() instanceof Cons);
4305                    list.setCdr(list2);
4306                    list1.setCdr(list3);
4307                  }
4308                LispObject h = list.car();
4309                list.setCar(list3.car());
4310                list3.setCar(h);
4311                list3.setCdr(obj);
4312              }
4313            else if (list3 == NIL)
4314              {
4315                list.setCdr(obj);
4316              }
4317            else
4318              type_error(list3, Symbol.LIST);
4319            return list;
4320          }
4321        else if (list == NIL)
4322          return obj;
4323        else
4324          return type_error(list, Symbol.LIST);
4325      }
4326    };
4327
4328  // ### reverse
4329  private static final Primitive REVERSE =
4330    new Primitive(Symbol.REVERSE, "sequence")
4331    {
4332      @Override
4333      public LispObject execute(LispObject arg)
4334      {
4335        return arg.reverse();
4336      }
4337    };
4338
4339  // ### delete-eq item sequence => result-sequence
4340  private static final Primitive DELETE_EQ =
4341    new Primitive("delete-eq", PACKAGE_SYS, true, "item sequence")
4342    {
4343      @Override
4344      public LispObject execute(LispObject item, LispObject sequence)
4345
4346      {
4347        if (sequence instanceof AbstractVector)
4348          return ((AbstractVector)sequence).deleteEq(item);
4349        else
4350          return LIST_DELETE_EQ.execute(item, sequence);
4351      }
4352    };
4353
4354  // ### delete-eql item seqluence => result-seqluence
4355  private static final Primitive DELETE_EQL =
4356    new Primitive("delete-eql", PACKAGE_SYS, true, "item sequence")
4357    {
4358      @Override
4359      public LispObject execute(LispObject item, LispObject sequence)
4360
4361      {
4362        if (sequence instanceof AbstractVector)
4363          return ((AbstractVector)sequence).deleteEql(item);
4364        else
4365          return LIST_DELETE_EQL.execute(item, sequence);
4366      }
4367    };
4368
4369  // ### list-delete-eq item list => result-list
4370  private static final Primitive LIST_DELETE_EQ =
4371    new Primitive("list-delete-eq", PACKAGE_SYS, true, "item list")
4372    {
4373      @Override
4374      public LispObject execute(LispObject item, LispObject list)
4375
4376      {
4377        if (list instanceof Cons)
4378          {
4379            LispObject tail = list;
4380            LispObject splice = list;
4381            while (tail instanceof Cons)
4382              {
4383                LispObject car = tail.car();
4384                if (car == item)
4385                  {
4386                    if (tail.cdr() != NIL)
4387                      {
4388                        LispObject temp = tail;
4389                        tail.setCar(temp.cadr());
4390                        tail.setCdr(temp.cddr());
4391                      }
4392                    else
4393                      {
4394                        // Last item.
4395                        if (tail == list)
4396                          return NIL;
4397                        splice.setCdr(NIL);
4398                        return list;
4399                      }
4400                  }
4401                else
4402                  {
4403                    splice = tail;
4404                    tail = tail.cdr();
4405                  }
4406              }
4407            if (tail == NIL)
4408              return list;
4409            else
4410              return type_error(tail, Symbol.LIST);
4411          }
4412        else if (list == NIL)
4413          return list;
4414        else
4415          return type_error(list, Symbol.LIST);
4416      }
4417    };
4418
4419  // ### list-delete-eql item list => result-list
4420  private static final Primitive LIST_DELETE_EQL =
4421    new Primitive("list-delete-eql", PACKAGE_SYS, true, "item list")
4422    {
4423      @Override
4424      public LispObject execute(LispObject item, LispObject list)
4425
4426      {
4427        if (list instanceof Cons)
4428          {
4429            LispObject tail = list;
4430            LispObject splice = list;
4431            while (tail instanceof Cons)
4432              {
4433                LispObject car = tail.car();
4434                if (car.eql(item))
4435                  {
4436                    if (tail.cdr() != NIL)
4437                      {
4438                        LispObject temp = tail;
4439                        tail.setCar(temp.cadr());
4440                        tail.setCdr(temp.cddr());
4441                      }
4442                    else
4443                      {
4444                        // Last item.
4445                        if (tail == list)
4446                          return NIL;
4447                        splice.setCdr(NIL);
4448                        return list;
4449                      }
4450                  }
4451                else
4452                  {
4453                    splice = tail;
4454                    tail = tail.cdr();
4455                  }
4456              }
4457            if (tail == NIL)
4458              return list;
4459            else
4460              return type_error(tail, Symbol.LIST);
4461          }
4462        else if (list == NIL)
4463          return list;
4464        else
4465          return type_error(list, Symbol.LIST);
4466      }
4467    };
4468
4469  // ### vector-delete-eq item vector => result-vector
4470  private static final Primitive VECTOR_DELETE_EQ =
4471    new Primitive("vector-delete-eq", PACKAGE_SYS, true, "item vector")
4472    {
4473      @Override
4474      public LispObject execute(LispObject item, LispObject vector)
4475
4476      {
4477          checkVector(vector).deleteEq(item);
4478          return vector;
4479      }
4480    };
4481
4482  // ### vector-delete-eql item vector => result-vector
4483  private static final Primitive VECTOR_DELETE_EQL =
4484    new Primitive("vector-delete-eql", PACKAGE_SYS, true, "item vector")
4485    {
4486      @Override
4487      public LispObject execute(LispObject item, LispObject vector)
4488
4489      {
4490          checkVector(vector).deleteEql(item);
4491          return vector;
4492      }
4493    };
4494
4495  // ### %set-elt
4496  // %setelt sequence index newval => newval
4497  private static final Primitive _SET_ELT =
4498    new Primitive("%set-elt", PACKAGE_SYS, false)
4499    {
4500      @Override
4501      public LispObject execute(LispObject first, LispObject second,
4502                                LispObject third)
4503
4504      {
4505        if (first instanceof AbstractVector)
4506          {
4507            ((AbstractVector)first).aset(Fixnum.getValue(second), third);
4508            return third;
4509          }
4510        if (first instanceof Cons)
4511          {
4512            int index = Fixnum.getValue(second);
4513            if (index < 0)
4514              error(new TypeError());
4515            LispObject list = first;
4516            int i = 0;
4517            while (true)
4518              {
4519                if (i == index)
4520                  {
4521                    list.setCar(third);
4522                    return third;
4523                  }
4524                list = list.cdr();
4525                if (list == NIL)
4526                  error(new TypeError());
4527                ++i;
4528              }
4529          }
4530        return type_error(first, Symbol.SEQUENCE);
4531      }
4532    };
4533
4534  // ### %make-list
4535  private static final Primitive _MAKE_LIST =
4536    new Primitive("%make-list", PACKAGE_SYS, true)
4537    {
4538      @Override
4539      public LispObject execute(LispObject first, LispObject second)
4540
4541      {
4542        int size = Fixnum.getValue(first);
4543        if (size < 0)
4544          return type_error(first, list(Symbol.INTEGER, Fixnum.ZERO,
4545                                              Symbol.MOST_POSITIVE_FIXNUM.getSymbolValue()));
4546        LispObject result = NIL;
4547        for (int i = size; i-- > 0;)
4548          result = new Cons(second, result);
4549        return result;
4550      }
4551    };
4552
4553  // ### %member item list key test test-not => tail
4554  private static final Primitive _MEMBER =
4555    new Primitive("%member", PACKAGE_SYS, true)
4556    {
4557      @Override
4558      public LispObject execute(LispObject item, LispObject list,
4559                                LispObject key, LispObject test,
4560                                LispObject testNot)
4561
4562      {
4563        LispObject tail = checkList(list);
4564        if (test != NIL && testNot != NIL)
4565          error(new LispError("MEMBER: test and test-not both supplied"));
4566        if (testNot == NIL)
4567          {
4568            if (test == NIL || test == Symbol.EQL)
4569              test = EQL;
4570          }
4571        if (key == NIL)
4572          {
4573            if (test == EQL)
4574              {
4575                while (tail instanceof Cons)
4576                  {
4577                    if (item.eql(((Cons)tail).car))
4578                      return tail;
4579                    tail = ((Cons)tail).cdr;
4580                  }
4581              }
4582            else if (test != NIL)
4583              {
4584                while (tail instanceof Cons)
4585                  {
4586                    LispObject candidate = ((Cons)tail).car;
4587                    if (test.execute(item, candidate) != NIL)
4588                      return tail;
4589                    tail = ((Cons)tail).cdr;
4590                  }
4591              }
4592            else
4593              {
4594                // test == NIL
4595                while (tail instanceof Cons)
4596                  {
4597                    LispObject candidate = ((Cons)tail).car;
4598                    if (testNot.execute(item, candidate) == NIL)
4599                      return tail;
4600                    tail = ((Cons)tail).cdr;
4601                  }
4602              }
4603          }
4604        else
4605          {
4606            // key != NIL
4607            while (tail instanceof Cons)
4608              {
4609                LispObject candidate = key.execute(((Cons)tail).car);
4610                if (test != NIL)
4611                  {
4612                    if (test.execute(item, candidate) != NIL)
4613                      return tail;
4614                  }
4615                else
4616                  {
4617                    if (testNot.execute(item, candidate) == NIL)
4618                      return tail;
4619                  }
4620                tail = ((Cons)tail).cdr;
4621              }
4622          }
4623        if (tail != NIL)
4624          type_error(tail, Symbol.LIST);
4625        return NIL;
4626      }
4627    };
4628
4629  // ### funcall-key function-or-nil element
4630  private static final Primitive FUNCALL_KEY =
4631    new Primitive("funcall-key", PACKAGE_SYS, false)
4632    {
4633      @Override
4634      public LispObject execute(LispObject first, LispObject second)
4635
4636      {
4637        if (first != NIL)
4638          return LispThread.currentThread().execute(first, second);
4639        return second;
4640      }
4641    };
4642
4643  // ### coerce-to-function
4644  private static final Primitive COERCE_TO_FUNCTION =
4645    new Primitive("coerce-to-function", PACKAGE_SYS, true)
4646    {
4647      @Override
4648      public LispObject execute(LispObject arg)
4649      {
4650        return coerceToFunction(arg);
4651      }
4652    };
4653
4654  // ### make-closure lambda-form environment => closure
4655  private static final Primitive MAKE_CLOSURE =
4656    new Primitive("make-closure", PACKAGE_SYS, true)
4657    {
4658      @Override
4659      public LispObject execute(LispObject first, LispObject second)
4660
4661      {
4662        if (first instanceof Cons && ((Cons)first).car == Symbol.LAMBDA)
4663          {
4664            final Environment env;
4665            if (second == NIL)
4666              env = new Environment();
4667            else
4668              env = checkEnvironment(second);
4669            return new Closure(first, env);
4670          }
4671        return error(new TypeError("The argument to MAKE-CLOSURE is not a lambda form."));
4672      }
4673    };
4674
4675  // ### streamp
4676  private static final Primitive STREAMP =
4677    new Primitive(Symbol.STREAMP, "object")
4678    {
4679      @Override
4680      public LispObject execute(LispObject arg)
4681      {
4682        return arg instanceof Stream ? T : NIL;
4683      }
4684    };
4685
4686  // ### integerp
4687  private static final Primitive INTEGERP =
4688    new Primitive(Symbol.INTEGERP, "object")
4689    {
4690      @Override
4691      public LispObject execute(LispObject arg)
4692      {
4693        return arg.INTEGERP();
4694      }
4695    };
4696
4697  // ### evenp
4698  private static final Primitive EVENP =
4699    new Primitive(Symbol.EVENP, "integer")
4700    {
4701      @Override
4702      public LispObject execute(LispObject arg)
4703      {
4704        return arg.EVENP();
4705      }
4706    };
4707
4708  // ### oddp
4709  private static final Primitive ODDP = new Primitive(Symbol.ODDP, "integer")
4710    {
4711      @Override
4712      public LispObject execute(LispObject arg)
4713      {
4714        return arg.ODDP();
4715      }
4716    };
4717
4718  // ### numberp
4719  private static final Primitive NUMBERP =
4720    new Primitive(Symbol.NUMBERP, "object")
4721    {
4722      @Override
4723      public LispObject execute(LispObject arg)
4724      {
4725        return arg.NUMBERP();
4726      }
4727    };
4728
4729  // ### realp
4730  private static final Primitive REALP =
4731    new Primitive(Symbol.REALP, "object")
4732    {
4733      @Override
4734      public LispObject execute(LispObject arg)
4735      {
4736        return arg.REALP();
4737      }
4738    };
4739
4740  // ### rationalp
4741  private static final Primitive RATIONALP =
4742    new Primitive(Symbol.RATIONALP,"object")
4743    {
4744      @Override
4745      public LispObject execute(LispObject arg)
4746      {
4747        return arg.RATIONALP();
4748      }
4749    };
4750
4751  // ### complex
4752  private static final Primitive COMPLEX =
4753    new Primitive(Symbol.COMPLEX, "realpart &optional imagpart")
4754    {
4755      @Override
4756      public LispObject execute(LispObject arg)
4757      {
4758        if (arg instanceof SingleFloat)
4759          return Complex.getInstance(arg, SingleFloat.ZERO);
4760        if (arg instanceof DoubleFloat)
4761          return Complex.getInstance(arg, DoubleFloat.ZERO);
4762        if (arg.realp())
4763          return arg;
4764        return type_error(arg, Symbol.REAL);
4765      }
4766      @Override
4767      public LispObject execute(LispObject first, LispObject second)
4768
4769      {
4770        return Complex.getInstance(first, second);
4771      }
4772    };
4773
4774  // ### complexp
4775  private static final Primitive COMPLEXP =
4776    new Primitive(Symbol.COMPLEXP, "object")
4777    {
4778      @Override
4779      public LispObject execute(LispObject arg)
4780      {
4781        return arg.COMPLEXP();
4782      }
4783    };
4784
4785  // ### numerator
4786  private static final Primitive NUMERATOR =
4787    new Primitive(Symbol.NUMERATOR, "rational")
4788    {
4789      @Override
4790      public LispObject execute(LispObject arg)
4791      {
4792        return arg.NUMERATOR();
4793      }
4794    };
4795
4796  // ### denominator
4797  private static final Primitive DENOMINATOR =
4798    new Primitive(Symbol.DENOMINATOR, "rational")
4799    {
4800      @Override
4801      public LispObject execute(LispObject arg)
4802      {
4803        return arg.DENOMINATOR();
4804      }
4805    };
4806
4807  // ### realpart
4808  private static final Primitive REALPART =
4809    new Primitive(Symbol.REALPART, "number")
4810    {
4811      @Override
4812      public LispObject execute(LispObject arg)
4813      {
4814        if (arg instanceof Complex)
4815          return ((Complex)arg).getRealPart();
4816        if (arg.numberp())
4817          return arg;
4818        return type_error(arg, Symbol.NUMBER);
4819      }
4820    };
4821
4822  // ### imagpart
4823  private static final Primitive IMAGPART =
4824    new Primitive(Symbol.IMAGPART, "number")
4825    {
4826      @Override
4827      public LispObject execute(LispObject arg)
4828      {
4829        if (arg instanceof Complex)
4830          return ((Complex)arg).getImaginaryPart();
4831        return arg.multiplyBy(Fixnum.ZERO);
4832      }
4833    };
4834
4835  // ### integer-length
4836  private static final Primitive INTEGER_LENGTH =
4837    new Primitive(Symbol.INTEGER_LENGTH, "integer")
4838    {
4839      @Override
4840      public LispObject execute(LispObject arg)
4841      {
4842        if (arg instanceof Fixnum)
4843          {
4844            int n = ((Fixnum)arg).value;
4845            if (n < 0)
4846              n = ~n;
4847            int count = 0;
4848            while (n > 0)
4849              {
4850                n = n >>> 1;
4851                ++count;
4852              }
4853            return Fixnum.getInstance(count);
4854          }
4855        if (arg instanceof Bignum)
4856          return Fixnum.getInstance(((Bignum)arg).value.bitLength());
4857        return type_error(arg, Symbol.INTEGER);
4858      }
4859    };
4860
4861  // ### gcd-2
4862  private static final Primitive GCD_2 =
4863    new Primitive("gcd-2", PACKAGE_SYS, false)
4864    {
4865      @Override
4866      public LispObject execute(LispObject first, LispObject second)
4867
4868      {
4869        BigInteger n1, n2;
4870        if (first instanceof Fixnum)
4871          n1 = BigInteger.valueOf(((Fixnum)first).value);
4872        else if (first instanceof Bignum)
4873          n1 = ((Bignum)first).value;
4874        else
4875          return type_error(first, Symbol.INTEGER);
4876        if (second instanceof Fixnum)
4877          n2 = BigInteger.valueOf(((Fixnum)second).value);
4878        else if (second instanceof Bignum)
4879          n2 = ((Bignum)second).value;
4880        else
4881          return type_error(second, Symbol.INTEGER);
4882        return number(n1.gcd(n2));
4883      }
4884    };
4885
4886  // ### identity-hash-code
4887  private static final Primitive IDENTITY_HASH_CODE =
4888    new Primitive("identity-hash-code", PACKAGE_SYS, true)
4889    {
4890      @Override
4891      public LispObject execute(LispObject arg)
4892      {
4893        return Fixnum.getInstance(System.identityHashCode(arg));
4894      }
4895    };
4896
4897  // ### simple-vector-search pattern vector => position
4898  // Searches vector for pattern.
4899  private static final Primitive SIMPLE_VECTOR_SEARCH =
4900    new Primitive("simple-vector-search", PACKAGE_SYS, false)
4901    {
4902      @Override
4903      public LispObject execute(LispObject first, LispObject second)
4904
4905      {
4906        AbstractVector v = checkVector(second);
4907        if (first.length() == 0)
4908          return Fixnum.ZERO;
4909        final int patternLength = first.length();
4910        final int limit = v.length() - patternLength;
4911        if (first instanceof AbstractVector)
4912          {
4913            AbstractVector pattern = (AbstractVector) first;
4914            LispObject element = pattern.AREF(0);
4915            for (int i = 0; i <= limit; i++)
4916              {
4917                if (v.AREF(i).eql(element))
4918                  {
4919                    // Found match for first element of pattern.
4920                    boolean match = true;
4921                    // We've already checked the first element.
4922                    int j = i + 1;
4923                    for (int k = 1; k < patternLength; k++)
4924                      {
4925                        if (v.AREF(j).eql(pattern.AREF(k)))
4926                          {
4927                            ++j;
4928                          }
4929                        else
4930                          {
4931                            match = false;
4932                            break;
4933                          }
4934                      }
4935                    if (match)
4936                      return Fixnum.getInstance(i);
4937                  }
4938              }
4939          }
4940        else
4941          {
4942            // Pattern is a list.
4943            LispObject element = first.car();
4944            for (int i = 0; i <= limit; i++)
4945              {
4946                if (v.AREF(i).eql(element))
4947                  {
4948                    // Found match for first element of pattern.
4949                    boolean match = true;
4950                    // We've already checked the first element.
4951                    int j = i + 1;
4952                    for (LispObject rest = first.cdr(); rest != NIL; rest = rest.cdr())
4953                      {
4954                        if (v.AREF(j).eql(rest.car()))
4955                          {
4956                            ++j;
4957                          }
4958                        else
4959                          {
4960                            match = false;
4961                            break;
4962                          }
4963                      }
4964                    if (match)
4965                      return Fixnum.getInstance(i);
4966                  }
4967              }
4968          }
4969        return NIL;
4970      }
4971    };
4972
4973  // ### uptime
4974  private static final Primitive UPTIME =
4975    new Primitive("uptime", PACKAGE_EXT, true)
4976    {
4977      @Override
4978      public LispObject execute()
4979      {
4980        return number(System.currentTimeMillis() - Main.startTimeMillis);
4981      }
4982    };
4983
4984  // ### built-in-function-p
4985  private static final Primitive BUILT_IN_FUNCTION_P =
4986    new Primitive("built-in-function-p", PACKAGE_SYS, true)
4987    {
4988      @Override
4989      public LispObject execute(LispObject arg)
4990      {
4991            return checkSymbol(arg).isBuiltInFunction() ? T : NIL;
4992      }
4993    };
4994
4995  // ### inspected-parts
4996  private static final Primitive INSPECTED_PARTS =
4997    new Primitive("inspected-parts", PACKAGE_SYS, true)
4998    {
4999      @Override
5000      public LispObject execute(LispObject arg)
5001      {
5002        return arg.getParts();
5003      }
5004    };
5005
5006  // ### inspected-description
5007  private static final Primitive INSPECTED_DESCRIPTION =
5008    new Primitive("inspected-description", PACKAGE_SYS, false)
5009    {
5010      @Override
5011      public LispObject execute(LispObject arg)
5012      {
5013        return arg.getDescription();
5014      }
5015    };
5016
5017  // ### symbol-name
5018  public static final Primitive SYMBOL_NAME =
5019    new Primitive(Symbol.SYMBOL_NAME, "symbol")
5020    {
5021      @Override
5022      public LispObject execute(LispObject arg)
5023      {
5024          return checkSymbol(arg).name;
5025      }
5026    };
5027
5028  // ### symbol-package
5029  public static final Primitive SYMBOL_PACKAGE =
5030    new Primitive(Symbol.SYMBOL_PACKAGE, "symbol")
5031    {
5032      @Override
5033      public LispObject execute(LispObject arg)
5034      {
5035          return checkSymbol(arg).getPackage();
5036      }
5037    };
5038
5039  // ### symbol-function
5040  public static final Primitive SYMBOL_FUNCTION =
5041    new Primitive(Symbol.SYMBOL_FUNCTION, "symbol")
5042    {
5043      @Override
5044      public LispObject execute(LispObject arg)
5045      {
5046            LispObject function = checkSymbol(arg).getSymbolFunction();
5047            if (function != null)
5048              return function;
5049            return error(new UndefinedFunction(arg));
5050
5051      }
5052    };
5053
5054  // ### %set-symbol-function
5055  public static final Primitive _SET_SYMBOL_FUNCTION =
5056    new Primitive("%set-symbol-function", PACKAGE_SYS, false, "symbol function")
5057    {
5058      @Override
5059      public LispObject execute(LispObject first, LispObject second)
5060
5061      {
5062            checkSymbol(first).setSymbolFunction(second);
5063            return second;
5064      }
5065    };
5066
5067  // ### symbol-plist
5068  public static final Primitive SYMBOL_PLIST =
5069    new Primitive(Symbol.SYMBOL_PLIST, "symbol")
5070    {
5071      @Override
5072      public LispObject execute(LispObject arg)
5073      {
5074            return checkSymbol(arg).getPropertyList();
5075      }
5076    };
5077
5078  // ### keywordp
5079  public static final Primitive KEYWORDP =
5080    new Primitive(Symbol.KEYWORDP, "object")
5081    {
5082      @Override
5083      public LispObject execute(LispObject arg)
5084      {
5085        if (arg instanceof Symbol)
5086          {
5087            if (checkSymbol(arg).getPackage() == PACKAGE_KEYWORD)
5088              return T;
5089          }
5090        return NIL;
5091      }
5092    };
5093
5094  // ### make-symbol
5095  public static final Primitive MAKE_SYMBOL =
5096    new Primitive(Symbol.MAKE_SYMBOL, "name")
5097    {
5098      @Override
5099      public LispObject execute(LispObject arg)
5100      {
5101        if (arg instanceof SimpleString)
5102          return new Symbol((SimpleString)arg);
5103        // Not a simple string.
5104        if (arg instanceof AbstractString)
5105          return new Symbol(arg.getStringValue());
5106        return type_error(arg, Symbol.STRING);
5107      }
5108    };
5109
5110  // ### makunbound
5111  public static final Primitive MAKUNBOUND =
5112    new Primitive(Symbol.MAKUNBOUND, "symbol")
5113    {
5114      @Override
5115      public LispObject execute(LispObject arg)
5116      {
5117            checkSymbol(arg).setSymbolValue(null);
5118            return arg;
5119      }
5120    };
5121
5122  // ### %class-name
5123  private static final Primitive _CLASS_NAME =
5124    new Primitive("%class-name", PACKAGE_SYS, true, "class")
5125    {
5126      @Override
5127      public LispObject execute(LispObject arg)
5128      {
5129          return checkClass(arg).symbol;
5130      }
5131    };
5132
5133  // ### %set-class-name
5134  private static final Primitive _SET_CLASS_NAME =
5135    new Primitive("%set-class-name", PACKAGE_SYS, true)
5136    {
5137      @Override
5138      public LispObject execute(LispObject first, LispObject second)
5139
5140      {
5141          checkClass(first).symbol = checkSymbol(second);
5142          return second;
5143      }
5144    };
5145
5146  // ### class-layout
5147  private static final Primitive CLASS_LAYOUT =
5148    new Primitive("class-layout", PACKAGE_SYS, true, "class")
5149    {
5150      @Override
5151      public LispObject execute(LispObject arg)
5152      {
5153          Layout layout = checkClass(arg).getClassLayout();
5154          return layout != null ? layout : NIL;
5155      }
5156    };
5157
5158  // ### %set-class-layout
5159  private static final Primitive _SET_CLASS_LAYOUT =
5160    new Primitive("%set-class-layout", PACKAGE_SYS, true, "class layout")
5161    {
5162      @Override
5163      public LispObject execute(LispObject first, LispObject second)
5164
5165      {
5166        if (second instanceof Layout)
5167          {
5168            checkClass(first).setClassLayout((Layout)second);
5169            return second;
5170          }
5171        return type_error(second, Symbol.LAYOUT);
5172      }
5173    };
5174
5175  // ### class-direct-superclasses
5176  private static final Primitive CLASS_DIRECT_SUPERCLASSES =
5177    new Primitive("class-direct-superclasses", PACKAGE_SYS, true)
5178    {
5179      @Override
5180      public LispObject execute(LispObject arg)
5181      {
5182            return checkClass(arg).getDirectSuperclasses();
5183      }
5184    };
5185
5186  // ### %set-class-direct-superclasses
5187  private static final Primitive _SET_CLASS_DIRECT_SUPERCLASSES =
5188    new Primitive("%set-class-direct-superclasses", PACKAGE_SYS, true)
5189    {
5190      @Override
5191      public LispObject execute(LispObject first, LispObject second)
5192
5193      {
5194            checkClass(first).setDirectSuperclasses(second);
5195            return second;
5196      }
5197    };
5198
5199  // ### class-direct-subclasses
5200  private static final Primitive CLASS_DIRECT_SUBCLASSES =
5201    new Primitive("class-direct-subclasses", PACKAGE_SYS, true)
5202    {
5203      @Override
5204      public LispObject execute(LispObject arg)
5205      {
5206            return checkClass(arg).getDirectSubclasses();
5207      }
5208    };
5209
5210  // ### %set-class-direct-subclasses
5211  private static final Primitive _SET_CLASS_DIRECT_SUBCLASSES =
5212    new Primitive("%set-class-direct-subclasses", PACKAGE_SYS, true,
5213                  "class direct-subclasses")
5214    {
5215      @Override
5216      public LispObject execute(LispObject first, LispObject second)
5217
5218      {
5219          checkClass(first).setDirectSubclasses(second);
5220          return second;
5221      }
5222    };
5223
5224  // ### %class-precedence-list
5225  private static final Primitive _CLASS_PRECEDENCE_LIST =
5226    new Primitive("%class-precedence-list", PACKAGE_SYS, true)
5227    {
5228      @Override
5229      public LispObject execute(LispObject arg)
5230      {
5231          return checkClass(arg).getCPL();
5232      }
5233    };
5234
5235  // ### set-class-precedence-list
5236  private static final Primitive SET_CLASS_PRECEDENCE_LIST =
5237    new Primitive("set-class-precedence-list", PACKAGE_SYS, true)
5238    {
5239      @Override
5240      public LispObject execute(LispObject first, LispObject second)
5241
5242      {
5243          checkClass(first).classPrecedenceList = second;
5244          return second;
5245      }
5246    };
5247
5248  // ### class-direct-methods
5249  private static final Primitive CLASS_DIRECT_METHODS =
5250    new Primitive("class-direct-methods", PACKAGE_SYS, true)
5251    {
5252      @Override
5253      public LispObject execute(LispObject arg)
5254
5255      {
5256          return checkClass(arg).directMethods;
5257      }
5258    };
5259
5260  // ### %set-class-direct-methods
5261  private static final Primitive _SET_CLASS_DIRECT_METHODS =
5262    new Primitive("%set-class-direct-methods", PACKAGE_SYS, true)
5263    {
5264      @Override
5265      public LispObject execute(LispObject first, LispObject second)
5266
5267      {
5268          checkClass(first).directMethods = second;
5269          return second;
5270      }
5271    };
5272
5273  // ### class-documentation
5274  private static final Primitive CLASS_DOCUMENTATION =
5275    new Primitive("class-documentation", PACKAGE_SYS, true)
5276    {
5277      @Override
5278      public LispObject execute(LispObject arg)
5279
5280      {
5281          return checkClass(arg).documentation;
5282      }
5283    };
5284
5285  // ### %set-class-documentation
5286  private static final Primitive _SET_CLASS_DOCUMENTATION =
5287    new Primitive("%set-class-documentation", PACKAGE_SYS, true)
5288    {
5289      @Override
5290      public LispObject execute(LispObject first, LispObject second)
5291
5292      {
5293          checkClass(first).documentation = second;
5294          return second;
5295      }
5296    };
5297
5298  // ### class-finalized-p
5299  private static final Primitive CLASS_FINALIZED_P =
5300    new Primitive("class-finalized-p", PACKAGE_SYS, true)
5301    {
5302      @Override
5303      public LispObject execute(LispObject arg)
5304      {
5305            return checkClass(arg).isFinalized() ? T : NIL;
5306      }
5307    };
5308
5309  // ### %set-class-finalized-p
5310  private static final Primitive _SET_CLASS_FINALIZED_P =
5311    new Primitive("%set-class-finalized-p", PACKAGE_SYS, true)
5312    {
5313      @Override
5314      public LispObject execute(LispObject first, LispObject second)
5315
5316      {
5317          checkClass(first).setFinalized(second != NIL);
5318          return second;
5319      }
5320    };
5321
5322  // ### classp
5323  private static final Primitive CLASSP =
5324    new Primitive("classp", PACKAGE_EXT, true)
5325    {
5326      @Override
5327      public LispObject execute(LispObject arg)
5328      {
5329        return arg instanceof LispClass ? T : NIL;
5330      }
5331    };
5332
5333  // ### char-to-utf8 char => octets
5334  private static final Primitive CHAR_TO_UTF8 =
5335    new Primitive("char-to-utf8", PACKAGE_EXT, true)
5336    {
5337      @Override
5338      public LispObject execute(LispObject arg)
5339      {
5340        final LispCharacter c;
5341        c = checkCharacter( arg);
5342        char[] chars = new char[1];
5343        chars[0] = c.value;
5344        String s = new String(chars);
5345        final byte[] bytes;
5346        try
5347          {
5348            bytes = s.getBytes("UTF8");
5349          }
5350        catch (java.io.UnsupportedEncodingException e)
5351          {
5352            return error(new LispError("UTF8 is not a supported encoding."));
5353          }
5354        LispObject[] objects = new LispObject[bytes.length];
5355        for (int i = bytes.length; i-- > 0;)
5356          {
5357            int n = bytes[i];
5358            if (n < 0)
5359              n += 256;
5360            objects[i] = Fixnum.getInstance(n);
5361          }
5362        return new SimpleVector(objects);
5363      }
5364    };
5365
5366  // ### %documentation
5367  private static final Primitive _DOCUMENTATION =
5368    new Primitive("%documentation", PACKAGE_SYS, true,
5369                  "object doc-type")
5370    {
5371      @Override
5372      public LispObject execute(LispObject object, LispObject docType)
5373
5374      {
5375        LispObject doc = object.getDocumentation(docType);
5376        if (doc == NIL)
5377          {
5378            if (docType == Symbol.FUNCTION && object instanceof Symbol)
5379              {
5380                LispObject function = object.getSymbolFunction();
5381                if (function != null)
5382                  doc = function.getDocumentation(docType);
5383              }
5384          }
5385        return doc;
5386      }
5387    };
5388
5389  // ### %set-documentation
5390  private static final Primitive _SET_DOCUMENTATION =
5391    new Primitive("%set-documentation", PACKAGE_SYS, true,
5392                  "object doc-type documentation")
5393    {
5394      @Override
5395      public LispObject execute(LispObject object, LispObject docType,
5396                                LispObject documentation)
5397
5398      {
5399        object.setDocumentation(docType, documentation);
5400        return documentation;
5401      }
5402    };
5403
5404  // ### %putf
5405  private static final Primitive _PUTF =
5406    new Primitive("%putf", PACKAGE_SYS, true,
5407                  "plist indicator new-value")
5408    {
5409      @Override
5410      public LispObject execute(LispObject plist, LispObject indicator,
5411                                LispObject newValue)
5412
5413      {
5414        return putf(plist, indicator, newValue);
5415      }
5416    };
5417
5418  // ### function-plist
5419  private static final Primitive FUNCTION_PLIST =
5420    new Primitive("function-plist", PACKAGE_SYS, true, "function")
5421    {
5422      @Override
5423      public LispObject execute(LispObject arg)
5424      {
5425          return checkFunction(arg).getPropertyList();
5426      }
5427    };
5428
5429  // ### make-keyword
5430  private static final Primitive MAKE_KEYWORD =
5431    new Primitive("make-keyword", PACKAGE_SYS, true, "symbol")
5432    {
5433      @Override
5434      public LispObject execute(LispObject arg)
5435      {
5436          return PACKAGE_KEYWORD.intern(checkSymbol(arg).name);
5437      }
5438    };
5439
5440  // ### standard-object-p object => generalized-boolean
5441  private static final Primitive STANDARD_OBJECT_P =
5442    new Primitive("standard-object-p", PACKAGE_SYS, true, "object")
5443    {
5444      @Override
5445      public LispObject execute(LispObject arg)
5446      {
5447        return arg instanceof StandardObject ? T : NIL;
5448      }
5449    };
5450
5451  // ### copy-tree
5452  private static final Primitive COPY_TREE =
5453    new Primitive(Symbol.COPY_TREE, "object")
5454    {
5455      @Override
5456      public LispObject execute(LispObject arg)
5457      {
5458        if (arg instanceof Cons)
5459          {
5460            Cons cons = (Cons) arg;
5461            return new Cons(execute(cons.car), execute(cons.cdr));
5462          }
5463        else
5464          return arg;
5465      }
5466    };
5467   
5468}
Note: See TracBrowser for help on using the repository browser.