--- stack/symbols.c 2003/08/04 11:23:43 1.1 +++ stack/symbols.c 2003/08/04 14:13:16 1.2 @@ -1282,6 +1282,78 @@ toss(env); if(env->err) return; } + +/* General assoc function */ +void assocgen(environment *env, funcp eqfunc) +{ + value *key, *item; + + /* Needs two values on the stack, the top one must be an association + list */ + if(env->head->type==empty || CDR(env->head)->type==empty) { + printerr("Too Few Arguments"); + env->err= 1; + return; + } + + if(CAR(env->head)->type!=tcons) { + printerr("Bad Argument Type"); + env->err= 2; + return; + } + + key=CAR(CDR(env->head)); + item=CAR(env->head); + + while(item->type == tcons){ + if(CAR(item)->type != tcons){ + printerr("Bad Argument Type"); + env->err= 2; + return; + } + push_val(env, key); + push_val(env, CAR(CAR(item))); + eqfunc(env); if(env->err) return; + + /* Check the result of 'eqfunc' */ + if(env->head->type==empty) { + printerr("Too Few Arguments"); + env->err= 1; + return; + } + if(CAR(env->head)->type!=integer) { + printerr("Bad Argument Type"); + env->err= 2; + return; + } + + if(CAR(env->head)->content.i){ + toss(env); if(env->err) return; + break; + } + toss(env); if(env->err) return; + + if(item->type!=tcons) { + printerr("Bad Argument Type"); + env->err= 2; + return; + } + + item=CDR(item); + } + + if(item->type == tcons){ /* A match was found */ + push_val(env, CAR(item)); + } else { + push_int(env, 0); + } + swap(env); if(env->err) return; + toss(env); if(env->err) return; + swap(env); if(env->err) return; + toss(env); +} + + /* 2: 3 => */ /* 1: [ [ 1 . 2 ] [ 3 . 4 ] ] => 1: [ 3 . 4 ] */ extern void assq(environment *env)