Beispiel #1
0
CSLbool minusp(Lisp_Object a)
{
    switch ((int)a & TAG_BITS)
    {
    case TAG_FIXNUM:
        return ((int32_t)a < 0);
    case TAG_SFLOAT:
    {   Float_union aa;
        aa.i = a - TAG_SFLOAT;
        return (aa.f < 0.0);
    }
    case TAG_NUMBERS:
    {   int32_t ha = type_of_header(numhdr(a));
        switch (ha)
        {
        case TYPE_BIGNUM:
        {   int32_t l = (bignum_length(a)-CELL-4)/4;
            return ((int32_t)bignum_digits(a)[l] < (int32_t)0);
        }
        case TYPE_RATNUM:
            return minusp(numerator(a));
        default:
            aerror1("Bad arg for minusp",  a);
            return 0;
        }
    }
    case TAG_BOXFLOAT:
    {   double d = float_of_number(a);
        return (d < 0.0);
    }
    default:
        aerror1("Bad arg for minusp",  a);
        return 0;
    }
}
Beispiel #2
0
static Lisp_Object Lrealpart(Lisp_Object nil, Lisp_Object a)
{
    CSL_IGNORE(nil);
    if (!is_number(a)) return aerror1("realpart", a);
    if (is_numbers(a) && is_complex(a))
        return onevalue(real_part(a));
    else return onevalue(a);
}
Beispiel #3
0
static Lisp_Object Lnumerator(Lisp_Object nil, Lisp_Object a)
{
    CSL_IGNORE(nil);
    if (!is_number(a)) return aerror1("numerator", a);
    if (is_numbers(a) && is_ratio(a))
        return onevalue(numerator(a));
    else return onevalue(a);
}
Beispiel #4
0
static Lisp_Object Ldenominator(Lisp_Object nil, Lisp_Object a)
{
    CSL_IGNORE(nil);
    if (!is_number(a)) return aerror1("denominator", a);
    if (is_numbers(a) && is_ratio(a))
        return onevalue(denominator(a));
    else return onevalue(fixnum_of_int(1));
}
Beispiel #5
0
static Lisp_Object Limagpart(Lisp_Object nil, Lisp_Object a)
{
    CSL_IGNORE(nil);
    if (!is_number(a)) return aerror1("imagpart", a);
    if (is_numbers(a) && is_complex(a))
        return onevalue(imag_part(a));
/* /* the 0.0 returned here ought to be the same type as a has */
    else return onevalue(fixnum_of_int(0));
}
Beispiel #6
0
static Lisp_Object Lfloat_sign1(Lisp_Object nil, Lisp_Object a)
{
    double d = float_of_number(a);
    CSL_IGNORE(nil);
    if (d < 0.0) d = -1.0; else d = 1.0;
#ifdef COMMON
    if (is_sfloat(a)) return onevalue(make_sfloat(d));
    else
#endif
    if (!is_bfloat(a)) return aerror1("bad arg for float-sign",  a);
    else return onevalue(make_boxfloat(d, type_of_header(flthdr(a))));
}
Beispiel #7
0
static Lisp_Object Lscale_float(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
{
    double d = float_of_number(a);
    CSL_IGNORE(nil);
    if (!is_fixnum(b)) return aerror("scale-float");
    d = ldexp(d, int_of_fixnum(b));
#ifdef COMMON
    if (is_sfloat(a)) return onevalue(make_sfloat(d));
    else
#endif
    if (!is_bfloat(a)) return aerror1("bad arg for scale-float",  a);
    else return onevalue(make_boxfloat(d, type_of_header(flthdr(a))));
}
Beispiel #8
0
CSLbool plusp(Lisp_Object a)
{
    switch ((int)a & TAG_BITS)
    {
    case TAG_FIXNUM:
        return (a > fixnum_of_int(0));
    case TAG_SFLOAT:
    {   Float_union aa;
        aa.i = a - TAG_SFLOAT;
        return (aa.f > 0.0);
    }
    case TAG_NUMBERS:
    {   int32_t ha = type_of_header(numhdr(a));
        switch (ha)
        {
        case TYPE_BIGNUM:
        {   int32_t l = (bignum_length(a)-CELL-4)/4;
            /* This is OK because a bignum can never have the value zero */
            return ((int32_t)bignum_digits(a)[l] >= (int32_t)0);
        }
        case TYPE_RATNUM:
            return plusp(numerator(a));
        default:
            aerror1("Bad arg for plusp",  a);
            return 0;
        }
    }
    case TAG_BOXFLOAT:
    {   double d = float_of_number(a);
        return (d > 0.0);
    }
    default:
        aerror1("Bad arg for plusp",  a);
        return 0;
    }
}
Beispiel #9
0
static Lisp_Object Lconjugate(Lisp_Object nil, Lisp_Object a)
{
    if (!is_number(a)) return aerror1("conjugate", a);
    if (is_numbers(a) && is_complex(a))
    {   Lisp_Object r = real_part(a),
                    i = imag_part(a);
        push(r);
        i = negate(i);
        pop(r);
        errexit();
        a = make_complex(r, i);
        errexit();
        return onevalue(a);
    }
    else return onevalue(a);
}
Beispiel #10
0
static Lisp_Object MS_CDECL Lboole(Lisp_Object nil, int nargs, ...)
{
    Lisp_Object r, op, a, b;
    va_list aa;
    argcheck(nargs, 3, "boole");
    va_start(aa, nargs);
    op = va_arg(aa, Lisp_Object);
    a = va_arg(aa, Lisp_Object);
    b = va_arg(aa, Lisp_Object);
    va_end(aa);
    switch (op)
    {
case fixnum_of_int(boole_clr):
        return onevalue(fixnum_of_int(0));
case fixnum_of_int(boole_and):
        r = logand2(a, b);
        break;
case fixnum_of_int(boole_andc2):
        push(a);
        b = lognot(b);
        pop(a);
        errexit();
        r = logand2(a, b);
        break;
case fixnum_of_int(boole_1):
        return onevalue(a);
case fixnum_of_int(boole_andc1):
        push(b);
        a = lognot(a);
        pop(b);
        errexit();
        r = logand2(a, b);
        break;
case fixnum_of_int(boole_2):
        return onevalue(b);
case fixnum_of_int(boole_xor):
        r = logxor2(a, b);
        break;
case fixnum_of_int(boole_ior):
        r = logior2(a, b);
        break;
case fixnum_of_int(boole_nor):
        a = logior2(a, b);
        errexit();
        r = lognot(a);
        break;
case fixnum_of_int(boole_eqv):
        r = logeqv2(a, b);
        break;
case fixnum_of_int(boole_c2):
        r = lognot(b);
        break;
case fixnum_of_int(boole_orc2):
        b = lognot(b);
        errexit();
        r = logior2(a, b);
        break;
case fixnum_of_int(boole_c1):
        r = lognot(a);
        break;
case fixnum_of_int(boole_orc1):
        push(b);
        a = lognot(a);
        pop(b);
        errexit();
        r = logior2(a, b);
        break;
case fixnum_of_int(boole_nand):
        a = logand2(a, b);
        errexit();
        r = lognot(a);
        break;
case fixnum_of_int(boole_set):
        return onevalue(fixnum_of_int(-1));
default:
        return aerror1("bad arg for boole",  op);
    }
    errexit();
    return onevalue(r);
}
Beispiel #11
0
static Lisp_Object Lbyte_size(Lisp_Object nil, Lisp_Object a)
{
    if (!consp(a)) return aerror1("byte-size", a);
    else return onevalue(qcar(a));
}
Beispiel #12
0
static Lisp_Object Lbyte_position(Lisp_Object nil, Lisp_Object a)
{
    if (!consp(a)) return aerror1("byte-position", a);
    else return onevalue(qcdr(a));
}
Beispiel #13
0
Lisp_Object modulus(Lisp_Object a, Lisp_Object b)
{
    switch ((int)a & TAG_BITS)
    {
    case TAG_FIXNUM:
        switch ((int)b & TAG_BITS)
        {
        case TAG_FIXNUM:
            /*
             * This is where fixnum % fixnum arithmetic happens - the case I most want to
             * make efficient.
             */
        {   int32_t p = int_of_fixnum(a);
            int32_t q = int_of_fixnum(b);
            if (q == 0) return aerror2("bad arg for mod", a, b);
            p = p % q;
            if (q < 0)
            {   if (p > 0) p += q;
            }
            else if (p < 0) p += q;
            /* No overflow is possible in a modulus operation */
            return fixnum_of_int(p);
        }
        /*
         * Common Lisp defines a meaning for the modulus function when applied
         * to floating point values - so there is a whole pile of mess here to
         * support that.  Standard Lisp is only concerned with fixnums and
         * bignums.
         */
        case TAG_SFLOAT:
            return modis(a, b);
        case TAG_NUMBERS:
        {   int32_t hb = type_of_header(numhdr(b));
            switch (hb)
            {
            case TYPE_BIGNUM:
                return modib(a, b);
            case TYPE_RATNUM:
                return modir(a, b);
            default:
                return aerror1("Bad arg for mod",  b);
            }
        }
        case TAG_BOXFLOAT:
            return modif(a, b);
        default:
            return aerror1("Bad arg for mod",  b);
        }
    case TAG_SFLOAT:
        switch ((int)b & TAG_BITS)
        {
        case TAG_FIXNUM:
            return modsi(a, b);
        case TAG_SFLOAT:
        {   Float_union aa, bb;
            aa.i = a - TAG_SFLOAT;
            bb.i = b - TAG_SFLOAT;
            aa.f = (float) (aa.f + bb.f);
            return (aa.i & ~(int32_t)0xf) + TAG_SFLOAT;
        }
        case TAG_NUMBERS:
        {   int32_t hb = type_of_header(numhdr(b));
            switch (hb)
            {
            case TYPE_BIGNUM:
                return modsb(a, b);
            case TYPE_RATNUM:
                return modsr(a, b);
            default:
                return aerror1("Bad arg for mod",  b);
            }
        }
        case TAG_BOXFLOAT:
            return modsf(a, b);
        default:
            return aerror1("Bad arg for mod",  b);
        }
    case TAG_NUMBERS:
    {   int32_t ha = type_of_header(numhdr(a));
        switch (ha)
        {
        case TYPE_BIGNUM:
            switch ((int)b & TAG_BITS)
            {
            case TAG_FIXNUM:
                return modbi(a, b);
            case TAG_SFLOAT:
                return modbs(a, b);
            case TAG_NUMBERS:
            {   int32_t hb = type_of_header(numhdr(b));
                switch (hb)
                {
                case TYPE_BIGNUM:
                    return modbb(a, b);
                case TYPE_RATNUM:
                    return modbr(a, b);
                default:
                    return aerror1("Bad arg for mod",  b);
                }
            }
            case TAG_BOXFLOAT:
                return modbf(a, b);
            default:
                return aerror1("Bad arg for mod",  b);
            }
        case TYPE_RATNUM:
            switch ((int)b & TAG_BITS)
            {
            case TAG_FIXNUM:
                return modri(a, b);
            case TAG_SFLOAT:
                return modrs(a, b);
            case TAG_NUMBERS:
            {   int32_t hb = type_of_header(numhdr(b));
                switch (hb)
                {
                case TYPE_BIGNUM:
                    return modrb(a, b);
                case TYPE_RATNUM:
                    return modrr(a, b);
                default:
                    return aerror1("Bad arg for mod",  b);
                }
            }
            case TAG_BOXFLOAT:
                return modrf(a, b);
            default:
                return aerror1("Bad arg for mod",  b);
            }
        default:
            return aerror1("Bad arg for mod",  a);
        }
    }
    case TAG_BOXFLOAT:
        switch ((int)b & TAG_BITS)
        {
        case TAG_FIXNUM:
            return modfi(a, b);
        case TAG_SFLOAT:
            return modfs(a, b);
        case TAG_NUMBERS:
        {   int32_t hb = type_of_header(numhdr(b));
            switch (hb)
            {
            case TYPE_BIGNUM:
                return modfb(a, b);
            case TYPE_RATNUM:
                return modfr(a, b);
            default:
                return aerror1("Bad arg for mod",  b);
            }
        }
        case TAG_BOXFLOAT:
            return ccl_modff(a, b);
        default:
            return aerror1("Bad arg for mod",  b);
        }
    default:
        return aerror1("Bad arg for mod",  a);
    }
}
Beispiel #14
0
Lisp_Object Cremainder(Lisp_Object a, Lisp_Object b)
{
    int32_t c;
    switch ((int)a & TAG_BITS)
    {
    case TAG_FIXNUM:
        switch ((int)b & TAG_BITS)
        {
        case TAG_FIXNUM:
            /*
             * This is where fixnum % fixnum arithmetic happens - the case I most want to
             * make efficient.
             */
            if (b == fixnum_of_int(0))
                return aerror2("bad arg for remainder", a, b);
            /* No overflow is possible in a remaindering operation */
            {   int32_t aa = int_of_fixnum(a);
                int32_t bb = int_of_fixnum(b);
                c = aa % bb;
                /*
                 * C does not specify just what happens when % is used with negative
                 * operands (except maybe if the division went exactly), so here I do
                 * some adjusting, assuming that the quotient returned was one of the
                 * integral values surrounding the exact result.
                 */
                if (aa < 0)
                {   if (c > 0) c -= bb;
                }
                else if (c < 0) c += bb;
                return fixnum_of_int(c);
            }
        /*
         * Common Lisp defines a meaning for the remainder function when applied
         * to floating point values - so there is a whole pile of mess here to
         * support that.  Standard Lisp is only concerned with fixnums and
         * bignums, but can tolerate the extra generality.
         */
        case TAG_SFLOAT:
            return remis(a, b);
        case TAG_NUMBERS:
        {   int32_t hb = type_of_header(numhdr(b));
            switch (hb)
            {
            case TYPE_BIGNUM:
                /*
                 * When I divide a fixnum a by a bignum b the remainder is a except in
                 * the case that a = 0xf8000000 and b = 0x08000000 in which case the
                 * answer is zero.
                 */
                if (int_of_fixnum(a) == fix_mask &&
                        bignum_length(b) == CELL+4 &&
                        bignum_digits(b)[0] == 0x08000000)
                    return fixnum_of_int(0);
                else return a;
            case TYPE_RATNUM:
                return remir(a, b);
            default:
                return aerror1("Bad arg for remainder",  b);
            }
        }
        case TAG_BOXFLOAT:
            return remif(a, b);
        /*
            case TAG_BOXFLOAT:
                {   double v = (double) int_of_fixnum(a);
                    double u = float_of_number(b);
                    v = v - (v/u)*u;
                    return make_boxfloat(v, TYPE_DOUBLE_FLOAT);
                }
         */
        default:
            return aerror1("Bad arg for remainder",  b);
        }
    case TAG_SFLOAT:
        switch ((int)b & TAG_BITS)
        {
        case TAG_FIXNUM:
            return remsi(a, b);
        case TAG_SFLOAT:
        {   Float_union aa, bb;
            aa.i = a - TAG_SFLOAT;
            bb.i = b - TAG_SFLOAT;
            aa.f = (float) (aa.f + bb.f);
            return (aa.i & ~(int32_t)0xf) + TAG_SFLOAT;
        }
        case TAG_NUMBERS:
        {   int32_t hb = type_of_header(numhdr(b));
            switch (hb)
            {
            case TYPE_BIGNUM:
                return remsb(a, b);
            case TYPE_RATNUM:
                return remsr(a, b);
            default:
                return aerror1("Bad arg for remainder",  b);
            }
        }
        case TAG_BOXFLOAT:
            return remsf(a, b);
        default:
            return aerror1("Bad arg for remainder",  b);
        }
    case TAG_NUMBERS:
    {   int32_t ha = type_of_header(numhdr(a));
        switch (ha)
        {
        case TYPE_BIGNUM:
            switch ((int)b & TAG_BITS)
            {
            case TAG_FIXNUM:
                return rembi(a, b);
            case TAG_SFLOAT:
                return rembs(a, b);
            case TAG_NUMBERS:
            {   int32_t hb = type_of_header(numhdr(b));
                switch (hb)
                {
                case TYPE_BIGNUM:
                    return rembb(a, b);
                case TYPE_RATNUM:
                    return rembr(a, b);
                default:
                    return aerror1("Bad arg for remainder",  b);
                }
            }
            case TAG_BOXFLOAT:
                return rembf(a, b);
            default:
                return aerror1("Bad arg for remainder",  b);
            }
        case TYPE_RATNUM:
            switch ((int)b & TAG_BITS)
            {
            case TAG_FIXNUM:
                return remri(a, b);
            case TAG_SFLOAT:
                return remrs(a, b);
            case TAG_NUMBERS:
            {   int32_t hb = type_of_header(numhdr(b));
                switch (hb)
                {
                case TYPE_BIGNUM:
                    return remrb(a, b);
                case TYPE_RATNUM:
                    return remrr(a, b);
                default:
                    return aerror1("Bad arg for remainder",  b);
                }
            }
            case TAG_BOXFLOAT:
                return remrf(a, b);
            default:
                return aerror1("Bad arg for remainder",  b);
            }
        default:
            return aerror1("Bad arg for remainder",  a);
        }
    }
    case TAG_BOXFLOAT:
        switch ((int)b & TAG_BITS)
        {
        /*
            case TAG_FIXNUM:
                    {   double u = (double) int_of_fixnum(b);
                        double v = float_of_number(a);
                        v = v - (v/u)*u;
                        return make_boxfloat(v, TYPE_DOUBLE_FLOAT);
                    }
            case TAG_BOXFLOAT:
                    {   double u = float_of_number(b);
                        double v = float_of_number(a);
                        v = v - (v/u)*u;
                        return make_boxfloat(v, TYPE_DOUBLE_FLOAT);
                    }
         */
        case TAG_FIXNUM:
            return remfi(a, b);
        case TAG_SFLOAT:
            return remfs(a, b);
        case TAG_NUMBERS:
        {   int32_t hb = type_of_header(numhdr(b));
            switch (hb)
            {
            case TYPE_BIGNUM:
                return remfb(a, b);
            case TYPE_RATNUM:
                return remfr(a, b);
            default:
                return aerror1("Bad arg for remainder",  b);
            }
        }
        case TAG_BOXFLOAT:
            return remff(a, b);
        default:
            return aerror1("Bad arg for remainder",  b);
        }
    default:
        return aerror1("Bad arg for remainder",  a);
    }
}
Beispiel #15
0
Lisp_Object negate(Lisp_Object a)
{
#ifdef COMMON
    Lisp_Object nil;  /* needed for errexit() */
#endif
    switch ((int)a & TAG_BITS)
    {
case TAG_FIXNUM:
        {   int32_t aa = -int_of_fixnum(a);
/*
 * negating the number -#x8000000 (which is a fixnum) yields a value
 * which just fails to be a fixnum.
 */
            if (aa != 0x08000000) return fixnum_of_int(aa);
            else return make_one_word_bignum(aa);
        }
#ifdef COMMON
case TAG_SFLOAT:
        {   Float_union aa;
            aa.i = a - TAG_SFLOAT;
            aa.f = (float) (-aa.f);
            return (aa.i & ~(int32_t)0xf) + TAG_SFLOAT;
        }
#endif
case TAG_NUMBERS:
        {   int32_t ha = type_of_header(numhdr(a));
            switch (ha)
            {
    case TYPE_BIGNUM:
                return negateb(a);
#ifdef COMMON
    case TYPE_RATNUM:
                {   Lisp_Object n = numerator(a),
                                d = denominator(a);
                    push(d);
                    n = negate(n);
                    pop(d);
                    errexit();
                    return make_ratio(n, d);
                }
    case TYPE_COMPLEX_NUM:
                {   Lisp_Object r = real_part(a),
                                i = imag_part(a);
                    push(i);
                    r = negate(r);
                    pop(i);
                    errexit();
                    push(r);
                    i = negate(i);
                    pop(r);
                    errexit();
                    return make_complex(r, i);
                }
#endif
    default:
                return aerror1("bad arg for minus",  a);
            }
        }
case TAG_BOXFLOAT:
        {   double d = float_of_number(a);
            return make_boxfloat(-d, type_of_header(flthdr(a)));
        }
default:
        return aerror1("bad arg for minus",  a);
    }
}
Beispiel #16
0
Lisp_Object plus2(Lisp_Object a, Lisp_Object b)
/*
 * I probably want to change the specification of plus2 so that the fixnum +
 * fixnum case is always expected to be done before the main body of the code
 * is entered.  Well maybe even if I do that it then costs very little to
 * include the fixnum code here as well, so I will not delete it.
 */
{
    switch ((int)a & TAG_BITS)
    {
case TAG_FIXNUM:
        switch ((int)b & TAG_BITS)
        {
    case TAG_FIXNUM:
/*
 * This is where fixnum + fixnum arithmetic happens - the case I most want to
 * make efficient. Note that even if this becomes a bignum it can only be a
 * one word one.
 */
            {   int32_t r = int_of_fixnum(a) + int_of_fixnum(b);
                int32_t t = r & fix_mask;
                if (t == 0 || t == fix_mask) return fixnum_of_int(r);
                else return make_one_word_bignum(r);
            }
#ifdef COMMON
    case TAG_SFLOAT:
            return plusis(a, b);
#endif
    case TAG_NUMBERS:
            {   int32_t hb = type_of_header(numhdr(b));
                switch (hb)
                {
        case TYPE_BIGNUM:
                return plusib(a, b);
#ifdef COMMON
        case TYPE_RATNUM:
                return plusir(a, b);
        case TYPE_COMPLEX_NUM:
                return plusic(a, b);
#endif
        default:
                return aerror1("bad arg for plus", b);
                }
            }
    case TAG_BOXFLOAT:
            return plusif(a, b);
    default:
            return aerror1("bad arg for plus",  b);
        }
#ifdef COMMON
case TAG_SFLOAT:
        switch (b & TAG_BITS)
        {
    case TAG_FIXNUM:
            return plussi(a, b);
    case TAG_SFLOAT:
            {   Float_union aa, bb;
                aa.i = a - TAG_SFLOAT;
                bb.i = b - TAG_SFLOAT;
                aa.f = (float)(aa.f + bb.f);
                return (aa.i & ~(int32_t)0xf) + TAG_SFLOAT;
            }
    case TAG_NUMBERS:
            {   int32_t hb = type_of_header(numhdr(b));
                switch (hb)
                {
        case TYPE_BIGNUM:
                return plussb(a, b);
        case TYPE_RATNUM:
                return plussr(a, b);
        case TYPE_COMPLEX_NUM:
                return plussc(a, b);
        default:
                return aerror1("bad arg for plus",  b);
                }
            }
    case TAG_BOXFLOAT:
            return plussf(a, b);
    default:
            return aerror1("bad arg for plus",  b);
        }
#endif
case TAG_NUMBERS:
        {   int32_t ha = type_of_header(numhdr(a));
            switch (ha)
            {
    case TYPE_BIGNUM:
                switch ((int)b & TAG_BITS)
                {
            case TAG_FIXNUM:
                    return plusbi(a, b);
#ifdef COMMON
            case TAG_SFLOAT:
                    return plusbs(a, b);
#endif
            case TAG_NUMBERS:
                    {   int32_t hb = type_of_header(numhdr(b));
                        switch (hb)
                        {
                case TYPE_BIGNUM:
                        return plusbb(a, b);
#ifdef COMMON
                case TYPE_RATNUM:
                        return plusbr(a, b);
                case TYPE_COMPLEX_NUM:
                        return plusbc(a, b);
#endif
                default:
                        return aerror1("bad arg for plus",  b);
                        }
                    }
            case TAG_BOXFLOAT:
                    return plusbf(a, b);
            default:
                    return aerror1("bad arg for plus",  b);
                }
#ifdef COMMON
    case TYPE_RATNUM:
                switch (b & TAG_BITS)
                {
            case TAG_FIXNUM:
                    return plusri(a, b);
            case TAG_SFLOAT:
                    return plusrs(a, b);
            case TAG_NUMBERS:
                    {   int32_t hb = type_of_header(numhdr(b));
                        switch (hb)
                        {
                case TYPE_BIGNUM:
                        return plusrb(a, b);
                case TYPE_RATNUM:
                        return plusrr(a, b);
                case TYPE_COMPLEX_NUM:
                        return plusrc(a, b);
                default:
                        return aerror1("bad arg for plus",  b);
                        }
                    }
            case TAG_BOXFLOAT:
                    return plusrf(a, b);
            default:
                    return aerror1("bad arg for plus",  b);
                }
    case TYPE_COMPLEX_NUM:
                switch (b & TAG_BITS)
                {
            case TAG_FIXNUM:
                    return plusci(a, b);
            case TAG_SFLOAT:
                    return pluscs(a, b);
            case TAG_NUMBERS:
                    {   int32_t hb = type_of_header(numhdr(b));
                        switch (hb)
                        {
                case TYPE_BIGNUM:
                        return pluscb(a, b);
                case TYPE_RATNUM:
                        return pluscr(a, b);
                case TYPE_COMPLEX_NUM:
                        return pluscc(a, b);
                default:
                        return aerror1("bad arg for plus",  b);
                        }
                    }
            case TAG_BOXFLOAT:
                    return pluscf(a, b);
            default:
                    return aerror1("bad arg for plus",  b);
                }
#endif
    default:    return aerror1("bad arg for plus",  a);
            }
        }
case TAG_BOXFLOAT:
        switch ((int)b & TAG_BITS)
        {
    case TAG_FIXNUM:
            return plusfi(a, b);
#ifdef COMMON
    case TAG_SFLOAT:
            return plusfs(a, b);
#endif
    case TAG_NUMBERS:
            {   int32_t hb = type_of_header(numhdr(b));
                switch (hb)
                {
        case TYPE_BIGNUM:
                return plusfb(a, b);
#ifdef COMMON
        case TYPE_RATNUM:
                return plusfr(a, b);
        case TYPE_COMPLEX_NUM:
                return plusfc(a, b);
#endif
        default:
                return aerror1("bad arg for plus",  b);
                }
            }
    case TAG_BOXFLOAT:
            return plusff(a, b);
    default:
            return aerror1("bad arg for plus",  b);
        }
default:
        return aerror1("bad arg for plus",  a);
    }
}