--- microscheme/scheme.c 2015/11/27 04:37:26 1.25 +++ microscheme/scheme.c 2015/11/28 05:13:08 1.27 @@ -184,12 +184,12 @@ enum scheme_types { - T_FREE, + T_INTEGER, + T_REAL, T_STRING, - T_NUMBER, T_SYMBOL, T_PROC, - T_PAIR, + T_PAIR, /* also used for free cells */ T_CLOSURE, T_CONTINUATION, T_FOREIGN, @@ -209,6 +209,32 @@ #define T_ATOM 0x0040 /* only for gc */ #define T_MARK 0x0080 /* only for gc */ +/* num, for generic arithmetic */ +struct num +{ + IVALUE ivalue; +#if USE_REAL + RVALUE rvalue; + char is_fixnum; +#endif +}; + +#if USE_REAL +# define num_is_fixnum(n) (n).is_fixnum +# define num_set_fixnum(n,f) (n).is_fixnum = (f) +# define num_ivalue(n) (n).ivalue +# define num_rvalue(n) (n).rvalue +# define num_set_ivalue(n,i) (n).rvalue = (n).ivalue = (i) +# define num_set_rvalue(n,r) (n).rvalue = (r) +#else +# define num_is_fixnum(n) 1 +# define num_set_fixnum(n,f) 0 +# define num_ivalue(n) (n).ivalue +# define num_rvalue(n) (n).ivalue +# define num_set_ivalue(n,i) (n).ivalue = (i) +# define num_set_rvalue(n,r) (n).ivalue = (r) +#endif + enum num_op { NUM_ADD, NUM_SUB, NUM_MUL, NUM_INTDIV }; static num num_op (enum num_op op, num a, num b); @@ -238,8 +264,6 @@ #define strvalue(p) ((p)->object.string.svalue) #define strlength(p) ((p)->object.string.length) -INTERFACE int is_list (SCHEME_P_ pointer p); - INTERFACE int is_vector (pointer p) { @@ -260,21 +284,22 @@ } INTERFACE int -is_number (pointer p) +is_integer (pointer p) { - return type (p) == T_NUMBER; + return type (p) == T_INTEGER; } +/* not the same as in scheme, where integers are (correctly :) reals */ INTERFACE int -is_integer (pointer p) +is_real (pointer p) { - return is_number (p) && num_is_fixnum (p->object.number); + return type (p) == T_REAL; } INTERFACE int -is_real (pointer p) +is_number (pointer p) { - return is_number (p) && !num_is_fixnum (p->object.number); + return is_integer (p) || is_real (p); } INTERFACE int @@ -289,45 +314,15 @@ return strvalue (p); } -ecb_inline num -nvalue (pointer p) -{ - return (p)->object.number; -} +#define ivalue_unchecked(p) (p)->object.ivalue +#define set_ivalue(p,v) (p)->object.ivalue = (v) -static IVALUE -num_get_ivalue (const num n) -{ - return num_is_fixnum (n) ? num_ivalue (n) : (IVALUE)num_rvalue (n); -} - -static RVALUE -num_get_rvalue (const num n) -{ - return num_is_fixnum (n) ? (RVALUE)num_ivalue (n) : num_rvalue (n); -} - -INTERFACE IVALUE -ivalue (pointer p) -{ - return num_get_ivalue (p->object.number); -} - -INTERFACE RVALUE -rvalue (pointer p) -{ - return num_get_rvalue (p->object.number); -} - -#define ivalue_unchecked(p) ((p)->object.number.value.ivalue) #if USE_REAL -# define rvalue_unchecked(p) ((p)->object.number.value.rvalue) -# define set_num_integer(p) (p)->object.number.is_fixnum=1; -# define set_num_real(p) (p)->object.number.is_fixnum=0; +#define rvalue_unchecked(p) (p)->object.rvalue +#define set_rvalue(p,v) (p)->object.rvalue = (v) #else -# define rvalue_unchecked(p) ((p)->object.number.value.ivalue) -# define set_num_integer(p) 0 -# define set_num_real(p) 0 +#define rvalue_unchecked(p) (p)->object.ivalue +#define set_rvalue(p,v) (p)->object.ivalue = (v) #endif INTERFACE long @@ -442,7 +437,7 @@ return strvalue (car (p)); } -#define procnum(p) ivalue (p) +#define procnum(p) ivalue_unchecked (p) static const char *procname (pointer x); INTERFACE int @@ -515,6 +510,60 @@ #endif } +/* Result is: + proper list: length + circular list: -1 + not even a pair: -2 + dotted list: -2 minus length before dot +*/ +INTERFACE int +list_length (SCHEME_P_ pointer a) +{ + int i = 0; + pointer slow, fast; + + slow = fast = a; + + while (1) + { + if (fast == NIL) + return i; + + if (!is_pair (fast)) + return -2 - i; + + fast = cdr (fast); + ++i; + + if (fast == NIL) + return i; + + if (!is_pair (fast)) + return -2 - i; + + ++i; + fast = cdr (fast); + + /* Safe because we would have already returned if `fast' + encountered a non-pair. */ + slow = cdr (slow); + + if (fast == slow) + { + /* the fast pointer has looped back around and caught up + with the slow pointer, hence the structure is circular, + not of finite length, and therefore not a list */ + return -1; + } + } +} + +INTERFACE int +is_list (SCHEME_P_ pointer a) +{ + return list_length (SCHEME_A_ a) >= 0; +} + #if USE_CHAR_CLASSIFIERS ecb_inline int Cisalpha (int c) @@ -666,6 +715,33 @@ static int syntaxnum (pointer p); static void assign_proc (SCHEME_P_ enum scheme_opcodes, const char *name); +static IVALUE +ivalue (pointer x) +{ + return is_integer (x) ? ivalue_unchecked (x) : rvalue_unchecked (x); +} + +static RVALUE +rvalue (pointer x) +{ + return is_integer (x) ? ivalue_unchecked (x) : rvalue_unchecked (x); +} + +INTERFACE num +nvalue (pointer x) +{ + num n; + + num_set_fixnum (n, is_integer (x)); + + if (num_is_fixnum (n)) + num_set_ivalue (n, ivalue_unchecked (x)); + else + num_set_rvalue (n, rvalue_unchecked (x)); + + return n; +} + static num num_op (enum num_op op, num a, num b) { @@ -675,34 +751,30 @@ if (num_is_fixnum (ret)) { - IVALUE av = num_get_ivalue (a); - IVALUE bv = num_get_ivalue (b); - switch (op) { - case NUM_ADD: av += bv; break; - case NUM_SUB: av -= bv; break; - case NUM_MUL: av *= bv; break; - case NUM_INTDIV: av /= bv; break; + case NUM_ADD: a.ivalue += b.ivalue; break; + case NUM_SUB: a.ivalue -= b.ivalue; break; + case NUM_MUL: a.ivalue *= b.ivalue; break; + case NUM_INTDIV: a.ivalue /= b.ivalue; break; } - num_set_ivalue (ret, av); + num_set_ivalue (ret, a.ivalue); } +#if USE_REAL else { - RVALUE av = num_get_rvalue (a); - RVALUE bv = num_get_rvalue (b); - switch (op) { - case NUM_ADD: av += bv; break; - case NUM_SUB: av -= bv; break; - case NUM_MUL: av *= bv; break; - case NUM_INTDIV: av /= bv; break; + case NUM_ADD: a.rvalue += b.rvalue; break; + case NUM_SUB: a.rvalue -= b.rvalue; break; + case NUM_MUL: a.rvalue *= b.rvalue; break; + case NUM_INTDIV: a.rvalue /= b.rvalue; break; } - num_set_rvalue (ret, av); + num_set_rvalue (ret, a.rvalue); } +#endif return ret; } @@ -712,12 +784,12 @@ { num ret; - num_set_fixnum (ret, num_is_fixnum (a) && num_is_fixnum (b) && num_get_ivalue (a) % num_get_ivalue (b) == 0); + num_set_fixnum (ret, num_is_fixnum (a) && num_is_fixnum (b) && num_ivalue (a) % num_ivalue (b) == 0); if (num_is_fixnum (ret)) - num_set_ivalue (ret, num_get_ivalue (a) / num_get_ivalue (b)); + num_set_ivalue (ret, num_ivalue (a) / num_ivalue (b)); else - num_set_rvalue (ret, num_get_rvalue (a) / num_get_rvalue (b)); + num_set_rvalue (ret, num_rvalue (a) / num_rvalue (b)); return ret; } @@ -729,8 +801,8 @@ long e1, e2, res; num_set_fixnum (ret, num_is_fixnum (a) && num_is_fixnum (b)); - e1 = num_get_ivalue (a); - e2 = num_get_ivalue (b); + e1 = num_ivalue (a); + e2 = num_ivalue (b); res = e1 % e2; /* remainder should have same sign as second operand */ @@ -756,8 +828,8 @@ long e1, e2, res; num_set_fixnum (ret, num_is_fixnum (a) && num_is_fixnum (b)); - e1 = num_get_ivalue (a); - e2 = num_get_ivalue (b); + e1 = num_ivalue (a); + e2 = num_ivalue (b); res = e1 % e2; /* modulo should have same sign as second operand */ @@ -777,15 +849,15 @@ if (is_fixnum) { - IVALUE av = num_get_ivalue (a); - IVALUE bv = num_get_ivalue (b); + IVALUE av = num_ivalue (a); + IVALUE bv = num_ivalue (b); ret = av == bv ? 0 : av < bv ? -1 : +1; } else { - RVALUE av = num_get_rvalue (a); - RVALUE bv = num_get_rvalue (b); + RVALUE av = num_rvalue (a); + RVALUE bv = num_rvalue (b); ret = av == bv ? 0 : av < bv ? -1 : +1; } @@ -882,7 +954,7 @@ for (p = newp; p <= last; p++) { - set_typeflag (p, T_FREE); + set_typeflag (p, T_PAIR); set_car (p, NIL); set_cdr (p, p + 1); } @@ -1183,41 +1255,48 @@ pointer x = get_cell (SCHEME_A_ NIL, NIL); set_typeflag (x, (T_CHARACTER | T_ATOM)); - ivalue_unchecked (x) = c & 0xff; - set_num_integer (x); + set_ivalue (x, c & 0xff); + return x; } /* get number atom (integer) */ INTERFACE pointer -mk_integer (SCHEME_P_ long num) +mk_integer (SCHEME_P_ long n) { pointer x = get_cell (SCHEME_A_ NIL, NIL); - set_typeflag (x, (T_NUMBER | T_ATOM)); - ivalue_unchecked (x) = num; - set_num_integer (x); + set_typeflag (x, (T_INTEGER | T_ATOM)); + set_ivalue (x, n); + return x; } INTERFACE pointer mk_real (SCHEME_P_ RVALUE n) { +#if USE_REAL pointer x = get_cell (SCHEME_A_ NIL, NIL); - set_typeflag (x, (T_NUMBER | T_ATOM)); - rvalue_unchecked (x) = n; - set_num_real (x); + set_typeflag (x, (T_REAL | T_ATOM)); + set_rvalue (x, n); + return x; +#else + return mk_integer (SCHEME_A_ n); +#endif } static pointer mk_number (SCHEME_P_ const num n) { - if (num_is_fixnum (n)) - return mk_integer (SCHEME_A_ num_get_ivalue (n)); - else - return mk_real (SCHEME_A_ num_get_rvalue (n)); +#if USE_REAL + return num_is_fixnum (n) + ? mk_integer (SCHEME_A_ num_ivalue (n)) + : mk_real (SCHEME_A_ num_rvalue (n)); +#else + return mk_integer (SCHEME_A_ num_ivalue (n)); +#endif } /* allocate name to string area */ @@ -1403,8 +1482,7 @@ { if (!has_fp_exp) { - has_dec_point = 1; /* decimal point illegal - from now on */ + has_dec_point = 1; /* decimal point illegal from now on */ p++; if ((*p == '-') || (*p == '+') || isdigit (*p)) @@ -1610,10 +1688,10 @@ else { /* reclaim cell */ - if (typeflag (p) != T_FREE) + if (typeflag (p) != T_PAIR) { finalize_cell (SCHEME_A_ p); - set_typeflag (p, T_FREE); + set_typeflag (p, T_PAIR); set_car (p, NIL); } @@ -1625,7 +1703,9 @@ } if (SCHEME_V->gc_verbose) - xwrstr ("done: "); xwrnum (SCHEME_V->fcells); xwrstr (" cells were recovered.\n"); + { + xwrstr ("done: "); xwrnum (SCHEME_V->fcells); xwrstr (" cells were recovered.\n"); + } } static void @@ -3121,10 +3201,10 @@ while (cont != NIL) { - frame->op = ivalue (car (cont)); cont = cdr (cont); - frame->args = car (cont) ; cont = cdr (cont); - frame->envir = car (cont) ; cont = cdr (cont); - frame->code = car (cont) ; cont = cdr (cont); + frame->op = ivalue_unchecked (car (cont)); cont = cdr (cont); + frame->args = car (cont) ; cont = cdr (cont); + frame->envir = car (cont) ; cont = cdr (cont); + frame->code = car (cont) ; cont = cdr (cont); ++frame; ++i; @@ -3163,10 +3243,10 @@ if (dump == NIL) return -1; - SCHEME_V->op = ivalue (car (dump)); dump = cdr (dump); - SCHEME_V->args = car (dump) ; dump = cdr (dump); - SCHEME_V->envir = car (dump) ; dump = cdr (dump); - SCHEME_V->code = car (dump) ; dump = cdr (dump); + SCHEME_V->op = ivalue_unchecked (car (dump)); dump = cdr (dump); + SCHEME_V->args = car (dump) ; dump = cdr (dump); + SCHEME_V->envir = car (dump) ; dump = cdr (dump); + SCHEME_V->code = car (dump) ; dump = cdr (dump); SCHEME_V->dump = dump; @@ -3382,7 +3462,7 @@ { int tr = SCHEME_V->tracing; - SCHEME_V->tracing = ivalue (car (args)); + SCHEME_V->tracing = ivalue_unchecked (car (args)); s_return (mk_integer (SCHEME_A_ tr)); } @@ -3911,20 +3991,21 @@ pointer x = car (args); num v; -#if USE_MATH - RVALUE dd; -#endif - switch (op) { #if USE_MATH case OP_INEX2EX: /* inexact->exact */ - if (is_integer (x)) - s_return (x); - else if (modf (rvalue_unchecked (x), &dd) == 0) - s_return (mk_integer (SCHEME_A_ ivalue (x))); - else - Error_1 ("inexact->exact: not integral:", x); + { + if (is_integer (x)) + s_return (x); + + RVALUE r = rvalue_unchecked (x); + + if (r == (RVALUE)(IVALUE)r) + s_return (mk_integer (SCHEME_A_ rvalue_unchecked (x))); + else + Error_1 ("inexact->exact: not integral:", x); + } case OP_EXP: s_return (mk_real (SCHEME_A_ exp (rvalue (x)))); case OP_LOG: s_return (mk_real (SCHEME_A_ log (rvalue (x)))); @@ -3968,7 +4049,7 @@ { long result_as_long = result; - if (result != (RVALUE) result_as_long) + if (result != result_as_long) real_result = 1; } @@ -3983,18 +4064,12 @@ case OP_TRUNCATE: { - RVALUE rvalue_of_x; - - rvalue_of_x = rvalue (x); - - if (rvalue_of_x > 0) - s_return (mk_real (SCHEME_A_ floor (rvalue_of_x))); - else - s_return (mk_real (SCHEME_A_ ceil (rvalue_of_x))); + RVALUE n = rvalue (x); + s_return (mk_real (SCHEME_A_ n > 0 ? floor (n) : ceil (n))); } case OP_ROUND: - if (num_is_integer (x)) + if (is_integer (x)) s_return (x); s_return (mk_real (SCHEME_A_ round_per_R5RS (rvalue (x)))); @@ -4124,21 +4199,21 @@ Error_0 ("set-cdr!: unable to alter immutable pair"); case OP_CHAR2INT: /* char->integer */ - s_return (mk_integer (SCHEME_A_ ivalue (x))); + s_return (mk_integer (SCHEME_A_ ivalue_unchecked (x))); case OP_INT2CHAR: /* integer->char */ - s_return (mk_character (SCHEME_A_ ivalue (x))); + s_return (mk_character (SCHEME_A_ ivalue_unchecked (x))); case OP_CHARUPCASE: { - unsigned char c = ivalue (x); + unsigned char c = ivalue_unchecked (x); c = toupper (c); s_return (mk_character (SCHEME_A_ c)); } case OP_CHARDNCASE: { - unsigned char c = ivalue (x); + unsigned char c = ivalue_unchecked (x); c = tolower (c); s_return (mk_character (SCHEME_A_ c)); } @@ -4225,13 +4300,8 @@ case OP_MKSTRING: /* make-string */ { - int fill = ' '; - int len; - - len = ivalue (x); - - if (cdr (args) != NIL) - fill = charvalue (cadr (args)); + int fill = cdr (args) != NIL ? charvalue (cadr (args)) : ' '; + int len = ivalue_unchecked (x); s_return (mk_empty_string (SCHEME_A_ len, fill)); } @@ -4241,12 +4311,8 @@ case OP_STRREF: /* string-ref */ { - char *str; - int index; - - str = strvalue (x); - - index = ivalue (cadr (args)); + char *str = strvalue (x); + int index = ivalue_unchecked (cadr (args)); if (index >= strlength (x)) Error_1 ("string-ref: out of bounds:", cadr (args)); @@ -4256,17 +4322,13 @@ case OP_STRSET: /* string-set! */ { - char *str; - int index; + char *str = strvalue (x); + int index = ivalue_unchecked (cadr (args)); int c; if (is_immutable (x)) Error_1 ("string-set!: unable to alter immutable string:", x); - str = strvalue (x); - - index = ivalue (cadr (args)); - if (index >= strlength (x)) Error_1 ("string-set!: out of bounds:", cadr (args)); @@ -4298,21 +4360,17 @@ case OP_SUBSTR: /* substring */ { - char *str; - int index0; + char *str = strvalue (x); + int index0 = ivalue_unchecked (cadr (args)); int index1; int len; - str = strvalue (x); - - index0 = ivalue (cadr (args)); - if (index0 > strlength (x)) Error_1 ("substring: start out of bounds:", cadr (args)); if (cddr (args) != NIL) { - index1 = ivalue (caddr (args)); + index1 = ivalue_unchecked (caddr (args)); if (index1 > strlength (x) || index1 < index0) Error_1 ("substring: end out of bounds:", caddr (args)); @@ -4353,10 +4411,8 @@ case OP_MKVECTOR: /* make-vector */ { pointer fill = NIL; - int len; pointer vec; - - len = ivalue (x); + int len = ivalue_unchecked (x); if (cdr (args) != NIL) fill = cadr (args); @@ -4379,9 +4435,7 @@ case OP_VECREF: /* vector-ref */ { - int index; - - index = ivalue (cadr (args)); + int index = ivalue_unchecked (cadr (args)); if (index >= veclength (car (args)) && USE_ERROR_CHECKING) Error_1 ("vector-ref: out of bounds:", cadr (args)); @@ -4391,13 +4445,11 @@ case OP_VECSET: /* vector-set! */ { - int index; + int index = ivalue_unchecked (cadr (args)); if (is_immutable (x)) Error_1 ("vector-set!: unable to alter immutable vector:", x); - index = ivalue (cadr (args)); - if (index >= veclength (car (args)) && USE_ERROR_CHECKING) Error_1 ("vector-set!: out of bounds:", cadr (args)); @@ -4409,60 +4461,6 @@ if (USE_ERROR_CHECKING) abort (); } -INTERFACE int -is_list (SCHEME_P_ pointer a) -{ - return list_length (SCHEME_A_ a) >= 0; -} - -/* Result is: - proper list: length - circular list: -1 - not even a pair: -2 - dotted list: -2 minus length before dot -*/ -INTERFACE int -list_length (SCHEME_P_ pointer a) -{ - int i = 0; - pointer slow, fast; - - slow = fast = a; - - while (1) - { - if (fast == NIL) - return i; - - if (!is_pair (fast)) - return -2 - i; - - fast = cdr (fast); - ++i; - - if (fast == NIL) - return i; - - if (!is_pair (fast)) - return -2 - i; - - ++i; - fast = cdr (fast); - - /* Safe because we would have already returned if `fast' - encountered a non-pair. */ - slow = cdr (slow); - - if (fast == slow) - { - /* the fast pointer has looped back around and caught up - with the slow pointer, hence the structure is circular, - not of finite length, and therefore not a list */ - return -1; - } - } -} - static int opexe_2 (SCHEME_P_ enum scheme_opcodes op) { @@ -4516,11 +4514,11 @@ case OP_CHARP: /* char? */ r = is_character (a) ; break; #if USE_CHAR_CLASSIFIERS - case OP_CHARAP: /* char-alphabetic? */ r = Cisalpha (ivalue (a)); break; - case OP_CHARNP: /* char-numeric? */ r = Cisdigit (ivalue (a)); break; - case OP_CHARWP: /* char-whitespace? */ r = Cisspace (ivalue (a)); break; - case OP_CHARUP: /* char-upper-case? */ r = Cisupper (ivalue (a)); break; - case OP_CHARLP: /* char-lower-case? */ r = Cislower (ivalue (a)); break; + case OP_CHARAP: /* char-alphabetic? */ r = Cisalpha (ivalue_unchecked (a)); break; + case OP_CHARNP: /* char-numeric? */ r = Cisdigit (ivalue_unchecked (a)); break; + case OP_CHARWP: /* char-whitespace? */ r = Cisspace (ivalue_unchecked (a)); break; + case OP_CHARUP: /* char-upper-case? */ r = Cisupper (ivalue_unchecked (a)); break; + case OP_CHARLP: /* char-lower-case? */ r = Cislower (ivalue_unchecked (a)); break; #endif #if USE_PORTS @@ -4731,7 +4729,7 @@ if (!is_pair (args) || !is_number (a)) Error_0 ("new-segment: argument must be a number"); - alloc_cellseg (SCHEME_A_ (int)ivalue (a)); + alloc_cellseg (SCHEME_A_ ivalue (a)); s_return (S_T); @@ -5271,19 +5269,19 @@ typedef int (*test_predicate)(pointer); static int -is_any (pointer p) +tst_any (pointer p) { return 1; } static int -is_nonneg (pointer p) +tst_inonneg (pointer p) { - return ivalue (p) >= 0 && is_integer (p); + return is_integer (p) && ivalue_unchecked (p) >= 0; } static int -tst_is_list (pointer p) +tst_is_list (SCHEME_P_ pointer p) { return p == NIL || is_pair (p); } @@ -5293,22 +5291,21 @@ { test_predicate fct; const char *kind; -} tests[] = -{ - { is_any, 0 }, - { is_string, "string" }, - { is_symbol, "symbol" }, - { is_port, "port" }, - { is_inport, "input port" }, - { is_outport, "output port" }, +} tests[] = { + { tst_any , 0 }, + { is_string , "string" }, + { is_symbol , "symbol" }, + { is_port , "port" }, + { is_inport , "input port" }, + { is_outport , "output port" }, { is_environment, "environment" }, - { is_pair, "pair" }, - { tst_is_list, "pair or '()" }, - { is_character, "character" }, - { is_vector, "vector" }, - { is_number, "number" }, - { is_integer, "integer" }, - { is_nonneg, "non-negative integer" } + { is_pair , "pair" }, + { 0 , "pair or '()" }, + { is_character , "character" }, + { is_vector , "vector" }, + { is_number , "number" }, + { is_integer , "integer" }, + { tst_inonneg , "non-negative integer" } }; #define TST_NONE 0 /* TST_NONE used for built-ins, 0 for internal ops */ @@ -5359,13 +5356,19 @@ uint8_t func; /*dispatch_func func;*//*TODO: maybe optionally keep the pointer, for speed? */ uint8_t builtin; +#if USE_ERROR_CHECKING uint8_t min_arity; uint8_t max_arity; char arg_tests_encoding[3]; +#endif } op_code_info; static const op_code_info dispatch_table[] = { +#if USE_ERROR_CHECKING #define OP_DEF(func,name,minarity,maxarity,argtest,op) { func, sizeof (name) > 1, minarity, maxarity, argtest }, +#else +#define OP_DEF(func,name,minarity,maxarity,argtest,op) { func, sizeof (name) > 1 }, +#endif #include "opdefines.h" #undef OP_DEF {0} @@ -5417,8 +5420,17 @@ j = t[0]; - if (!tests[j - 1].fct (arg)) - break; + /*TODO: tst_is_list has different prototype - fix if other tests acquire same prototype */ + if (j == TST_LIST[0]) + { + if (!tst_is_list (SCHEME_A_ arg)) + break; + } + else + { + if (!tests[j - 1].fct (arg)) + break; + } if (t[1]) /* last test is replicated as necessary */ t++; @@ -5485,7 +5497,6 @@ pointer y = get_cell (SCHEME_A_ NIL, NIL); set_typeflag (y, (T_PROC | T_ATOM)); ivalue_unchecked (y) = op; - set_num_integer (y); return y; }