|
@@ -121,7 +121,7 @@ S Bread(Bt*buf){if(buf->used==0||buf->str[buf->used-1])Bappend(buf,0);
|
|
|
S str=buf->str;
|
|
|
FR(buf);R str;}
|
|
|
V BappendS(Bt*buf,S s){WH(*s)Bappend(buf,*s++);}
|
|
|
-typedef struct{enum Tkt{T_PUNCT,T_LPAR,T_RPAR,T_NAME,T_NUM,T_QUOTE}tag;
|
|
|
+typedef struct{enum Tkt{T_PUNCT,T_LPAR,T_RPAR,T_NAME,T_NUM,T_BNUM,T_QUOTE}tag;
|
|
|
S text;}Tkt;
|
|
|
typedef struct{S source;
|
|
|
Z len;
|
|
@@ -164,7 +164,13 @@ V Llex(Lt*lexer,S s){lexer->source=s;
|
|
|
WH(lexer->pos<lexer->len){C c=Llook(lexer,0);
|
|
|
if(c=='/'&&!lexer->tokens->data)BR;
|
|
|
if(isspace(c)){Leat(lexer);
|
|
|
- if(Llook(lexer,0)=='/')BR;}elif(isdigit(c)||c=='.'){Llnum(lexer,F);}elif(isalpha(c)){Bt*buf=Bnew();
|
|
|
+ if(Llook(lexer,0)=='/')BR;}elif(c=='0'&&(Llook(lexer,1)=='x'||Llook(lexer,1)=='b'||Llook(lexer,1)=='o')){Leat(lexer);
|
|
|
+ Bt*buf=Bnew();
|
|
|
+ C b=Leat(lexer);
|
|
|
+ Bappend(buf,b);
|
|
|
+ cS base=b=='x'?"0123456789abcdefABCDEF":b=='b'?"01":"01234567";
|
|
|
+ WH(strchr(base,Llook(lexer,0))!=N)Bappend(buf,Leat(lexer));
|
|
|
+ LpT(lexer,T_BNUM,Bread(buf));}elif(isdigit(c)||c=='.'){Llnum(lexer,F);}elif(isalpha(c)){Bt*buf=Bnew();
|
|
|
do{Bappend(buf,Leat(lexer));}WH(isalpha(Llook(lexer,0)));
|
|
|
if(buf->used==1&&Llook(lexer,0)=='.'){Bappend(buf,Leat(lexer));
|
|
|
LpT(lexer,T_PUNCT,Bread(buf));}else LpT(lexer,T_NAME,Bread(buf));}elif(c=='('||c==')'){Leat(lexer);
|
|
@@ -431,6 +437,16 @@ B Cap(Ar*a){for(Z i=0;i<a->length;i++){Vt*v=a->data[i];
|
|
|
B Aap(Ar*a){for(Z i=0;i<a->length;i++){Vt*v=a->data[i];
|
|
|
if(v->tag!=ARRAY)R F;}
|
|
|
R T;}
|
|
|
+B nonar(Ar*a){if(!a->data)R T;
|
|
|
+ for(Z i=1;i<a->length;i++){Vt*v=a->data[i];
|
|
|
+ if(v->tag==ARRAY)R F;}
|
|
|
+ R T;}
|
|
|
+B matp(Ar*a){if(a->length<2)R F;
|
|
|
+ Z rwl=((Vt*)a->data[0])->val.array->length;
|
|
|
+ if(rwl<1)R F;
|
|
|
+ for(Z i=0;i<a->length;i++){Vt*v=a->data[i];
|
|
|
+ if(v->tag!=ARRAY||v->val.array->length!=rwl||!nonar(v->val.array)||Cap(v->val.array))R F;}
|
|
|
+ R T;}
|
|
|
S Vshow(Vt*v);
|
|
|
S show_array(Vt*v){if(v->tag!=ARRAY)R Vshow(v);
|
|
|
Ar*t=v->val.array;
|
|
@@ -445,7 +461,31 @@ S show_array(Vt*v){if(v->tag!=ARRAY)R Vshow(v);
|
|
|
BappendS(buf,ts);
|
|
|
FR(ts);
|
|
|
if(i!=t->length-1)Bappend(buf,' ');}
|
|
|
- else for(Z i=0;i<t->length;i++){S ts=show_array(t->data[i]);
|
|
|
+ elif(matp(t)){Z rwl=0;
|
|
|
+ Z pad=0;
|
|
|
+ Z padl=0;
|
|
|
+ Ar*ss=An();
|
|
|
+ for(Z i=0;i<t->length;i++){Vt*rw=t->data[i];
|
|
|
+ Ar*rwt=rw->val.array;
|
|
|
+ if(rwl<1)rwl=rwt->length;
|
|
|
+ for(Z j=0;j<rwt->length;j++){S s=Vshow(rwt->data[j]);
|
|
|
+ Z z=strlen(s);
|
|
|
+ if(z>pad)pad=z;
|
|
|
+ if(j==0&&z>padl)padl=z;
|
|
|
+ Ap(ss,s);}}
|
|
|
+ Z k=0;
|
|
|
+ for(Z i=0;i<ss->length;i++){S s=ss->data[i];
|
|
|
+ Z mp=(k==0?padl:pad)-strlen(s);
|
|
|
+ WH(mp--)Bappend(buf,' ');
|
|
|
+ BappendS(buf,s);
|
|
|
+ FR(s);
|
|
|
+ if(i!=ss->length-1){if(k==rwl-1){k=0;
|
|
|
+ Bappend(buf,'\n');}else{Bappend(buf,' ');
|
|
|
+ k++;}}}
|
|
|
+ FR(ss->data);
|
|
|
+ FR(ss);}
|
|
|
+ else for(Z i=0;i<t->length;i++){Vt*rw=t->data[i];
|
|
|
+ S ts=show_array(rw);
|
|
|
BappendS(buf,ts);
|
|
|
FR(ts);
|
|
|
if(i!=t->length-1)Bappend(buf,'\n');}
|
|
@@ -1340,7 +1380,7 @@ Vt*vreshape(St*st,vt*self,Vt*x,Vt*y){if(yt!=ARRAY)y=venlist(st,N,y);
|
|
|
Ar*t=An();
|
|
|
flatten(y,t);
|
|
|
r=Ank(k);
|
|
|
- for(Z i=0;i<k;i++)r->data[i]=t->data[i>=t->length?t->length-1:i];}elif(xal>1){Vt*a=xad[0];
|
|
|
+ for(Z i=0;i<k;i++)r->data[i]=t->data[i%t->length];}elif(xal>1){Vt*a=xad[0];
|
|
|
if(a->tag!=NUM)R st->udf;
|
|
|
Vt*b=xad[1];
|
|
|
if(a->tag!=NUM)R st->udf;
|
|
@@ -1348,8 +1388,9 @@ Vt*vreshape(St*st,vt*self,Vt*x,Vt*y){if(yt!=ARRAY)y=venlist(st,N,y);
|
|
|
Z l=fabs(b->val.number);
|
|
|
y=vreshape(st,self,venlist(st,N,Vnn(k*l)),y);
|
|
|
r=An();
|
|
|
+ Z yp=0;
|
|
|
WH(k--){Ar*rw=An();
|
|
|
- for(Z i=0;i<l;i++)Ap(rw,yad[i]);
|
|
|
+ for(Z i=0;i<l;i++)Ap(rw,yad[yp++]);
|
|
|
Ap(r,Vna(rw));}}else R st->udf;R Vna(r);}
|
|
|
Vt*vrepr(St*st,vt*self,Vt*x){S s=Vshow(x);
|
|
|
Ar*r=An();
|
|
@@ -1645,8 +1686,10 @@ Vt*vcombine(St*st,vt*self,Vt*x,Vt*y){if(xt==NUM&&yt==NUM&&!spnp(xn)&&!spnp(yn)){
|
|
|
y=vbase(st,N,NUMS[10],y);
|
|
|
Vt*n=vjoin(st,N,x,y);R vunbase(st,N,NUMS[10],n);}
|
|
|
R _NAN;}
|
|
|
-Vt*voutof(St*st,vt*self,Vt*x,Vt*y){if(xt==NUM&&yt==NUM&&!spnp(xn)&&!spnp(yn)&&xn>0&&yn>0){U64 a=(U64)fabs(xn);
|
|
|
- U64 b=(U64)fabs(yn);R Vnn(factorial(b)/(factorial(a)*(a>=b?1:factorial(b-a))));}
|
|
|
+Vt*voutof(St*st,vt*self,Vt*x,Vt*y){if(xt==NUM&&yt==NUM&&!spnp(xn)&&!spnp(yn)){U64 a=(U64)fabs(xn);
|
|
|
+ U64 b=(U64)fabs(yn);
|
|
|
+ if(a==0)R NUMS[1];
|
|
|
+ if(b==0)R NUMS[0];R Vnn(factorial(b)/(factorial(a)*(a>=b?1:factorial(b-a))));}
|
|
|
R _NAN;}
|
|
|
Vt*vsort(St*st,vt*self,Vt*x){Vt*i=vgradeup(st,N,x);R tgth(st,st->at,x,i,0,0,st->at->rank[1],st->at->rank[2]);}
|
|
|
Vt*vunsort(St*st,vt*self,Vt*x){Vt*i=vgradedown(st,N,x);R tgth(st,st->at,x,i,0,0,st->at->rank[1],st->at->rank[2]);}
|
|
@@ -2090,6 +2133,9 @@ Nt*PPatom(Pt*parser){Tkt*tok=Plook(parser,0);
|
|
|
if(!node)node=PPcnjatom(parser);
|
|
|
if(!node)Perror(parser,"parse");BR;
|
|
|
CS T_NUM:node=Nnl(Vnn(strtod(tok->text,N)));BR;
|
|
|
+ CS T_BNUM:{if(!tok->text[1])Perror(parser,"trailing-base");
|
|
|
+ I base=tok->text[0]=='x'?16:tok->text[0]=='b'?2:8;
|
|
|
+ node=Nnl(Vnn(strtol(tok->text+1,N,base)));}BR;
|
|
|
CS T_NAME:node=Nnl(Vny(sdup(tok->text)));BR;
|
|
|
CS T_QUOTE:if(!*tok->text)node=Nnl(parser->st->unit);
|
|
|
elif(!*(tok->text+1))node=Nnl(Vnc(tok->text[0]));
|
|
@@ -2100,7 +2146,7 @@ Nt*PPatom(Pt*parser){Tkt*tok=Plook(parser,0);
|
|
|
if(!node)Perror(parser,"parse");
|
|
|
Peat(parser);R node;}
|
|
|
Nt*PPa(Pt*parser,Nt*a,enum Tkt tag){Tkt*tok;
|
|
|
- if((tok=Plook(parser,0))&&tok->tag==tag){Ar*as=An();
|
|
|
+ if((tok=Plook(parser,0))&&(tok->tag==tag||(tag==T_NUM&&tok->tag==T_BNUM))){Ar*as=An();
|
|
|
Ap(as,a->v);
|
|
|
do{a=PPatom(parser);
|
|
|
Ap(as,a->v);}WH((tok=Plook(parser,0))&&tok->tag==tag);R Nnl(Vna(as));}
|
|
@@ -2405,6 +2451,9 @@ cS SHELP =\
|
|
|
"'a'%2 / = nan, nan used to denote illegal numeric operation" "\n"\
|
|
|
"+1 2 3 / = udf, attempt to transpose flat vector, udf/undefined used to denote illegal operation" "\n"\
|
|
|
"5 5.5 -5 42 / number (double-precision floats)" "\n"\
|
|
|
+"1`000 1`000`000 /" "\n"\
|
|
|
+".5 .429 /" "\n"\
|
|
|
+"0xff 0o4 0b0101 /" "\n"\
|
|
|
"nan inf /" "\n"\
|
|
|
"'a' 'b' 'g' / chars (bytes)" "\n"\
|
|
|
"4t.0 / 0 NUL byte" "\n"\
|