view sl.c @ 0:e0bbaa717f41 draft default tip

lol J
author Jordi Gutiérrez Hermoso <jordigh@octave.org>
date Mon, 25 Nov 2013 11:56:30 -0500
parents
children
line wrap: on
line source

/* Copyright 1990-2011, Jsoftware Inc.  All rights reserved. */
/* License in license.txt.                                   */
/*                                                                         */
/* Symbol Table: Locales                                                   */

#include "j.h"


A jtstcreate(J jt,C k,I p,I n,C*u){A g,*pv,x,y;C s[20];I m,*nv;L*v;
 GA(g,SYMB,ptab[p],1,0); 
 RZ(v=symnew(AV(g))); v->flag|=LINFO; v->sn=jt->symindex++;
 switch(k){
  case 0:  /* named    locale */
   RZ(x=nfs(n,u));
   LOCNAME(g)=x; LOCPATH(g)=ra(1==n&&'z'==*u?vec(BOX,0L,0L):zpath);
   symbis(x,g,jt->stloc);
   break;
  case 1:  /* numbered locale */
   ASSERT(0<=jt->stmax,EVLOCALE);
   sprintf(s,FMTI,n); RZ(x=nfs(strlen(s),s));
   LOCNAME(g)=x; LOCPATH(g)=ra(zpath);
   ++jt->stused;
   m=AN(jt->stnum);
   if(m<jt->stused){
    x=ext(1,jt->stnum); y=ext(1,jt->stptr); RZ(x&&y); jt->stnum=x; jt->stptr=y;
    nv=m+AV(jt->stnum); pv=m+AAV(jt->stptr); DO(AN(x)-m, *nv++=-1; *pv++=0;); 
   }
   pv=AAV(jt->stptr);
   DO(AN(jt->stnum), if(!pv[i]){pv[i]=ra(g); *(i+AV(jt->stnum))=n; break;});
   jt->stmax=n<IMAX?MAX(jt->stmax,1+n):-1;
   break;
  case 2:  /* local symbol table */
   ;
 }
 R g;
}    /* create locale, named (0==k) or numbered (1==k) */

B jtsymbinit(J jt){A q;I n=40;
 jt->locsize[0]=3;  /* default hash table size for named    locales */
 jt->locsize[1]=2;  /* default hash table size for numbered locales */
 RZ(symext(0));     /* initialize symbol pool                       */
 GA(q,SYMB,ptab[3],1,0); jt->stloc=q;
 RZ(q=apv(n,-1L,0L));    jt->stnum=q;
 GA(q,INT,n,1,0);        jt->stptr=q; memset(AV(q),C0,n*SZI);
 RZ(jt->global=stcreate(0,5L,4L,"base"));
 RZ(           stcreate(0,7L,1L,"z"   ));
 R 1;
}


F1(jtlocsizeq){I*v; ASSERTMTV(w); v=jt->locsize; R v2(v[0],v[1]);}
     /* 9!:38 default locale size query */

F1(jtlocsizes){I p,q,*v;
 RZ(w);
 ASSERT(1==AR(w),EVRANK);
 ASSERT(2==AN(w),EVLENGTH);
 RZ(w=vi(w)); v=AV(w); p=v[0]; q=v[1];
 ASSERT(0<=p&&0<=q,EVDOMAIN);
 ASSERT(p<nptab&&q<nptab,EVLIMIT);
 jt->locsize[0]=p;
 jt->locsize[1]=q;
 R mtm;
}    /* 9!:39 default locale size set */


static A jtstfindnum(J jt,B b,I k){A y;I j;
 RZ(y=indexof(jt->stnum,sc(k))); j=*AV(y); 
 if(j<AN(jt->stnum))R*(j+AAV(jt->stptr)); 
 else if(b){ASSERT(k>=jt->stmax,EVLOCALE); R stcreate(1,jt->locsize[1],k,0L);}
 else R 0;
}    /* stfind for numbered locales */

A jtstfind(J jt,B b,I n,C*u){I old;L*v;
 if(!n){n=4; u="base";}
 if('9'>=*u)R stfindnum(b,strtol(u,NULL,10));
 else{
  old=jt->tbase+jt->ttop; v=probe(nfs(n,u),jt->stloc); tpop(old);
  R v?v->val:b?stcreate(0,jt->locsize[0],n,u):0;
}}   /* find the symbol table for locale u, create if b and non-existent */

static A jtvlocnl(J jt,B b,A w){A*wv,y;C*s;I i,m,n,wd;
 RZ(w);
 n=AN(w);
 ASSERT(!n||BOX&AT(w),EVDOMAIN);
 wv=AAV(w); wd=(I)w*ARELATIVE(w);
 for(i=0;i<n;++i){
  y=WVR(i); m=AN(y); s=CAV(y);
  ASSERT(1>=AR(y),EVRANK);
  ASSERT(m,EVLENGTH);
  ASSERT(LIT&AT(y),EVDOMAIN);
  if(b)ASSERTN(vlocnm(m,s),EVILNAME,nfs(m,s));
 }
 R w;
}    /* validate namelist of locale names */

static I jtprobenum(J jt,C*u){I j; 
 RE(j=i0(indexof(jt->stnum,sc((I)strtol(u,NULL,(I)10))))); 
 R j<AN(jt->stnum)?j:-1;
}    /* probe for numbered locales */


F1(jtlocnc){A*wv,y,z;C c,*u;I i,m,n,wd,*zv;
 RZ(vlocnl(0,w));
 n=AN(w); wv=AAV(w); wd=(I)w*ARELATIVE(w);
 GA(z,INT,n,AR(w),AS(w)); zv=AV(z);
 for(i=0;i<n;++i){
  y=WVR(i); m=AN(y); u=CAV(y); c=*u; 
  if(!vlocnm(m,u))zv[i]=-2;
  else if(c<='9') zv[i]=0<=probenum(u)?1:-1;
  else            zv[i]=probe(nfs(m,u),jt->stloc)?0:-1;
 }
 R z;
}    /* 18!:0 locale name class */

static F1(jtlocnlx){A*pv,y,*yv,z;B*wv;C s[20];I m=0,n=0,*nv;
 RZ(w=cvt(B01,w)); wv=BAV(w); DO(AN(w), m|=1+wv[i];);
 if(1&m)z=nlsym(jt->stloc);
 if(2&m){
  GA(y,BOX,jt->stused,1,0); yv=AAV(y); pv=AAV(jt->stptr); nv=AV(jt->stnum);
  DO(AN(jt->stptr), if(pv[i]){sprintf(s,FMTI,nv[i]); 
      if(jt->nla[*s]){RZ(yv[n++]=cstr(s)); if(n==jt->stused)break;}});
  y=take(sc(n),y);
 }
 z=0==m?mtv:1==m?z:2==m?y:over(y,z);
 R grade2(z,ope(z));
}

F1(jtlocnl1){memset(jt->nla,C1,256); R locnlx(w);}
    /* 18!:1 locale name list */

F2(jtlocnl2){UC*u;
 RZ(a&&w);
 ASSERT(LIT&AT(a),EVDOMAIN);
 memset(jt->nla,C0,256); 
 u=UAV(a); DO(AN(a),jt->nla[*u++]=1;);
 R locnlx(w); 
}    /* 18!:1 locale name list */

static A jtlocale(J jt,B b,A w){A g,*wv,y;I wd;
 RZ(vlocnl(1,w));
 wv=AAV(w); wd=(I)w*ARELATIVE(w);
 DO(AN(w), y=WVR(i); RZ(g=stfind(b,AN(y),CAV(y))););
 R g;
}    /* last locale (symbol table) from boxed locale names */

F1(jtlocpath1){A g; F1RANK(0,jtlocpath1,0); RZ(g=locale(1,w)); R LOCPATH(g);}
     /* 18!:2  query locale path */

F2(jtlocpath2){A g,x;
 F2RANK(1,0,jtlocpath2,0);
 RZ(  locale(1,a)); RZ(x=every(ravel(a),0L,jtravel));
 RZ(g=locale(1,w));
 fa(LOCPATH(g)); LOCPATH(g)=ra(x);
 R mtm;
}    /* 18!:2  set locale path */


static F2(jtloccre){A g,y;C*s;I n,p,*u;L*v;
 RZ(a&&w);
 if(MARK&AT(a))p=jt->locsize[0]; else{RE(p=i0(a)); ASSERT(0<=p,EVDOMAIN); ASSERT(p<nptab,EVLIMIT);}
 y=AAV0(w); n=AN(y); s=CAV(y);
 if(v=probe(nfs(n,s),jt->stloc)){
  g=v->val; 
  u=1+AV(g); DO(AN(g)-1, ASSERT(!u[i],EVLOCALE););
  RZ(symfreeh(g,v));
 } 
 RZ(stcreate(0,p,n,s));
 R box(ca(y));
}    /* create a locale named w with hash table size a */

static F1(jtloccrenum){C s[20];I k=jt->stmax,p;
 RZ(w);
 if(MARK&AT(w))p=jt->locsize[1]; else{RE(p=i0(w)); ASSERT(0<=p,EVDOMAIN); ASSERT(p<nptab,EVLIMIT);}
 RZ(stcreate(1,p,k,0L));
 sprintf(s,FMTI,k); 
 R box(cstr(s));
}    /* create a numbered locale with hash table size n */

