#include "tintin.h"
#include <ctype.h>
int stacks[100][3];
extern struct listnode *common_myvars;
#if IRIX
#include <stdlib.h>
#include <unistd.h>
#endif
extern char *get_arg_in_braces();
extern struct listnode *searchnode_list();
void math_command(line, ses)
char *line;
struct session *ses;
{
/* char left[BUFFER_SIZE], right[BUFFER_SIZE], arg2[BUFFER_SIZE], */
char left[BUFFER_SIZE], right[BUFFER_SIZE],
temp[BUFFER_SIZE], result[BUFFER_SIZE];
struct listnode *my_vars, *ln;
int i;
my_vars=(ses) ? ses->myvars : common_myvars;
line=get_arg_in_braces(line, left, 0);
line=get_arg_in_braces(line, right, 1);
substitute_vars(right, result);
substitute_myvars(result, right,ses);
i=eval_expression(right);
sprintf(temp,"%d",i);
if ((ln=searchnode_list(my_vars,left))!=NULL)
deletenode_list(my_vars, ln);
insertnode_list(my_vars, left, temp, "0", ALPHA);
}
void if_command(line, ses)
char *line;
struct session *ses;
{
/* char left[BUFFER_SIZE], right[BUFFER_SIZE], arg2[BUFFER_SIZE], */
char left[BUFFER_SIZE], right[BUFFER_SIZE],
temp[BUFFER_SIZE];
/* int i; */
line=get_arg_in_braces(line, left, 0);
line=get_arg_in_braces(line, right, 1);
substitute_vars(right,temp);
substitute_myvars(temp,right,ses);
substitute_vars(left,temp);
substitute_myvars(temp,left,ses);
if (eval_expression(left)) {
parse_input(right, ses);
}
}
int eval_expression(arg)
char *arg;
{
/* int i, begin, end, flag, prev, ptr; */
int i, begin, end, flag, prev;
char temp[BUFFER_SIZE];
i=conv_to_ints(arg);
if (i) {
while(1) {
i=0;
flag=1;
begin= -1;
end= -1;
prev= -1;
while(stacks[i][0] && flag) {
if (stacks[i][1]==0) {
begin=i;
}
else if(stacks[i][1]==1) {
end=i;
flag=0;
}
prev=i;
i=stacks[i][0];
}
if ((flag && (begin!= -1)) || (!flag && (begin== -1))) {
tintin_puts2("#Unmatched parentheses error.", (struct session *)NULL);
return 0;
}
if (flag) {
if (prev== -1)
return(stacks[0][2]);
begin= -1;
end=i;
}
i=do_one_inside(begin,end);
if (!i) {
sprintf(temp, "#Invalid expression to evaluate in {%s}", arg);
tintin_puts2(temp, (struct session *)NULL);
return 0;
}
}
}
else return 0;
}
int conv_to_ints(arg)
char *arg;
{
int i, flag;
char *ptr, *tptr;
i=0;
ptr=arg;
while (*ptr) {
if (*ptr==' ') ;
else if (*ptr=='(') {
stacks[i][1]=0;
}
else if(*ptr==')') {
stacks[i][1]=1;
}
else if(*ptr=='!') {
if (*(ptr+1)=='=') {
stacks[i][1]=12;
ptr++;
}
else
stacks[i][1]=2;
}
else if(*ptr=='*') {
stacks[i][1]=3;
}
else if(*ptr=='/') {
stacks[i][1]=4;
}
else if(*ptr=='+') {
stacks[i][1]=5;
}
else if(*ptr=='-') {
flag= -1;
if (i>0)
flag=stacks[i-1][1];
if (flag==15)
stacks[i][1]=6;
else {
tptr=ptr;
ptr++;
while(isdigit(*ptr))
ptr++;
sscanf(tptr,"%d",&stacks[i][2]);
stacks[i][1]=15;
ptr--;
}
}
else if(*ptr=='>') {
if (*(ptr+1)=='=') {
stacks[i][1]=8;
ptr++;
}
else
stacks[i][1]=7;
}
else if(*ptr=='<') {
if (*(ptr+1)=='=') {
ptr++;
stacks[i][1]=10;
}
else
stacks[i][1]=9;
}
else if(*ptr=='=') {
stacks[i][1]=11;
if (*(ptr+1)=='=')
ptr++;
}
else if(*ptr=='&') {
stacks[i][1]=13;
if (*(ptr+1)=='&')
ptr++;
}
else if(*ptr=='|') {
stacks[i][1]=14;
if (*(ptr+1)=='|')
ptr++;
}
else if (isdigit(*ptr)) {
stacks[i][1]=15;
tptr=ptr;
while (isdigit(*ptr))
ptr++;
sscanf(tptr,"%d",&stacks[i][2]);
ptr--;
}
else if (*ptr=='T') {
stacks[i][1]=15;
stacks[i][2]=1;
}
else if(*ptr=='F') {
stacks[i][1]=15;
stacks[i][2]=0;
}
else {
tintin_puts2("#Error. Invalid expression in #if or #math", (struct session *)NULL);
return 0;
}
if (*ptr!=' ') {
stacks[i][0]=i+1;
i++;
}
ptr++;
}
if (i>0)
stacks[i][0]=0;
return 1;
}
int do_one_inside(begin, end)
int begin;
int end;
{
/* int prev, ptr, highest, loc, ploc, next, nval, flag; */
int prev, ptr, highest, loc, ploc, next;
while(1) {
ptr=0;
if (begin>-1)
ptr=stacks[begin][0];
highest=16;
loc= -1;
ploc= -1;
prev= -1;
while (ptr<end) {
if (stacks[ptr][1]<highest) {
highest=stacks[ptr][1];
loc=ptr;
ploc=prev;
}
prev=ptr;
ptr=stacks[ptr][0];
}
if (highest==15) {
if (begin>-1) {
stacks[begin][1]=15;
stacks[begin][2]=stacks[loc][2];
stacks[begin][0]=stacks[end][0];
return 1;
}
else {
stacks[0][0]=stacks[end][0];
stacks[0][1]=15;
stacks[0][2]=stacks[loc][2];
return 1;
}
}
else if (highest==2) {
next=stacks[loc][0];
if (stacks[next][1]!=15 || stacks[next][0]==0) {
return 0;
}
stacks[loc][0]=stacks[next][0];
stacks[loc][1]=15;
stacks[loc][2]=!stacks[next][2];
}
else {
next=stacks[loc][0];
if (ploc== -1 || stacks[next][0]==0 || stacks[next][1]!=15)
return 0;
if (stacks[ploc][1]!=15)
return 0;
switch (highest) {
case 3: /* highest priority is * */
stacks[ploc][0]=stacks[next][0];
stacks[ploc][2]*=stacks[next][2];
break;
case 4: /* highest priority is / */
stacks[ploc][0]=stacks[next][0];
stacks[ploc][2]/=stacks[next][2];
break;
case 5: /* highest priority is + */
stacks[ploc][0]=stacks[next][0];
stacks[ploc][2]+=stacks[next][2];
break;
case 6: /* highest priority is - */
stacks[ploc][0]=stacks[next][0];
stacks[ploc][2]-=stacks[next][2];
break;
case 7: /* highest priority is > */
stacks[ploc][0]=stacks[next][0];
stacks[ploc][2]=(stacks[ploc][2]>stacks[next][2]);
break;
case 8: /* highest priority is >= */
stacks[ploc][0]=stacks[next][0];
stacks[ploc][2]=(stacks[ploc][2]>=stacks[next][2]);
break;
case 9: /* highest priority is < */
stacks[ploc][0]=stacks[next][0];
stacks[ploc][2]=(stacks[ploc][2]<stacks[next][2]);
break;
case 10: /* highest priority is <= */
stacks[ploc][0]=stacks[next][0];
stacks[ploc][2]=(stacks[ploc][2]<=stacks[next][2]);
break;
case 11: /* highest priority is == */
stacks[ploc][0]=stacks[next][0];
stacks[ploc][2]=(stacks[ploc][2]==stacks[next][2]);
break;
case 12: /* highest priority is != */
stacks[ploc][0]=stacks[next][0];
stacks[ploc][2]=(stacks[ploc][2]!=stacks[next][2]);
break;
case 13: /* highest priority is && */
stacks[ploc][0]=stacks[next][0];
stacks[ploc][2]=(stacks[ploc][2]&&stacks[next][2]);
break;
case 14: /* highest priority is || */
stacks[ploc][0]=stacks[next][0];
stacks[ploc][2]=(stacks[ploc][2]||stacks[next][2]);
break;
default:
tintin_puts2("#Programming error *slap Bill*", (struct session *)NULL);
return 0;
}
}
}
}