#include <math.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <limits.h>
#include "stack.h"
#include "output.h"
#include "funcs.h"
#include "interval.h"
#include "builtin.h"
#include "express.h"
#include "spread.h"
#include "udf.h"
#include "matrix.h"
#include "linear.h"
#include "command.h"
#include "input.h"
void scan_summe (void);
extern int nosubmref,trace;
int udfon=0,actargn=0,actsp=0;
char *next;
/**************** builtin operators ****************/
void cscalp (double *s, double *si, double *x, double *xi,
double *y, double *yi)
{ *s += *x * *y - *xi * *yi;
*si += *x * *yi + *xi * *y;
}
void iscalp (double *s, double *si, double *x, double *xi,
double *y, double *yi)
{ double a,b;
interval_mult(x,xi,y,yi,&a,&b);
interval_add(s,si,&a,&b,s,si);
}
void ccopy (double *y, double *x, double *xi)
{ *y++=*x; *y=*xi;
}
void icopy (double *y, double *x, double *xi)
{ *y++=*x; *y=*xi;
}
void multiply (header *hd, header *hd1)
/***** multiply
matrix multiplication.
*****/
{ header *result,*st=hd;
dims *d,*d1;
double *m,*m1,*m2,*mm1,*mm2,x,y,null=0.0;
int i,j,c,r,k;
hd=getvalue(hd); hd1=getvalue(hd1);
if (error) return;
if (hd->type==s_matrix && hd1->type==s_matrix)
{ d=dimsof(hd);
d1=dimsof(hd1);
if (d->c != d1->r)
{ error=8; output("Cannot multiply these!\n");
return;
}
r=d->r; c=d1->c;
result=new_matrix(r,c,"");
if (error) return;
m=matrixof(result);
m1=matrixof(hd);
m2=matrixof(hd1);
for (i=0; i<r; i++)
for (j=0; j<c; j++)
{ mm1=mat(m1,d->c,i,0); mm2=m2+j;
x=0.0;
for (k=0; k<d->c; k++)
{ x+=(*mm1)*(*mm2);
mm1++; mm2+=d1->c;
}
*mat(m,c,i,j)=x;
}
moveresult(st,result);
return;
}
if (hd->type==s_matrix)
{ if (hd1->type==s_cmatrix)
{ d=dimsof(hd);
d1=dimsof(hd1);
if (d->c != d1->r)
{ error=8; output("Cannot multiply these!\n");
return;
}
r=d->r; c=d1->c;
result=new_cmatrix(r,c,"");
if (error) return;
m=matrixof(result);
m1=matrixof(hd);
m2=matrixof(hd1);
for (i=0; i<r; i++)
for (j=0; j<c; j++)
{ mm1=mat(m1,d->c,i,0); mm2=m2+(long)2*j;
x=0.0; y=0.0;
for (k=0; k<d->c; k++)
{ cscalp(&x,&y,mm1,&null,mm2,mm2+1);
mm1++; mm2+=2*d1->c;
}
ccopy(cmat(m,c,i,j),&x,&y);
}
moveresult(st,result);
return;
}
if (hd1->type==s_imatrix)
{ d=dimsof(hd);
d1=dimsof(hd1);
if (d->c != d1->r)
{ error=8; output("Cannot multiply these!\n");
return;
}
r=d->r; c=d1->c;
result=new_imatrix(r,c,"");
if (error) return;
m=matrixof(result);
m1=matrixof(hd);
m2=matrixof(hd1);
for (i=0; i<r; i++)
for (j=0; j<c; j++)
{ mm1=mat(m1,d->c,i,0); mm2=m2+(long)2*j;
x=0.0; y=0.0;
for (k=0; k<d->c; k++)
{ iscalp(&x,&y,mm1,mm1,mm2,mm2+1);
mm1++; mm2+=2*d1->c;
}
icopy(imat(m,c,i,j),&x,&y);
}
moveresult(st,result);
return;
}
}
if (hd->type==s_cmatrix && hd1->type==s_matrix)
{ d=dimsof(hd);
d1=dimsof(hd1);
if (d->c != d1->r)
{ error=8; output("Cannot multiply these!\n");
return;
}
r=d->r; c=d1->c;
result=new_cmatrix(r,c,"");
if (error) return;
m=matrixof(result);
m1=matrixof(hd);
m2=matrixof(hd1);
for (i=0; i<r; i++)
for (j=0; j<c; j++)
{ mm1=cmat(m1,d->c,i,0); mm2=m2+j;
x=0.0; y=0.0;
for (k=0; k<d->c; k++)
{ cscalp(&x,&y,mm1,mm1+1,mm2,&null);
mm1+=2; mm2+=d1->c;
}
ccopy(cmat(m,c,i,j),&x,&y);
}
moveresult(st,result);
return;
}
if (hd->type==s_cmatrix && hd1->type==s_cmatrix)
{ d=dimsof(hd);
d1=dimsof(hd1);
if (d->c != d1->r)
{ error=8; output("Cannot multiply these!\n");
return;
}
r=d->r; c=d1->c;
result=new_cmatrix(r,c,"");
if (error) return;
m=matrixof(result);
m1=matrixof(hd);
m2=matrixof(hd1);
for (i=0; i<r; i++)
for (j=0; j<c; j++)
{ mm1=cmat(m1,d->c,i,0); mm2=m2+(long)2*j;
x=0.0; y=0.0;
for (k=0; k<d->c; k++)
{ cscalp(&x,&y,mm1,mm1+1,mm2,mm2+1);
mm1+=2; mm2+=2*d1->c;
}
ccopy(cmat(m,c,i,j),&x,&y);
}
moveresult(st,result);
return;
}
if (hd->type==s_imatrix)
{ if (hd1->type==s_matrix)
{ d=dimsof(hd);
d1=dimsof(hd1);
if (d->c != d1->r)
{ error=8; output("Cannot multiply these!\n");
return;
}
r=d->r; c=d1->c;
result=new_imatrix(r,c,"");
if (error) return;
m=matrixof(result);
m1=matrixof(hd);
m2=matrixof(hd1);
for (i=0; i<r; i++)
for (j=0; j<c; j++)
{ mm1=imat(m1,d->c,i,0); mm2=m2+j;
x=0.0; y=0.0;
for (k=0; k<d->c; k++)
{ iscalp(&x,&y,mm1,mm1+1,mm2,mm2);
mm1+=2; mm2+=d1->c;
}
icopy(imat(m,c,i,j),&x,&y);
}
moveresult(st,result);
return;
}
if (hd1->type==s_imatrix)
{ d=dimsof(hd);
d1=dimsof(hd1);
if (d->c != d1->r)
{ error=8; output("Cannot multiply these!\n");
return;
}
r=d->r; c=d1->c;
result=new_imatrix(r,c,"");
if (error) return;
m=matrixof(result);
m1=matrixof(hd);
m2=matrixof(hd1);
for (i=0; i<r; i++)
for (j=0; j<c; j++)
{ mm1=imat(m1,d->c,i,0); mm2=m2+(long)2*j;
x=0.0; y=0.0;
for (k=0; k<d->c; k++)
{ iscalp(&x,&y,mm1,mm1+1,mm2,mm2+1);
mm1+=2; mm2+=2*d1->c;
}
icopy(imat(m,c,i,j),&x,&y);
}
moveresult(st,result);
return;
}
}
else dotmultiply(st,nextof(st));
}
void divide (header *hd, header *hd1)
{ dotdivide(hd,hd1);
}
void real_invert (double *x, double *y)
{ *y= -*x;
}
void complex_invert (double *x, double *xi, double *y, double *yi)
{ *y= -*x;
*yi= -*xi;
}
void invert (header *hd)
/***** invert
compute -matrix.
*****/
{ header *result,*st=hd;
hd=getvalue(hd);
if (error) return;
if (isinterval(hd))
result=map1i(interval_invert,hd);
else result=map1(real_invert,complex_invert,hd);
if (!error) moveresult(st,result);
}
/***************** scanning ***************************/
void scan_space (void)
{ start: while (*next==' ' || *next==TAB) next++;
if (!udfon && *next=='.' && *(next+1)=='.')
{ next_line(); if (error) return; goto start; }
}
void scan_namemax (char *name, int lmax)
{ int count=0;
if (*next=='\"')
{ next++;
while (*next!='\"' && *next)
{ *name++=*next++; count++;
if (count>=lmax-1)
{ output("Name too long!\n");
error=11; break;
}
}
if (*next=='\"') next++;
}
else if (!isalpha(*next) && *next!='_')
{ output1("Name expected at:\n%s<EOL>\n",next);
error=11; *name=0; return;
}
else
{ if (*next=='_') { *name++=*next++; count++; }
while (isalpha(*next) || isdigit(*next))
{ *name++=*next++; count++;
if (count>=lmax-1)
{ output("Name too long!\n");
error=11; break;
}
}
}
*name=0;
}
void scan_name (char *name)
{ scan_namemax (name,16);
}
int scan_arguments (int *scount)
/* look ahead for arguments */
{ int count=0,olds=nosubmref,nocount=0;
header *hd,*hdold;
*scount=0;
nosubmref=1;
while (1)
{ scan_space();
if (*next==')' || *next==']') break;
if (*next==',')
hd=new_reference(0,"");
else
{ hd=scan(); scan_space();
}
if (*next=='=')
{ next++;
hdold=(header *)newram;
scan_value();
if (!error)
{ strcpy(hdold->name,hd->name);
hdold->xor=hd->xor;
moveresult(hd,hdold);
nocount=1;
}
}
else if (nocount)
{ output("Illegal parameter after named parameter!\n");
error=2700;
}
if (error)
{ nosubmref=olds;
return 0;
}
while (hd<(header *)newram)
{ if (!nocount) count++;
hd=nextof(hd);
}
if (count>=20)
{ output("To many arguments!\n"); error=56; return 0; }
if (*next==';')
{ *scount=count;
}
else if (*next!=',') break;
next++;
}
if (*next!=')' && *next!=']')
{ output("Error in arguments!\n"); error=19; return 0; }
next++;
nosubmref=olds;
return count;
}
void scan_matrix (void)
/***** scan_matrix
scan a matrix from input.
form: [x y z ... ; v w u ...],
where x,y,z,u,v,w are sums.
*****/
{ header *hd,*result;
dims *d;
int c,r,count,i,j,complex=0,interval=0,n;
unsigned long ic;
unsigned long allcount;
double *m,*ms,cnull[2]={0,0},*mr;
hd=new_matrix(0,0,""); /* don't know how big it will be! */
if (error) return;
count=0;
getmatrix(hd,&r,&c,&m); ms=m;
r=0; c=0;
scan_space();
while (1)
{ scan_space();
if (*next==0) { next_line(); scan_space(); }
/* matrix is allowed to pass line ends */
if (*next==';' || *next==']')
/* new column starts */
{ if (*next==';') next++;
if (!freeramfrom(ms,count*(long)(r+1)*sizeof(double)))
{ output("Memory overflow!\n"); error=18; return;
}
if (count>c) /* this column is to long */
{ if (r>0) /* expand matrix */
{ for (j=count-1; j>=0; j--)
{ if (complex)
copy_complex(cmat(ms,count,r,j),
cmat(ms,c,r,j));
else if (interval)
copy_interval(imat(ms,count,r,j),
imat(ms,c,r,j));
else *mat(ms,count,r,j)=*mat(ms,c,r,j);
}
for (i=r-1; i>=0; i--)
{ if (i>0)
for (j=c-1; j>=0; j--)
{ if (complex)
copy_complex(cmat(ms,count,i,j),
cmat(ms,c,i,j));
else if (interval)
copy_interval(imat(ms,count,i,j),
imat(ms,c,i,j));
else *mat(ms,count,i,j)=*mat(ms,c,i,j);
}
for (j=c; j<count; j++)
if (complex)
copy_complex(cmat(ms,count,i,j),cnull);
else if (interval)
copy_interval(imat(ms,count,i,j),
cnull);
else *mat(ms,count,i,j)=0.0;
}
}
c=count;
}
else if (count<c)
{ for (j=count; j<c; j++)
if (complex) copy_complex(cmat(ms,c,r,j),
cnull);
else if (interval) copy_interval(
imat(ms,c,r,j),cnull);
else *mat(ms,c,r,j)=0.0;
}
r++; newram=
(char *)(ms+(complex||interval?2l:1l)*(long)c*r);
m=(double *)newram;
count=0;
}
if (*next==']') break;
if (*next==',') next++;
if (*next==0) next_line();
result=scan_value(); if (error) return;
newram=(char *)result;
if (!complex &&
(result->type==s_complex || result->type==s_cmatrix))
{ if (interval)
{ output("Cannot make an interval matrix complex.\n");
error=16; return;
}
complex=1;
/* make matrix complex up to now (oh boy!) */
allcount=((char *)m-(char *)ms)/sizeof(double);
if (!freeram(allcount*sizeof(double)+result->size))
{ output("Memory overflow!\n"); error=16; return;
}
if (allcount)
{ memmove(newram+allcount*sizeof(double),newram,result->size);
result=(header *)((char *)result+allcount*sizeof(double));
for (ic=allcount-1; ic>0; ic--)
{ *(ms+(long)2*ic)=*(ms+ic);
*(ms+(long)2*ic+1)=0.0;
}
*(ms+1)=0.0;
newram=(char *)(ms+(long)2*allcount);
m=(double *)newram;
}
hd->type=s_cmatrix;
}
else if (!interval &&
(result->type==s_interval || result->type==s_imatrix))
{ if (complex)
{ output("Cannot make a complex matrix interval.\n");
error=16; return;
}
interval=1;
/* make matrix complex up to now (oh boy!) */
allcount=((char *)m-(char *)ms)/sizeof(double);
if (!freeram(allcount*sizeof(double)+result->size))
{ output("Memory overflow!\n"); error=16; return;
}
if (allcount)
{ memmove(newram+allcount*sizeof(double),newram,result->size);
result=(header *)((char *)result+allcount*sizeof(double));
for (ic=allcount-1; ic>0; ic--)
{ *(ms+(long)2*ic)=*(ms+ic);
*(ms+(long)2*ic+1)=*(ms+ic);
}
*(ms+1)=*ms;
newram=(char *)(ms+(long)2*allcount);
m=(double *)newram;
}
hd->type=s_imatrix;
}
if (result->type==s_real)
{ if (interval) *m++=*aof(result);
else *m++=*realof(result);
count++;
if (complex) *m++=0.0;
else if (interval) *m++=*aof(result);
}
else if (result->type==s_matrix)
{ if (dimsof(result)->r!=1 || dimsof(result)->c<1)
{ output("Illegal matrix element\n");
error=16; return;
}
n=dimsof(result)->c; mr=matrixof(result);
if (complex)
{ for (j=0; j<n; j++)
{ *m++=*mr++;
*m++=0.0;
count++;
}
}
else if (interval)
{ for (j=0; j<n; j++)
{ *m++=*mr;
*m++=*mr++;
count++;
}
}
else
{ n=dimsof(result)->c; mr=matrixof(result);
for (j=0; j<n; j++)
{ *m++=*mr++;
count++;
}
}
}
else if (result->type==s_cmatrix)
{ if (dimsof(result)->r!=1 || dimsof(result)->c<1)
{ output("Illegal matrix element\n");
error=16; return;
}
n=dimsof(result)->c; mr=matrixof(result);
if (complex)
{ for (j=0; j<n; j++)
{ *m++=*mr++;
*m++=*mr++;
count++;
}
}
}
else if (result->type==s_imatrix)
{ if (dimsof(result)->r!=1 || dimsof(result)->c<1)
{ output("Illegal matrix element\n");
error=16; return;
}
n=dimsof(result)->c; mr=matrixof(result);
if (interval)
{ for (j=0; j<n; j++)
{ *m++=*mr++;
*m++=*mr++;
count++;
}
}
}
else if (result->type==s_complex && complex)
{ *m++=*realof(result);
*m++=*imagof(result);
count++;
}
else if (result->type==s_interval && interval)
{ *m++=*aof(result);
*m++=*bof(result);
count++;
}
else
{ error=-1; output("Illegal vector!\n"); return;
}
if (count>=INT_MAX)
{ output1("Matrix has more than %d columns!\n",INT_MAX);
error=17; return;
}
newram=(char *)m;
if (!freeram(16))
{ output("Memory overflow!\n"); error=16; return;
}
}
next++;
d=(dims *)(hd+1);
if (c==0) r=0;
d->c=c; d->r=r;
if (r>=INT_MAX)
{ output1("Matrix has more than %d rows!\n",INT_MAX);
error=18; return;
}
if (complex) hd->size=cmatrixsize(c,r);
else if (interval) hd->size=imatrixsize(c,r);
else hd->size=matrixsize(c,r);
newram=(char *)hd+hd->size;
}
#define myisdigit(c) ((c)>='0' && (c)<='9')
void scan_elementary (void)
/***** scan_elemtary
scan an elementary expression, like a value or variable.
scans also (...).
*****/
{ double x;
int n,nargs,hadargs=0,sp;
header *hd=(header *)newram,*var,*hd1;
char name[16],*s;
scan_space();
if ((*next=='.' && myisdigit(*(next+1))) || myisdigit(*next))
{ sscanf(next,"%lf%n",&x,&n);
next+=n;
if (*next=='i') /* complex number! */
{ next++;
new_complex(0,x,"");
}
else new_real(x,"");
}
else if (*next==2) /* a double stored in binary form */
{ next++;
#ifdef SPECIAL_ALIGNMENT
memmove((char *)(&x),next,sizeof(double));
#else
x=*((double *)next);
#endif
next+=sizeof(double);
if (*next=='i') /* complex number! */
{ next++;
new_complex(0,x,"");
}
else new_real(x,"");
}
else if (*next==3)
{ output("Command name used as variable!\n");
error=4000; return;
}
else if (isalpha(*next) || *next=='_')
{ scan_name(name); if (error) return;
scan_space(); nargs=0;
if (*next=='{')
{ next++; scan(); if (error) return; scan_space();
if (*next!='}')
{ output("} missing!\n"); error=1010; return;
}
next++;
get_element1(name,hd);
goto after;
}
if (*next=='(' || *next=='[') /* arguments or indices */
{ hadargs=(*next=='[')?2:1;
next++; nargs=scan_arguments(&sp);
if (error) return;
}
if (name[0]=='_')
{ if (hadargs==1 && exec_builtin(name+1,nargs,hd));
#ifdef DLL
else if (hadargs==1 && exec_dll(name+1,nargs,hd));
#endif
else
{ output1(
"%s no function or variable, or wrong argument number!\n",
name);
error=1;
return;
}
return;
}
if (hadargs==2) var=searchvar(name);
else if (hadargs==1)
{ var=searchudf(name);
if (!var) var=searchvar(name);
}
else var=searchvar(name);
if (var && var->type==s_udf && hadargs==1)
{ interpret_udf(var,hd,nargs,sp); if (error) return;
}
else if (!var && hadargs)
{ if (hadargs==1 && exec_builtin(name,nargs,hd));
#ifdef DLL
else if (hadargs==1 && exec_dll(name,nargs,hd));
#endif
else
{ error=24;
if (hadargs==2)
output1("%s no variable!\n",name);
else
output1(
"%s no function or variable, or wrong argument number!\n",
name);
return;
}
}
else if (var && hadargs)
{ get_element(nargs,var,hd);
}
else hd=new_reference(var,name);
}
else if (*next=='#' && *(next+1)!='#')
{ next++; mindex(hd);
}
else if (*next=='+')
{ next++; scan_elementary();
}
else if (*next=='-')
{ next++; scan_elementary();
if (!error) invert(hd);
}
else if (*next=='(')
{ next++;
scan(); if (error) return;
scan_space();
if (*next!=')')
{ output("Closing bracket ) missing!\n");
error=5; return;
}
newram=(char *)nextof(hd);
next++;
}
else if (*next=='[')
{ next++;
scan_matrix();
}
else if (*next=='~' && *(next+1)!='=')
{ next++;
scan_value();
if (error) return;
newram=(char *)nextof(hd);
hd1=(header *)newram;
scan_space();
if (*next=='~')
{ next++;
minterval1(hd);
}
else
{ if (*next!=',') { error=1; return; }
next++;
scan_value();
if (error) return;
newram=(char *)nextof(hd1);
scan_space();
if (*next!='~') { error=1; return; }
next++;
minterval(hd);
}
}
else if (*next=='\"')
{ next++;
s=next;
while (*next!='\"' && *next!=0) next++;
hd=new_string(s,next-s,"");
if (*next!='\"') { output("\" missing\n"); error=1; return; }
next++;
}
else if (*next=='\'' && *(next+1)=='\'')
{ next+=2;
s=next;
while ((*next!='\'' || *(next+1)!='\'') && *next!=0) next++;
hd=new_string(s,next-s,"");
if (*next!='\'' || *(next+1)!='\'')
{ output("\'\' missing\n"); error=1; return; }
next+=2;
}
else error=1;
after: if (error) return;
/* for things, that come after an elementary expression */
if (*next=='\'') { next++; transpose(hd); return; }
if (*next=='°') { next++; mdegree(hd); return; }
scan_space();
if (*next=='^' || (*next=='*' && *(next+1)=='*'))
{ if (*next=='^') next++;
else next+=2;
newram=(char *)nextof(hd);
scan_elementary();
if (error) return;
mpower(hd);
}
}
void scan_factor (void)
{ scan_elementary();
}
void scan_summand (void)
{ header *hd=(header *)newram,*hd1;
scan_space();
scan_factor();
if (error) return;
while (1)
{ hd1=(header *)newram;
scan_space();
if ((*next=='*' && *(next+1)!='*')
|| (*next=='.' && *(next+1)=='*'))
{ if (*next=='*') next++;
else next+=2;
scan_factor();
if (!error) dotmultiply(hd,hd1);
}
else if (*next=='/' || (*next=='.' && *(next+1)=='/'))
{ if (*next=='/') next++;
else next+=2;
scan_factor();
if (!error) dotdivide(hd,hd1);
}
else if (*next=='.')
{ next++;
scan_factor();
if (!error) multiply(hd,hd1);
}
else if (*next=='\\')
{ next++;
newram=(char *)nextof(hd);
scan_factor();
if (!error) msolve(hd);
}
else break;
if (error) break;
}
}
void scan_summe (void)
{ header *hd=(header *)newram,*hd1;
scan_space();
scan_summand();
if (error) return;
while (1)
{ hd1=(header *)newram;
scan_space();
if (*next=='+')
{ next++;
scan_summand();
if (!error) add(hd,hd1);
}
else if (*next=='-')
{ next++;
scan_summand();
if (!error) subtract(hd,hd1);
}
else break;
if (error) break;
}
}
void scan_dp (void)
{ header *hd=(header *)newram,*hd1,*hd2;
scan_space();
if (*next==':')
{ next++;
new_command(c_allv);
return;
}
scan_summe();
if (*next==':') /* a vector a:b:c or a:c */
{ next++;
hd1=(header *)newram; scan_summe();
if (error) return;
scan_space();
if (*next==':')
{ next++; hd2=(header *)newram;
scan_summe(); if (error) return;
}
else
{ hd2=hd1; hd1=new_real(1.0,"");
}
if (error) return;
vectorize(hd,hd1,hd2);
}
}
void scan_compare (void)
{ header *hd=(header *)newram;
scan_space();
if (*next=='!')
{ next++; scan_compare(); mnot(hd); return;
}
scan_dp(); if (error) return;
scan_space();
if (*next=='<')
{ if (*(next+1)!='<')
{ next++;
newram=(char *)nextof(hd);
if (*next=='=')
{ next++; scan_dp(); if (error) return; mlesseq(hd); return;
}
else if (*next=='>')
{ next++; scan_dp(); if (error) return; munequal(hd); return;
}
scan_dp(); if (error) return;
mless(hd);
}
else
{ next+=2;
newram=(char *)nextof(hd);
if (*next=='=')
{ next++; scan_dp(); if (error) return; milesseq(hd); return;
}
scan_dp(); if (error) return;
miless(hd);
}
}
else if (*next=='>')
{ next++;
newram=(char *)nextof(hd);
if (*next=='=')
{ next++; scan_dp(); if (error) return; mgreatereq(hd); return;
}
scan_dp(); if (error) return;
mgreater(hd);
}
else if (*next=='=' && *(next+1)=='=')
{ next+=2;
newram=(char *)nextof(hd);
scan_dp(); if (error) return;
mequal(hd);
}
else if (*next=='~' && *(next+1)=='=' && *(next+2)!='=')
{ next+=2;
newram=(char *)nextof(hd);
scan_dp(); if (error) return;
maboutequal(hd);
}
else if (*next=='!' && *(next+1)=='=')
{ next+=2;
newram=(char *)nextof(hd);
scan_dp(); if (error) return;
munequal(hd);
}
else if (*next=='_')
{ next++;
newram=(char *)nextof(hd);
scan_compare(); if (error) return;
mvconcat(hd);
}
else if (*next=='|' && *(next+1)!='|')
{ next++;
newram=(char *)nextof(hd);
scan_compare(); if (error) return;
mhconcat(hd);
}
}
void scan_andlogical (void)
{ header *hd=(header *)newram;
scan_compare(); if (error) return;
scan_space();
if (*next=='&' && *(next+1)=='&')
{ next+=2;
newram=(char *)nextof(hd);
scan_andlogical(); if (error) return;
mand(hd);
}
}
void scan_logical (void)
{ header *hd=(header *)newram;
scan_andlogical(); if (error) return;
scan_space();
if (*next=='|' && *(next+1)=='|')
{ next+=2;
newram=(char *)nextof(hd);
scan_logical(); if (error) return;
mor(hd);
}
}
header *scan (void)
{ header *result=(header *)newram;
scan_space();
if (*next=='{')
{ next++; scan_logical(); if (error) return result;
while (1)
{ scan_space();
if (*next=='}') { next++; return result; }
if (*next!=',')
{ output("Error in {}!\n"); error=104; return result;
}
next++; scan_logical();
if (error) return result;
}
}
else
{ scan_logical();
}
return result;
}
header *scan_value (void)
{ header *result=(header *)newram,*hd,*hd1,*marker,*nextresult,
*endresults;
int oldnosubmref;
unsigned long size,hd1size;
scan_space();
if (*next=='{')
{ next++;
oldnosubmref=nosubmref; nosubmref=1;
scan_logical(); nosubmref=oldnosubmref;
hd1=getvalue(result);
if (error) return result;
moveresult(result,hd1);
while (1)
{ scan_space();
if (*next=='}') { next++; return result; }
if (*next!=',')
{ output("Error in {}!\n"); error=104; return result;
}
next++; hd=(header *)newram; scan_value();
if (error) return result;
hd1=getvalue(hd); if (error) return result;
moveresult(hd,hd1);
}
}
else
{ scan_logical();
marker=result;
endresults=(header *)newram;
while (marker<endresults)
{ hd1=getvalue(marker);
if (error) return result;
nextresult=nextof(marker);
if (hd1!=marker)
{ if (nextresult==endresults)
{ if (hd1>=nextresult && (char *)hd1<newram)
{ hd1size=newram-(char *)hd1;
size=(char *)hd1-(char *)marker;
memmove((char *)marker,(char *)hd1,hd1size);
newram-=size;
break;
}
else
{ memmove((char *)marker,(char *)hd1,hd1->size);
newram=(char *)nextof(marker);
break;
}
}
if (hd1>nextresult && (char *)hd1<newram)
hd1size=(newram-(char *)hd1);
else hd1size=hd1->size;
size=hd1size-marker->size;
memmove((char *)nextresult+size,(char *)nextresult,
newram-(char *)nextresult);
if (hd1>nextresult && (char *)hd1<newram)
hd1=(header *)((char *)hd1+size);
nextresult=(header *)((char *)nextresult+size);
endresults=(header *)((char *)endresults+size);
memmove((char *)marker,(char *)hd1,hd1size);
newram=(char *)endresults;
}
marker=nextresult;
}
}
return result;
}
syntax highlighted by Code2HTML, v. 0.9.1