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

toplevel.c

/*
Copyright (C) 2002-2003  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 <ctype.h>
#include "header.h"

static int toplevel=0;
int initnode=0;

char *basename(char *s)
{
  long i;
  long l=strlen(s);
  for(i=l-1;i>=0;i--)
    if (s[i]=='/')
      return s+i+1;
  return s;
}
char *nameinitfunc(void)
{
  const char *initname="init_";
  char *p,*q,*name;
  char *absname;
  absname=basename(nameparse);
  name=calloc(strlen(initname)+strlen(absname)+1,sizeof(*name));
  sprintf(name,"%s",initname);
  q=name+strlen(name);
  for(p=absname;*p && *p!='.';p++,q++)
    if (isalnum(*p))
      *q=*p;
    else
      *q='_';
  *q=0;
  return name;
}
int addinitfunc(int n)
{
  int code;
  int ret;
  int nf;
  char *name;
  gpfunc *gp;
  name=nameinitfunc();
  nf=findfunction(name);
  if (nf!=-1)
  {
    warning(lfunc[nf].user->defnode,"Redefining automatic function %s",name);
    return n;
  }
  code=toplevel?toplevel:-1;
  code=addseqleft(newnode(Fentryfunc,newentry("_initfunc"),-1),code);
  code=addseqright(code,GNIL);
  initnode=newnode(Fdeffunc,newnode(Fentryfunc,newentry(name),-1),code);
  gp=lfunc+newuserfunc(entryname(tree[initnode].x));
  gp->user->pdefnode=n;
  gp->user->defnode=initnode;
  ret=addseqright(initnode,n);
  return ret;
}

/*
  n: node
  p:parent node
*/
void gentoplevel(int n, int p)
{
  int x,y;
  if (n<0)
    return;
  x=tree[n].x;
  y=tree[n].y;
  switch(tree[n].f)
  {
  case Fseq:
    if (x>=0 && tree[x].f!=Fdeffunc && tree[x].f!=Fseq)
    {
      if (isfunc(x,"local"))
        warning(x,"`local' at top-level discarded");
      else
        toplevel=addseqright(toplevel,x);
      tree[n].x=GNIL;
    }
    else
      gentoplevel(x,n);
    if (y>=0 && tree[y].f!=Fdeffunc)
    {
      if (isfunc(y,"local"))
        warning(y,"`local' at top-level discarded");
      else
        toplevel=addseqright(toplevel,y);
      tree[n].y=GNIL;
    }
    else
      gentoplevel(y,n);
    break;
  case Fentryfunc:
    die(n,"Fentryfunc in toplevel");
    gentoplevel(y,n);
    break;
  case Fdeffunc:
    {
      gpfunc *gp;
      const char *name=entryname(x);
      int nf=findfunction(name);
      if (nf==-1)
        gp=lfunc+newuserfunc(name);
      else
      {
        gp=lfunc+nf;
        if (gp->spec!=GPuser)
          die(n,"Trying to redefine function %s",name);
        else
        {
          userfunc *ufunc=gp->user;
          int parent=ufunc->pdefnode;
          int node=ufunc->defnode;
          if (tree[node].y>=0)
            warning(node,"Function %s redefined line %d",name,tree[n].lineno);
          if (tree[parent].x==node)
            tree[parent].x=GNIL;
          else
            tree[parent].y=GNIL;
        }
      }
      gp->user->pdefnode=p;
      gp->user->defnode=n;
    }
    break;
  case Fentry:
  case Fconst:
  case Fsmall:
  case Fgnil:
    break;
  case Frefarg:
  case Ftag:
    die(n,"%s in toplevel",funcname(tree[n].f));
    gentoplevel(x,n);
    break;
  default:
    if (tree[n].f>=FneedENTRY)
    {
      die(n,"Internal error: unknown func %s in gentoplevel",funcname(tree[n].f));
    }
    else
    {
      gentoplevel(x,n);
      gentoplevel(y,n);
    }
  }
}


Generated by  Doxygen 1.6.0   Back to index