Logo Search packages:      
Sourcecode: gp2c version File versions  Download package

funcspec.c

/*
Copyright (C) 2000-2005  The PARI group.

This file is part of the GP2C package.

PARI/GP is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation. It is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY WHATSOEVER.

Check the License for details. You should have received a copy of it, along
with the package; see the file 'COPYING'. If not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */

#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "header.h"
#include "patchfunc.h"
extern int indent;
void patchfunclist(void)
{
  int i;
  for(i=0;patchfunc[i].gpname;i++)
  {
    int nf=getfunc(patchfunc[i].gpname);
    lfunc[nf].proto.code=patchfunc[i].code;
    functype(lfunc[nf])=patchfunc[i].type;
    funcmode(lfunc[nf])=patchfunc[i].mode;
    lfunc[nf].spec=patchfunc[i].spec;
  }
}
void printlistfunc(FILE *fout)
{
  int i;
  for(i=0;lfunc[i].gpname;i++)
    fprintf(fout,"%s %s %s\n",lfunc[i].gpname,lfunc[i].proto.cname,(lfunc[i].proto.code?lfunc[i].proto.code:""));
}
void checkisvar(int aff, const char *func, int *var, int *t)
{
  *var=aff;
  switch(tree[*var].f)
  {
    case Fentry:
      *t=Gnotype;
      break;
    case Ftag:
      *t=tree[*var].y;
      *var=tree[*var].x;
      if (tree[*var].f!=Fentry)
        die(aff,"incorrect syntax for %s",func);
      break;
    default:
      die(aff,"incorrect syntax for %s",func);
  }
}

int guesstype(int n)
{
  switch(tree[n].f)
  {
  case Fsmall:
    return Gsmall;
  case Fgnil:
    return Gvoid;
  case Ftag:
    return tree[n].y;
  case Fmat: case Fvec:
    return Gvec;
  case Fconst:
    switch(value[tree[n].x].type)
    {
    case CSTsmall:
      return Gsmall;
    case CSTint:
      return Gint;
    case CSTsmallreal:
    case CSTreal:
      return Greal;
    case CSTstr:
      return Gstr;
    }
  case Fentry:
    return vartype(ctxstack[getvarerr(n)]);
  case Fentryfunc:
    if (!strcmp(entryname(n),"length"))
      return Glg;
  default: /*FALL THROUGH*/
    return Gnotype;
  }
}

void genequal(int aff, const char *func, int *var, int *binf, int *t)
{
  if (tree[aff].f!=Faffect)
    die(aff,"incorrect syntax for %s",func);
  checkisvar(tree[aff].x,func,var,t);
  *binf=tree[aff].y;
}
void genequaltosmall(int binf,int bsup, int *tv)
{
  if (*tv==Gnotype)
  {
    int tinf=guesstype(binf);
    int tsup=guesstype(bsup);
    if  (is_subtype(tinf,Gsmall) && is_subtype(tsup,Gsmall))
      *tv=Gsmall;
    else
      *tv=Ggen;
  }
}

int addseqright(int seq, int n);
int gengerepile(int bl)
{
  int arg[4];
  block[bl].gc|=(1<<GCneeded);
  arg[0]=newnode(Fentry,newentry("btop"),-1);
  pushvar(arg[0],1<<Cuser,Gpari_sp,newcall("_avma",-1));
  arg[1]=newnode(Fentry,newentry("st_lim"),-1);
  pushvar(arg[1],1<<Cuser,Gpari_sp,
      newcall("_stack_lim",newnode(Flistarg,arg[0],newsmall(1))));
  arg[2]=(FC_gerepileall<0)?newnode(Fentry,newentry("bptr"),-1):GNOARG;
  arg[3]=newsmall(bl);
  return listtoseq(arg,4);
}

void gengerepileend(int bl)
{
  int gptr=newnode(Fentry,newentry("bptr"),-1);
  int blo=newsmall(bl);
  if (FC_gerepileall<0)
    pushvar(gptr,1<<Cuser,Ggptr,newcall("_gerepilelist",blo));
}

int newgetg(int v, int l, const char *t)
{
  return newcall("_cgetg", newnode(Flistarg, newnode(Flistarg,
          v, l), newstringnode(t,-1)));
}

int genblockinit(int seq, int start, int narg, int isglobal)
{
  int i;
  for(i=narg-1;i>=0;i--)
  {
    ctxvar *v=ctxstack+start+i;
    int val=v->initval;
    if (val>=0 && (isglobal || tree[val].f!=Fsmall))
    {
      int n=newnode(Faffect,newleaf(v->node),val);
      seq=addseqleft(n,seq);
      v->initval=-1;
    }
  }
  return seq;
}

/*
   The 6 operations which order is very important are
are:

  pushvar/newdecl(var)
  gpm=gengerepile(bl2);
  bseq=geninsertvar(arg,var)
  genblock(bseq,p)
  seq=addseqright(seq,newcall("_gerepilemany",gpm));
  gengerepileend(bl2);
  savx=s_ctx.n

  savx=s_ctx.n start the recording of var in the block
  pushvar/newdecl(var) must be before geninsert(arg,var) obviously,

  if you use geninsertvar to store the value a a node, then
  geninsertvar must be called before genblock and genblock must be
  called on the geninsertvar node, with p=-1 since the return value is really
  ignored.
  G.N.^H^H^H^HB.A. (well it still lacks 20 lines more to really be G.N.)*/
