Created
March 23, 2010 13:57
-
-
Save karno/341192 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Arithmetic Operation Block | |
#include "litbas.h" | |
#include "arith_i.h" | |
BOOL g_ArithmeticError = FALSE; | |
BOOL g_NoPrintError = FALSE; | |
//arithession root | |
double Arith(const char *arith) | |
{ | |
G_ERR_Arith = FALSE; | |
g_ArithmeticError = FALSE; | |
g_NoPrintError = FALSE; | |
double retval = 0; | |
char *buffer; | |
buffer = (char*)calloc(strlen(arith) + 1,sizeof(char)); | |
assert(buffer); | |
strcpy(buffer,arith); | |
StrRmvSpacesTabs(buffer); | |
transArith(buffer); | |
retval = arithRoot(buffer); | |
free(buffer); | |
if(g_ArithmeticError) | |
{ | |
G_ERR_Arith = TRUE; | |
return 0; | |
} | |
else | |
{ | |
return retval; | |
} | |
} | |
void transArith(char *arith) | |
{ | |
StrToUpper(arith); | |
char *p = NULL; | |
if(p = strstr(arith, "MOD")) | |
StrReplChr(arith, p - arith, 3, '%'); | |
if(p = strstr(arith, "AND")) | |
StrReplChr(arith, p - arith, 3, '&'); | |
if(p = strstr(arith, "XOR")) | |
StrReplChr(arith, p - arith, 3, ARITH_XOR); | |
if(p = strstr(arith, "OR")) | |
StrReplChr(arith, p - arith, 2, '|'); | |
if(p = strstr(arith, "NOT")) | |
StrReplChr(arith, p - arith, 2, '!'); | |
if(p = strstr(arith, "<=")) | |
StrReplChr(arith, p - arith, 2, ARITH_LT_OR_EQ); | |
if(p = strstr(arith, "=<")) | |
StrReplChr(arith, p - arith, 2, ARITH_LT_OR_EQ); | |
if(p = strstr(arith, ">=")) | |
StrReplChr(arith, p - arith, 2, ARITH_MT_OR_EQ); | |
if(p = strstr(arith, "=>")) | |
StrReplChr(arith, p - arith, 2, ARITH_MT_OR_EQ); | |
if(p = strstr(arith, "<>")) | |
StrReplChr(arith, p - arith, 2, ARITH_NEQ); | |
} | |
BOOL BracketsExists(const char *arith) | |
{ | |
const char *p; | |
for(p = arith; *p; p++) | |
{ | |
if(*p == '(' || *p == ')') | |
return TRUE; | |
} | |
return FALSE; | |
} | |
int GetBracketInnerStr(const char *arith, char *dest) | |
{ | |
const char *p, *startpoint; | |
int len = 0,brctcnt = 0; | |
BOOL endflag = FALSE; | |
for(p = arith; *p; p++) | |
{ | |
if(*p == '(') | |
{ | |
if(brctcnt == 0) | |
startpoint = p + 1; | |
brctcnt++; | |
} | |
else if(*p == ')') | |
{ | |
brctcnt--; | |
if(brctcnt == 0) | |
{ | |
endflag = TRUE; | |
break; | |
} | |
} | |
if(brctcnt != 0) | |
len++; | |
} | |
if(!endflag) | |
{ | |
g_ArithmeticError = TRUE; | |
return 0; | |
} | |
else | |
{ | |
memcpy(dest, startpoint, len * sizeof(char)); | |
*(dest + len - 1) = '\0'; | |
return startpoint - arith; | |
} | |
} | |
double arithRoot(const char *arith) | |
{ | |
char *buffer = (char *)calloc(strlen(arith) + 1,sizeof(char)); | |
assert(buffer); | |
strcpy(buffer, arith); | |
double value = 0; | |
if(BracketsExists(buffer)) | |
{ | |
int startpoint = 0; | |
int blen = 0,diff = 0; | |
double replValue = 0; | |
char *replbuf = (char *)calloc( | |
(strlen(arith) + 1) > ARITH_INTERNAL_MAXLEN ? (strlen(arith) + 1) : ARITH_INTERNAL_MAXLEN, | |
sizeof(char)); | |
assert(replbuf); | |
while(BracketsExists(buffer)) | |
{ | |
startpoint = GetBracketInnerStr(buffer, replbuf); | |
replValue = arithRoot(replbuf); | |
if(g_ArithmeticError) | |
return 0; | |
blen = strlen(replbuf); | |
sprintf(replbuf, "%lf", replValue); | |
diff = strlen(replbuf) - blen; | |
if(diff > 0) | |
buffer = (char *)realloc(buffer,(strlen(buffer) + diff + 1) * sizeof(char)); | |
StrReplace(buffer, startpoint - 1, blen + 2, replbuf); | |
} | |
free(replbuf); | |
} | |
char *bufptr = buffer; | |
value = arith1(&bufptr); | |
free(buffer); | |
return value; | |
} | |
double arith1(char **arith) | |
{ | |
if(g_ArithmeticError) return 0; | |
//AND,OR,XOR | |
double curval = arith2(arith); | |
while(**arith) | |
{ | |
switch((unsigned char)*(*arith)++) | |
{ | |
case '&': | |
curval = (unsigned int)curval & (unsigned int)arith2(arith); | |
break; | |
case '|': | |
curval = (unsigned int)curval | (unsigned int)arith2(arith); | |
break; | |
case ARITH_XOR: | |
curval = (unsigned int)curval ^ (unsigned int)arith2(arith); | |
break; | |
case '!': | |
curval = !arith2(arith); | |
break; | |
default: | |
//end of arithession err | |
g_ArithmeticError = TRUE; | |
return 0; | |
} | |
} | |
return curval; | |
} | |
double arith2(char **arith) | |
{ | |
if(g_ArithmeticError) return 0; | |
//<,>,<=,>=,= | |
double curval = arith3(arith); | |
while(**arith) | |
{ | |
switch((unsigned char)*(*arith)++) | |
{ | |
case '>': | |
curval = (curval > arith3(arith)); | |
break; | |
case '<': | |
curval = (curval < arith3(arith)); | |
break; | |
case ARITH_MT_OR_EQ: | |
curval = (curval >= arith3(arith)); | |
break; | |
case ARITH_LT_OR_EQ: | |
curval = (curval <= arith3(arith)); | |
break; | |
case '=': | |
curval = (curval == arith3(arith)); | |
break; | |
case ARITH_NEQ: | |
curval = (curval != arith3(arith)); | |
break; | |
default: | |
(*arith)--; | |
return curval; | |
} | |
} | |
return curval; | |
} | |
double arith3(char **arith) | |
{ | |
if(g_ArithmeticError) return 0; | |
//+,- | |
double curval = arith4(arith); | |
while(**arith) | |
{ | |
switch((unsigned char)*(*arith)++) | |
{ | |
case '+': | |
curval += arith4(arith); | |
break; | |
case '-': | |
curval -= arith4(arith); | |
break; | |
default: | |
(*arith)--; | |
return curval; | |
} | |
} | |
return curval; | |
} | |
double arith4(char **arith) | |
{ | |
if(g_ArithmeticError) return 0; | |
//*,/ | |
double curval = arith5(arith); | |
while(**arith) | |
{ | |
switch((unsigned char)*(*arith)++) | |
{ | |
case '*': | |
curval *= arith5(arith); | |
break; | |
case '/': | |
curval /= arith5(arith); | |
break; | |
case '%': | |
curval = (int)curval % (int)arith5(arith); | |
break; | |
default: | |
(*arith)--; | |
return curval; | |
} | |
} | |
return curval; | |
} | |
double arith5(char **arith) | |
{ | |
if(g_ArithmeticError) return 0; | |
//^(power) | |
double curval = getValue(arith); | |
while(**arith) | |
{ | |
switch((unsigned char)*(*arith)++) | |
{ | |
case '^': | |
curval = pow(curval,getValue(arith)); | |
break; | |
default: | |
(*arith)--; | |
return curval; | |
} | |
} | |
return curval; | |
} | |
double getValue(char **arith) | |
{ | |
char *buf = NULL; | |
double val = 0; | |
if(strlen(*arith) == 0) | |
return 0; | |
if(**arith >= '0' && **arith <= '9') | |
{ | |
//mathematics opr | |
val = strtod(*arith, &buf); | |
*arith = buf; | |
} | |
else | |
{ | |
buf = (char *)calloc(sizeof(char),(strlen(*arith) + 1)); | |
int c = 0; | |
while( | |
(**arith >= 'A' && **arith <= 'Z') || | |
(**arith >= '0' && **arith <= '9') || | |
(**arith == '(' || **arith == ')') ) | |
{ | |
buf[c++] = **arith; | |
(*arith)++; | |
} | |
if(**arith == '$') | |
{ | |
//character variable | |
g_ArithmeticError = TRUE; | |
g_NoPrintError = TRUE; | |
PrintError("Type mismatch"); | |
return 0; | |
} | |
if(buf[strlen(buf) - 1] == ')') | |
{ | |
val = 0; | |
} | |
else | |
{ | |
val = LookupNumVar(buf); | |
} | |
free(buf); | |
} | |
return val; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment