-
Notifications
You must be signed in to change notification settings - Fork 50
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changed non-destructive list-insert for 0th position to a desctructiv… #369
base: cl-compatible
Are you sure you want to change the base?
Changed non-destructive list-insert for 0th position to a desctructiv… #369
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your contribution.
However, there are some problems that should be fixed before merging:
- You modify a total of 5 files, but we only have interest in
common.l
. Please remove the other 4 files from this PR (eusmap
,include
,Makefile
andcommon.l~
) - It would also be nice to have destructive effect for null lists (not only for zero pos).
nreverse
is allowed to have arbitrary side effects. From CLHS:
(setq l (list 1 2 3)) => (1 2 3)
(nreverse l) => (3 2 1)
l => implementation-dependent
In eus it appears to be granted to have the list match the result, but code should not depend on this.
Lines 249 to 301 in 9cfd655
pointer NREVERSE(ctx,n,argv) | |
register context *ctx; | |
int n; | |
pointer argv[]; | |
{ register pointer a=argv[0],r=NIL, *vp; | |
register eusinteger_t i,k,s,kk,x,y; | |
register byte *cp; | |
ckarg(1); | |
if (a==NIL) return(NIL); | |
else if (islist(a)) { | |
i=0; r=a; | |
while (islist(r)) { ckpush(ccar(r)); r=ccdr(r); i++;} | |
r=a; | |
while (i>0) { pointer_update(ccar(r),vpop()); r=ccdr(r); i--;} | |
return(a);} | |
else if (isarray(a)) { | |
if (a->c.ary.rank>makeint(1)) error(E_NOSEQ); | |
s=intval(a->c.ary.offset); | |
k=intval(a->c.ary.dim[0]); | |
a=a->c.ary.entity;} | |
else if (isvector(a)) { k=vecsize(a); s=0;} | |
else error(E_NOSEQ); | |
kk=k/2; vp=a->c.vec.v; | |
cp=a->c.str.chars; | |
switch(elmtypeof(a)) { | |
case ELM_BIT: | |
for(i=0; i<kk; i++, s++) { | |
x=bitref(a,s); | |
y=bitref(a,k-i-1); | |
#if (WORD_SIZE == 64) | |
if (y) a->c.ivec.iv[s/64] |= (1L<<(s%64)); | |
else a->c.ivec.iv[s/64] &= ~(1L<<(s%64)); | |
if (x) a->c.ivec.iv[(k-i-1)/64] |= (1L<<((k-i-1)%64)); | |
else a->c.ivec.iv[(k-i-1)/64] &= ~(1L<<((k-i-1)%64)); | |
#else | |
if (y) a->c.ivec.iv[s/32] |= (1<<(s%32)); | |
else a->c.ivec.iv[s/32] &= ~(1<<(s%32)); | |
if (x) a->c.ivec.iv[(k-i-1)/32] |= (1<<((k-i-1)%32)); | |
else a->c.ivec.iv[(k-i-1)/32] &= ~(1<<((k-i-1)%32)); | |
#endif | |
} | |
break; | |
case ELM_FOREIGN: cp=a->c.foreign.chars; | |
case ELM_CHAR: case ELM_BYTE: | |
for(i=0; i<kk; i++, s++) { | |
x=cp[s]; cp[s]=cp[k-i-1]; cp[k-i-1]=x;} | |
break; | |
default: | |
vp=a->c.vec.v; | |
for(i=0; i<kk; i++, s++) { | |
r=vp[s]; pointer_update(vp[s],vp[k-i-1]); vp[k-i-1]=r;} | |
break; } | |
return(a);} |
Ok, Thanks I will look into the changes. And can you please elaborate on the side effects of nreverse? |
In other words, the input may be destroyed as a way of optimizing the algorithm, having no guarantee that the result will correctly be stored in the input back again. In the case of sbcl, for example: CL-USER> (setq lst (list 1 2 3))
(1 2 3)
CL-USER> (nreverse lst)
(3 2 1)
CL-USER> lst
(1) |
I will try to find a work around. |
Changed non-destructive list-insert for 0th position to a destructive one