void genblockfuncspec(int n, int p, gpfunc *gp)
{
  int arg[STACKSZ];
  int nb;
  int y=tree[n].y;
  int binf,bsup,seq;
  int var=-1,vinf,vsup,vprime;
  int bseq=-1,aseq=-1,ret=-1;
  int tv;
  int gpm=-1,bl1,bl2;
  int savx;
  Clabel_t lab;
  switch(gp->spec)
  {
    case GPaddhelp:
    {  /*prototype vSs*/
      gpfunc *gp;
      int d, nf;
      nb=genlistargs(n,arg,2,2);
      d=detag(arg[0]);
      if (tree[d].f!=Fentry && !is_const(d,CSTstr))
        die(n,"Incorrect function name in addhelp");
      tree[d].f=Fconst;
      nf=getfunc(entryname(d)); gp=lfunc+nf;
      d=detag(arg[1]);
      if (tree[d].f!=Fentry && !is_const(d,CSTstr))
        die(n,"Incorrect help text in addhelp");
      gp->proto.help=entryname(d);
    }
    break;
  case GPgrandO:
    if (tree[y].f==Fentryfunc && tree[y].x==OPpow)
      tree[y]=tree[tree[y].y];
    tree[n].x=newentry("O(_^_)");
    genblock(y,n);
    break;
  case GPif:
    nb=genlistargs(n,arg,2,3);
    if (nb==3 && arg[2]==GNOARG)
      /*Some people type 'if(x!=0,print(x),)'*/
      nb--;
    if (nb==3 && arg[1]==GNOARG)
    {
      /*Some people type 'if(x!=0,,print(x))'*/
      arg[0]=newopcall(OPnb,arg[0],-1);
      arg[1]=arg[2];
      nb--;
    }
    if (tree[arg[0]].f==Fsmall && tree[arg[0]].x)
    {
      /*if(1,...) expr are often used to create block. We honor it here*/
      if (p>=0 && tree[p].f!=Fseq)
        newdecl((1<<Cauto)|(1<<Cconst),Gvoid,GNIL,&ret);
      arg[1]=geninsertvar(arg[1],ret);
      genblock(arg[1],-1);
      aseq=arg[1];
    }
    else
    {
      if (p>=0 && tree[p].f!=Fseq)
      {
        if(nb==3)
          newdecl((1<<Cauto)|(1<<Cimmutable),Gvoid,GNIL,&ret);
        else
          newdecl((1<<Cauto)|(1<<Cimmutable),Gvoid,GNIL,&ret);
      }
      genblock(arg[0],n);
      arg[1]=geninsertvar(arg[1],ret);
      genblock(arg[1],-1);
      if(nb==3)
      {
        arg[2]=geninsertvar(arg[2],ret==-1?-1:newleaf(ret));
        genblock(arg[2],-1);
      }
      aseq=newnode(tree[n].f,tree[n].x,listtoseq(arg,nb));
    }
    makeblock(newblock(),n,aseq,ret,s_ctx.n);
    break;
  case GPinstall:
    {
      gpfunc *gp;
      const char *p;
      int d, nf;
      /* We should not use genblock(y,n) since prototype is
       * {rrD\"\",r,D\"\",s,}
       * Instead we fix Fentry to Fconst.
       */
      nb=genlistargs(n,arg,2,4);
      /*What to do with arg[3]? add a linking ??*/
      if (nb<3 || arg[2]==GNOARG) arg[2]=arg[0];
      d=detag(arg[2]);
      if (tree[d].f!=Fentry && !is_const(d,CSTstr))
        die(n,"Incorrect GP name in install");
      tree[d].f=Fconst;
      nf=getfunc(entryname(d)); gp=lfunc+nf;
      d=detag(arg[0]);
      if (tree[d].f!=Fentry && !is_const(d,CSTstr))
        die(n,"Incorrect C name in install");
      tree[d].f=Fconst;
      gp->proto.cname=entryname(d);
      if (nb==4 && arg[3]!=GNOARG)
      {
        d=detag(arg[3]);
        if (!is_const(d,CSTstr))
          die(n,"Incorrect library name in install");
        gp->proto.origin=entryname(d);
      }
      d=detag(arg[1]);
      if (tree[d].f!=Fentry && !is_const(d,CSTstr))
        die(n,"Incorrect code in install");
      tree[d].f=Fconst;
      p=entryname(d);
      gp->proto.code=p+1;
      funcmode(*gp)=0;
      switch(p[0])
      {
      case 'v':
        functype(*gp)=Gvoid;
        break;
      case 'l':
        functype(*gp)=Gsmall;
        break;
      case 'i':
        functype(*gp)=Gsmall_int;
        break;
      case 'm':
        functype(*gp)=Ggen;
        funcmode(*gp)=(1<<Mcopy);
        break;
      default:
        functype(*gp)=Ggen;
        gp->proto.code--;
      }
      if (tree[arg[1]].f==Ftag)
        functype(*gp)=tree[arg[1]].y;
      for(;*p;p++) if (*p=='p') funcmode(*gp)|=(1<<Mprec);
      gp->spec=GPinstalled;
    }
    break;
  case GPfor:
    nb=genlistargs(n,arg,3,3);
    genequal(arg[0],gp->gpname,&var,&binf,&tv);
    bsup=arg[1];seq=arg[2];
    newdecl((1<<Cauto)|(1<<Cconst),Gempty,-1,&vinf);
    bseq=addseqright(bseq,geninsertvar(binf,newleaf(vinf)));
    newdecl((1<<Cauto)|(1<<Cconst),Gempty,-1,&vsup);
    bseq=addseqright(bseq,geninsertvar(bsup,newleaf(vsup)));
    genblock(bseq,-1);
    savx=s_ctx.n;
    bl1=newblock();
    bl2=newblock();
    if (autogc)
      gpm=gengerepile(bl2);
    genequaltosmall(binf,bsup,&tv);
    pushvar(var,1<<Cuser,tv,-1);
    lab=genblock_label(seq,-1);
    if (lab.ne)
      seq=newseq(seq,newcall("_label",newsmall(lab.ne)));
    if (autogc)
    {
      seq=addseqright(seq,newcall("_gerepilemany",gpm));
      gengerepileend(bl2);
    }
    arg[0]=newnode(Faffect,var,vinf);
    arg[1]=newopcall(OPle,newleaf(var),vsup);
    arg[2]=seq;
    arg[3]=newopcall(OPpp,newleaf(var),-1);
    aseq=newnode(tree[n].f,tree[n].x,listtoseq(arg,4));
    if (lab.go)
      aseq=newseq(aseq,newcall("_label",newsmall(lab.go)));
    makeblocks(bl1,bl2,n,bseq,aseq,ret,savx);
    break;
  case GPforvec:
    {
      int flag, vfvdat,vfvnext,next,sav0,bl0;
      nb=genlistargs(n,arg,2,3);
      genequal(arg[0],gp->gpname,&var,&binf,&tv);
      seq=arg[1];
      flag=(nb==3)?arg[2]:newsmall(0);
      newdecl((1<<Cauto)|(1<<Cconst),Gvec,-1,&vinf);
      vfvdat=newnode(Fentry,newentry("fv_data"),-1);
      vfvnext=newnode(Fentry,newentry("fv_next"),-1);
      bseq=addseqright(bseq,geninsertvar(binf,newleaf(vinf)));
      genblock(bseq,-1);
      sav0=s_ctx.n;
      bl0=newblock();
      pushvar(vfvdat,(1<<Cuser)|(1<<Cconst),Ggen,-1);
      pushvar(vfvnext,(1<<Cuser)|(1<<Cconst),Gfunc_GG,-1);
      pushvar(var,(1<<Cuser)|(1<<Ccompo),Gvec,newcall("_forvec_start",
            newnode(Flistarg,newnode(Flistarg,newnode(Flistarg,
              newleaf(vinf),newleaf(flag)),
              newnode(Frefarg,newnode(Fentry,newentry("fv_data"),-1),-1)),
              newnode(Frefarg,newnode(Fentry,newentry("fv_next"),-1),-1))));
      savx=s_ctx.n;
      bl1=newblock();
      bl2=newblock();
      if (autogc)
        gpm=gengerepile(bl2);
      next = newnode(Faffect,newleaf(var),newnode(Ftag,
          newcall("_call_GG",newnode(Flistarg,newnode(Flistarg,
              newleaf(vfvnext),newleaf(vfvdat)),newleaf(var))),Gvec));
      lab=genblock_label(seq,-1);
      if (lab.ne)
        seq=newseq(seq,newcall("_label",newsmall(lab.ne)));
      if (autogc)
      {
        seq=addseqright(seq,newcall("_gerepilemany",gpm));
        gengerepileend(bl2);
      }
      arg[0]=GNOARG;
      arg[1]=newleaf(var);
      arg[3]=next;
      arg[2]=seq;
      aseq=newcall("for",listtoseq(arg,4));
      if (lab.go)
        aseq=newseq(aseq,newcall("_label",newsmall(lab.go)));
      makeblocks3(bl0,bl1,bl2,n,bseq,aseq,ret,sav0,savx);
    }
    break;
  case GPfordiv:
    {
      int vdiv,div;
      int vloop;
      nb=genlistargs(n,arg,3,3);
      seq=arg[2];
      checkisvar(arg[1],gp->gpname,&var,&tv);
      newdecl(1<<Cconst,Gvec,-1,&vdiv);
      div=newcall("divisors",arg[0]);
      bseq=addseqright(bseq,geninsertvar(div,vdiv));
      genblock(bseq,-1);
      savx=s_ctx.n;
      bl1=newblock();
      bl2=newblock();
      if (autogc)
        gpm=gengerepile(bl2);
      newdecl(0,Gsmall,-1,&vloop);
      if (tv==Gnotype) tv=Gint;
      pushvar(var,1<<Cuser,tv,-1);
      lab=genblock_label(seq,-1);
      if (lab.ne)
        seq=newseq(seq,newcall("_label",newsmall(lab.ne)));
      if (autogc)
      {
        seq=addseqright(seq,newcall("_gerepilemany",gpm));
        gengerepileend(bl2);
      }
      seq=addseqleft(
          newnode(Faffect,newleaf(var),
            newnode(Ftag,
              newcoeff(newleaf(vdiv),newleaf(vloop),-1),Gint)),seq);
      arg[0]=newnode(Faffect,vloop,newsmall(1));
      arg[1]=newopcall(OPle,newleaf(vloop),newcall("length",vdiv));
      arg[2]=seq;
      arg[3]=newopcall(OPpp,newleaf(vloop),-1);
      aseq=newnode(tree[n].f,newentry("for"),listtoseq(arg,4));
      if (lab.go)
        aseq=newseq(aseq,newcall("_label",newsmall(lab.go)));
      makeblocks(bl1,bl2,n,bseq,aseq,ret,savx);
      break;
    }
  case GPforstep:
    {
      int bstep;
      int vstep,vindex,vsign;
      int dosign,isvec;
      nb=genlistargs(n,arg,4,4);
      genequal(arg[0],gp->gpname,&var,&binf,&tv);
      bsup=arg[1];bstep=arg[2];seq=arg[3];
      newdecl((1<<Cauto)|(1<<Cconst),Gempty,-1,&vinf);
      bseq=addseqright(bseq,geninsertvar(binf,newleaf(vinf)));
      newdecl((1<<Cauto)|(1<<Cconst),Gempty,-1,&vsup);
      bseq=addseqright(bseq,geninsertvar(bsup,newleaf(vsup)));
      newdecl((1<<Cauto)|(1<<Cconst),Gempty,-1,&vstep);
      bseq=addseqright(bseq,geninsertvar(bstep,newleaf(vstep)));
      if (guesstype(bstep)==Gvec)
      {
        isvec=1;
        newdecl(0,Gsmall,-1,&vindex);
        dosign=0;
      }
      else
      {
        isvec=0;
        dosign=tree[bstep].f!=Fsmall;
      }
      genblock(bseq,-1);
      savx=s_ctx.n;
      bl1=newblock();
      bl2=newblock();
      if (autogc)
        gpm=gengerepile(bl2);
      if (tv==Gnotype)
        tv=Ggen;
      pushvar(var,1<<Cuser,tv,-1);
      if (dosign)
        newdecl(0,Gbool,newopcall(OPg,newleaf(vstep),0),&vsign);
      lab=genblock_label(seq,-1);
      if (lab.ne)
        seq=newseq(seq,newcall("_label",newsmall(lab.ne)));
      if (autogc)
      {
        seq=addseqright(seq,newcall("_gerepilemany",gpm));
        gengerepileend(bl2);
      }
      arg[0]=newnode(Faffect,var,vinf);
      if (isvec)
      {
        arg[4]=vindex;
        arg[5]=newcall("length",vstep);
        arg[3]=newopcall(OPle,newleaf(var),vsup);
        arg[2]=newopcall(OPpe,var,newcoeff(vstep,vindex,-1));
        nb=6;
      }
      else
      {
        if ( !dosign )
        {
          if ( tree[bstep].x>0 )
            arg[3]=newopcall(OPle,newleaf(var),vsup);
          else
            arg[3]=newopcall(OPge,newleaf(var),vsup);
          nb=4;
        }
        else
        {
          arg[3]=newleaf(vsign);
          arg[4]=newopcall(OPle,newleaf(var),vsup);
          arg[5]=newopcall(OPge,newleaf(var),vsup);
          nb=6;
        }
        arg[2]=newopcall(OPpe,var,vstep);
      }
      arg[1]=seq;
      if (isvec)
        aseq=newcall("forstepvec",listtoseq(arg,nb));
      else
        aseq=newnode(tree[n].f,tree[n].x,listtoseq(arg,nb));
      if (lab.go)
        aseq=newseq(aseq,newcall("_label",newsmall(lab.go)));
      makeblocks(bl1,bl2,n,bseq,aseq,ret,savx);
    }
    break;
  case GPforprime:
  case GPprodeuler:
    nb=genlistargs(n,arg,3,3);
    genequal(arg[0],gp->gpname,&var,&binf,&tv);
    bsup=arg[1];seq=arg[2];
    newdecl((1<<Cauto)|(1<<Cconst),Gempty,-1,&vinf);
    bseq=addseqright(bseq,geninsertvar(binf,newleaf(vinf)));
    newdecl((1<<Cauto)|(1<<Cconst),Gempty,-1,&vsup);
    bseq=addseqright(bseq,geninsertvar(bsup,newleaf(vsup)));
    if (gp->spec==GPprodeuler)
    {
      newdecl(0,Ggen,-1,&ret);
      aseq=addseqright(aseq,geninsertvar(
            newnode(Fconst,newsmallrealvalue(1),-1),newleaf(ret)));
    }
    genblock(bseq,-1);
    savx=s_ctx.n;
    bl1=newblock();
    bl2=newblock();
    if (autogc)
      gpm=gengerepile(bl2);
    if (tv==Gnotype)
      tv=Gsmall;
    pushvar(var,1<<Cuser,tv,FC_forprime_next>=0?newsmall(0):-1);
    vprime=newnode(Fentry,newentry("primepointer"),-1);
    pushvar(vprime,1<<Cuser,Gbptr,newcall("_diffptr",-1));
    if (gp->spec==GPprodeuler)
    {
      seq=geninsertvarop(seq,ret,OPme);
      genblock_nolabel(seq,-1);
      lab.go=0;
    }
    else
    {
      lab=genblock_label(seq,-1);
      if (lab.ne)
        seq=newseq(seq,newcall("_label",newsmall(lab.ne)));
    }
    if (autogc)
    {
      seq=addseqright(seq,newcall("_gerepilemany",gpm));
      gengerepileend(bl2);
    }
    /*if (vsup>maxprime()) err(primer1);*/
    aseq=addseqleft(newcall("if",newnode(Flistarg,
              newopcall(OPg,vsup,newcall("_maxprime",-1)),
              newcall("_err_primes",-1)))
              ,aseq);
    if (tree[binf].f!=Fsmall || tree[binf].x>2)
      /*if(var<vinf) continue;*/
      seq=addseqleft(newcall("if",newnode(Flistarg,
              newopcall(OPl,newleaf(var),vinf),
              newcall("next",-1)
              )),seq);
    if (FC_forprime_next>=0)
    {
      seq=addseqleft(newcall("if",newnode(Flistarg,
              newopcall(OPg,newleaf(var),vsup),
              newcall("break",-1)
              )),seq);
      /*NEXT_PRIME_VIA_DIFF(var,vprime);*/
      seq=addseqleft(newcall("_forprime_next",newnode(Flistarg,
              newleaf(var),newleaf(vprime))),seq);
      aseq=addseqright(aseq,newcall("_doloop",seq));
    }
    else
    {
      arg[0]=newnode(Faffect,var,newsmall(2));
      /*var<=vsup*/
      arg[1]=newopcall(OPle,newleaf(var),newleaf(vsup));
      arg[2]=seq;
      /*var+=*++primepointer*/
      arg[3]=geninsertvarop(newopcall(OPpp,newleaf(vprime),-1),
          newleaf(var),OPpe);
      aseq=addseqright(aseq,newcall("for",listtoseq(arg,4)));
    }
    if (gp->spec==GPforprime && lab.go)
      aseq=newseq(aseq,newcall("_label",newsmall(lab.go)));
    makeblocks(bl1,bl2,n,bseq,aseq,ret,savx);
    break;
  case GPsum:
  case GPprod:
    nb=genlistargs(n,arg,3,4);
    genequal(arg[0],gp->gpname,&var,&binf,&tv);
    bsup=arg[1];seq=arg[2];
    newdecl((1<<Cauto)|(1<<Cconst),Gempty,-1,&vinf);
    bseq=addseqright(bseq,geninsertvar(binf,newleaf(vinf)));
    newdecl((1<<Cauto)|(1<<Cconst),Gempty,-1,&vsup);
    bseq=addseqright(bseq,geninsertvar(bsup,newleaf(vsup)));
    newdecl(0,Ggen,-1,&ret);
    if (nb==3)
      aseq=addseqright(aseq,geninsertvar(newsmall(gp->spec==GPsum?0:1),
                                         newleaf(ret)));
    else
      bseq=addseqright(bseq,geninsertvar(arg[3],newleaf(ret)));
    genblock(bseq,-1);
    savx=s_ctx.n;
    bl1=newblock();
    bl2=newblock();
    if (autogc)
      gpm=gengerepile(bl2);
    genequaltosmall(binf,bsup,&tv);
    pushvar(var,1<<Cuser,tv,-1);
    seq=geninsertvarop(seq,ret,(gp->spec==GPsum?OPpe:OPme));
    genblock_nolabel(seq,-1);
    if (autogc)
    {
      seq=addseqright(seq,newcall("_gerepilemany",gpm));
      gengerepileend(bl2);
    }
    arg[0]=newnode(Faffect,var,vinf);
    arg[1]=newopcall(OPle,newleaf(var),vsup);
    arg[2]=seq;
    arg[3]=newopcall(OPpp,newleaf(var),-1);
    aseq=addseqright(aseq,newcall("for",listtoseq(arg,4)));
    makeblocks(bl1,bl2,n,bseq,aseq,ret,savx);
    break;
  case GPsumdiv:
    {
      int vdiv,div;
      int vloop;
      nb=genlistargs(n,arg,3,3);
      seq=arg[2];
      checkisvar(arg[1],gp->gpname,&var,&tv);
      newdecl(1<<Cconst,Gvec,-1,&vdiv);
      div=newcall("divisors",arg[0]);
      bseq=addseqright(bseq,geninsertvar(div,vdiv));
      newdecl(0,Ggen,-1,&ret);
      bseq=addseqright(bseq,geninsertvar(newsmall(0),newleaf(ret)));
      genblock(bseq,-1);
      savx=s_ctx.n;
      bl1=newblock();
      bl2=newblock();
      if (autogc)
        gpm=gengerepile(bl2);
      newdecl(0,Gsmall,-1,&vloop);
      if (tv==Gnotype) tv=Gint;
      pushvar(var,1<<Cuser,tv,-1);
      seq=geninsertvarop(seq,ret,OPpe);
      genblock_nolabel(seq,-1);
      if (autogc)
      {
        seq=addseqright(seq,newcall("_gerepilemany",gpm));
        gengerepileend(bl2);
      }
      seq=addseqleft(
          newnode(Faffect,newleaf(var),
            newnode(Ftag,
              newcoeff(newleaf(vdiv),newleaf(vloop),-1),Gint)),seq);
      arg[0]=newnode(Faffect,vloop,newsmall(1));
      arg[1]=newopcall(OPle,newleaf(vloop),newcall("length",vdiv));
      arg[2]=seq;
      arg[3]=newopcall(OPpp,newleaf(vloop),-1);
      aseq=newnode(tree[n].f,newentry("for"),listtoseq(arg,4));
      makeblocks(bl1,bl2,n,bseq,aseq,ret,savx);
      break;
    }
  case GPuntil:
  case GPwhile:
    nb=genlistargs(n,arg,2,2);
    bl1=newblock();
    savx=s_ctx.n;
    seq=arg[1];
    if(autogc)
      gpm=gengerepile(bl1);
    genblock_nolabel(arg[0],n);
    lab=genblock_label(seq,-1);
    if (lab.ne)
      seq=newseq(seq,newcall("_label",newsmall(lab.ne)));
    if (autogc)
    {
      gengerepileend(bl1);
      seq=addseqright(seq,newcall("_gerepilemany",gpm));
    }
    arg[1]=seq;
    aseq=newnode(tree[n].f,tree[n].x,listtoseq(arg,nb));
    if (lab.go)
      aseq=newseq(aseq,newcall("_label",newsmall(lab.go)));
    makeblock(bl1,n,aseq,ret,savx);
    break;
  case GPvector:
  case GPvectorv:
  case GPvectorsmall:
    nb=genlistargs(n,arg,1,3);
    bsup=arg[0];seq=nb<3?newsmall(0):arg[2];
    newdecl((1<<Cauto)|(1<<Cconst),Gempty,-1,&vsup);
    bseq=addseqright(bseq,geninsertvar(bsup,newleaf(vsup)));
    genblock(bseq,-1);
    newdecl(0,gp->spec==GPvectorsmall?Gvecsmall:Gvec,-1,&ret);
    savx=s_ctx.n;
    bl1=newblock();
    bl2=newblock();
    if (nb>=2)
    {
      checkisvar(arg[1],gp->gpname,&var,&tv);
      pushvar(var,1<<Cuser,tv==Gnotype?Gsmall:tv,-1);
    }
    else
      newdecl(0,Gsmall,-1,&var);
    aseq=addseqright(aseq,newgetg(ret,newleaf(vsup),
        gp->spec==GPvector?"t_VEC":gp->spec==GPvectorv?"t_COL":"t_VECSMALL"));
    arg[0]=newnode(Faffect,var,newsmall(1));
    arg[1]=newopcall(OPle,newleaf(var),vsup);
    arg[2]=newcoeff(newleaf(ret),newleaf(var),-1);
    arg[2]=geninsertvar(seq,arg[2]);
    genblock_nolabel(arg[2],-1);
    arg[3]=newopcall(OPpp,newleaf(var),-1);
    aseq=addseqright(aseq,newcall("for",listtoseq(arg,4)));
    makeblocks(bl1,bl2,n,bseq,aseq,ret,savx);
    break;
  case GPmatrix:
    {
      int var1,bsup1,vsup1,var2,bsup2,vsup2;
      int tv1,tv2;
      nb=genlistargs(n,arg,2,5);
      bsup2=arg[0];bsup1=arg[1];
      newdecl((1<<Cauto)|(1<<Cconst),Gempty,-1,&vsup1);
      newdecl((1<<Cauto)|(1<<Cconst),Gempty,-1,&vsup2);
      bseq=addseqright(bseq,geninsertvar(bsup1,newleaf(vsup1)));
      bseq=addseqright(bseq,geninsertvar(bsup2,newleaf(vsup2)));
      genblock(bseq,-1);
      newdecl(0,Gvec,-1,&ret);
      savx=s_ctx.n;
      bl1=newblock();
      bl2=newblock();
      if (nb>=3)
      {
        checkisvar(arg[2],gp->gpname,&var2,&tv2);
        pushvar(var2,1<<Cuser,tv2==Gnotype?Gsmall:tv2,-1);
      }
      else
        newdecl(0,Gsmall,-1,&var2);
      if (nb>=4)
      {
        checkisvar(arg[3],gp->gpname,&var1,&tv1);
        pushvar(var1,1<<Cuser,tv1==Gnotype?Gsmall:tv1,-1);
      }
      else
        newdecl(0,Gsmall,-1,&var1);
      if(nb<5)
        seq=newsmall(0);
      else
        seq=arg[4];
      aseq=newgetg(newcoeff(newleaf(ret),newleaf(var1),-1),
                     newleaf(vsup2),"t_COL");
      arg[0]=newnode(Faffect,var2,newsmall(1));
      arg[1]=newopcall(OPle,newleaf(var2),vsup2);
      arg[3]=newopcall(OPpp,newleaf(var2),-1);
      arg[2]=newcoeff(newleaf(ret),newleaf(var2),newleaf(var1));
      arg[2]=geninsertvar(seq,arg[2]);
      genblock_nolabel(arg[2],-1);
      arg[2]=addseqright(aseq,newcall("for",listtoseq(arg,4)));
      aseq=newgetg(ret,newleaf(vsup1),"t_MAT");
      arg[0]=newnode(Faffect,var1,newsmall(1));
      arg[1]=newopcall(OPle,newleaf(var1),vsup1);
      arg[3]=newopcall(OPpp,newleaf(var1),-1);
      aseq=addseqright(aseq,newcall("for",listtoseq(arg,4)));
      makeblocks(bl1,bl2,n,bseq,aseq,ret,savx);
    }
    break;
  case GPglobal:
  case GPlocal:
    {
      int narg;
      int aseq=GNIL;
      int flag=1<<Cuser;
      int mint=(tree[p].f==Ftag)?tree[p].y:-1;
      if (gp->spec==GPglobal)
        flag|=1<<Cglobal;
      savx=s_ctx.n;
      narg=genblockdeclaration(y,n,flag,mint);
      aseq=genblockinit(aseq,savx,narg,gp->spec==GPglobal);
      makeblock(newblock(),n,aseq,-1,s_ctx.n);
      if (tree[p].f==Ftag) tree[p]=tree[n];
    }
    break;
  case GPreturn:
    if (y==GNOARG || y<0)
      y=tree[n].y=GNIL;
    else
      genblock(y,n);
    /* If we don't do garbage collecting, don't bother adding blocks.*/
    if (!autogc) break;
    if (tree[y].f==Fentry)
    {
      var=y;
      bseq=-1;
      y=newleaf(var);
    }
    else if (tree[y].f==Fblock)
    {
      /*Use the block value variable as the return variable*/
      var=block[tree[y].x].ret;
      bseq=y;
      y=newleaf(var);
    }
    else if (tree[y].f!=Fsmall)
    {
      /*Use the returned variable as the return variable*/
      newdecl((1<<Cauto),Gempty,-1,&var);
      bseq=geninsertvar(y,var);
      y=newleaf(var);
    }
    bl1=newblock();
    bl2=newblock();
    savx=s_ctx.n;
    block[bl2].gc|=(1<<GCneeded)|(1<<GCglobal)|(1<<GCreturn);
    block[bl2].egc=var;
    arg[0]=newnode(Fentry,newentry("ltop"),-1);
    arg[1]=GNOARG;
    arg[2]=(FC_gerepileall<0)?newnode(Fentry,newentry("gptr"),-1):GNOARG;
    arg[3]=newsmall(bl2);
    gpm=listtoseq(arg,4);
    aseq=addseqright(aseq,newcall("_gerepilemany",gpm));
    if (FC_gerepileall<0)
      pushvar(newleaf(arg[2]),1<<Cuser,Ggptr,newcall("_gerepilelist",arg[3]));
    aseq=addseqright(aseq,newnode(tree[n].f,tree[n].x,y));
    makeblocks(bl1,bl2,n,bseq,aseq,ret,savx);
    break;
  case GPbreak:
  case GPnext:
    {
      int k,l;
      static int labbrk=0;
      if (y>=0 && y!=GNOARG)
      {
        if (tree[y].f!=Fsmall || tree[y].x<=0)
          die(n,"%s(n) only supported for constant n>0",gp->gpname);
        nb=tree[y].x;
      }
      else
      {
        nb=1;
        tree[n].y=GNOARG;
      }
      l=s_label.n;
      k=nb;
      while(k--)
        if (!label[--l].ok)
          die(n,"%s not allowed here",gp->gpname);
      if (nb>1)
      {
        if (gp->spec==GPbreak)
        {
          if (label[l].go==0)
            label[l].go=++labbrk;
          tree[y].x=labbrk;
        }
        else
        {
          if (label[l].ne==0)
            label[l].ne=++labbrk;
          tree[y].x=labbrk;
        }
      }
    }
    break;
  default:
    /*treat as a normal function*/
    genblock(tree[n].y,n);
  }
}
void gentypemode(int nb, int *arg, int *mode)
{
  int i;
  *mode=0;
  for (i=0;i<nb;i++)
    if (arg[i]!=GNOARG)
    {
      gentype(arg[i]);
      *mode|=(tree[arg[i]].m&MODHERIT);
    }
}

int gentypefuncspec(int n, gpfunc *gp)
{
  int arg[STACKSZ];
  int nb;
  int y=tree[n].y;
  switch(gp->spec)
  {
  case GPif:
    nb=genlistargs(n,arg,2,3);
    gentype(arg[0]);
    gentype(arg[1]);
    tree[n].m=(tree[arg[0]].m|(tree[arg[1]].m&~(1<<Mterm)))&MODHERIT;
    if (nb==3)
    {
      gentype(arg[2]);
      /*We must not set Gterm if we are not sure.
        In this case we must set Gsidef instead.*/
      tree[n].m|=(1<<Melse)|((tree[arg[2]].m&(~(1<<Mterm)))&MODHERIT);
      if ((tree[arg[1]].m&(1<<Mterm)) && (tree[arg[2]].m&(1<<Mterm)))
        tree[n].m|=(1<<Mterm);
      else
        if ((tree[arg[1]].m&(1<<Mterm)) || (tree[arg[2]].m&(1<<Mterm)))
          tree[n].m|=(1<<Msidef);
      return typemax[tree[arg[1]].t][tree[arg[2]].t];
    }
    if ((tree[arg[1]].m&(1<<Mterm)))
      tree[n].m|=(1<<Msidef);
    return tree[arg[1]].t;
  case GPdoloop:
    gentype(y);
    tree[n].m=tree[y].m&MODHERIT;
    return Gvoid;
  case GPfor:
    nb=genlistargs(n,arg,4,4);
    gentypemode(nb,arg,&tree[n].m);
    tree[n].m&=~(1<<Mterm);
    return Gvoid;
  case GPforstep:
  case GPforstepvec:
    nb=genlistargs(n,arg,4,7);
    gentypemode(nb,arg,&tree[n].m);
    tree[n].m&=~(1<<Mterm);
   return Gvoid;
  case GPuntil:
  case GPwhile:
    nb=genlistargs(n,arg,2,2);
    gentype(arg[0]);
    gentype(arg[1]);
    if(gp->spec==GPwhile)
      tree[n].m=(tree[arg[0]].m|(tree[arg[1]].m&~(1<<Mterm)))&MODHERIT;
    else
      tree[n].m=(tree[arg[0]].m|tree[arg[1]].m)&MODHERIT;
    return Gvoid;
  case GPreturn:
    {
      gpfunc *cf=lfunc+currfunc;
      int t;
      if (y>=0)
      {
        gentype(y);
        tree[n].m=(1<<Mterm)|(tree[y].m&MODHERIT);
        t=typemax[functype(*cf)][tree[y].t];
      }
      else
      {
        tree[n].m=(1<<Mterm);
        t=typemax[functype(*cf)][Gvoid];
      }
      if (!is_subtype(t,functype(*cf)))
      {
        if(debug==2)
          fprintf(stderr,"%s returned %s now %s (%s)\n",cf->gpname,GPname(functype(*cf)),GPname(t),GPname(tree[y].t));
        functype(*cf)=t;
        lastpass++;
      }
    }
    return Gempty;
  case GPinstall:
  case GPaddhelp:
    tree[n].m=0;
    return Gvoid;
  case GPmakevec:
    gentype(y);
    tree[n].m=(tree[y].m&MODHERIT)|(1<<Msidef);
    return Gvec;
  case GPgplist:
    tree[n].m=0;
    return Ggptr;
  default:
    if (gp->spec>0)
      die(n,"gentypefuncspec : func spec not implemented");
    else
      die(n,"Internal error : gentypefuncspec called with no spec");
  }
}

void gencopyarg(FILE *fout)
{
  gpfunc *gp=lfunc+currfunc;
  userfunc *ufunc=gp->user;
  context *fc=block+ufunc->bl;
  int n=tree[ufunc->defnode].y;
  long i;
  if (tree[n].x!=ufunc->bl || !fc->var) return;
  for (i=0;i<fc->s.n;i++)
    if (fc->c[i].flag&(1<<Carg))
    {
      ctxvar *v=fc->c+i;
      long j;
      for(j=0;j<fc->v.n;j++)
        if (fc->var[j].f==AFaffectcompo && fc->var[j].idx==i+fc->savb-fc->s.n )
        {
          genindent(fout);
          fprintf(fout,"%s = ",v->cvar);
          genfuncbydesc1(fout,v->node,FC_copy,n);
          gensemicomma(fout,v->node);
          break;
        }
    }
}

void geninitfunc(FILE *fout)
{
  gpfunc *gp=lfunc+currfunc;
  int i;
  for (i=0;i<gp->user->savb;i++)
  {
    ctxvar *v=ctxstack+i;
    if (!(v->flag&(1<<Cundeclared)))
      continue;
    /* We need the varlist which is not available at gentype() time, so we do
     * it here instead. Given that v->initval is equal to 'v, this is harmless.
     */
    gentype(v->initval);
    genindent(fout);
    fprintf(fout,"%s = ", v->cvar);
    gencast(fout,v->initval,vartype(*v));
    fprintf(fout,";\n");
  }
}

void genentryspec(FILE *fout, int n, gpfunc *gp)
{
  int arg[STACKSZ];
  int nb;
  int y=tree[n].y;
  int i;
  context *bl;
  switch(gp->spec)
  {
    case GPbreak:
    case GPnext:
      if (y>=0 && tree[y].f==Fsmall)
        fprintf(fout,"goto label%d",tree[y].x);
      else
        fprintf(fout,gp->spec==GPbreak?"break":"continue");
      break;
    case GPif:
      nb=genlistargs(n,arg,2,3);
#if 0
      /*generate nice `? :' */
    if (t!=Gvoid && tree[arg[1]].f!=Fseq && (nb==2 || tree[arg[2]].f!=Fseq) )
    {
      fprintf(fout,"((");
      genbool(fout,arg[0],tree[arg[0]].t);
      fprintf(fout,")?");
      gencast(fout,arg[3],t);
      fprintf(fout,":");
      if (nb==5)
        gencast(fout,arg[4],t);
      else/*the type of left and right must be equal.*/
        gensmallval(fout,0,t);
      fprintf(fout,")");
    }
#endif
    genindent(fout);
    fprintf(fout,"if (");
    gencast(fout,arg[0],Gbool);
    fprintf(fout,")\n");
    if (nb==2)
      genbrace(fout,arg[1]);
    else
    {
      /*Be paranoid with dangling 'else' */
      int brace=(tree[arg[1]].f==Fseq || tree[arg[1]].f==Fblock);
      if (brace)
      {
        genindent(fout);
        fprintf(fout,"{\n");
      }
      indent++;
      genindentseq(fout,arg[1]);
      gencodeg(fout,arg[1]);
      gensemicomma(fout,arg[1]);
      indent--;
      if (brace)
      {
        genindent(fout);
        fprintf(fout,"}\n");
      }
      genindent(fout);
      fprintf(fout,"else\n");
      genbrace(fout,arg[2]);
    }
    break;
  case GPwhile:
    nb=genlistargs(n,arg,2,2);
    genindent(fout);
    if (tree[arg[0]].f!=Fseq && tree[arg[0]].f!=Fblock)
    {
      fprintf(fout,"while (");
      gencast(fout,arg[0],Gbool);
      fprintf(fout,")\n");
      genbrace(fout,arg[1]);
    }
    else
    {
      int x=tree[arg[0]].x;
      int y=tree[arg[0]].y;
      if (tree[arg[0]].f==Fblock)
      {
        y=block[x].ret;
        x=tree[arg[0]].y;
      }
      fprintf(fout,"for(;;)\n");
      genindent(fout);
      fprintf(fout,"{\n");
      indent++;
      genindentseq(fout,x);
      gencodeg(fout,x);
      gensemicomma(fout,x);
      if (tree[y].f==Fblock)
      {
        gencodeg(fout,y);
        y=block[tree[y].x].ret;
      }
      genindent(fout);
      fprintf(fout,"if (");
      gencast(fout,y,Gnegbool);
      fprintf(fout,")\n");
      indent++;
      genindent(fout);
      fprintf(fout,"break;\n");
      indent--;
      genindentseq(fout,arg[1]);
      gencodeg(fout,arg[1]);
      gensemicomma(fout,arg[1]);
      indent--;
      genindent(fout);
      fprintf(fout,"}\n");
    }
    break;
  case GPuntil:
    nb=genlistargs(n,arg,2,2);
    genindent(fout);
    if ( tree[arg[0]].f!=Fseq && tree[arg[0]].f!=Fblock)
    {
      fprintf(fout,"do\n");
      genindent(fout);
      fprintf(fout,"{\n");
      indent++;
      genindentseq(fout,arg[1]);
      gencodeg(fout,arg[1]);
      gensemicomma(fout,arg[1]);
      indent--;
      genindent(fout);
      fprintf(fout,"} while(");/*KB style*/
      gencast(fout,arg[0],Gnegbool);
      fprintf(fout,");\n");
    }
    else
    {
      int x=tree[arg[0]].x;
      int y=tree[arg[0]].y;
      if (tree[arg[0]].f==Fblock)
      {
        y=block[x].ret;
        x=tree[arg[0]].y;
      }
      fprintf(fout,"for(;;)\n");
      genindent(fout);
      fprintf(fout,"{\n");
      indent++;
      genindentseq(fout,arg[1]);
      gencodeg(fout,arg[1]);
      gensemicomma(fout,arg[1]);
      genindentseq(fout,x);
      gencodeg(fout,x);
      gensemicomma(fout,x);
      genindent(fout);
      if (tree[y].f==Fblock)
      {
        gencodeg(fout,y);
        y=block[tree[y].x].ret;
      }
      fprintf(fout,"if (");
      gencast(fout,y,Gbool);
      fprintf(fout,")\n");
      indent++;
      genindent(fout);
      fprintf(fout,"break;\n");
      indent--;
      indent--;
      genindent(fout);
      fprintf(fout,"}\n");
    }
    break;
  case GPfor:
    nb=genlistargs(n,arg,4,4);
    genindent(fout);
    fprintf(fout,"for (");
    if (arg[0]!=GNOARG)
      gencode(fout,arg[0]);
    else
      fprintf(fout,"  ");
    fprintf(fout,"; ");
    if (arg[1]!=GNOARG)
      gencode(fout,arg[1]);
    fprintf(fout,"; ");
    if (arg[3]!=GNOARG)
      gencode(fout,arg[3]);
    fprintf(fout,")\n");
    genbrace(fout,arg[2]);
    break;
  case GPdoloop:
    genindent(fout);
    fprintf(fout,"for (;;)\n");
    genbrace(fout,y);
    break;
  case GPforstep:
    nb=genlistargs(n,arg,4,6);
    genindent(fout);
    fprintf(fout,"for (");
    gencode(fout,arg[0]);
    fprintf(fout,"; ");
    if ( nb==4 )
      gencode(fout,arg[3]);
    else
    {
      gencode(fout,arg[3]);
      fprintf(fout,"?");
      gencode(fout,arg[4]);
      fprintf(fout,":");
      gencode(fout,arg[5]);
    }
    fprintf(fout,"; ");
    gencode(fout,arg[2]);
    fprintf(fout,")\n");
    genbrace(fout,arg[1]);
    break;
#if 0
    forstep(x=binf,bsup,step,SEQ)
    {
      int idx;

      for( idx=0,x=binf; x<=bsup; i=i==lg(step)?1:i+1,x+=step[i])
      {
      }
    }
#endif
  case GPforstepvec:
    nb=genlistargs(n,arg,6,6);
    genindent(fout);
    fprintf(fout,"for (");
    gencode(fout,arg[4]);
    fprintf(fout," = 0, ");
    gencode(fout,arg[0]);
    fprintf(fout,"; ");
    gencode(fout,arg[3]);
    fprintf(fout,"; ");
    gencode(fout,arg[4]);
    fprintf(fout," = ");
    gencode(fout,arg[4]);
    fprintf(fout," == ");
    gencast(fout,arg[5],Gsmall);
    fprintf(fout," ? 1 :");
    gencode(fout,arg[4]);
    fprintf(fout," + 1, ");
    gencode(fout,arg[2]);
    fprintf(fout,")\n");
    genbrace(fout,arg[1]);
    break;
  case GPmakevec:
    nb=genlistargs(n,arg,1,STACKSZ);
    genindent(fout);
    gencode(fout,arg[0]);
    gensemicomma(fout,arg[0]);
    for(i=1;i<nb;i++)
    {
      genindentseq(fout,arg[i]);
      gencodeg(fout,arg[i]);
      gensemicomma(fout,arg[i]);
    }
    break;
  case GPgplist:
    bl=block+tree[y].x;
    fprintf(fout,"{ ");
    for(i=0;i<bl->g.n;i++)
    {
      if (i) fprintf(fout,", ");
      fprintf(fout,"&%s",ctxstack[bl->gcvar[i]].cvar);
    }
    fprintf(fout," }");
    break;
  case GPgpmany:
    nb=genlistargs(n,arg,4,STACKSZ);
    bl=block+tree[arg[3]].x;
    if (!(bl->gc&(1<<GCneeded)))
      break;
    genindent(fout);
    if (!bl->g.n)
    {
      genfuncbydesc(fout,0,NULL,FC_avma,n);
      fprintf(fout," = ");
      gencode(fout,arg[0]);
      fprintf(fout,";\n");
    }
    else if (bl->gc&(1<<GCupto))
    {
      int var=ctxstack[bl->gcvar[0]].node;
      int parg[2];
      gencode(fout,var);
      fprintf(fout," = ");
      parg[0]=arg[0]; parg[1]=var;
      genfuncbydesc(fout,2,parg,FC_gerepileupto,n);
      fprintf(fout,";\n");
    }
    else
    {
      /*FIXME:Putting an if statement in the wilderness is not secure*/
      if (arg[1]!=GNOARG)
      {
        int parg[2];
        parg[0]=arg[1]; parg[1]=arg[0];
        fprintf(fout,"if (");
        genfuncbydesc(fout,2,parg,FC_low_stack_lim,n);
        fprintf(fout,")\n");
        indent++;
        genindent(fout);
        indent--;
      }
      if (arg[2]!=GNOARG)
      {
        fprintf(fout,"gerepilemany(");
        gencode(fout,arg[0]);
        fprintf(fout,", ");
        gencode(fout,arg[2]);
        fprintf(fout,", %d);\n",bl->g.n);
      }
      else
      {
        int parg[STACKSZ+1];
        parg[0]=arg[0];
        for(i=0;i<bl->g.n;i++)
          parg[i+1]=ctxstack[bl->gcvar[i]].node;
        genfuncbydesc(fout,bl->g.n+1,parg,FC_gerepileall,n);
        fprintf(fout,";\n");
      }
    }
    break;
  case GPreturn:
    fprintf(fout,"return");
    if (functype(lfunc[currfunc])!=Gvoid)
    {
      /*I don't like to see `return ;'*/
      fprintf(fout," ");
      gencast(fout,y,functype(lfunc[currfunc]));
    }
    break;
  case GPlabel:
    fprintf(fout,"label%d:",tree[y].x);
    break;
  case GPcopyarg:
    gencopyarg(fout);
    break;
  case GPinitfunc:
    geninitfunc(fout);
    break;
  case GPaddhelp:
  case GPinstall:
    break;
  default:
    if (gp->spec>0)
      die(n,"genentryspec: func spec not implemented");
    else
      die(n,"Internal error: genentryspec called with no spec");
  }
}

Generated by  Doxygen 1.6.0   Back to index