From 687f9c92d93242921853526686e156ea3e829108 Mon Sep 17 00:00:00 2001 From: Henry Rich Date: Sat, 19 Oct 2024 12:48:40 -0400 Subject: [PATCH] In error display, insert a space between { {. --- jsrc/d.c | 33 ++++++++++++++++++--------------- jsrc/r.c | 10 +++++----- test/gparse.ijs | 6 ++++++ 3 files changed, 29 insertions(+), 20 deletions(-) diff --git a/jsrc/d.c b/jsrc/d.c index 06b053e59..fa043a12e 100644 --- a/jsrc/d.c +++ b/jsrc/d.c @@ -63,14 +63,15 @@ void jtshowerr(J jt){F1PREFJT;C b[1+2*NETX],*p,*q,*r; static I jtdisp(J jt,A w,I nflag); // format one non-noun entity into the error line -// nflags contains display flags: 1=space before number, 2=parens around non-primitive +// nflag contains display flags: 1=space before number, 2=parens around non-primitive, 4=space before { // The entity came from a single sentence but may be compound. Display it on a single line +// returns new nflag, which is 4 if the primitive was { alone (the 1 and 2 flags must be 0 after primitive output) // maintenance note: don't use GA(). This gets called after jbreak, which causes all memory requests to fail. -static void jtdspell(J jt,C id,A w,I nflag){C c,s[5]; +static I jtdspell(J jt,C id,A w,I nflag){C c,s[5]; // constant verbs require looking at h - if(id==CFCONS){if((nflag&1))eputc(' '); eputv(FAV(w)->fgh[2]); eputc(':');} - else{ - // get fgh if any. Format f if any, then the primitive, then g if any. fgh are present only in ACV type (ASGN doesn't have them at all) + if(id==CFCONS){if((nflag&1))eputc(' '); eputv(FAV(w)->fgh[2]); eputc(':'); nflag=0; + }else{ + // get fgh if any. Format f if any, then the primitive, then g if any. fgh are present only in ACV type (ASGN doesn't have them at all), and not in primitives A f,g,h; if(AT(w)&VERB+ADV+CONJ){f=FAV(w)->fgh[0], g=id==CBOX?0:FAV(w)->fgh[1], h=FAV(w)->fgh[2];}else{f=g=h=0;} // plain value for fgh; ignore g field in BOX, which is there to resemble <@] if(id==CFORK){if(h==0){h=g; g=f; f=ds(CCAP);}}else h=0; // reconstitute [: g h; otherwise we display h only for fork @@ -80,25 +81,27 @@ static void jtdspell(J jt,C id,A w,I nflag){C c,s[5]; I parenhere=(g||h)&&(invisiblemod||nflag&2); // set if we need parens around our value if(parenhere)eputc('('); if(f)nflag=disp(f,0); // display left side if any - // display the primitive, with a leading space if it begins with inflection or a digit. Don't display the code for an invisible modifier - that's used only for ARs + // display the primitive, with a leading space if it begins with inflection, a digit, or {. Don't display the code for an invisible modifier - that's used only for ARs if(!invisiblemod){ s[0]=' '; s[4]=0; spellit(id,1+s); c=s[1]; - eputs(s+!(c==CESC1||c==CESC2||(nflag&1)&&((ctype[(UC)c]&~CA)==0))); + eputs(s+!(c==CESC1||c==CESC2||(nflag&4)&&c=='{'||(nflag&1)&&((ctype[(UC)c]&~CA)==0))); } - if(g)nflag=disp(g,2); // display right side if any - if(h)nflag=disp(h,2); // display end of fork/trident if any + nflag=(id==CFROM)<<2; // set flag bit 2 if { bare + if(g)nflag=disp(g,2|nflag); // display right side if any + if(h)nflag=disp(h,2|nflag); // display end of fork/trident if any if(parenhere)eputc(')'); } + R nflag; } static F1(jtsfn0){R sfn(0,w);} // return string form of full name for a NAME block EVERYFS(sfn0overself,jtsfn0,jtover,0,VFLAGNONE) -// print a noun; nflag if space needed before name/numeric; return new value of nflag +// print a word; nflag bits if (space needed before name/numeric),(parens needed),(space before { needed); return new value of nflag // maintenance note: don't use GA(). This gets called after jbreak, which causes all memory requests to fail. -static I jtdisp(J jt,A w,I nflag){B b=1&&AT(w)&NAME+NUMERIC; +static I jtdisp(J jt,A w,I nflag){B b=1&&AT(w)&NAME+NUMERIC; // b if this is name or numeric, which needs a space before the next name/numeric // if this is a noun from a (( )) block, we have to take its linear rep, since it might not be displayable in 1 line if(AFLAG(w)&AFDPAREN&&AT(w)&NOUN){ // linear rep may fail, or parts of it may fail; so we must reset errors. We set etxn neg to indicate that the error line is frozen @@ -107,7 +110,7 @@ static I jtdisp(J jt,A w,I nflag){B b=1&&AT(w)&NAME+NUMERIC; } // If this is a PPPP, enclose it in () if(AFLAG(w)&AFDPAREN)eputc('('); // leading ( of PPPP - if(b&&(nflag&1))eputc(' '); + if(b&&(nflag&1))eputc(' '); // if prev was name/numeric and this is too, put in the space switch(CTTZ(AT(w))){ case B01X: case INTX: case INT2X: case INT4X: @@ -119,16 +122,16 @@ static I jtdisp(J jt,A w,I nflag){B b=1&&AT(w)&NAME+NUMERIC; if(!(AT(w)&BOXMULTIASSIGN)){eputs(" a:"+!(nflag&1)); break;} // If this is an array of names, turn it back into a character string with spaces between // we can't do this by simply executing }: (string&.> names) ,&.> ' ' because if we are out of memory we need to get the string out. So we do it by hand - eputc('\''); DO(AN(w), if(i!=0)eputc(' '); A b=AAV(w)[i]; ep(AN(b),NAV(b)->s);) eputc('\''); break; + eputc('\''); DO(AN(w), if(i!=0)eputc(' '); A bx=AAV(w)[i]; ep(AN(bx),NAV(bx)->s);) eputc('\''); break; case LITX: eputq(w,(nflag&1)); break; case NAMEX: ep(AN(w),NAV(w)->s); if(unlikely((AT(w)&NAMEABANDON)!=0)){ep(2,"_:");} break; case LPARX: eputc('('); break; case RPARX: eputc(')'); break; case ASGNX: dspell(CAV(w)[0],w,(nflag&1)); break; case MARKX: break; - default: dspell(FAV(w)->id,w,(nflag&1)|(AFLAG(w)&AFDPAREN?0:2)); break; // force parens on non-primitive if not PPPP + default: b|=dspell(FAV(w)->id,w,(nflag&5)|(AFLAG(w)&AFDPAREN?0:2)); break; // VERB comes here - force parens on non-primitive if not PPPP, and pass space-before-{ flag in & out } - if(AFLAG(w)&AFDPAREN)eputc(')'); // trailing ) of PPPP + if(AFLAG(w)&AFDPAREN){eputc(')'); b&=~4;} // trailing ) of PPPP, which extinguishes the need for space before { R b; // new nflag } diff --git a/jsrc/r.c b/jsrc/r.c index 3a3da8117..e3fdb95c6 100644 --- a/jsrc/r.c +++ b/jsrc/r.c @@ -342,15 +342,15 @@ static F2(jtxrep){A h,*hv,*v,x,z,*zv;CW*u;I i,j,n,q[3],*s;V*wv; if(!(h&&CCOLONE==wv->id))R reshape(v2(0L,3L),ds(CACE)); // if not explicit defn or no body, return empty hv=AAV(h); x=hv[j]; v=CWBASE(x); n=AN(x)==0?0:CWNC(x)-1; // empty x is not formatted control words - GATV0(z,BOX,3*n,2); s=AS(z); s[0]=n; s[1]=3; + GATV0(z,BOX,3*n,2); s=AS(z); s[0]=n; s[1]=3; // allocate result area zv=AAV(z); UI4 prevorigt=0; // we must revert the change of BBEND END BB[END] to BBEND BBEND BB[END] - for(i=0;i>TCESXTYPEX; if(prevorigt==CBBLOCKEND&&newt==CBBLOCKEND){newt=CEND; tcesx^=(CBBLOCKEND^CEND)<tcesx>>TCESXTYPEX; q[1]=u->go; q[1]=q[1]>=CWMAX?65535:q[1]; q[2]=u->source; RZ(*zv++=incorp(vec(INT,3L,q))); // 65535 for testcases - RZ(*zv++=incorp(unparse1(u,vec(BOX,(u[1].tcesx-u[0].tcesx)&TCESXSXMSK,&v[u[0].tcesx&TCESXSXMSK]),-1L,0L))); + RZ(*zv++=incorp(sc(i))); // box 0: line# + q[0]=u->tcesx>>TCESXTYPEX; q[1]=u->go; q[1]=q[1]>=CWMAX?65535:q[1]; q[2]=u->source; RZ(*zv++=incorp(vec(INT,3L,q))); // Box 1: cwtype, go, source line. 65535 for testcases + RZ(*zv++=incorp(unparse1(u,vec(BOX,(u[1].tcesx-u[0].tcesx)&TCESXSXMSK,&v[u[0].tcesx&TCESXSXMSK]),-1L,0L))); // box 2: line text } R z; } /* explicit representation -- h parameter for : definitions */ diff --git a/test/gparse.ijs b/test/gparse.ijs index d8592383e..ddae24efa 100644 --- a/test/gparse.ijs +++ b/test/gparse.ijs @@ -196,6 +196,12 @@ a =: 'a' '|domain error: efx| a +__ _1' -:&(}.~ i:&'|') efx 'a + __ _1.' '|domain error: efx| a +_. _1' -:&(}.~ i:&'|') efx 'a + _. _1.' +NB. { followed by {. adds space +'|domain error: efx| { {.2 +a:' -:&(}.~ i:&'|') efx '{ {. 2 + a:' +'|domain error: efx| { {.2 +a:' -:&(}.~ i:&'|') efx '{ {. 2 + a:' +'|domain error: efx| {+2 +a:' -:&(}.~ i:&'|') efx '{ + 2 + a:' + + 4!:55 ;:'a aa bc locnm multi swd t '