making nconc, assq, and memq builtins

some small optimizations to string.map, string.trim,
string.inc, string.dec, aref
This commit is contained in:
JeffBezanson 2009-03-17 03:29:17 +00:00
parent 5681745bc3
commit 5edb75af2c
7 changed files with 113 additions and 73 deletions

View File

@ -26,7 +26,59 @@ size_t llength(value_t v)
return n; return n;
} }
value_t fl_exit(value_t *args, u_int32_t nargs) static value_t fl_nconc(value_t *args, u_int32_t nargs)
{
if (nargs == 0)
return NIL;
value_t first=NIL;
value_t *pcdr = &first;
cons_t *c;
int a;
for(a=0; a < (int)nargs-1; a++) {
if (iscons(args[a])) {
*pcdr = args[a];
c = (cons_t*)ptr(args[a]);
while (iscons(c->cdr))
c = (cons_t*)ptr(c->cdr);
pcdr = &c->cdr;
}
else if (args[a] != NIL) {
type_error("nconc", "cons", args[a]);
}
}
*pcdr = args[a];
return first;
}
static value_t fl_assq(value_t *args, u_int32_t nargs)
{
argcount("assq", nargs, 2);
value_t item = args[0];
value_t v = args[1];
value_t bind;
while (iscons(v)) {
bind = car_(v);
if (iscons(bind) && car_(bind) == item)
return bind;
v = cdr_(v);
}
return FL_F;
}
static value_t fl_memq(value_t *args, u_int32_t nargs)
{
argcount("memq", nargs, 2);
while (iscons(args[1])) {
cons_t *c = (cons_t*)ptr(args[1]);
if (c->car == args[0])
return args[1];
args[1] = c->cdr;
}
return FL_F;
}
static value_t fl_exit(value_t *args, u_int32_t nargs)
{ {
if (nargs > 0) if (nargs > 0)
exit(tofixnum(args[0], "exit")); exit(tofixnum(args[0], "exit"));
@ -34,7 +86,7 @@ value_t fl_exit(value_t *args, u_int32_t nargs)
return NIL; return NIL;
} }
value_t fl_intern(value_t *args, u_int32_t nargs) static value_t fl_intern(value_t *args, u_int32_t nargs)
{ {
argcount("intern", nargs, 1); argcount("intern", nargs, 1);
if (!isstring(args[0])) if (!isstring(args[0]))
@ -42,7 +94,7 @@ value_t fl_intern(value_t *args, u_int32_t nargs)
return symbol(cvalue_data(args[0])); return symbol(cvalue_data(args[0]));
} }
value_t fl_setconstant(value_t *args, u_int32_t nargs) static value_t fl_setconstant(value_t *args, u_int32_t nargs)
{ {
argcount("set-constant!", nargs, 2); argcount("set-constant!", nargs, 2);
symbol_t *sym = tosymbol(args[0], "set-constant!"); symbol_t *sym = tosymbol(args[0], "set-constant!");
@ -55,7 +107,7 @@ value_t fl_setconstant(value_t *args, u_int32_t nargs)
extern value_t LAMBDA; extern value_t LAMBDA;
value_t fl_setsyntax(value_t *args, u_int32_t nargs) static value_t fl_setsyntax(value_t *args, u_int32_t nargs)
{ {
argcount("set-syntax!", nargs, 2); argcount("set-syntax!", nargs, 2);
symbol_t *sym = tosymbol(args[0], "set-syntax!"); symbol_t *sym = tosymbol(args[0], "set-syntax!");
@ -73,7 +125,7 @@ value_t fl_setsyntax(value_t *args, u_int32_t nargs)
return args[1]; return args[1];
} }
value_t fl_symbolsyntax(value_t *args, u_int32_t nargs) static value_t fl_symbolsyntax(value_t *args, u_int32_t nargs)
{ {
argcount("symbol-syntax", nargs, 1); argcount("symbol-syntax", nargs, 1);
symbol_t *sym = tosymbol(args[0], "symbol-syntax"); symbol_t *sym = tosymbol(args[0], "symbol-syntax");
@ -111,7 +163,7 @@ static void global_env_assoc_list(symbol_t *root, value_t *pv)
extern symbol_t *symtab; extern symbol_t *symtab;
value_t fl_syntax_env(value_t *args, u_int32_t nargs) static value_t fl_syntax_env(value_t *args, u_int32_t nargs)
{ {
(void)args; (void)args;
argcount("syntax-environment", nargs, 0); argcount("syntax-environment", nargs, 0);
@ -130,7 +182,7 @@ value_t fl_global_env(value_t *args, u_int32_t nargs)
extern value_t QUOTE; extern value_t QUOTE;
value_t fl_constantp(value_t *args, u_int32_t nargs) static value_t fl_constantp(value_t *args, u_int32_t nargs)
{ {
argcount("constant?", nargs, 1); argcount("constant?", nargs, 1);
if (issymbol(args[0])) if (issymbol(args[0]))
@ -143,7 +195,7 @@ value_t fl_constantp(value_t *args, u_int32_t nargs)
return FL_T; return FL_T;
} }
value_t fl_integerp(value_t *args, u_int32_t nargs) static value_t fl_integerp(value_t *args, u_int32_t nargs)
{ {
argcount("integer?", nargs, 1); argcount("integer?", nargs, 1);
value_t v = args[0]; value_t v = args[0];
@ -172,7 +224,7 @@ value_t fl_integerp(value_t *args, u_int32_t nargs)
return FL_F; return FL_F;
} }
value_t fl_fixnum(value_t *args, u_int32_t nargs) static value_t fl_fixnum(value_t *args, u_int32_t nargs)
{ {
argcount("fixnum", nargs, 1); argcount("fixnum", nargs, 1);
if (isfixnum(args[0])) { if (isfixnum(args[0])) {
@ -194,7 +246,7 @@ value_t fl_fixnum(value_t *args, u_int32_t nargs)
lerror(ArgError, "fixnum: cannot convert argument"); lerror(ArgError, "fixnum: cannot convert argument");
} }
value_t fl_truncate(value_t *args, u_int32_t nargs) static value_t fl_truncate(value_t *args, u_int32_t nargs)
{ {
argcount("truncate", nargs, 1); argcount("truncate", nargs, 1);
if (isfixnum(args[0])) if (isfixnum(args[0]))
@ -217,7 +269,7 @@ value_t fl_truncate(value_t *args, u_int32_t nargs)
type_error("truncate", "number", args[0]); type_error("truncate", "number", args[0]);
} }
value_t fl_vector_alloc(value_t *args, u_int32_t nargs) static value_t fl_vector_alloc(value_t *args, u_int32_t nargs)
{ {
fixnum_t i; fixnum_t i;
value_t f, v; value_t f, v;
@ -239,7 +291,7 @@ value_t fl_vector_alloc(value_t *args, u_int32_t nargs)
return v; return v;
} }
value_t fl_time_now(value_t *args, u_int32_t nargs) static value_t fl_time_now(value_t *args, u_int32_t nargs)
{ {
argcount("time.now", nargs, 0); argcount("time.now", nargs, 0);
(void)args; (void)args;
@ -258,7 +310,7 @@ static double todouble(value_t a, char *fname)
type_error(fname, "number", a); type_error(fname, "number", a);
} }
value_t fl_time_string(value_t *args, uint32_t nargs) static value_t fl_time_string(value_t *args, uint32_t nargs)
{ {
argcount("time.string", nargs, 1); argcount("time.string", nargs, 1);
double t = todouble(args[0], "time.string"); double t = todouble(args[0], "time.string");
@ -267,7 +319,7 @@ value_t fl_time_string(value_t *args, uint32_t nargs)
return string_from_cstr(buf); return string_from_cstr(buf);
} }
value_t fl_path_cwd(value_t *args, uint32_t nargs) static value_t fl_path_cwd(value_t *args, uint32_t nargs)
{ {
if (nargs > 1) if (nargs > 1)
argcount("path.cwd", nargs, 1); argcount("path.cwd", nargs, 1);
@ -282,7 +334,7 @@ value_t fl_path_cwd(value_t *args, uint32_t nargs)
return FL_T; return FL_T;
} }
value_t fl_os_getenv(value_t *args, uint32_t nargs) static value_t fl_os_getenv(value_t *args, uint32_t nargs)
{ {
argcount("os.getenv", nargs, 1); argcount("os.getenv", nargs, 1);
char *name = tostring(args[0], "os.getenv"); char *name = tostring(args[0], "os.getenv");
@ -293,7 +345,7 @@ value_t fl_os_getenv(value_t *args, uint32_t nargs)
return cvalue_static_cstring(val); return cvalue_static_cstring(val);
} }
value_t fl_os_setenv(value_t *args, uint32_t nargs) static value_t fl_os_setenv(value_t *args, uint32_t nargs)
{ {
argcount("os.setenv", nargs, 2); argcount("os.setenv", nargs, 2);
char *name = tostring(args[0], "os.setenv"); char *name = tostring(args[0], "os.setenv");
@ -310,7 +362,7 @@ value_t fl_os_setenv(value_t *args, uint32_t nargs)
return FL_T; return FL_T;
} }
value_t fl_rand(value_t *args, u_int32_t nargs) static value_t fl_rand(value_t *args, u_int32_t nargs)
{ {
(void)args; (void)nargs; (void)args; (void)nargs;
fixnum_t r; fixnum_t r;
@ -321,7 +373,7 @@ value_t fl_rand(value_t *args, u_int32_t nargs)
#endif #endif
return fixnum(r); return fixnum(r);
} }
value_t fl_rand32(value_t *args, u_int32_t nargs) static value_t fl_rand32(value_t *args, u_int32_t nargs)
{ {
(void)args; (void)nargs; (void)args; (void)nargs;
ulong r = random(); ulong r = random();
@ -331,18 +383,18 @@ value_t fl_rand32(value_t *args, u_int32_t nargs)
return mk_uint32(r); return mk_uint32(r);
#endif #endif
} }
value_t fl_rand64(value_t *args, u_int32_t nargs) static value_t fl_rand64(value_t *args, u_int32_t nargs)
{ {
(void)args; (void)nargs; (void)args; (void)nargs;
uint64_t 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) static value_t fl_randd(value_t *args, u_int32_t nargs)
{ {
(void)args; (void)nargs; (void)args; (void)nargs;
return mk_double(rand_double()); return mk_double(rand_double());
} }
value_t fl_randf(value_t *args, u_int32_t nargs) static value_t fl_randf(value_t *args, u_int32_t nargs)
{ {
(void)args; (void)nargs; (void)args; (void)nargs;
return mk_float(rand_float()); return mk_float(rand_float());
@ -365,6 +417,9 @@ static builtinspec_t builtin_info[] = {
{ "fixnum", fl_fixnum }, { "fixnum", fl_fixnum },
{ "truncate", fl_truncate }, { "truncate", fl_truncate },
{ "integer?", fl_integerp }, { "integer?", fl_integerp },
{ "nconc", fl_nconc },
{ "assq", fl_assq },
{ "memq", fl_memq },
{ "vector.alloc", fl_vector_alloc }, { "vector.alloc", fl_vector_alloc },

View File

@ -275,7 +275,7 @@ num_init(uint64, uint64, T_UINT64)
num_init(float, double, T_FLOAT) num_init(float, double, T_FLOAT)
num_init(double, double, T_DOUBLE) num_init(double, double, T_DOUBLE)
#define num_ctor(typenam, ctype, tag) \ #define num_ctor_init(typenam, ctype, tag) \
value_t cvalue_##typenam(value_t *args, u_int32_t nargs) \ value_t cvalue_##typenam(value_t *args, u_int32_t nargs) \
{ \ { \
if (nargs==0) { PUSH(fixnum(0)); args = &Stack[SP-1]; } \ if (nargs==0) { PUSH(fixnum(0)); args = &Stack[SP-1]; } \
@ -284,7 +284,9 @@ value_t cvalue_##typenam(value_t *args, u_int32_t nargs) \
args[0], cp_data((cprim_t*)ptr(cp)))) \ args[0], cp_data((cprim_t*)ptr(cp)))) \
type_error(#typenam, "number", args[0]); \ type_error(#typenam, "number", args[0]); \
return cp; \ return cp; \
} \ }
#define num_ctor_ctor(typenam, ctype, tag) \
value_t mk_##typenam(ctype##_t n) \ value_t mk_##typenam(ctype##_t n) \
{ \ { \
value_t cp = cprim(typenam##type, sizeof(ctype##_t)); \ value_t cp = cprim(typenam##type, sizeof(ctype##_t)); \
@ -292,6 +294,10 @@ value_t mk_##typenam(ctype##_t n) \
return cp; \ return cp; \
} }
#define num_ctor(typenam, ctype, tag) \
num_ctor_init(typenam, ctype, tag) \
num_ctor_ctor(typenam, ctype, tag)
num_ctor(int8, int8, T_INT8) num_ctor(int8, int8, T_INT8)
num_ctor(uint8, uint8, T_UINT8) num_ctor(uint8, uint8, T_UINT8)
num_ctor(int16, int16, T_INT16) num_ctor(int16, int16, T_INT16)
@ -823,8 +829,20 @@ static value_t cvalue_array_aref(value_t *args)
{ {
char *data; ulong_t index; char *data; ulong_t index;
fltype_t *eltype = cv_class((cvalue_t*)ptr(args[0]))->eltype; fltype_t *eltype = cv_class((cvalue_t*)ptr(args[0]))->eltype;
value_t el = cvalue(eltype, eltype->size); value_t el;
numerictype_t nt = eltype->numtype;
if (nt >= T_INT32)
el = cvalue(eltype, eltype->size);
check_addr_args("aref", args[0], args[1], &data, &index); check_addr_args("aref", args[0], args[1], &data, &index);
if (nt < T_INT32) {
if (nt == T_INT8)
return fixnum((int8_t)data[index]);
else if (nt == T_UINT8)
return fixnum((uint8_t)data[index]);
else if (nt == T_INT16)
return fixnum(((int16_t*)data)[index]);
return fixnum(((uint16_t*)data)[index]);
}
char *dest = cptr(el); char *dest = cptr(el);
size_t sz = eltype->size; size_t sz = eltype->size;
if (sz == 1) if (sz == 1)

View File

@ -71,7 +71,7 @@ static char *builtin_names[] =
"compare", "compare",
// sequences // sequences
"vector", "aref", "aset!", "length", "assq", "for", "vector", "aref", "aset!", "length", "for",
"", "", "" }; "", "", "" };
#define N_STACK 98304 #define N_STACK 98304
@ -608,20 +608,6 @@ int isnumber(value_t v)
// eval ----------------------------------------------------------------------- // eval -----------------------------------------------------------------------
// return a cons element of v whose car is item
static value_t assq(value_t item, value_t v)
{
value_t bind;
while (iscons(v)) {
bind = car_(v);
if (iscons(bind) && car_(bind) == item)
return bind;
v = cdr_(v);
}
return FL_F;
}
/* /*
take the final cdr as an argument so the list builtin can give take the final cdr as an argument so the list builtin can give
the same result as (lambda x x). the same result as (lambda x x).
@ -1299,10 +1285,6 @@ static value_t eval_sexpr(value_t e, uint32_t penv, int tail)
lerror(ArgError, "prog1: too few arguments"); lerror(ArgError, "prog1: too few arguments");
v = Stack[saveSP+1]; v = Stack[saveSP+1];
break; break;
case F_ASSQ:
argcount("assq", nargs, 2);
v = assq(Stack[SP-2], Stack[SP-1]);
break;
case F_FOR: case F_FOR:
argcount("for", nargs, 3); argcount("for", nargs, 3);
lo = tofixnum(Stack[SP-3], "for"); lo = tofixnum(Stack[SP-3], "for");

View File

@ -112,7 +112,7 @@ enum {
F_EVAL, F_EVALSTAR, F_APPLY, F_PROG1, F_RAISE, F_EVAL, F_EVALSTAR, F_APPLY, F_PROG1, F_RAISE,
F_ADD, F_SUB, F_MUL, F_DIV, F_LT, F_BNOT, F_BAND, F_BOR, F_BXOR, F_ASH, F_ADD, F_SUB, F_MUL, F_DIV, F_LT, F_BNOT, F_BAND, F_BOR, F_BXOR, F_ASH,
F_COMPARE, F_COMPARE,
F_VECTOR, F_AREF, F_ASET, F_LENGTH, F_ASSQ, F_FOR, F_VECTOR, F_AREF, F_ASET, F_LENGTH, F_FOR,
F_TRUE, F_FALSE, F_NIL, F_TRUE, F_FALSE, F_NIL,
N_BUILTINS, N_BUILTINS,
}; };

View File

@ -264,7 +264,7 @@ value_t fl_string_inc(value_t *args, u_int32_t nargs)
while (cnt--) { while (cnt--) {
if (i >= len) if (i >= len)
bounds_error("string.inc", args[0], args[1]); bounds_error("string.inc", args[0], args[1]);
u8_inc(s, &i); (void)(isutf(s[++i]) || isutf(s[++i]) || isutf(s[++i]) || ++i);
} }
return size_wrap(i); return size_wrap(i);
} }
@ -285,7 +285,7 @@ value_t fl_string_dec(value_t *args, u_int32_t nargs)
while (cnt--) { while (cnt--) {
if (i == 0) if (i == 0)
bounds_error("string.dec", args[0], args[1]); bounds_error("string.dec", args[0], args[1]);
u8_dec(s, &i); (void)(isutf(s[--i]) || isutf(s[--i]) || isutf(s[--i]) || --i);
} }
return size_wrap(i); return size_wrap(i);
} }

View File

@ -60,14 +60,6 @@
(map (lambda (c) (if (pair? c) (cadr c) #f)) binds)))) (map (lambda (c) (if (pair? c) (cadr c) #f)) binds))))
#f)) #f))
(define (nconc . lsts)
(cond ((null? lsts) ())
((null? (cdr lsts)) (car lsts))
((null? (car lsts)) (apply nconc (cdr lsts)))
(#t (prog1 (car lsts)
(set-cdr! (last (car lsts))
(apply nconc (cdr lsts)))))))
(define (append . lsts) (define (append . lsts)
(cond ((null? lsts) ()) (cond ((null? lsts) ())
((null? (cdr lsts)) (car lsts)) ((null? (cdr lsts)) (car lsts))
@ -81,10 +73,6 @@
(cond ((atom? lst) #f) (cond ((atom? lst) #f)
((equal? (car lst) item) lst) ((equal? (car lst) item) lst)
(#t (member item (cdr lst))))) (#t (member item (cdr lst)))))
(define (memq item lst)
(cond ((atom? lst) #f)
((eq? (car lst) item) lst)
(#t (memq item (cdr lst)))))
(define (memv item lst) (define (memv item lst)
(cond ((atom? lst) #f) (cond ((atom? lst) #f)
((eqv? (car lst) item) lst) ((eqv? (car lst) item) lst)
@ -121,9 +109,6 @@
(define (cadr x) (car (cdr x))) (define (cadr x) (car (cdr x)))
;(set! *special-forms* '(quote cond if and or while lambda trycatch
; set! begin))
(define (macroexpand e) (define (macroexpand e)
((label mexpand ((label mexpand
(lambda (e env f) (lambda (e env f)
@ -574,27 +559,27 @@
(define (string.trim s at-start at-end) (define (string.trim s at-start at-end)
(define (trim-start s chars i L) (define (trim-start s chars i L)
(if (and (< i L) (if (and (#.< i L)
(string.find chars (string.char s i))) (#.string.find chars (#.string.char s i)))
(trim-start s chars (string.inc s i) L) (trim-start s chars (#.string.inc s i) L)
i)) i))
(define (trim-end s chars i) (define (trim-end s chars i)
(if (and (> i 0) (if (and (> i 0)
(string.find chars (string.char s (string.dec s i)))) (#.string.find chars (#.string.char s (#.string.dec s i))))
(trim-end s chars (string.dec s i)) (trim-end s chars (#.string.dec s i))
i)) i))
(let ((L (length s))) (let ((L (#.length s)))
(string.sub s (string.sub s
(trim-start s at-start 0 L) (trim-start s at-start 0 L)
(trim-end s at-end L)))) (trim-end s at-end L))))
(define (string.map f s) (define (string.map f s)
(let ((b (buffer)) (let ((b (buffer))
(n (length s))) (n (#.length s)))
(let ((i 0)) (let ((i 0))
(while (< i n) (while (#.< i n)
(begin (io.putc b (f (string.char s i))) (begin (#.io.putc b (f (#.string.char s i)))
(set! i (string.inc s i))))) (set! i (#.string.inc s i)))))
(io.tostring! b))) (io.tostring! b)))
(define (print-to-string v) (define (print-to-string v)

View File

@ -137,6 +137,8 @@ for internal use:
instead, unless the value is part of an aggregate (e.g. struct). instead, unless the value is part of an aggregate (e.g. struct).
. this avoids allocating a new type for every size. . this avoids allocating a new type for every size.
. and/or add function array.alloc . and/or add function array.alloc
x preallocate all byte,int8,uint8 values, and some wchars (up to 0x31B7?)
. this made no difference in a string.map microbenchmark
bugs: bugs:
* with the fully recursive (simpler) relocate(), the size of cons chains * with the fully recursive (simpler) relocate(), the size of cons chains
@ -957,8 +959,6 @@ consolidated todo list as of 8/30:
- eliminate string copy in lerror() when possible - eliminate string copy in lerror() when possible
* fix printing lists of short strings * fix printing lists of short strings
- preallocate all byte,int8,uint8 values, and some wchars
- remaining c types - remaining c types
- remaining cvalues functions - remaining cvalues functions
- finish ios - finish ios