adding apply1, using it in trycatch (avoids consing)
allowing left bit shift to overflow to larger types fixing bug in number->string on uint64 fixing bug in rand.uint64
This commit is contained in:
		
							parent
							
								
									dceced2bb0
								
							
						
					
					
						commit
						5681745bc3
					
				| 
						 | 
					@ -334,7 +334,7 @@ value_t fl_rand32(value_t *args, u_int32_t nargs)
 | 
				
			||||||
value_t fl_rand64(value_t *args, u_int32_t nargs)
 | 
					value_t fl_rand64(value_t *args, u_int32_t nargs)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    (void)args; (void)nargs;
 | 
					    (void)args; (void)nargs;
 | 
				
			||||||
    ulong r = (((uint64_t)random())<<32) | random();
 | 
					    uint64_t r = (((uint64_t)random())<<32) | random();
 | 
				
			||||||
    return mk_uint64(r);
 | 
					    return mk_uint64(r);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
value_t fl_randd(value_t *args, u_int32_t nargs)
 | 
					value_t fl_randd(value_t *args, u_int32_t nargs)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1303,32 +1303,39 @@ static value_t fl_bitwise_not(value_t a)
 | 
				
			||||||
    return NIL;
 | 
					    return NIL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define BITSHIFT_OP(name, op)                                       \
 | 
					static value_t fl_ash(value_t a, int n)
 | 
				
			||||||
