allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (09/24/89)
Posting-number: Volume 8, Issue 54 Submitted-by: net@tub.UUCP (Oliver Laumann) Archive-name: elk/part06 [Let this be a lesson to submitters: this was submitted as uuencoded, compressed files. I lost the source information while unpacking it; this is the best approximation I could come up with. ++bsa] #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 6 (of 14)." # Contents: src/math.c src/special.c src/dump.c src/type.c src/bool.c # src/bignum.c src/alloca.s.386 tst # Wrapped by net@tub on Sun Sep 17 17:32:26 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f src/math.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"src/math.c\" else echo shar: Extracting \"src/math.c\" \(14868 characters\) sed "s/^X//" >src/math.c <<'END_OF_src/math.c' X/* Numbers X */ X X#include <math.h> X#include <errno.h> X X#include "scheme.h" X XObject Generic_Multiply(), Generic_Divide(); X XInit_Math () { X (void)srandom (getpid ()); X} X XObject Make_Fixnum (n) { X Object num; X X SET(num, T_Fixnum, n); X return num; X} X XObject Make_Integer (n) register n; { X if (FIXNUM_FITS(n)) X return Make_Fixnum (n); X else X return Integer_To_Bignum (n); X} X XObject Make_Unsigned (n) register unsigned n; { X if (FIXNUM_FITS_UNSIGNED(n)) X return Make_Fixnum (n); X else X return Unsigned_To_Bignum (n); X} X XGet_Integer (x) Object x; { X switch (TYPE(x)) { X case T_Fixnum: X return FIXNUM(x); X case T_Bignum: X return Bignum_To_Integer (x); X default: X Wrong_Type (x, T_Fixnum); X } X /*NOTREACHED*/ X} X XGet_Index (n, obj) Object n, obj; { X register size, i; X X i = Get_Integer (n); X size = TYPE(obj) == T_Vector ? VECTOR(obj)->size : STRING(obj)->size; X if (i < 0 || i >= size) X Range_Error (n); X return i; X} X XObject Make_Reduced_Flonum (d) double d; { X Object num; X register char *p; X int expo; X X if (floor (d) == d) { X if (d == 0) X return Zero; X (void)frexp (d, &expo); X if (expo <= VALBITS-1) X return Make_Fixnum ((int)d); X } X p = Get_Bytes (sizeof (struct S_Flonum)); X SET(num, T_Flonum, (struct S_Flonum *)p); X FLONUM(num)->tag = Null; X FLONUM(num)->val = d; X return num; X} X XObject P_Integerp (x) Object x; { X return TYPE(x) == T_Fixnum || TYPE(x) == T_Bignum ? True : False; X} X XObject P_Rationalp (x) Object x; { X return P_Integerp (x); X} X XObject P_Realp (x) Object x; { X register t = TYPE(x); X return t == T_Flonum || t == T_Fixnum || t == T_Bignum ? True : False; X} X XObject P_Complexp (x) Object x; { X return P_Realp (x); X} X XObject P_Numberp (x) Object x; { X return P_Complexp (x); X} X X#define General_Generic_Predicate(prim,op,bigop) Object prim (x) Object x; {\ X register ret;\ X Check_Number (x);\ X switch (TYPE(x)) {\ X case T_Flonum:\ X ret = FLONUM(x)->val op 0; break;\ X case T_Fixnum:\ X ret = FIXNUM(x) op 0; break;\ X case T_Bignum:\ X ret = bigop (x); break;\ X }\ X return ret ? True : False;\ X} X XGeneral_Generic_Predicate (P_Zerop, ==, Bignum_Zero) XGeneral_Generic_Predicate (P_Negativep, <, Bignum_Negative) XGeneral_Generic_Predicate (P_Positivep, >, Bignum_Positive) X XObject P_Evenp (x) Object x; { X register ret; X X Check_Integer (x); X switch (TYPE(x)) { X case T_Fixnum: X ret = !(FIXNUM(x) & 1); break; X case T_Bignum: X ret = Bignum_Even (x); break; X } X return ret ? True : False; X} X XObject P_Oddp (x) Object x; { X Object tmp; X tmp = P_Evenp (x); X return EQ(tmp,True) ? False : True; X} X XObject P_Exactp (x) Object x; { X Check_Number (x); X return False; X} X XObject P_Inexactp (x) Object x; { X Check_Number (x); X return True; X} X X#define General_Generic_Compare(name,op,bigop) name (x, y) Object x, y; {\ X Object b; register ret;\ X GC_Node;\ X \ X switch (TYPE(x)) {\ X case T_Fixnum:\ X switch (TYPE(y)) {\ X case T_Fixnum:\ X return FIXNUM(x) op FIXNUM(y);\ X case T_Flonum:\ X return FIXNUM(x) op FLONUM(y)->val;\ X case T_Bignum:\ X GC_Link (y);\ X b = Integer_To_Bignum (FIXNUM(x));\ X ret = bigop (b, y);\ X GC_Unlink;\ X return ret;\ X }\ X case T_Flonum:\ X switch (TYPE(y)) {\ X case T_Fixnum:\ X return FLONUM(x)->val op FIXNUM(y);\ X case T_Flonum:\ X return FLONUM(x)->val op FLONUM(y)->val;\ X case T_Bignum:\ X return FLONUM(x)->val op Bignum_To_Double (y);\ X }\ X case T_Bignum:\ X switch (TYPE(y)) {\ X case T_Fixnum:\ X GC_Link (x);\ X b = Integer_To_Bignum (FIXNUM(y));\ X ret = bigop (x, b);\ X GC_Unlink;\ X return ret;\ X case T_Flonum:\ X return Bignum_To_Double (x) op FLONUM(y)->val;\ X case T_Bignum:\ X return bigop (x, y);\ X }\ X }\ X /*NOTREACHED*/\ X} X XGeneral_Generic_Compare (Generic_Equal, ==, Bignum_Equal) XGeneral_Generic_Compare (Generic_Less, <, Bignum_Less) XGeneral_Generic_Compare (Generic_Greater, >, Bignum_Greater) XGeneral_Generic_Compare (Generic_Eq_Less, <=, Bignum_Eq_Less) XGeneral_Generic_Compare (Generic_Eq_Greater, >=, Bignum_Eq_Greater) X XObject General_Compare (argc, argv, op) Object *argv; register (*op)(); { X register i; X X Check_Number (argv[0]); X for (i = 1; i < argc; i++) { X Check_Number (argv[i]); X if (!(*op) (argv[i-1], argv[i])) X return False; X } X return True; X} X XObject P_Generic_Equal (argc, argv) Object *argv; { X return General_Compare (argc, argv, Generic_Equal); X} X XObject P_Generic_Less (argc, argv) Object *argv; { X return General_Compare (argc, argv, Generic_Less); X} X XObject P_Generic_Greater (argc, argv) Object *argv; { X return General_Compare (argc, argv, Generic_Greater); X} X XObject P_Generic_Eq_Less (argc, argv) Object *argv; { X return General_Compare (argc, argv, Generic_Eq_Less); X} X XObject P_Generic_Eq_Greater (argc, argv) Object *argv; { X return General_Compare (argc, argv, Generic_Eq_Greater); X} X X#define General_Generic_Operator(name,op,bigop) Object name (x, y)\ X Object x, y; {\ X Object b1, b2, ret; register i;\ X GC_Node2;\ X \ X switch (TYPE(x)) {\ X case T_Fixnum:\ X switch (TYPE(y)) {\ X case T_Fixnum:\ X i = FIXNUM(x) op FIXNUM(y);\ X if (FIXNUM_FITS(i))\ X return Make_Fixnum (i);\ X b1 = b2 = Null;\ X GC_Link2 (b1, b2);\ X b1 = Integer_To_Bignum (FIXNUM(x));\ X b2 = Integer_To_Bignum (FIXNUM(y));\ X ret = bigop (b1, b2);\ X GC_Unlink;\ X return ret;\ X case T_Flonum:\ X return Make_Reduced_Flonum (FIXNUM(x) op FLONUM(y)->val);\ X case T_Bignum:\ X return bigop (Integer_To_Bignum (FIXNUM(x)), y);\ X }\ X case T_Flonum:\ X switch (TYPE(y)) {\ X case T_Fixnum:\ X return Make_Reduced_Flonum (FLONUM(x)->val op FIXNUM(y));\ X case T_Flonum:\ X return Make_Reduced_Flonum (FLONUM(x)->val op FLONUM(y)->val);\ X case T_Bignum:\ X return Make_Reduced_Flonum (FLONUM(x)->val op\ X Bignum_To_Double (y));\ X }\ X case T_Bignum:\ X switch (TYPE(y)) {\ X case T_Fixnum:\ X return bigop (x, Integer_To_Bignum (FIXNUM(y)));\ X case T_Flonum:\ X return Make_Reduced_Flonum (Bignum_To_Double (x) op\ X FLONUM(y)->val);\ X case T_Bignum:\ X return bigop (x, y);\ X }\ X }\ X /*NOTREACHED*/\ X} X XGeneral_Generic_Operator (Generic_Plus, +, Bignum_Plus) XGeneral_Generic_Operator (Generic_Minus, -, Bignum_Minus) X XObject P_Inc (x) Object x; { X Check_Number (x); X return Generic_Plus (x, One); X} X XObject P_Dec (x) Object x; { X Check_Number (x); X return Generic_Minus (x, One); X} X XObject General_Operator (argc, argv, start, op) Object *argv, start; X register Object (*op)(); { X register i; X Object accum; X X if (argc > 0) X Check_Number (argv[0]); X accum = start; X switch (argc) { X case 0: X break; X case 1: X accum = (*op) (accum, argv[0]); break; X default: X for (accum = argv[0], i = 1; i < argc; i++) { X Check_Number (argv[i]); X accum = (*op) (accum, argv[i]); X } X } X return accum; X} X XObject P_Generic_Plus (argc, argv) Object *argv; { X return General_Operator (argc, argv, Zero, Generic_Plus); X} X XObject P_Generic_Minus (argc, argv) Object *argv; { X return General_Operator (argc, argv, Zero, Generic_Minus); X} X XObject P_Generic_Multiply (argc, argv) Object *argv; { X return General_Operator (argc, argv, One, Generic_Multiply); X} X XObject P_Generic_Divide (argc, argv) Object *argv; { X return General_Operator (argc, argv, One, Generic_Divide); X} X XObject Generic_Multiply (x, y) Object x, y; { X Object b, ret; X X switch (TYPE(x)) { X case T_Fixnum: X switch (TYPE(y)) { X case T_Fixnum: X ret = Fixnum_Multiply (FIXNUM(x), FIXNUM(y)); X if (Nullp (ret)) { X b = Integer_To_Bignum (FIXNUM(x)); X return Bignum_Fixnum_Multiply (b, y); X } X return ret; X case T_Flonum: X return Make_Reduced_Flonum (FIXNUM(x) * FLONUM(y)->val); X case T_Bignum: X return Bignum_Fixnum_Multiply (y, x); X } X case T_Flonum: X switch (TYPE(y)) { X case T_Fixnum: X return Make_Reduced_Flonum (FLONUM(x)->val * FIXNUM(y)); X case T_Flonum: X return Make_Reduced_Flonum (FLONUM(x)->val * FLONUM(y)->val); X case T_Bignum: X return Make_Reduced_Flonum (FLONUM(x)->val * Bignum_To_Double (y)); X } X case T_Bignum: X switch (TYPE(y)) { X case T_Fixnum: X return Bignum_Fixnum_Multiply (x, y); X case T_Flonum: X return Make_Reduced_Flonum (Bignum_To_Double (x) * FLONUM(y)->val); X case T_Bignum: X return Bignum_Multiply (x, y); X } X } X /*NOTREACHED*/ X} X XObject Generic_Divide (x, y) Object x, y; { X register t = TYPE(y); X Object b, ret; X GC_Node2; X X if (t == T_Fixnum ? FIXNUM(y) == 0 : X (t == T_Flonum ? FLONUM(y) == 0 : Bignum_Zero (y))) X Range_Error (y); X switch (TYPE(x)) { X case T_Fixnum: X switch (t) { X case T_Fixnum: X return Make_Reduced_Flonum ((double)FIXNUM(x) / (double)FIXNUM(y)); X case T_Flonum: X return Make_Reduced_Flonum ((double)FIXNUM(x) / FLONUM(y)->val); X case T_Bignum: X GC_Link (y); X b = Integer_To_Bignum (FIXNUM(x)); X ret = Bignum_Divide (b, y); X GC_Unlink; X if (EQ(Cdr (ret),Zero)) X return Car (ret); X return Make_Reduced_Flonum ((double)FIXNUM(x) / X Bignum_To_Double (y)); X } X case T_Flonum: X switch (t) { X case T_Fixnum: X return Make_Reduced_Flonum (FLONUM(x)->val / (double)FIXNUM(y)); X case T_Flonum: X return Make_Reduced_Flonum (FLONUM(x)->val / FLONUM(y)->val); X case T_Bignum: X return Make_Reduced_Flonum (FLONUM(x)->val / Bignum_To_Double (y)); X } X case T_Bignum: X switch (t) { X case T_Fixnum: X GC_Link (x); X ret = Bignum_Fixnum_Divide (x, y); X GC_Unlink; X if (EQ(Cdr (ret),Zero)) X return Car (ret); X return Make_Reduced_Flonum (Bignum_To_Double (x) / X (double)FIXNUM(y)); X case T_Flonum: X return Make_Reduced_Flonum (Bignum_To_Double (x) / FLONUM(y)->val); X case T_Bignum: X GC_Link2 (x, y); X ret = Bignum_Divide (x, y); X GC_Unlink; X if (EQ(Cdr (ret),Zero)) X return Car (ret); X return Make_Reduced_Flonum (Bignum_To_Double (x) / X Bignum_To_Double (y)); X } X } X /*NOTREACHED*/ X} X XObject P_Abs (x) Object x; { X register i; X X Check_Number (x); X switch (TYPE(x)) { X case T_Fixnum: X i = FIXNUM(x); X return i < 0 ? Make_Integer (-i) : x; X case T_Flonum: X return Make_Reduced_Flonum (fabs (FLONUM(x)->val)); X case T_Bignum: X return Bignum_Abs (x); X } X /*NOTREACHED*/ X} X XObject General_Integer_Divide (x, y, rem) Object x, y; { X register fx = FIXNUM(x), fy = FIXNUM(y); X Object b, ret; X GC_Node; X X Check_Integer (x); X Check_Integer (y); X if (TYPE(y) == T_Fixnum ? FIXNUM(y) == 0 : Bignum_Zero (y)) X Range_Error (y); X switch (TYPE(x)) { X case T_Fixnum: X switch (TYPE(y)) { X case T_Fixnum: X return Make_Fixnum (rem ? (fx % fy) : (fx / fy)); X case T_Bignum: X GC_Link (y); X b = Integer_To_Bignum (fx); X GC_Unlink; X ret = Bignum_Divide (b, y); Xdone: X return rem ? Cdr (ret) : Car (ret); X } X case T_Bignum: X switch (TYPE(y)) { X case T_Fixnum: X ret = Bignum_Fixnum_Divide (x, y); X goto done; X case T_Bignum: X ret = Bignum_Divide (x, y); X goto done; X } X } X /*NOTREACHED*/ X} X XObject P_Quotient (x, y) Object x, y; { X return General_Integer_Divide (x, y, 0); X} X XObject P_Remainder (x, y) Object x, y; { X return General_Integer_Divide (x, y, 1); X} X XObject P_Modulo (x, y) Object x, y; { X Object rem, xneg, yneg; X GC_Node2; X X GC_Link2 (x, y); X rem = General_Integer_Divide (x, y, 1); X xneg = P_Negativep (x); X yneg = P_Negativep (y); X if (!EQ(xneg,yneg)) X rem = Generic_Plus (rem, y); X GC_Unlink; X return rem; X} X XObject gcd (x, y) Object x, y; { X Object r, z; X GC_Node2; X X Check_Integer (x); X Check_Integer (y); X GC_Link2 (x, y); X while (1) { X z = P_Zerop (x); X if (EQ(z,True)) { X r = y; X break; X } X z = P_Zerop (y); X if (EQ(z,True)) { X r = x; X break; X } X r = General_Integer_Divide (x, y, 1); X x = y; X y = r; X } X GC_Unlink; X return r; X} X XObject P_Gcd (argc, argv) Object *argv; { X return P_Abs (General_Operator (argc, argv, Zero, gcd)); X} X XObject lcm (x, y) Object x, y; { X Object ret, p, z; X GC_Node3; X X ret = Null; X GC_Link3 (x, y, ret); X ret = gcd (x, y); X z = P_Zerop (ret); X if (!EQ(z,True)) { X p = Generic_Multiply (x, y); X ret = General_Integer_Divide (p, ret, 0); X } X GC_Unlink; X return ret; X} X XObject P_Lcm (argc, argv) Object *argv; { X return P_Abs (General_Operator (argc, argv, One, lcm)); X} X X#define General_Conversion(name,op) Object name (x) Object x; {\ X double d; int expo;\ X \ X Check_Number (x);\ X if (TYPE(x) != T_Flonum)\ X return x;\ X d = op (FLONUM(x)->val);\ X (void)frexp (d, &expo);\ X return (expo <= VALBITS-1) ? Make_Fixnum ((int)d) : Double_To_Bignum (d);\ X} X X#define trunc(x) (x) X#define round(x) ((x) >= 0 ? (x) + 0.5 : (x) - 0.5) X XGeneral_Conversion (P_Floor, floor) XGeneral_Conversion (P_Ceiling, ceil) XGeneral_Conversion (P_Truncate, trunc) XGeneral_Conversion (P_Round, round) X Xdouble Get_Double (x) Object x; { X Check_Number (x); X switch (TYPE(x)) { X case T_Fixnum: X return (double)FIXNUM(x); X case T_Flonum: X return FLONUM(x)->val; X case T_Bignum: X return Bignum_To_Double (x); X } X /*NOTREACHED*/ X} X XObject General_Function (x, y, fun) Object x, y; double (*fun)(); { X double d, ret; X X d = Get_Double (x); X errno = 0; X if (Nullp (y)) X ret = (*fun) (d); X else X ret = (*fun) (d, Get_Double (y)); X if (errno == ERANGE || errno == EDOM) X Range_Error (x); X return Make_Reduced_Flonum (ret); X} X XObject P_Sqrt (x) Object x; { return General_Function (x, Null, sqrt); } X XObject P_Exp (x) Object x; { return General_Function (x, Null, exp); } X XObject P_Log (x) Object x; { return General_Function (x, Null, log); } X XObject P_Sin (x) Object x; { return General_Function (x, Null, sin); } X XObject P_Cos (x) Object x; { return General_Function (x, Null, cos); } X XObject P_Tan (x) Object x; { return General_Function (x, Null, tan); } X XObject P_Asin (x) Object x; { return General_Function (x, Null, asin); } X XObject P_Acos (x) Object x; { return General_Function (x, Null, acos); } X XObject P_Atan (argc, argv) Object *argv; { X register a2 = argc == 2; X return General_Function (argv[0], a2 ? argv[1] : Null, a2 ? atan2 : atan); X} X XObject Min (x, y) Object x, y; { X return Generic_Less (x, y) ? x : y; X} X XObject Max (x, y) Object x, y; { X return Generic_Less (x, y) ? y : x; X} X XObject P_Min (argc, argv) Object *argv; { X return General_Operator (argc, argv, argv[0], Min); X} X XObject P_Max (argc, argv) Object *argv; { X return General_Operator (argc, argv, argv[0], Max); X} X XObject P_Random () { X extern long random(); X return Make_Fixnum ((int)random () & ~SIGNMASK); X} X XObject P_Srandom (x) Object x; { X Check_Integer (x); X (void)srandom (Get_Integer (x)); X return x; X} END_OF_src/math.c if test 14868 -ne `wc -c <src/math.c`; then echo shar: \"src/math.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f src/special.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"src/special.c\" else echo shar: Extracting \"src/special.c\" \(9557 characters\) sed "s/^X//" >src/special.c <<'END_OF_src/special.c' X/* Miscellaneous special forms X */ X X#include "scheme.h" X Xstatic Object Sym_Else; X XInit_Special () { X Define_Symbol (&Sym_Else, "else"); X} X XObject P_Quote (argl) Object argl; { X return Car (argl); X} X XObject Quasiquote (x, level) Object x; { X Object form, list, tail, cell, qcar, qcdr, ret; X TC_Prolog; X X if (TYPE(x) != T_Pair) X return x; X if (EQ(Car (x), Sym_Unquote)) { X x = Cdr (x); X if (TYPE(x) != T_Pair) X Primitive_Error ("bad unquote form: ~s", x); X if (level) { X ret = Cons (Car (x), Null); X ret = Quasiquote(ret, level-1); X ret = Cons (Sym_Unquote, ret); X } else { X TC_Disable; X ret = Eval (Car (x)); X TC_Enable; X } X return ret; X } else if (TYPE(Car (x)) == T_Pair X && EQ(Car (Car (x)), Sym_Unquote_Splicing)) { X GC_Node6; X X qcdr = Cdr (x); X form = list = tail = cell = Null; X x = Car (x); X if (TYPE(Cdr (x)) != T_Pair) X Primitive_Error ("bad unquote-splicing form: ~s", x); X if (level) { X GC_Link2 (list, qcdr); X list = Quasiquote(Cdr (x), level-1); X list = Cons (Sym_Unquote_Splicing, list); X qcdr = Quasiquote(qcdr, level); X list = Cons (list, qcdr); X GC_Unlink; X return list; X } X GC_Link6 (x, qcdr, form, list, tail, cell); X TC_Disable; X form = Eval (Car (Cdr (x))); X TC_Enable; X for ( ; TYPE(form) == T_Pair; tail = cell, form = Cdr (form)) { X cell = Cons (Car (form), Null); X if (Nullp (list)) X list = cell; X else X P_Setcdr (tail, cell); X } X qcdr = Quasiquote (qcdr, level); X GC_Unlink; X if (Nullp (list)) X return qcdr; X P_Setcdr (tail, qcdr); X return list; X } else { X GC_Node3; X X qcar = qcdr = Null; X GC_Link3 (x, qcar, qcdr); X if (EQ(Car (x), Sym_Quasiquote)) /* hack! */ X ++level; X qcar = Quasiquote (Car (x), level); X qcdr = Quasiquote (Cdr (x), level); X list = Cons (qcar, qcdr); X GC_Unlink; X return list; X } X} X XObject P_Quasiquote (argl) Object argl; { X return Quasiquote (Car (argl), 0); X} X XObject P_If (argl) Object argl; { X Object cond, ret; X GC_Node; X TC_Prolog; X X GC_Link (argl); X TC_Disable; X cond = Eval (Car (argl)); X TC_Enable; X if (Truep(cond)) X ret = Eval (Car (Cdr (argl))); X else X ret = Begin (Cdr (Cdr (argl))); X GC_Unlink; X return ret; X} X XObject P_Case (argl) Object argl; { X Object ret, key, clause, select; X GC_Node; X TC_Prolog; X X GC_Link (argl); X ret = False; X TC_Disable; X key = Eval (Car (argl)); X for (argl = Cdr (argl); !Nullp (argl); argl = Cdr (argl)) { X clause = Car (argl); X Check_List (clause); X if (Nullp (clause)) X Primitive_Error ("empty clause"); X select = Car (clause); X if (EQ(select, Sym_Else)) { X if (!Nullp (Cdr (argl))) X Primitive_Error ("`else' not in last clause"); X if (Nullp (Cdr (clause))) X Primitive_Error ("no forms in `else' clause"); X } else if (TYPE(select) == T_Pair) { X select = P_Memv (key, select); X } else X select = P_Eqv (key, select); X if (Truep (select)) { X clause = Cdr (clause); X TC_Enable; X ret = Nullp (clause) ? True : Begin (clause); X break; X } X } X TC_Enable; X GC_Unlink; X return ret; X} X XObject P_Cond (argl) Object argl; { X Object ret, clause, guard; X GC_Node3; X TC_Prolog; X X ret = False; X clause = guard = Null; X GC_Link3 (argl, clause, guard); X TC_Disable; X for ( ; !Nullp (argl); argl = Cdr (argl)) { X clause = Car (argl); X Check_List (clause); X if (Nullp (clause)) X Primitive_Error ("empty clause"); X guard = Car (clause); X if (EQ(guard, Sym_Else)) { X if (!Nullp (Cdr (argl))) X Primitive_Error ("`else' not in last clause"); X if (Nullp (Cdr (clause))) X Primitive_Error ("no forms in `else' clause"); X } else X guard = Eval (Car (clause)); X if (Truep (guard)) { X clause = Cdr (clause); X TC_Enable; X ret = Nullp (clause) ? guard : Begin (clause); X break; X } X } X TC_Enable; X GC_Unlink; X return ret; X} X XObject General_Junction (argl, and) Object argl; register and; { X Object ret; X GC_Node; X TC_Prolog; X X ret = and ? True : False; X if (Nullp (argl)) X return ret; X GC_Link (argl); X TC_Disable; X for ( ; !Nullp (Cdr (argl)); argl = Cdr (argl)) { X ret = Eval (Car (argl)); X if (and != Truep (ret)) X break; X } X TC_Enable; X if (Nullp (Cdr (argl))) X ret = Eval (Car (argl)); X GC_Unlink; X return ret; X} X XObject P_And (argl) Object argl; { X return General_Junction (argl, 1); X} X XObject P_Or (argl) Object argl; { X return General_Junction (argl, 0); X} X XObject P_Do (argl) Object argl; { X Object tail, b, val, test, frame, newframe, len, ret; X register local_vars; X GC_Node6; X TC_Prolog; X X b = test = frame = newframe = Null; X GC_Link6 (argl, tail, b, test, frame, newframe); X TC_Disable; X for (tail = Car (argl); !Nullp (tail); tail = Cdr (tail)) { X Check_List (tail); X b = Car (tail); X if (Nullp (b)) X Primitive_Error ("bad initialization form"); X val = P_Cdr (b); X Check_List (val); X Check_Type (Car (b), T_Symbol); X if (!Nullp (val)) X val = Eval (Car (val)); X frame = Add_Binding (frame, Car (b), val); X } X if (local_vars = !Nullp (frame)) X Push_Frame (frame); X test = Car (Cdr (argl)); X Check_Type (test, T_Pair); X while (1) { X b = Eval (Car (test)); X if (Truep (b)) X break; X (void)Begin (Cdr (Cdr (argl))); X if (!local_vars) X continue; X newframe = Null; X for (tail = Car (argl); !Nullp (tail); tail = Cdr (tail)) { X b = Car (tail); X /* Gosh! This could be done much more X * efficiently, but I'm too lazy... X */ X val = Cdr (b); X len = P_Length (val); X val = FIXNUM(len) > 1 ? Car (Cdr (val)) : Car (b); X newframe = Add_Binding (newframe, Car (b), Eval (val)); X } X Pop_Frame (); X Push_Frame (newframe); X } X Check_List (Cdr (test)); X TC_Enable; X ret = Begin (Cdr (test)); X if (local_vars) X Pop_Frame (); X GC_Unlink; X return ret; X} X XObject General_Let (argl, disc) Object argl; { X Object frame, b, val, tail, ret; X GC_Node5; X TC_Prolog; X X frame = b = val = Null; X GC_Link5 (argl, frame, b, val, tail); X TC_Disable; X for (tail = Car (argl); !Nullp (tail); tail = Cdr (tail)) { X Check_List (tail); X b = Car (tail); X if (Nullp (b)) X Primitive_Error ("bad binding form"); X val = P_Cdr (b); X Check_List (val); X Check_Type (Car (b), T_Symbol); X if (!Nullp (val)) X val = Car (val); X if (disc == 0) { X val = Eval (val); X } else if (disc == 1) { X Push_Frame (frame); X val = Eval (val); X Pop_Frame (); X } else if (disc == 2) X val = Null; X frame = Add_Binding (frame, Car (b), val); X } X Push_Frame (frame); X if (disc == 2) { X for (tail = Car (argl); !Nullp (tail); tail = Cdr (tail)) { X b = Car (tail); X val = Cdr (b); X if (Nullp (val)) continue; X val = Car (val); X b = Lookup_Symbol (Car (b), 1); X val = Eval (val); X Cdr (b) = val; X SYMBOL(Car (b))->value = val; X } X } X TC_Enable; X ret = Begin (Cdr (argl)); X Pop_Frame (); X GC_Unlink; X return ret; X} X XObject Named_Let (argl) Object argl; { X Object b, val, tail, vlist, vtail, flist, ftail, cell; X GC_Node6; X TC_Prolog; X X tail = vlist = vtail = flist = ftail = Null; X GC_Link6 (argl, tail, vlist, vtail, flist, ftail); X TC_Disable; X for (tail = Car (Cdr (argl)); !Nullp (tail); tail = Cdr (tail)) { X Check_List (tail); X b = Car (tail); X if (Nullp (b)) X Primitive_Error ("bad binding form"); X val = P_Cdr (b); X Check_List (val); X Check_Type (Car (b), T_Symbol); X if (!Nullp (val)) X val = Car (val); X cell = Cons (val, Null); X if (Nullp (flist)) X flist = cell; X else X P_Setcdr (ftail, cell); X ftail = cell; X cell = Cons (Car (Car (tail)), Null); X if (Nullp (vlist)) X vlist = cell; X else X P_Setcdr (vtail, cell); X vtail = cell; X } X Push_Frame (Add_Binding (Null, Car (argl), Null)); X tail = Cons (vlist, Cdr (Cdr (argl))); X tail = P_Lambda (tail); X COMPOUND(tail)->name = Car (argl); X b = Lookup_Symbol (Car (argl), 1); X Cdr (b) = tail; X SYMBOL(Car (argl))->value = tail; X TC_Enable; X tail = Funcall_Compound (tail, flist, 1); X Pop_Frame (); X GC_Unlink; X return tail; X} X XObject P_Let (argl) Object argl; { X if (TYPE(Car (argl)) == T_Symbol) X return Named_Let (argl); X else X return General_Let (argl, 0); X} X XObject P_Letseq (argl) Object argl; { X return General_Let (argl, 1); X} X XObject P_Letrec (argl) Object argl; { X return General_Let (argl, 2); X} X XObject P_Fluid_Let (argl) Object argl; { X Object b, sym, val, tail, ret; X register WIND *w, *first = First_Wind, *last = Last_Wind; X GC_Node5; X TC_Prolog; X X sym = b = val = Null; X GC_Link5 (argl, sym, b, val, tail); X TC_Disable; X for (tail = Car (argl); !Nullp (tail); tail = Cdr (tail)) { X Check_List (tail); X b = Car (tail); X if (Nullp (b)) X Primitive_Error ("bad binding form"); X sym = Car (b); X val = P_Cdr (b); X Check_List (val); X Check_Type (sym, T_Symbol); X if (!Nullp (val)) X val = Car (val); X val = Eval (val); X b = Lookup_Symbol (sym, 1); X w = (WIND *)alloca (sizeof (WIND)); X Add_Wind (w, Null, Null); X w->in = Cons (sym, val); X w->out = Cons (sym, Cdr (b)); X Cdr (b) = val; X SYMBOL(sym)->value = val; X } X ret = Begin (Cdr (argl)); X for (w = Last_Wind; w != last; w = w->prev) { X sym = Car (w->out); val = Cdr (w->out); X b = Lookup_Symbol (sym, 0); X if (Nullp (b)) X Panic ("fluid-let1"); X Cdr (b) = val; X SYMBOL(sym)->value = val; X } X if (Last_Wind = last) X last->next = 0; X First_Wind = first; X GC_Unlink; X TC_Enable; X return ret; X} END_OF_src/special.c if test 9557 -ne `wc -c <src/special.c`; then echo shar: \"src/special.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f src/dump.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"src/dump.c\" else echo shar: Extracting \"src/dump.c\" \(6831 characters\) sed "s/^X//" >src/dump.c <<'END_OF_src/dump.c' X/* Create a.out from running interpreter X * X * COFF doesn't work together with dynamic loading. X * Some of the COFF code has been taken from GNU Emacs's unexec.c X * (in a modified form). X */ X X#include <signal.h> X X#include "scheme.h" X X#ifdef CAN_DUMP X X#include <sys/types.h> X#include <sys/stat.h> X X#ifdef COFF X# include <filehdr.h> X# include <aouthdr.h> X# include <scnhdr.h> X# include <syms.h> X# ifndef N_BADMAG X# define N_BADMAG(x) (0) X# endif X#else X# include <a.out.h> X#endif X XObject Dump_Control_Point; X XInit_Dump () { X Global_GC_Link (Dump_Control_Point); X} X XObject P_Dump (ofile) Object ofile; { X#ifdef COFF X static struct scnhdr thdr, dhdr, bhdr, scn; X static struct filehdr hdr; X static struct aouthdr ohdr; X unsigned bias; X unsigned lnno_start, syms_start; X unsigned text_scn_start, data_scn_start; X unsigned data_end; X int pagemask = PAGESIZE-1; X#else X struct exec hdr, shdr; X unsigned data_start, data_end; X int pagemask = getpagesize () - 1; X#endif X char *afn; X register n; X char buf[BUFSIZ]; X Object ret, port; X int ofd, afd; X struct stat st; X GC_Node; X X if (!EQ (Curr_Input_Port, Standard_Input_Port) || X !EQ (Curr_Output_Port, Standard_Output_Port)) X Primitive_Error ("cannot dump with current ports redirected"); X Flush_Output (Curr_Output_Port); X Close_All_Files (); X X GC_Link (ofile); X n = stksize (); X Dump_Control_Point = Make_Control_Point (n); X SETFAST(ret,saveenv (CONTROL(Dump_Control_Point)->stack)); X if (TYPE(ret) != T_Special) { X Enable_Interrupts; X return ret; X } X GC_Unlink; X X Disable_Interrupts; X port = General_Open_File (ofile, 0, Null); X ofd = dup (fileno (PORT(port)->file)); X P_Close_Port (port); X if (ofd < 0) X Primitive_Error ("out of file descriptors"); X X if ((afd = open (myname, 0)) == -1) { X Saved_Errno = errno; X close (ofd); X Primitive_Error ("cannot open a.out file: ~E"); X } X if (read (afd, (char *)&hdr, sizeof (hdr)) != sizeof (hdr) X || N_BADMAG(hdr)) { Xbadaout: X close (ofd); X close (afd); X Primitive_Error ("corrupt a.out file"); X } X#ifdef COFF X data_end = ((unsigned)sbrk (0) + pagemask) & ~pagemask; X syms_start = sizeof (hdr); X if (hdr.f_opthdr > 0) { X if (read (afd, (char *)&ohdr, sizeof (ohdr)) != sizeof (ohdr)) X goto badaout; X } X for (n = 0; n < hdr.f_nscns; n++) { X if (read (afd, (char *)&scn, sizeof (scn)) != sizeof (scn)) X goto badaout; X if (scn.s_scnptr > 0 && syms_start < scn.s_scnptr + scn.s_size) X syms_start = scn.s_scnptr + scn.s_size; X if (strcmp (scn.s_name, ".text") == 0) X thdr = scn; X else if (strcmp (scn.s_name, ".data") == 0) X dhdr = scn; X else if (strcmp (scn.s_name, ".bss") == 0) X bhdr = scn; X } X hdr.f_flags |= (F_RELFLG|F_EXEC); X ohdr.dsize = data_end - ohdr.data_start; X ohdr.bsize = 0; X thdr.s_size = ohdr.tsize; X thdr.s_scnptr = sizeof (hdr) + sizeof (ohdr) X + hdr.f_nscns * sizeof (thdr); X lnno_start = thdr.s_lnnoptr; X text_scn_start = thdr.s_scnptr; X dhdr.s_paddr = dhdr.s_vaddr = ohdr.data_start; X dhdr.s_size = ohdr.dsize; X dhdr.s_scnptr = thdr.s_scnptr + thdr.s_size; X data_scn_start = dhdr.s_scnptr; X bhdr.s_paddr = bhdr.s_vaddr = ohdr.data_start + ohdr.dsize; X bhdr.s_size = ohdr.bsize; X bhdr.s_scnptr = 0; X X bias = dhdr.s_scnptr + dhdr.s_size - syms_start; X if (hdr.f_symptr > 0) X hdr.f_symptr += bias; X if (thdr.s_lnnoptr > 0) X thdr.s_lnnoptr += bias; X X if (write (ofd, (char *)&hdr, sizeof (hdr)) != sizeof (hdr)) { Xbadwrite: X Saved_Errno = errno; X close (ofd); X close (afd); X Primitive_Error ("error writing dump file: ~E"); X } X if (write (ofd, (char *)&ohdr, sizeof (ohdr)) != sizeof (ohdr)) X goto badwrite; X if (write (ofd, (char *)&thdr, sizeof (thdr)) != sizeof (thdr)) X goto badwrite; X if (write (ofd, (char *)&dhdr, sizeof (dhdr)) != sizeof (dhdr)) X goto badwrite; X if (write (ofd, (char *)&bhdr, sizeof (bhdr)) != sizeof (bhdr)) X goto badwrite; X lseek (ofd, (long)text_scn_start, 0); X if (write (ofd, (char *)ohdr.text_start, ohdr.tsize) != ohdr.tsize) X goto badwrite; X dumped = 1; X lseek (ofd, (long)data_scn_start, 0); X if (write (ofd, (char *)ohdr.data_start, ohdr.dsize) != ohdr.dsize) X goto badwrite; X lseek (afd, lnno_start ? (long)lnno_start : (long)syms_start, 0); X#else X close (afd); X data_start = hdr.a_text; X data_start = (data_start + SEGMENT_SIZE-1) & ~(SEGMENT_SIZE-1); X data_end = (unsigned)sbrk (0); X data_end = (data_end + pagemask) & ~pagemask; X hdr.a_data = data_end - data_start; X hdr.a_bss = 0; X hdr.a_trsize = hdr.a_drsize = 0; X X afn = Loader_Input; X if (afn[0] == 0) X afn = myname; X if ((afd = open (afn, 0)) == -1) { X Saved_Errno = errno; X close (ofd); X Primitive_Error ("cannot open symbol table file: ~E"); X } X if (read (afd, (char *)&shdr, sizeof (shdr)) != sizeof (shdr) X || N_BADMAG(shdr)) { X close (ofd); X close (afd); X Primitive_Error ("corrupt symbol table file"); X } X hdr.a_syms = shdr.a_syms; X X if (write (ofd, (char *)&hdr, sizeof (hdr)) != sizeof(hdr)) { Xbadwrite: X Saved_Errno = errno; X close (ofd); X close (afd); X Primitive_Error ("error writing dump file: ~E"); X } X X (void)lseek (ofd, (long)FILE_TEXT_START, 0); X n = hdr.a_text - TEXT_LENGTH_ADJ; X if (write (ofd, (char *)MEM_TEXT_START, n) != n) X goto badwrite; X dumped = 1; X if (Heap_Start > Free_Start) { X n = (unsigned)Free_Start - data_start; X if (write (ofd, (char *)data_start, n) != n) X goto badwrite; X (void)lseek (ofd, (long)(Free_End - Free_Start), 1); X n = Hp - Heap_Start; X if (write (ofd, Heap_Start, n) != n) X goto badwrite; X (void)lseek (ofd, (long)(Heap_End - Hp), 1); X n = data_end - (unsigned)Heap_End; X if (write (ofd, Heap_End, n) != n) X goto badwrite; X } else { X n = (unsigned)Hp - data_start; X if (write (ofd, (char *)data_start, n) != n) X goto badwrite; X (void)lseek (ofd, (long)(Free_End - Hp), 1); X n = data_end - (unsigned)Free_End; X if (write (ofd, Free_End, n) != n) X goto badwrite; X } X X (void)lseek (afd, (long)N_SYMOFF(shdr), 0); X#endif X while ((n = read (afd, buf, BUFSIZ)) > 0) { X if (write (ofd, buf, n) != n) X goto badwrite; X } X if (n < 0) { X Saved_Errno = errno; X close (ofd); X close (afd); X Primitive_Error ("error reading symbol table: ~E"); X } X close (afd); X if (fstat (ofd, &st) != -1) { X int omask = umask (0); X (void)umask (omask); X#ifdef FCHMOD_BROKEN X { X Object f = PORT(port)->name; X register n = STRING(f)->size; X register char *s = alloca (n+1); X bcopy (STRING(f)->data, s, n); X s[n] = '\0'; X (void)chmod (s, st.st_mode & 0777 | 0111 & ~omask); X } X#else X (void)fchmod (ofd, st.st_mode & 0777 | 0111 & ~omask); X#endif X } X close (ofd); X Enable_Interrupts; X return False; X} X#endif END_OF_src/dump.c if test 6831 -ne `wc -c <src/dump.c`; then echo shar: \"src/dump.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f src/type.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"src/type.c\" else echo shar: Extracting \"src/type.c\" \(2756 characters\) sed "s/^X//" >src/type.c <<'END_OF_src/type.c' X/* Types X */ X X#include "scheme.h" X X/*ARGSUSED*/ XDummy_Visit (p, fp) Object *p, (*fp)(); { X Panic ("Dummy_Visit"); X} X X/* User-defined types must be greater than T_Last and less than MAX_TYPE. X */ XTYPEDESCR Types[MAX_TYPE] = { X { 0, "integer", 0, 0, 0, 0, 0, 0, }, X { 1, "integer", /*bignum*/ 0, 0, 0, 0, 0, 0, }, X { 1, "real", 0, 0, 0, 0, 0, 0, }, X { 0, "null", 0, 0, 0, 0, 0, 0, }, X { 0, "boolean", 0, 0, 0, 0, 0, 0, }, X { 0, "void", 0, 0, 0, 0, 0, 0, }, X { 0, "unbound", 0, 0, 0, 0, 0, 0, }, X { 0, "special", 0, 0, 0, 0, 0, 0, }, X { 0, "character", 0, 0, 0, 0, 0, 0, }, X { 1, "symbol", 0, 0, 0, 0, 0, Dummy_Visit, }, X { 1, "pair", 0, 0, 0, 0, 0, Dummy_Visit, }, X { 1, "environment", 0, 0, 0, 0, 0, Dummy_Visit, }, X { 1, "string", 0, 0, 0, 0, 0, 0, }, X { 1, "vector", 0, 0, 0, 0, 0, Dummy_Visit, }, X { 1, "primitive", 0, 0, 0, 0, 0, 0, }, X { 1, "compound", 0, 0, 0, 0, 0, Dummy_Visit, }, X { 1, "control-point", 0, 0, 0, 0, 0, Dummy_Visit, }, X { 1, "promise", 0, 0, 0, 0, 0, Dummy_Visit, }, X { 1, "port", 0, 0, 0, 0, 0, Dummy_Visit, }, X { 0, "end-of-file", 0, 0, 0, 0, 0, 0, }, X { 1, "autoload", 0, 0, 0, 0, 0, Dummy_Visit, }, X { 1, "macro", 0, 0, 0, 0, 0, Dummy_Visit, }, X { 1, "!!broken-heart!!", 0, 0, 0, 0, 0, 0, }, X}; X XWrong_Type (x, t) Object x; register t; { X Wrong_Type_Combination (x, Types[t].name); X} X XWrong_Type_Combination (x, name) Object x; register char *name; { X register t = TYPE(x); X register char *p; X char buf[100]; X X if (t < 0 || t >= MAX_TYPE || !(p = Types[t].name)) X Panic ("bad type"); X sprintf (buf, "wrong argument type %s (expected %s)", p, name); X Primitive_Error (buf); X} X XObject P_Type (x) Object x; { X register t = TYPE(x); X register char *p; X X if (t < 0 || t >= MAX_TYPE || !(p = Types[t].name)) X Panic ("bad type"); X return Intern (p); X} X XDefine_Type (t, name, size, const_size, eqv, equal, print, visit) register t; X char *name; X int (*size)(), (*eqv)(), (*equal)(), (*print)(), (*visit)(); { X register TYPEDESCR *p; X X Error_Tag = "define-type"; X if (t == 0) { X for (t = T_Last+1; t < MAX_TYPE && Types[t].name; t++) X ; X if (t == MAX_TYPE) X Primitive_Error ("out of types"); X } else { X if (t < 0 || t >= MAX_TYPE) X Primitive_Error ("bad type"); X if (Types[t].name) X Primitive_Error ("type already in use"); X } X p = &Types[t]; X p->haspointer = 1; /* Assumption */ X p->name = name; X p->size = size; X p->const_size = const_size; X p->eqv = eqv; X p->equal = equal; X p->print = print; X p->visit = visit; X return t; X} X XObject P_Voidp (x) Object x; { /* Don't know a better place for this. */ X return TYPE(x) == T_Void ? True : False; X} END_OF_src/type.c if test 2756 -ne `wc -c <src/type.c`; then echo shar: \"src/type.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f src/bool.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"src/bool.c\" else echo shar: Extracting \"src/bool.c\" \(2385 characters\) sed "s/^X//" >src/bool.c <<'END_OF_src/bool.c' X/* Booleans, Equality/Equivalence X */ X X#include "scheme.h" X XObject P_Booleanp (x) Object x; { X return TYPE(x) == T_Boolean ? True : False; X} X XObject P_Not (x) Object x; { X return Truep (x) ? False : True; X} X XObject P_Eq (x1, x2) Object x1, x2; { X return EQ(x1, x2) ? True : False; X} X XObject P_Eqv (x1, x2) Object x1, x2; { X return Eqv (x1, x2) ? True : False; X} X XObject P_Equal (x1, x2) Object x1, x2; { X return Equal (x1, x2) ? True : False; X} X XEqv (x1, x2) Object x1, x2; { X register t1, t2; X if (EQ(x1, x2)) X return 1; X t1 = TYPE(x1); X t2 = TYPE(x2); X if (Numeric (t1) && Numeric (t2)) X return Generic_Equal (x1, x2); X if (t1 != t2) X return 0; X switch (t1) { X case T_String: X return STRING(x1)->size == 0 && STRING(x2)->size == 0; X case T_Vector: X return VECTOR(x1)->size == 0 && VECTOR(x2)->size == 0; X case T_Primitive: X return strcmp (PRIM(x1)->name, PRIM(x2)->name) == 0; X default: X if (t1 < 0 || t1 >= MAX_TYPE || !Types[t1].name) X Panic ("bad type in eqv"); X if (Types[t1].eqv == NOFUNC) X return 0; X return (*Types[t1].eqv)(x1, x2); X } X /*NOTREACHED*/ X} X XEqual (x1, x2) Object x1, x2; { X register t1, t2, i; X Xagain: X if (EQ(x1, x2)) X return 1; X t1 = TYPE(x1); X t2 = TYPE(x2); X if (Numeric (t1) && Numeric (t2)) X return Generic_Equal (x1, x2); X if (t1 != t2) X return 0; X switch (t1) { X case T_Boolean: X case T_Character: X case T_Compound: X case T_Control_Point: X case T_Promise: X case T_Port: X case T_Macro: X return 0; X case T_Primitive: X return Eqv (x1, x2); X case T_Symbol: X return Equal (SYMBOL(x1)->name, SYMBOL(x2)->name) && X Equal (SYMBOL(x1)->plist, SYMBOL(x2)->plist); X case T_Environment: X case T_Pair: X if (!Equal (Car (x1), Car (x2))) X return 0; X x1 = Cdr (x1); x2 = Cdr (x2); X goto again; X case T_String: X return STRING(x1)->size == STRING(x2)->size && X bcmp (STRING(x1)->data, STRING(x2)->data, STRING(x1)->size) == 0; X case T_Vector: X if (VECTOR(x1)->size != VECTOR(x2)->size) X return 0; X for (i = 0; i < VECTOR(x1)->size; i++) X if (!Equal (VECTOR(x1)->data[i], VECTOR(x2)->data[i])) X return 0; X return 1; X default: X if (t1 < 0 || t1 >= MAX_TYPE || !Types[t1].name) X Panic ("bad type in equal"); X if (Types[t1].equal == NOFUNC) X return 0; X return (*Types[t1].equal)(x1, x2); X } X /*NOTREACHED*/ X} END_OF_src/bool.c if test 2385 -ne `wc -c <src/bool.c`; then echo shar: \"src/bool.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f src/bignum.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"src/bignum.c\" else echo shar: Extracting \"src/bignum.c\" \(15711 characters\) sed "s/^X//" >src/bignum.c <<'END_OF_src/bignum.c' X/* Bignum arithmetic X */ X X#include <math.h> X#include <ctype.h> X X#include "scheme.h" X XObject Make_Uninitialized_Bignum (size) { X register char *p; X Object big; X X p = Get_Bytes ((sizeof (struct S_Bignum) - sizeof (gran_t)) + X (size * sizeof (gran_t))); X SET(big, T_Bignum, (struct S_Bignum *)p); X BIGNUM(big)->minusp = False; X BIGNUM(big)->size = size; X BIGNUM(big)->usize = 0; X return big; X} X XObject Copy_Bignum (x) Object x; { X Object big; X register size; X GC_Node; X X GC_Link (x); X big = Make_Uninitialized_Bignum (size = BIGNUM(x)->usize); X BIGNUM(big)->minusp = BIGNUM(x)->minusp; X BIGNUM(big)->usize = size; X bcopy ((char *)BIGNUM(x)->data, (char *)BIGNUM(big)->data, X size * sizeof (gran_t)); X GC_Unlink; X return big; X} X XObject Copy_S_Bignum (s) struct S_Bignum *s; { X Object big; X register size; X X big = Make_Uninitialized_Bignum (size = s->usize); X BIGNUM(big)->minusp = s->minusp; X BIGNUM(big)->usize = size; X bcopy ((char *)s->data, (char *)BIGNUM(big)->data, X size * sizeof (gran_t)); X return big; X} X XObject Make_Bignum (buf, neg, base) char *buf; { X Object big; X register char *p; X register c; X register size = (strlen (buf) + 4) / 4; X X big = Make_Uninitialized_Bignum (size); X BIGNUM(big)->minusp = neg ? True : False; X p = buf; X while (c = *p++) { X Bignum_Mult_In_Place (BIGNUM(big), base); X if (base == 16) { X if (isupper (c)) X c = tolower (c); X if (c >= 'a') X c = '9' + c - 'a' + 1; X } X Bignum_Add_In_Place (BIGNUM(big), c - '0'); X } X Bignum_Normalize_In_Place (BIGNUM(big)); /* to avoid -0 */ X return big; X} X XObject Reduce_Bignum (x) Object x; { X register i; X register struct S_Bignum *p = BIGNUM(x); X X if (p->usize > 2 || (p->usize == 2 && p->data[1] >= 32768)) X return x; X i = Bignum_To_Integer (x); X if (!FIXNUM_FITS(i)) X return x; X return Make_Fixnum (i); X} X XBignum_Mult_In_Place (x, n) register struct S_Bignum *x; { X register i = x->usize; X register gran_t *p = x->data; X register j; X register unsigned k = 0; X X for (j = 0; j < i; ++j) { X k += n * *p; X *p++ = k; X k >>= 16; X } X if (k) { X if (i >= x->size) X Panic ("Bignum_Mult_In_Place"); X *p++ = k; X x->usize++; X } X} X XBignum_Add_In_Place (x, n) register struct S_Bignum *x; { X register i = x->usize; X register gran_t *p = x->data; X register j = 0; X register unsigned k = n; X X if (i == 0) goto extend; X k += *p; X *p++ = k; X while (k >>= 16) { X if (++j >= i) { X extend: X if (i >= x->size) X Panic ("Bignum_Add_In_Place"); X *p++ = k; X x->usize++; X return; X } X k += *p; X *p++ = k; X } X} X XBignum_Div_In_Place (x, n) register struct S_Bignum *x; { X register i = x->usize; X register gran_t *p = x->data + i; X register unsigned k = 0; X for ( ; i; --i) { X k <<= 16; X k += *--p; X *p = k / n; X k %= n; X } X Bignum_Normalize_In_Place (x); X return k; X} X XBignum_Normalize_In_Place (x) register struct S_Bignum *x; { X register i = x->usize; X register gran_t *p = x->data + i; X while (i && !*--p) X --i; X x->usize = i; X if (!i) X x->minusp = False; X} X XPrint_Bignum (port, x) Object port, x; { X register char *buf, *p; X register size; X register struct S_Bignum *big; X X if (Bignum_Zero (x)) { X Printf (port, "0"); X return; X } X X size = BIGNUM(x)->usize * 5 + 3; X buf = alloca (size + 1); X p = buf + size; X *p = 0; X X size = (sizeof (struct S_Bignum) - sizeof (gran_t)) X + BIGNUM(x)->usize * sizeof (gran_t); X big = (struct S_Bignum *)alloca (size); X bcopy ((char *)POINTER(x), (char *)big, size); X big->size = BIGNUM(x)->usize; X X while (big->usize) { X register unsigned bigdig = Bignum_Div_In_Place (big, 10000); X *--p = '0' + bigdig % 10; X bigdig /= 10; X *--p = '0' + bigdig % 10; X bigdig /= 10; X *--p = '0' + bigdig % 10; X bigdig /= 10; X *--p = '0' + bigdig; X } X while (*p == '0') X ++p; X if (Truep (BIGNUM(x)->minusp)) X Printf (port, "-"); X Format (port, p, strlen (p), 0, (Object *)0); X} X XBignum_To_Integer (x) Object x; { X unsigned n = 0; X int s = BIGNUM(x)->usize; X X if (s) { X n = BIGNUM(x)->data[0]; X if (s > 1) { X n |= BIGNUM(x)->data[1] << 16; X if (s > 2) Xerr: X Primitive_Error ("integer out of range: ~s", x); X } X } X if (Truep (BIGNUM(x)->minusp)) { X if (n > (~(unsigned)0 >> 1) + 1) X goto err; X return -n; X } else { X if (n > ~(unsigned)0 >> 1) X goto err; X return n; X } X} X XObject Integer_To_Bignum (i) { X Object big = Make_Uninitialized_Bignum (2); X unsigned n = i; X X if (i < 0) { X BIGNUM(big)->minusp = True; X n = -i; X } X BIGNUM(big)->data[0] = n; X BIGNUM(big)->data[1] = n >> 16; X BIGNUM(big)->usize = 2; X Bignum_Normalize_In_Place (BIGNUM(big)); X return big; X} X XObject Unsigned_To_Bignum (i) unsigned i; { X Object big = Make_Uninitialized_Bignum (2); X X BIGNUM(big)->data[0] = i; X BIGNUM(big)->data[1] = i >> 16; X BIGNUM(big)->usize = 2; X Bignum_Normalize_In_Place (BIGNUM(big)); X return big; X} X XObject Double_To_Bignum (d) double d; { /* Truncates the double */ X Object big; X int expo, size; X double mantissa = frexp (d, &expo); X register gran_t *p; X X if (expo <= 0 || mantissa == 0.0) X return Make_Uninitialized_Bignum (0); X size = (expo + (16-1)) / 16; X big = Make_Uninitialized_Bignum (size); X BIGNUM(big)->usize = size; X if (mantissa < 0.0) { X BIGNUM(big)->minusp = True; X mantissa = -mantissa; X } X p = BIGNUM(big)->data; X bzero ((char *)p, size * sizeof (gran_t)); X p += size; X if (expo &= (16-1)) X mantissa = ldexp (mantissa, expo - 16); X while (mantissa != 0.0) { X if (--size < 0) X break; /* inexact */ X mantissa *= 65536.0; X *--p = (int)mantissa; X mantissa -= *p; X } X Bignum_Normalize_In_Place (BIGNUM(big)); /* Probably not needed */ X return Reduce_Bignum (big); X} X Xdouble Bignum_To_Double (x) Object x; { /* error if it ain't fit */ X double rx = 0.0; X register i = BIGNUM(x)->usize; X register gran_t *p = BIGNUM(x)->data + i; X X for (i = BIGNUM(x)->usize; --i >= 0; ) { X if (rx >= HUGE / 65536.0) X Primitive_Error ("cannot coerce to real: ~s", x); X rx *= 65536.0; X rx += *--p; X } X if (Truep (BIGNUM(x)->minusp)) X rx = -rx; X return rx; X} X XBignum_Zero (x) Object x; { X return BIGNUM(x)->usize == 0; X} X XBignum_Negative (x) Object x; { X return Truep (BIGNUM(x)->minusp); X} X XBignum_Positive (x) Object x; { X return !Truep (BIGNUM(x)->minusp) && BIGNUM(x)->usize != 0; X} X XBignum_Even (x) Object x; { X return BIGNUM(x)->usize == 0 || (BIGNUM(x)->data[0] & 1) == 0; X} X XObject Bignum_Abs (x) Object x; { X Object big; X X big = Copy_Bignum (x); X BIGNUM(big)->minusp = False; X return big; X} X XBignum_Mantissa_Cmp (x, y) register struct S_Bignum *x, *y; { X register i = x->usize; X if (i < y->usize) X return -1; X else if (i > y->usize) X return 1; X else { X register gran_t *xbuf = x->data + i; X register gran_t *ybuf = y->data + i; X for ( ; i; --i) { X register n; X if (n = (int)*--xbuf - (int)*--ybuf) X return n; X } X return 0; X } X} X XBignum_Cmp (x, y) register struct S_Bignum *x, *y; { X register xm = Truep (x->minusp); X register ym = Truep (y->minusp); X if (xm) { X if (ym) X return -Bignum_Mantissa_Cmp (x, y); X else return -1; X } else { X if (ym) X return 1; X else return Bignum_Mantissa_Cmp (x, y); X } X} X XBignum_Equal (x, y) Object x, y; { X return Bignum_Cmp (BIGNUM(x), BIGNUM(y)) == 0; X} X XBignum_Less (x, y) Object x, y; { X return Bignum_Cmp (BIGNUM(x), BIGNUM(y)) < 0; X} X XBignum_Greater (x, y) Object x, y; { X return Bignum_Cmp (BIGNUM(x), BIGNUM(y)) > 0; X} X XBignum_Eq_Less (x, y) Object x, y; { X return Bignum_Cmp (BIGNUM(x), BIGNUM(y)) <= 0; X} X XBignum_Eq_Greater (x, y) Object x, y; { X return Bignum_Cmp (BIGNUM(x), BIGNUM(y)) >= 0; X} X XObject General_Bignum_Plus_Minus (x, y, neg) Object x, y; { X Object big; X int size, xsize, ysize, xminusp, yminusp; X GC_Node2; X X GC_Link2 (x,y); X xsize = BIGNUM(x)->usize; X ysize = BIGNUM(y)->usize; X xminusp = Truep (BIGNUM(x)->minusp); X yminusp = Truep (BIGNUM(y)->minusp); X if (neg) X yminusp = !yminusp; X size = xsize > ysize ? xsize : ysize; X if (xminusp == yminusp) X size++; X big = Make_Uninitialized_Bignum (size); X BIGNUM(big)->usize = size; X GC_Unlink; X X if (xminusp == yminusp) { X /* Add x and y */ X register unsigned k = 0; X register i; X register gran_t *xbuf = BIGNUM(x)->data; X register gran_t *ybuf = BIGNUM(y)->data; X register gran_t *zbuf = BIGNUM(big)->data; X for (i = 0; i < size; ++i) { X if (i < xsize) X k += *xbuf++; X if (i < ysize) X k += *ybuf++; X *zbuf++ = k; X k >>= 16; X } X } else { X if (Bignum_Mantissa_Cmp (BIGNUM(x), BIGNUM(y)) < 0) { X Object temp = x; X x = y; y = temp; X xsize = ysize; X ysize = BIGNUM(y)->usize; X xminusp = yminusp; X } X /* Subtract y from x */ X { X register unsigned k = 1; X register i; X register gran_t *xbuf = BIGNUM(x)->data; X register gran_t *ybuf = BIGNUM(y)->data; X register gran_t *zbuf = BIGNUM(big)->data; X for (i = 0; i < size; ++i) { X if (i < xsize) X k += *xbuf++; X else Panic ("General_Bignum_Plus_Minus"); X if (i < ysize) X k += ~*ybuf++ & 0xFFFF; X else k += 0xFFFF; X *zbuf++ = k; X k >>= 16; X } X } X } X BIGNUM(big)->minusp = xminusp ? True : False; X Bignum_Normalize_In_Place (BIGNUM(big)); X return Reduce_Bignum (big); X} X XObject Bignum_Plus (x, y) Object x, y; { /* bignum + bignum */ X return General_Bignum_Plus_Minus (x, y, 0); X} X XObject Bignum_Minus (x, y) Object x, y; { /* bignum - bignum */ X return General_Bignum_Plus_Minus (x, y, 1); X} X XObject Bignum_Fixnum_Multiply (x, y) Object x, y; { /* bignum * fixnum */ X Object big; X register size, xsize, i; X register gran_t *xbuf, *zbuf; X int yn = FIXNUM(y); X register unsigned yl, yh; X GC_Node; X X GC_Link (x); X xsize = BIGNUM(x)->usize; X size = xsize + 2; X big = Make_Uninitialized_Bignum (size); X BIGNUM(big)->usize = size; X if (Truep (BIGNUM(x)->minusp) != (yn < 0)) X BIGNUM(big)->minusp = True; X bzero ((char *)BIGNUM(big)->data, size * sizeof (gran_t)); X xbuf = BIGNUM(x)->data; X if (yn < 0) X yn = -yn; X yl = yn & 0xFFFF; X yh = yn >> 16; X zbuf = BIGNUM(big)->data; X for (i = 0; i < xsize; ++i) { X register unsigned xf = xbuf[i]; X register unsigned k = 0; X register gran_t *r = zbuf + i; X k += xf * yl + *r; X *r++ = k; X k >>= 16; X k += xf * yh + *r; X *r++ = k; X k >>= 16; X *r = k; X } X GC_Unlink; X Bignum_Normalize_In_Place (BIGNUM(big)); X return Reduce_Bignum (big); X} X XObject Bignum_Multiply (x, y) Object x, y; { /* bignum * bignum */ X Object big; X register size, xsize, ysize, i, j; X register gran_t *xbuf, *ybuf, *zbuf; X GC_Node2; X X GC_Link2 (x, y); X xsize = BIGNUM(x)->usize; X ysize = BIGNUM(y)->usize; X size = xsize + ysize; X big = Make_Uninitialized_Bignum (size); X BIGNUM(big)->usize = size; X if (!EQ(BIGNUM(x)->minusp, BIGNUM(y)->minusp)) X BIGNUM(big)->minusp = True; X bzero ((char *)BIGNUM(big)->data, size * sizeof (gran_t)); X xbuf = BIGNUM(x)->data; X ybuf = BIGNUM(y)->data; X zbuf = BIGNUM(big)->data; X for (i = 0; i < xsize; ++i) { X register unsigned xf = xbuf[i]; X register unsigned k = 0; X register gran_t *p = ybuf; X register gran_t *r = zbuf + i; X for (j = 0; j < ysize; ++j) { X k += xf * *p++ + *r; X *r++ = k; X k >>= 16; X } X *r = k; X } X GC_Unlink; X Bignum_Normalize_In_Place (BIGNUM(big)); X return Reduce_Bignum (big); X} X X/* Returns cons cell (quotient . remainder); cdr is a fixnum X */ XObject Bignum_Fixnum_Divide (x, y) Object x, y; { /* bignum / fixnum */ X Object big; X register xsize, i; X register gran_t *xbuf, *zbuf; X int yn = FIXNUM(y); X int xminusp, yminusp = 0; X register unsigned rem; X GC_Node; X X GC_Link (x); X if (yn < 0) { X yn = -yn; X yminusp = 1; X } X if (yn > 0xFFFF) { X big = Integer_To_Bignum (FIXNUM(y)); X GC_Unlink; X return Bignum_Divide (x, big); X } X xsize = BIGNUM(x)->usize; X big = Make_Uninitialized_Bignum (xsize); X BIGNUM(big)->usize = xsize; X xminusp = Truep (BIGNUM(x)->minusp); X if (xminusp != yminusp) X BIGNUM(big)->minusp = True; X xbuf = BIGNUM(x)->data; X zbuf = BIGNUM(big)->data; X rem = 0; X for (i = xsize; --i >= 0; ) { X rem <<= 16; X rem += xbuf[i]; X zbuf[i] = rem / yn; X rem %= yn; X } X GC_Unlink; X Bignum_Normalize_In_Place (BIGNUM(big)); X if (xminusp) X rem = -(int)rem; X return Cons (Reduce_Bignum (big), Make_Fixnum ((int)rem)); X} X X/* Returns cons cell (quotient . remainder); cdr is a fixnum X */ XObject Bignum_Divide (x, y) Object x, y; { /* bignum / bignum */ X struct S_Bignum *dend, *dor; X int quotsize, dendsize, dorsize, scale; X unsigned dor1, dor2; X Object quot, rem; X register gran_t *qp, *dendp; X GC_Node2; X X if (BIGNUM(y)->usize < 2) X return Bignum_Fixnum_Divide (x, Make_Fixnum (Bignum_To_Integer (y))); X X GC_Link2 (x, y); X quotsize = BIGNUM(x)->usize - BIGNUM(y)->usize + 1; X if (quotsize < 0) X quotsize = 0; X quot = Make_Uninitialized_Bignum (quotsize); X GC_Unlink; X X dendsize = (sizeof (struct S_Bignum) - sizeof (gran_t)) X + (BIGNUM(x)->usize + 1) * sizeof (gran_t); X dend = (struct S_Bignum *)alloca (dendsize); X bcopy ((char *)POINTER(x), (char *)dend, dendsize); X dend->size = BIGNUM(x)->usize + 1; X X if (quotsize == 0 || Bignum_Mantissa_Cmp (dend, BIGNUM(y)) < 0) X goto zero; X X dorsize = (sizeof (struct S_Bignum) - sizeof (gran_t)) X + BIGNUM (y)->usize * sizeof (gran_t); X dor = (struct S_Bignum *)alloca (dorsize); X bcopy ((char *)POINTER(y), (char *)dor, dorsize); X dor->size = dorsize = BIGNUM(y)->usize; X X scale = 65536 / (dor->data[dor->usize - 1] + 1); X Bignum_Mult_In_Place (dend, scale); X if (dend->usize < dend->size) X dend->data[dend->usize++] = 0; X Bignum_Mult_In_Place (dor, scale); X X BIGNUM(quot)->usize = BIGNUM(quot)->size; X qp = BIGNUM(quot)->data + BIGNUM(quot)->size; X dendp = dend->data + dend->usize; X dor1 = dor->data[dor->usize - 1]; X dor2 = dor->data[dor->usize - 2]; X X while (qp > BIGNUM(quot)->data) { X unsigned msw, guess; X int k; X register gran_t *dep, *dop, *edop; X X msw = dendp[-1] << 16 | dendp[-2]; X guess = msw / dor1; X if (guess >= 65536) /* [65535, 0, 0] / [65535, 65535] */ X guess = 65535; X for (;;) { X unsigned d1, d2, d3; X d3 = dor2 * guess; X d2 = dor1 * guess + (d3 >> 16); X d3 &= 0xFFFF; X d1 = d2 >> 16; X d2 &= 0xFFFF; X if (d1 < dendp[-1] || (d1 == dendp[-1] && X (d2 < dendp[-2] || (d2 == dendp[-2] && X d3 <= dendp[-3])))) X break; X --guess; X } X --dendp; X k = 0; X dep = dendp - dorsize; X for (dop = dor->data, edop = dop + dor->usize; dop < edop; ) { X register unsigned prod = *dop++ * guess; X k += *dep; X k -= prod & 0xFFFF; X *dep++ = k; X k >>= 16; X k -= prod >> 16; X } X k += *dep; X *dep = k; X if (k < 0) { X k = 0; X dep = dendp - dorsize; X for (dop = dor->data, edop = dop + dor->usize; dop < edop; ) { X k += *dep + *dop++; X *dep++ = k; X k >>= 16; X } X k += *dep; X *dep = k; X --guess; X } X *--qp = guess; X } X X if (Bignum_Div_In_Place (dend, scale)) X Panic ("Bignum_Div scale"); X zero: X if (Truep (dend->minusp = BIGNUM(x)->minusp) != Truep (BIGNUM(y)->minusp)) X BIGNUM(quot)->minusp = True; X Bignum_Normalize_In_Place (BIGNUM(quot)); X Bignum_Normalize_In_Place (dend); X GC_Link (quot); X rem = Reduce_Bignum (Copy_S_Bignum (dend)); X GC_Unlink; X return Cons (Reduce_Bignum (quot), rem); X} END_OF_src/bignum.c if test 15711 -ne `wc -c <src/bignum.c`; then echo shar: \"src/bignum.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f src/alloca.s.386 -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"src/alloca.s.386\" else echo shar: Extracting \"src/alloca.s.386\" \(125 characters\) sed "s/^X//" >src/alloca.s.386 <<'END_OF_src/alloca.s.386' X .file "alloca.s" X .globl alloca X Xalloca: X popl %edx X subl 0(%esp),%esp X andl $0xfffffffc,%esp X leal 4(%esp),%eax X jmp *%edx END_OF_src/alloca.s.386 if test 125 -ne `wc -c <src/alloca.s.386`; then echo shar: \"src/alloca.s.386\" unpacked with wrong size! fi # end of overwriting check fi if test ! -d tst ; then echo shar: Creating directory \"tst\" mkdir tst fi echo shar: End of archive 6 \(of 14\). cp /dev/null ark6isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 14 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0