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

node.c

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

#define GP2C_MAX_INT_32 2147483647L

const char *Ffuncname[]={"Fseq",
                   "Fmatrix","FmatrixL","FmatrixR",
                   "Faffect",
                   "Ffacteurmat",
                   "Fmatrixelts","Fmatrixlines",
                   "Fmat","Fvec",
                   "Flistarg",
                   "Frefarg",

                   "Fconst","Fsmall","Fgnil",
                   "Ftag",
                   "Fentry","Fentryfunc","Fdeffunc",

                   /*These nodes are generated by genblock, not by parser*/
                   "Fblock", "Ffunction"
};

/* 0 not an integer
 * 1 a true integer
 * 2 a real which is an integer (1.,17.00)
 */
int isarealint(const char *s)
{
  while (*s>='0' && *s<='9')
    s++;
  if (!*s) return 1;
  if (*s != '.') return 0;
  while(*++s)
    if (*s != '0') return 0;
  return 2;
}

int linecount;
int newcomment(void)
{
  int n=stack_new(&s_comment);
  comment *c=com+n;
  stack_init(&c->s,sizeof(*c->txt),(void *)&c->txt);
  return n;
}

void pushcomment(int n, char x)
{
  comment *c=com+n;
  int m=stack_new(&c->s);
  c->txt[m]=x;
}

int newnodecom(Ffunc f, int x, int y, int com)
{
  int n=stack_new(&s_node);
  tree[n].f=f;
  tree[n].x=x;
  tree[n].y=y;
  tree[n].t=Gnotype;
  tree[n].m=0;
  tree[n].lineno=linecount;
  tree[n].comment=com;
  return n;
}
int newnode(Ffunc f, int x, int y)
{
  return newnodecom(f,x,y,-1);
}

int newsmall(int val)
{
  return newnode(Fsmall,val,-1);
}

int newopcall(OPerator op, int x, int y)
{
  if (y==-1)
    return newnode(Fentryfunc,op,x);
  else
    return newnode(Fentryfunc,op,newnode(Flistarg,x,y));
}

int newstringvalue(const char *s)
{
  int n=stack_new(&s_value);
  value[n].type=CSTstr;
  value[n].val.str=s;
  return n++;
}

int newsmallrealvalue(long small)
{
  int n=stack_new(&s_value);
  value[n].type=CSTsmallreal;
  value[n].val.small=small;
  return n++;
}

int newintvalue(const char *s)
{
  int n=stack_new(&s_value);
  value[n].type=CSTint;
  value[n].val.str=s;
  return n++;
}

int newrealvalue(const char *s)
{
  int n=stack_new(&s_value);
  value[n].type=CSTreal;
  value[n].val.str=s;
  return n++;
}

/* newxxxnode functions
 * These functions take a token value as a string and a comment index.
 * They must return a new Fconst or Fsmall node.
 * They must free the string if they do not reference it.
 * the cast free((char *)s) is to remove the const qualifier.
 */
int newintnode(const char *s, int c)
{
  long small;
  char *endptr;
  /* We do not want to inline 64bit integers to preserve the portability
   * of the resulting C code.*/
  errno=0;/* for catching strtol overflows*/
  small=strtol(s,&endptr,10);
  if (!*endptr && !errno && small<=GP2C_MAX_INT_32)
  {
    free((char *)s);
    return newnodecom(Fsmall,small,-1,c);
  }
  else
    return newnodecom(Fconst,newintvalue(s),-1,c);
}

int newrealnode(const char *s, int c)
{
  char *endptr;
  int val;
  if (!isarealint(s))
    val=newrealvalue(s);
  else
  {
    long small;
    errno=0;/* for catching strtol overflows*/
    small=strtol(s,&endptr,10);
    if (*endptr=='.' && !errno && small<=GP2C_MAX_INT_32)
    {
      val=newsmallrealvalue(small);
      free((char *)s);
    }
    else
      val=newrealvalue(s);
  }
  return newnodecom(Fconst,val,-1,c);
}

int newstringnode(const char *s, int c)
{
  return newnodecom(Fconst,newstringvalue(s),-1,c);
}

int newquotenode(const char *s, int c)
{
  return newcall("_const_quote",newstringnode(s,c));
}

int is_const(int n, CSTtype t)
{
  int f=tree[n].f;
  int x=tree[n].x;
  return f==Fconst && value[x].type==t;
}

int newentry(const char *s)
{
  return newstringvalue(s);
}

int isfunc(int n, const char *s)
{
  return tree[n].f==Fentryfunc && !strcmp(s,value[tree[n].x].val.str);
}