static value_t fl_##name(value_t a, int n)                          \
 | 
					{
 | 
				
			||||||
{                                                                   \
 | 
					    cprim_t *cp;
 | 
				
			||||||
    cprim_t *cp;                                                    \
 | 
					    int ta;
 | 
				
			||||||
    int ta;                                                         \
 | 
					    void *aptr;
 | 
				
			||||||
    void *aptr;                                                     \
 | 
					    if (iscprim(a)) {
 | 
				
			||||||
    if (iscprim(a)) {                                               \
 | 
					        if (n == 0) return a;
 | 
				
			||||||
        cp = (cprim_t*)ptr(a);                                      \
 | 
					        cp = (cprim_t*)ptr(a);
 | 
				
			||||||
        ta = cp_numtype(cp);                                        \
 | 
					        ta = cp_numtype(cp);
 | 
				
			||||||
        aptr = cp_data(cp);                                         \
 | 
					        aptr = cp_data(cp);
 | 
				
			||||||
        switch (ta) {                                               \
 | 
					        if (n < 0) {
 | 
				
			||||||
        case T_INT8:   return fixnum((*(int8_t *)aptr) op n);       \
 | 
					            n = -n;
 | 
				
			||||||
        case T_UINT8:  return fixnum((*(uint8_t *)aptr) op n);      \
 | 
					            switch (ta) {
 | 
				
			||||||
        case T_INT16:  return fixnum((*(int16_t *)aptr) op n);      \
 | 
					            case T_INT8:   return fixnum((*(int8_t *)aptr) >> n);
 | 
				
			||||||
        case T_UINT16: return fixnum((*(uint16_t*)aptr) op n);      \
 | 
					            case T_UINT8:  return fixnum((*(uint8_t *)aptr) >> n);
 | 
				
			||||||
        case T_INT32:  return mk_int32((*(int32_t *)aptr) op n);    \
 | 
					            case T_INT16:  return fixnum((*(int16_t *)aptr) >> n);
 | 
				
			||||||
        case T_UINT32: return mk_uint32((*(uint32_t*)aptr) op n);   \
 | 
					            case T_UINT16: return fixnum((*(uint16_t*)aptr) >> n);
 | 
				
			||||||
        case T_INT64:  return mk_int64((*(int64_t *)aptr) op n);    \
 | 
					            case T_INT32:  return mk_int32((*(int32_t *)aptr) >> n);
 | 
				
			||||||
        case T_UINT64: return mk_uint64((*(uint64_t*)aptr) op n);   \
 | 
					            case T_UINT32: return mk_uint32((*(uint32_t*)aptr) >> n);
 | 
				
			||||||
        }                                                           \
 | 
					            case T_INT64:  return mk_int64((*(int64_t *)aptr) >> n);
 | 
				
			||||||
    }                                                               \
 | 
					            case T_UINT64: return mk_uint64((*(uint64_t*)aptr) >> n);
 | 
				
			||||||
    type_error("ash", "integer", a);                                \
 | 
					            }
 | 
				
			||||||
    return NIL;                                                     \
 | 
					        }
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
 | 
					            if (ta == T_UINT64)
 | 
				
			||||||
 | 
					                return return_from_uint64((*(uint64_t*)aptr)<<n);
 | 
				
			||||||
 | 
					            int64_t i64 = conv_to_int64(aptr, ta);
 | 
				
			||||||
 | 
					            return return_from_int64(i64<<n);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    type_error("ash", "integer", a);
 | 
				
			||||||
 | 
					    return NIL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
BITSHIFT_OP(shl,<<)
 | 
					 | 
				
			||||||
BITSHIFT_OP(shr,>>)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static value_t fl_bitwise_op(value_t a, value_t b, int opcode, char *fname)
 | 
					static value_t fl_bitwise_op(value_t a, value_t b, int opcode, char *fname)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -280,7 +280,7 @@ char *symbol_name(value_t v)
 | 
				
			||||||
    if (ismanaged(v)) {
 | 
					    if (ismanaged(v)) {
 | 
				
			||||||
        gensym_t *gs = (gensym_t*)ptr(v);
 | 
					        gensym_t *gs = (gensym_t*)ptr(v);
 | 
				
			||||||
        gsnameno = 1-gsnameno;
 | 
					        gsnameno = 1-gsnameno;
 | 
				
			||||||
        char *n = int2str(gsname[gsnameno]+1, sizeof(gsname[0])-1, gs->id, 10);
 | 
					        char *n = uint2str(gsname[gsnameno]+1, sizeof(gsname[0])-1, gs->id, 10);
 | 
				
			||||||
        *(--n) = 'g';
 | 
					        *(--n) = 'g';
 | 
				
			||||||
        return n;
 | 
					        return n;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -449,6 +449,7 @@ static void trace_globals(symbol_t *root)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static value_t special_apply_form;
 | 
					static value_t special_apply_form;
 | 
				
			||||||
 | 
					static value_t apply1_args;
 | 
				
			||||||
static value_t memory_exception_value;
 | 
					static value_t memory_exception_value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void gc(int mustgrow)
 | 
					void gc(int mustgrow)
 | 
				
			||||||
| 
						 | 
					@ -476,6 +477,7 @@ void gc(int mustgrow)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    lasterror = relocate(lasterror);
 | 
					    lasterror = relocate(lasterror);
 | 
				
			||||||
    special_apply_form = relocate(special_apply_form);
 | 
					    special_apply_form = relocate(special_apply_form);
 | 
				
			||||||
 | 
					    apply1_args = relocate(apply1_args);
 | 
				
			||||||
    memory_exception_value = relocate(memory_exception_value);
 | 
					    memory_exception_value = relocate(memory_exception_value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sweep_finalizers();
 | 
					    sweep_finalizers();
 | 
				
			||||||
| 
						 | 
					@ -522,6 +524,12 @@ value_t apply(value_t f, value_t l)
 | 
				
			||||||
    return v;
 | 
					    return v;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					value_t apply1(value_t f, value_t a0)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    car_(apply1_args) = a0;
 | 
				
			||||||
 | 
					    return apply(f, apply1_args);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
value_t listn(size_t n, ...)
 | 
					value_t listn(size_t n, ...)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    va_list ap;
 | 
					    va_list ap;
 | 
				
			||||||
| 
						 | 
					@ -658,10 +666,8 @@ static value_t do_trycatch(value_t expr, uint32_t penv)
 | 
				
			||||||
            v = FL_F;   // 1-argument form
 | 
					            v = FL_F;   // 1-argument form
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else {
 | 
					        else {
 | 
				
			||||||
            Stack[SP-1] = car_(v);
 | 
					            Stack[SP-1] = eval(car_(v));
 | 
				
			||||||
            value_t quoted = list2(QUOTE, lasterror);
 | 
					            v = apply1(Stack[SP-1], lasterror);
 | 
				
			||||||
            expr = list2(Stack[SP-1], quoted);
 | 
					 | 
				
			||||||
            v = eval(expr);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return v;
 | 
					    return v;
 | 
				
			||||||
| 
						 | 
					@ -1202,19 +1208,22 @@ static value_t eval_sexpr(value_t e, uint32_t penv, int tail)
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        case F_ASH:
 | 
					        case F_ASH:
 | 
				
			||||||
          argcount("ash", nargs, 2);
 | 
					            argcount("ash", nargs, 2);
 | 
				
			||||||
          i = tofixnum(Stack[SP-1], "ash");
 | 
					            i = tofixnum(Stack[SP-1], "ash");
 | 
				
			||||||
          if (isfixnum(Stack[SP-2])) {
 | 
					            if (isfixnum(Stack[SP-2])) {
 | 
				
			||||||
            if (i < 0)
 | 
					                if (i <= 0)
 | 
				
			||||||
              v = fixnum(numval(Stack[SP-2])>>(-i));
 | 
					                    v = fixnum(numval(Stack[SP-2])>>(-i));
 | 
				
			||||||
 | 
					                else {
 | 
				
			||||||
 | 
					                    accum = ((int64_t)numval(Stack[SP-2]))<<i;
 | 
				
			||||||
 | 
					                    if (fits_fixnum(accum))
 | 
				
			||||||
 | 
					                        v = fixnum(accum);
 | 
				
			||||||
 | 
					                    else
 | 
				
			||||||
 | 
					                        v = return_from_int64(accum);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
              v = fixnum(numval(Stack[SP-2])<<i);
 | 
					                v = fl_ash(Stack[SP-2], i);
 | 
				
			||||||
          }
 | 
					            break;
 | 
				
			||||||
          else if (i < 0)
 | 
					 | 
				
			||||||
            v = fl_shr(Stack[SP-2], -i);
 | 
					 | 
				
			||||||
          else
 | 
					 | 
				
			||||||
            v = fl_shl(Stack[SP-2],  i);
 | 
					 | 
				
			||||||
          break;
 | 
					 | 
				
			||||||
        case F_COMPARE:
 | 
					        case F_COMPARE:
 | 
				
			||||||
            argcount("compare", nargs, 2);
 | 
					            argcount("compare", nargs, 2);
 | 
				
			||||||
            v = compare(Stack[SP-2], Stack[SP-1]);
 | 
					            v = compare(Stack[SP-2], Stack[SP-1]);
 | 
				
			||||||
| 
						 | 
					@ -1520,6 +1529,7 @@ static void lisp_init(void)
 | 
				
			||||||
    set(printwidthsym=symbol("*print-width*"), fixnum(SCR_WIDTH));
 | 
					    set(printwidthsym=symbol("*print-width*"), fixnum(SCR_WIDTH));
 | 
				
			||||||
    lasterror = NIL;
 | 
					    lasterror = NIL;
 | 
				
			||||||
    special_apply_form = fl_cons(builtin(F_SPECIAL_APPLY), NIL);
 | 
					    special_apply_form = fl_cons(builtin(F_SPECIAL_APPLY), NIL);
 | 
				
			||||||
 | 
					    apply1_args = fl_cons(NIL, NIL);
 | 
				
			||||||
    i = 0;
 | 
					    i = 0;
 | 
				
			||||||
    while (isspecial(builtin(i))) {
 | 
					    while (isspecial(builtin(i))) {
 | 
				
			||||||
        if (i != F_SPECIAL_APPLY)
 | 
					        if (i != F_SPECIAL_APPLY)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -125,6 +125,7 @@ value_t read_sexpr(value_t f);
 | 
				
			||||||
void print(ios_t *f, value_t v, int princ);
 | 
					void print(ios_t *f, value_t v, int princ);
 | 
				
			||||||
value_t toplevel_eval(value_t expr);
 | 
					value_t toplevel_eval(value_t expr);
 | 
				
			||||||
value_t apply(value_t f, value_t l);
 | 
					value_t apply(value_t f, value_t l);
 | 
				
			||||||
 | 
					value_t apply1(value_t f, value_t a0);
 | 
				
			||||||
value_t load_file(char *fname);
 | 
					value_t load_file(char *fname);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* object model manipulation */
 | 
					/* object model manipulation */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -295,11 +295,16 @@ value_t fl_numbertostring(value_t *args, u_int32_t nargs)
 | 
				
			||||||
    if (nargs < 1 || nargs > 2)
 | 
					    if (nargs < 1 || nargs > 2)
 | 
				
			||||||
        argcount("number->string", nargs, 2);
 | 
					        argcount("number->string", nargs, 2);
 | 
				
			||||||
    value_t n = args[0];
 | 
					    value_t n = args[0];
 | 
				
			||||||
    int64_t num;
 | 
					    int neg = 0;
 | 
				
			||||||
 | 
					    uint64_t num;
 | 
				
			||||||
    if (isfixnum(n))      num = numval(n);
 | 
					    if (isfixnum(n))      num = numval(n);
 | 
				
			||||||
    else if (!iscprim(n)) type_error("number->string", "integer", n);
 | 
					    else if (!iscprim(n)) type_error("number->string", "integer", n);
 | 
				
			||||||
    else num = conv_to_int64(cp_data((cprim_t*)ptr(n)),
 | 
					    else num = conv_to_uint64(cp_data((cprim_t*)ptr(n)),
 | 
				
			||||||
                             cp_numtype((cprim_t*)ptr(n)));
 | 
					                              cp_numtype((cprim_t*)ptr(n)));
 | 
				
			||||||
 | 
					    if (numval(compare(args[0],fixnum(0))) < 0) {
 | 
				
			||||||
 | 
					        num = -num;
 | 
				
			||||||
 | 
					        neg = 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    ulong radix = 10;
 | 
					    ulong radix = 10;
 | 
				
			||||||
    if (nargs == 2) {
 | 
					    if (nargs == 2) {
 | 
				
			||||||
        radix = toulong(args[1], "number->string");
 | 
					        radix = toulong(args[1], "number->string");
 | 
				
			||||||
| 
						 | 
					@ -307,7 +312,9 @@ value_t fl_numbertostring(value_t *args, u_int32_t nargs)
 | 
				
			||||||
            lerror(ArgError, "number->string: invalid radix");
 | 
					            lerror(ArgError, "number->string: invalid radix");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    char buf[128];
 | 
					    char buf[128];
 | 
				
			||||||
    char *str = int2str(buf, sizeof(buf), num, radix);
 | 
					    char *str = uint2str(buf, sizeof(buf), num, radix);
 | 
				
			||||||
 | 
					    if (neg && str > &buf[0])
 | 
				
			||||||
 | 
					        *(--str) = '-';
 | 
				
			||||||
    return string_from_cstr(str);
 | 
					    return string_from_cstr(str);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,15 +1,11 @@
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include "dtypes.h"
 | 
					#include "dtypes.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
char *int2str(char *dest, size_t len, int64_t num, uint32_t base)
 | 
					char *uint2str(char *dest, size_t len, uint64_t num, uint32_t base)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int i = len-1, neg = 0;
 | 
					    int i = len-1;
 | 
				
			||||||
    int64_t b = (int64_t)base;
 | 
					    uint64_t b = (uint64_t)base;
 | 
				
			||||||
    char ch;
 | 
					    char ch;
 | 
				
			||||||
    if (num < 0) {
 | 
					 | 
				
			||||||
        num = -num;
 | 
					 | 
				
			||||||
        neg = 1;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    dest[i--] = '\0';
 | 
					    dest[i--] = '\0';
 | 
				
			||||||
    while (i >= 0) {
 | 
					    while (i >= 0) {
 | 
				
			||||||
        ch = (char)(num % b);
 | 
					        ch = (char)(num % b);
 | 
				
			||||||
| 
						 | 
					@ -22,8 +18,6 @@ char *int2str(char *dest, size_t len, int64_t num, uint32_t base)
 | 
				
			||||||
        if (num == 0)
 | 
					        if (num == 0)
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (i >= 0 && neg)
 | 
					 | 
				
			||||||
        dest[i--] = '-';
 | 
					 | 
				
			||||||
    return &dest[i+1];
 | 
					    return &dest[i+1];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,7 +45,7 @@ void snprint_cplx(char *s, size_t cnt, double re, double im,
 | 
				
			||||||
                  // print spaces around sign in a+bi
 | 
					                  // print spaces around sign in a+bi
 | 
				
			||||||
                  int spflag);
 | 
					                  int spflag);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
char *int2str(char *dest, size_t len, int64_t num, uint32_t base);
 | 
					char *uint2str(char *dest, size_t len, uint64_t num, uint32_t base);
 | 
				
			||||||
int str2int(char *str, size_t len, int64_t *res, uint32_t base);
 | 
					int str2int(char *str, size_t len, int64_t *res, uint32_t base);
 | 
				
			||||||
int isdigit_base(char c, int base);
 | 
					int isdigit_base(char c, int base);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue