#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include "symtab.h"
#include "y.tab.h"
struct init
{
char *fname;
value (*fcnt)(const value &);
};
struct init2
{
char *fname;
value (*fcnt)(const value &,const value &);
};
struct init3
{
char *fname;
value (*fcnt)(void);
};
struct init arith_fncts[] =
{
#include "value.fn"
0,0
};
struct init2 arith_fncts2[] =
{
#include "value.fn2"
0,0
};
struct init3 arith_proc[] =
{
#include "value.fn0"
0,0
};
symrec *sym_table=(symrec *)0;
void init_table(void)
{
if(sym_table!=(symrec *)0)
return;
symrec *ptr;
int i;
for(i=0;arith_fncts[i].fname!=0;i++)
{
ptr=putsym(arith_fncts[i].fname,PARSERfunction);
ptr->ivalue.fnctptr=arith_fncts[i].fcnt;
}
for(i=0;arith_fncts2[i].fname!=0;i++)
{
ptr=putsym(arith_fncts2[i].fname,PARSERfunction2);
ptr->ivalue.fnctptr2=arith_fncts2[i].fcnt;
}
for(i=0;arith_proc[i].fname!=0;i++)
{
ptr=putsym(arith_proc[i].fname,PARSERprocedure);
ptr->ivalue.procptr=arith_proc[i].fcnt;
}
}
symrec * putsym(char *sym_name,int sym_type)
{
symrec *ptr;
#ifdef DEBUG
printf("putsym(%s,%d);\n",sym_name,sym_type);
#endif
ptr=new symrec();// (symrec *)malloc(sizeof(symrec));
ptr->name=(char *)malloc(strlen(sym_name)+1);
strcpy(ptr->name,sym_name);
ptr->type=sym_type;
ptr->var=value(0);
ptr->next=(struct symrec*)sym_table;
sym_table=ptr;
return ptr;
}
symrec * getsym(char *sym_name)
{
symrec *ptr;
#ifdef DEBUG
printf("getsym(%s);\n",sym_name);
#endif
if(sym_table==(symrec *)0)
init_table();
for(ptr=sym_table;ptr!=(symrec *)0;ptr=(symrec*)ptr->next)
if(strcmp(ptr->name,sym_name)==0)
return ptr;
return 0;
}
symrec * getsym(char *sym_name,int demanded_type)
{
symrec *ptr;
#ifdef DEBUG
printf("getsym(%s);\n",sym_name);
#endif
if(sym_table==(symrec *)0)
init_table();
for(ptr=sym_table;ptr!=(symrec *)0;ptr=(symrec*)ptr->next)
if(strcmp(ptr->name,sym_name)==0 && ptr->type==demanded_type)
return ptr;
return 0;
}
void * set_string_input(char *);
int yyparse (void);
void reset_input(void *);
extern value result;
value evaluate(const symrec *a)
{
// preferred: PARSERprocedure
symrec *b;
if(a->type!=PARSERprocedure && (b=getsym(a->name,PARSERprocedure))!=0)
a=b;
switch(a->type)
{
case PARSERprocedure:
return (*(a->ivalue.procptr))();
case PARSERfunction:
return (*(a->ivalue.fnctptr))(value());
case PARSERfunction2:
return (*(a->ivalue.fnctptr2))(value(),value());
case PARSERuserfunction:
{
int i;
char *var;
symrec *varrec;
value old;
char *body=a->ivalue.body;
void *buffer;
for(i=1;i<strlen(body) && body[i]!=')' && body[i]!=',';i++);
var=(char*)malloc(i);
for(i=1;i<strlen(body) && body[i]!=')' && body[i]!=',';i++)
var[i-1]=body[i];
var[i-1]=0;
#ifdef DEBUG
printf("Variable: %s Body: %s\n",var,body+i+2);
#endif
varrec=getsym(var);
if(varrec==0)
varrec=putsym(var,PARSERvariable);
old=varrec->var;
varrec->var=value();
for(;i<strlen(body) && body[i]!=')';i++);
for(;i<strlen(body) && (body[i]==' ' || body[i]=='\t' || body[i]=='=' || body[i]==')');i++);
buffer=set_string_input(body+i);
yyparse();
reset_input(buffer);
free(var);
varrec->var=old;
return result;
}
default:
return value((symrec *)a);
}
}
value evaluate(const symrec *a,const value &v)
{
// preferred: PARSERuserfunction then PARSERfunction
symrec *b;
if(a->type!=PARSERuserfunction && (b=getsym(a->name,PARSERuserfunction))!=0)
a=b;
else if(a->type!=PARSERfunction && (b=getsym(a->name,PARSERfunction))!=0)
a=b;
switch(a->type)
{
case PARSERprocedure:
return (*(a->ivalue.procptr))();
case PARSERfunction:
return (*(a->ivalue.fnctptr))(v);
case PARSERfunction2:
return (*(a->ivalue.fnctptr2))(v,value());
case PARSERuserfunction:
{
int i;
char *var;
symrec *varrec;
value old;
char *body=a->ivalue.body;
void *buffer;
for(i=1;i<strlen(body) && body[i]!=')' && body[i]!=',';i++);
var=(char*)malloc(i);
for(i=1;i<strlen(body) && body[i]!=')' && body[i]!=',';i++)
var[i-1]=body[i];
var[i-1]=0;
#ifdef DEBUG
printf("Variable: %s Body: %s\n",var,body+i+2);
#endif
varrec=getsym(var);
if(varrec==0)
varrec=putsym(var,PARSERvariable);
old=varrec->var;
varrec->var=v;
for(;i<strlen(body) && body[i]!=')';i++);
for(;i<strlen(body) && (body[i]==' ' || body[i]=='\t' || body[i]=='=' || body[i]==')');i++);
buffer=set_string_input(body+i);
yyparse();
reset_input(buffer);
free(var);
varrec->var=old;
return result;
}
default:
return value();
}
}
value evaluate(const symrec *a,const value &v1,const value &v2)
{
// preferred: PARSERfunction2
symrec *b;
if(a->type!=PARSERfunction2 && (b=getsym(a->name,PARSERfunction2))!=0)
a=b;
switch(a->type)
{
case PARSERprocedure:
return (*(a->ivalue.procptr))();
case PARSERfunction:
return (*(a->ivalue.fnctptr))(v1);
case PARSERfunction2:
return (*(a->ivalue.fnctptr2))(v1,v2);
case PARSERuserfunction:
{
int i;
char *var;
symrec *varrec;
value old;
char *body=a->ivalue.body;
void *buffer;
var=(char*)malloc(i);
for(i=1;i<strlen(body) && body[i]!=')' && body[i]!=',';i++)
var[i-1]=body[i];
var[i-1]=0;
#ifdef DEBUG
printf("Variable: %s Body: %s\n",var,body+i+2);
#endif
varrec=getsym(var);
if(varrec==0)
varrec=putsym(var,PARSERvariable);
old=varrec->var;
varrec->var=v1;
for(;i<strlen(body) && body[i]!=')';i++);
for(;i<strlen(body) && (body[i]==' ' || body[i]=='\t' || body[i]=='=' || body[i]==')');i++);
buffer=set_string_input(body+i);
yyparse();
reset_input(buffer);
free(var);
varrec->var=old;
return result;
}
default:
return value();
}
}
value evaluate_n(const symrec *a,const valuematrix &v)
{
// preferred: PARSERfunction2
symrec *b;
if(a->type!=PARSERfunction2 && (b=getsym(a->name,PARSERfunction2))!=0)
a=b;
switch(a->type)
{
case PARSERprocedure:
return (*(a->ivalue.procptr))();
case PARSERfunction:
// return (*(a->ivalue.fnctptr))(cell(v,1));
return (*(a->ivalue.fnctptr))(v);
case PARSERfunction2:
return (*(a->ivalue.fnctptr2))(cell(v,1),cell(v,2));
case PARSERuserfunction:
{
int i,k;
char *var;
symrec *varrec;
char *body=a->ivalue.body;
void *buffer;
for(i=0,k=1;i<strlen(body) && body[i]!=')';i++)
if(body[i]==',')
k++;
valuematrix old(k,1,0,0);
int ii=0;
k=0;
do {
ii++;
for(i=ii;i<strlen(body) && body[i]!=')' && body[i]!=',';i++);
var=(char*)malloc(i-ii+1);
for(i=ii;i<strlen(body) && body[i]!=')' && body[i]!=',';i++)
var[i-ii]=body[i];
var[i-ii]=0;
ii=i;
#ifdef DEBUG
printf("Variable: %s\n",var);
#endif
varrec=getsym(var);
if(varrec==0)
varrec=putsym(var,PARSERvariable);
old(k,0)=varrec->var;
if(k<size(v))
varrec->var=cell(v,k+1);
k++;
free(var);
} while(body[ii]==',');
for(i=ii;i<strlen(body) && (body[i]==' ' || body[i]=='\t' || body[i]=='=' || body[i]==')');i++);
#ifdef DEBUG
printf("Body: %s\n",body+i);
#endif
buffer=set_string_input(body+i);
yyparse();
reset_input(buffer);
k=ii=0;
do {
ii++;
for(i=ii;i<strlen(body) && body[i]!=')' && body[i]!=',';i++);
var=(char*)malloc(i-ii+1);
for(i=ii;i<strlen(body) && body[i]!=')' && body[i]!=',';i++)
var[i-ii]=body[i];
var[i-ii]=0;
ii=i;
#ifdef DEBUG
printf("Variable: %s\n",var);
#endif
varrec=getsym(var);
if(varrec==0)
varrec=putsym(var,PARSERvariable);
varrec->var=old(k,0);
k++;
free(var);
} while(body[ii]==',');
return result;
}
default:
return value();
}
}
int arguments(const symrec *a) // returns max number of arguments
{
// preferred: PARSERfunction2
symrec *b;
if(a->type!=PARSERfunction2 && (b=getsym(a->name,PARSERfunction2))!=0)
a=b;
switch(a->type)
{
case PARSERprocedure:
return 0;
case PARSERfunction:
return 1;
case PARSERfunction2:
return 2;
case PARSERuserfunction:
{
int i,k;
char *body=a->ivalue.body;
for(i=0,k=1;i<strlen(body) && body[i]!=')';i++)
if(body[i]==',')
k++;
return k;
}
default:
return 0;
}
}
syntax highlighted by Code2HTML, v. 0.9.1