Skip to content

Commit

Permalink
In error display, insert a space between { {.
Browse files Browse the repository at this point in the history
  • Loading branch information
HenryHRich committed Oct 19, 2024
1 parent 32fd40c commit 687f9c9
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 20 deletions.
33 changes: 18 additions & 15 deletions jsrc/d.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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:
Expand All @@ -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
}

Expand Down
10 changes: 5 additions & 5 deletions jsrc/r.c
Original file line number Diff line number Diff line change
Expand Up @@ -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<n;++i){
for(i=0;i<n;++i){ // loop over each line of the definition
UI4 tcesx=CWTCESX(v,~i); I newt=tcesx>>TCESXTYPEX; if(prevorigt==CBBLOCKEND&&newt==CBBLOCKEND){newt=CEND; tcesx^=(CBBLOCKEND^CEND)<<TCESXTYPEX;} prevorigt=newt; // undo the BBLOCKEND swap
CW u[2]; u[0].tcesx=tcesx; u[0].go=~CWGO(v,-(n+1),~i); u[0].source=CWSOURCE(v,-(n+1),~i); u[1].tcesx=CWTCESX(v,~(i+1)); // create CW to use
RZ(*zv++=incorp(sc(i)));
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))); // 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 */
Expand Down
6 changes: 6 additions & 0 deletions test/gparse.ijs
Original file line number Diff line number Diff line change
Expand Up @@ -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 '


Expand Down

0 comments on commit 687f9c9

Please sign in to comment.