F1(jtloccre1){
 RZ(w);
 if(AN(w))R rank2ex(mark,vlocnl(1,w),0L,0L,0L,jtloccre);
 ASSERT(1==AR(w),EVRANK);
 R loccrenum(mark);
}    /* 18!:3  create locale */

F2(jtloccre2){
 RZ(a&&w);
 if(AN(w))R rank2ex(a,vlocnl(1,w),0L,0L,0L,jtloccre);
 ASSERT(1==AR(w),EVRANK);
 R rank1ex(a,0L,0L,jtloccrenum);
}    /* 18!:3  create locale with specified hash table size */


F1(jtlocswitch){A g; 
 ASSERT(!AR(w),EVRANK); 
 RZ(g=locale(1,w)); 
 jt->global=g; jt->stswitched=1;
 R mtm;
}    /* 18!:4  switch locale */

F1(jtlocname){A g=jt->global;
 ASSERTMTV(w);
 ASSERT(g,EVLOCALE);
 R box(sfn(0,LOCNAME(g)));
}    /* 18!:5  current locale name */

static SYMWALK(jtlocmap1,I,INT,18,3,1,
    {I t=AT(d->val);
     *zv++=i; 
     *zv++=t&NOUN?0:t&VERB?3:t&ADV?1:t&CONJ?2:t&SYMB?6:-2;
     *zv++=(I)sfn(1,d->name);})

F1(jtlocmap){A g,q,x,y,*yv,z,*zv;I c=-1,d,j=0,m,*qv,*xv;
 RZ(w);
 ASSERT(!AR(w),EVRANK);
 RE(g=equ(w,zero)?jt->stloc:equ(w,one)?jt->local:locale(0,w));
 ASSERT(g,EVLOCALE);
 RZ(q=locmap1(g)); qv=AV(q);
 m=*AS(q);
 GA(x,INT,m*3,2,AS(q)); xv= AV(x);
 GA(y,BOX,m,  1,0    ); yv=AAV(y);
 DO(m, *xv++=d=*qv++; *xv++=j=c==d?1+j:0; *xv++=*qv++; c=d; *yv++=(A)*qv++;);
 GA(z,BOX,2,1,0); zv=AAV(z); zv[0]=x; zv[1]=y;
 R z;
}    /* 18!:30 locale map */

static SYMWALK(jtredefg,B,B01,100,1,1,RZ(redef(mark,d)))
     /* check for redefinition (erasure) of entire symbol table */

F1(jtlocexmark){A g,*pv,*wv,y,z;B b,c,*zv;C*u;I i,j,m,n,*nv,wd;L*v;
 RZ(vlocnl(1,w));
 n=AN(w); wv=AAV(w); wd=(I)w*ARELATIVE(w);
 nv=AV(jt->stnum); pv=AAV(jt->stptr);
 GA(z,B01,n,AR(w),AS(w)); zv=BAV(z);
 for(i=0;i<n;++i){
  zv[i]=1; y=WVR(i); g=0; m=AN(y); u=CAV(y); b='9'>=*u;
  if(b){j=probenum(u);               if(0<=j)g=pv[j]; }
  else {v=probe(nfs(m,u),jt->stloc); if(v   )g=v->val;}
  if(g){
   c=1;
   DO(1+jt->fcalli, if(g==jt->fcallg[i].g){jt->fcallg[i].flag=1+b; jt->fcallg[i].ptr=b?j:(I)v; c=0; break;});
   if(c){
    if(b){RZ(redefg(g)); RZ(symfreeh(g,0L)); pv[j]=0; nv[j]=-1; --jt->stused;}
    else {RZ(redefg(g)); RZ(symfreeh(g,v ));}
    if(g==jt->global)jt->global=0;
 }}}
 R z;
}    /* 18!:55 destroy a locale (but only mark for destruction if on stack) */

B jtlocdestroy(J jt,I i){A g,*pv;B b;I j,*nv;L*v;
 nv=AV(jt->stnum); pv=AAV(jt->stptr);
 g=jt->fcallg[i].g; b=1==jt->fcallg[i].flag?0:1;
 if(b){j=(I )jt->fcallg[i].ptr; RZ(redefg(g)); RZ(symfreeh(g,0L)); pv[j]=0; nv[j]=-1; --jt->stused;}
 else {v=(L*)jt->fcallg[i].ptr; RZ(redefg(g)); RZ(symfreeh(g,v ));}
 if(g==jt->global)jt->global=0;
 R 1;
}    /* destroy locale jt->callg[i] (marked earlier by 18!:55) */