extern char *optprefix;
const char *usercname(const char *s)
{
  const char *p;
  if (!optprefix)
  {
    if (s[0]=='p' || s[0]=='l')
    {
      for(p=s+1; *p=='_'; p++);
      if (isdigit(*p))
      {
        for (   ; isdigit(*p); p++);
        if (!*p)
        {
          char *q=calloc(sizeof(*s),2+strlen(s));
          sprintf(q,"%c_%s",s[0],s+1);
          return q;
        }
      }
    }
  }
  else
  {
    char *q=calloc(sizeof(*s),strlen(optprefix)+1+strlen(s));
    sprintf(q,"%s%s",optprefix,s);
    return q;
  }
  return s;
}

int newmember(const char *s)
{
  char *p;
  int n;
  p=calloc(sizeof(*s),3+strlen(s));
  sprintf(p,"_.%s",s);
  n=newentry(p);
  free((char *)s);
  return n;
}
void initoperators(void)
{
  int i;
  for (i=0;i<OPnboperator;i++)
    newentry(opname[i]);
}

const char *entryname(int n)
{
  return value[tree[n].x].val.str;
}

int newleaf(int n)
{
  int r;
  if (n==-1)
    return GNIL;
  r=newnode(tree[n].f,tree[n].x,tree[n].y);
  tree[r]=tree[n];
  return r;
}
int getlvalue(int n)
{
  int x;
  if (n==-1)
    return -1;
  switch(tree[n].f)
  {
    case Fentry:
      return n;
    case Ftag:
    case Ffacteurmat:
      return getlvalue(tree[n].x);
    case Fentryfunc:
      if (tree[n].x!=OPcoeff && !isfunc(n,"_[_,]"))
        return -1;
      x=tree[tree[n].y].x;
      if (tree[x].f==Flistarg)
        return getlvalue(tree[x].x);
      else
        return getlvalue(x);
    default:
      return -1;
  }
}

int newtag(int x, char *s, int c)
{
  int t=s_GPtype.n;
  int n=newnodecom(Ftag,x,strtotype(s),c);
  if (s_GPtype.n>t) die(n,"Unknown type '%s' or unexpected ':'",s);
  return n;
}

int detag(int n)
{
  while(tree[n].f==Ftag) n=tree[n].x;
  return n;
}

int getlvaluerr(int n)
{
  int ret=getlvalue(n);
  if(ret==-1)
    die(n,"not an lvalue");
  return ret;
}

int newctype(const char *s)
{
  int n=stack_new(&s_Ctype);
  Ctype[n].name=strdup(s);
  return n;
}

int strtoctype(const char *s)
{
  int i;
  for(i=0;i<s_Ctype.n;i++)
  {
    if (!strcmp(s,Ctype[i].name))
      return i;
  }
  return newctype(s);
}

int newtype(const char *s)
{
  int n=stack_new(&s_GPtype);
  GPtype[n].name=strdup(s);
  return n;
}

int strtotype_len(const char *s, size_t n)
{
  int i;
  for(i=0;i<s_GPtype.n;i++)
  {
    const char *t=GPtype[i].name;
    if (strlen(t)==n && !strncmp(s,t,n))
      return i;
  }
  die(-1,"no such type %s\n",s);
}

int strtotype(const char *s)
{
  int i;
  for(i=0;i<s_GPtype.n;i++)
  {
    if (!strcmp(s,GPtype[i].name))
      return i;
  }
  return newtype(s);
}

int newmode(const char *s)
{
  int n=stack_new(&s_Mmode);
  if (n >= 8*sizeof(long))
    die(err_desc,"GP2C only supports %ld modes",8*sizeof(long));
  Mmode[n].name=strdup(s);
  return n;
}

int strtomode(char *s)
{
  int i;
  for(i=0;i<s_Mmode.n;i++)
    if (!strcmp(s,Mmode[i].name))
      return i;
  return newmode(s);
}

const char *funcname(int f)
{
  if (f<0 || f>Flastfunc)
    return "Funknown";
  else
    return Ffuncname[f];
}

const char *GPname(int f)
{
  if (f<0 || f>s_GPtype.n)
    return "Gunknown";
  else
    return GPtype[f].name;
}

static int currlabel=0;
int newlabel(int ok)
{
  int n=stack_new(&s_label);
  label[n].num=currlabel;
  label[n].ok=ok;
  label[n].go=0;
  label[n].ne=0;
  currlabel+=2;
  return n;
}


Generated by  Doxygen 1.6.0   Back to index