// code to relocate cons chains iteratively pcdr = &cdr_(nc); while (iscons(d)) { if (car_(d) == FWD) { *pcdr = cdr_(d); return first; } *pcdr = nc = mk_cons(); a = car_(d); v = cdr_(d); car_(d) = FWD; cdr_(d) = nc; car_(nc) = relocate(a); pcdr = &cdr_(nc); d = v; } *pcdr = d; /* f = *rest; *rest = NIL; while (iscons(f)) { // nreverse! v = cdr_(f); cdr_(f) = *rest; *rest = f; f = v; }*/ int favailable(FILE *f) { fd_set set; struct timeval tv = {0, 0}; int fd = fileno(f); FD_ZERO(&set); FD_SET(fd, &set); return (select(fd+1, &set, NULL, NULL, &tv)!=0); } static void print_env(value_t *penv) { printf("<[ "); while (issymbol(*penv) && *penv!=NIL) { print(stdout, *penv, 0); printf(" "); penv++; print(stdout, *penv, 0); printf(" "); penv++; } printf("] "); print(stdout, *penv, 0); printf(">\n"); } #else PUSH(NIL); PUSH(NIL); value_t *rest = &Stack[SP-1]; // build list of rest arguments // we have to build it forwards, which is tricky while (iscons(v)) { v = eval(car_(v)); PUSH(v); v = cons_(&Stack[SP-1], &NIL); POP(); if (iscons(*rest)) cdr_(*rest) = v; else Stack[SP-2] = v; *rest = v; v = Stack[saveSP] = cdr_(Stack[saveSP]); } POP(); #endif // this version uses collective allocation. about 7-10% // faster for lists with > 2 elements, but uses more // stack space i = SP; while (iscons(v)) { v = eval(car_(v)); PUSH(v); v = Stack[saveSP] = cdr_(Stack[saveSP]); } if ((int)SP==i) { PUSH(NIL); } else { e = v = cons_reserve(nargs=(SP-i)); for(; i < (int)SP; i++) { car_(v) = Stack[i]; v = cdr_(v); } POPN(nargs); PUSH(e); } value_t list_to_vector(value_t l) { value_t v; size_t n = llength(l), i=0; v = alloc_vector(n, 0); while (iscons(l)) { vector_elt(v,i) = car_(l); i++; l = cdr_(l); } return v; }