1
0
Fork 0

Small code/style changes in math module

This commit is contained in:
Nukem 2015-03-28 15:03:58 -04:00
parent bf91af33e7
commit b56a1d4b91
3 changed files with 124 additions and 140 deletions

View File

@ -97,9 +97,7 @@ bool arraycontains(const char* cmd_list, const char* cmd)
bool scmp(const char* a, const char* b) bool scmp(const char* a, const char* b)
{ {
if(_stricmp(a, b)) return _stricmp(a, b) == 0;
return false;
return true;
} }
void formathex(char* string) void formathex(char* string)

View File

@ -4,6 +4,10 @@ template<typename T>
class Memory class Memory
{ {
public: public:
//
// This class guarantees that the returned allocated memory
// will always be zeroed
//
Memory(const char* Reason = "Memory:???") Memory(const char* Reason = "Memory:???")
{ {
m_Ptr = nullptr; m_Ptr = nullptr;

View File

@ -25,7 +25,8 @@ struct EXPRESSION
/* /*
operator precedence operator precedence
1 ( ) 0 (INVALID/NONE)
1 ( ) (PARENTHESIS)
2 ~ (NOT) 2 ~ (NOT)
3 * / % (MUL DIV) 3 * / % (MUL DIV)
4 + - (ADD SUB) 4 + - (ADD SUB)
@ -34,18 +35,21 @@ operator precedence
7 ^ (XOR) 7 ^ (XOR)
8 | (OR) 8 | (OR)
*/ */
int mathisoperator(char ch) int mathisoperator(char ch)
{ {
if(ch == '(' or ch == ')') //
// The lower the number, the higher the priority.
// Zero indicates no operator was found.
//
if(ch == '(' || ch == ')')
return 1; return 1;
else if(ch == '~') else if(ch == '~')
return 2; return 2;
else if(ch == '*' or ch == '`' or ch == '/' or ch == '%') else if(ch == '*' || ch == '`' || ch == '/' || ch == '%')
return 3; return 3;
else if(ch == '+' or ch == '-') else if(ch == '+' || ch == '-')
return 4; return 4;
else if(ch == '<' or ch == '>') else if(ch == '<' || ch == '>')
return 5; return 5;
else if(ch == '&') else if(ch == '&')
return 6; return 6;
@ -53,6 +57,7 @@ int mathisoperator(char ch)
return 7; return 7;
else if(ch == '|') else if(ch == '|')
return 8; return 8;
return 0; return 0;
} }
@ -64,10 +69,13 @@ void mathformat(char* text)
{ {
int len = (int)strlen(text); int len = (int)strlen(text);
Memory<char*> temp(len + 1, "mathformat:temp"); Memory<char*> temp(len + 1, "mathformat:temp");
memset(temp, 0, len + 1);
for(int i = 0, j = 0; i < len; i++) for (int i = 0, j = 0; i < len; i++)
if(mathisoperator(text[i]) < 3 or text[i] != text[i + 1]) {
j += sprintf(temp + j, "%c", text[i]); if (mathisoperator(text[i]) < 3 || text[i] != text[i + 1])
j += sprintf(temp + j, "%c", text[i]);
}
strcpy(text, temp); strcpy(text, temp);
} }
@ -76,12 +84,17 @@ void mathformat(char* text)
*/ */
bool mathcontains(const char* text) bool mathcontains(const char* text)
{ {
if(*text == '-') //ignore negative values // Skip negative values
if(*text == '-')
text++; text++;
int len = (int)strlen(text);
for(int i = 0; i < len; i++) // Search the entire string looking for a math operator
if(mathisoperator(text[i])) for (; text[0] != '\0'; text++)
return true; {
if (mathisoperator(text[0]))
return true;
}
return false; return false;
} }
@ -122,125 +135,86 @@ inline int mulhi(int x, int y)
} }
#endif //__MINGW64__ #endif //__MINGW64__
template<typename T>
bool MathDoOperation(char op, T left, T right, T* result)
{
switch (op)
{
case '*':
*result = left * right;
return true;
case '`':
*result = umulhi(left, right);
return true;
case '/':
if (right)
{
*result = left / right;
return true;
}
return false;
case '%':
if (right)
{
*result = left % right;
return true;
}
return false;
case '+':
*result = left + right;
return true;
case '-':
*result = left - right;
return true;
case '<':
*result = left << right;
return true;
case '>':
*result = left >> right;
return true;
case '&':
*result = left & right;
return true;
case '^':
*result = left ^ right;
return true;
case '|':
*result = left | right;
return true;
}
return false;
}
bool mathdounsignedoperation(char op, uint left, uint right, uint* result) bool mathdounsignedoperation(char op, uint left, uint right, uint* result)
{ {
switch(op) return MathDoOperation<uint>(op, left, right, result);
{
case '*':
*result = left * right;
return true;
case '`':
*result = umulhi(left, right);
return true;
case '/':
if(right)
{
*result = left / right;
return true;
}
return false;
case '%':
if(right)
{
*result = left % right;
return true;
}
return false;
case '+':
*result = left + right;
return true;
case '-':
*result = left - right;
return true;
case '<':
*result = left << right;
return true;
case '>':
*result = left >> right;
return true;
case '&':
*result = left & right;
return true;
case '^':
*result = left ^ right;
return true;
case '|':
*result = left | right;
return true;
}
return false;
} }
bool mathdosignedoperation(char op, sint left, sint right, sint* result) bool mathdosignedoperation(char op, sint left, sint right, sint* result)
{ {
switch(op) return MathDoOperation<sint>(op, left, right, result);
{
case '*':
*result = left * right;
return true;
case '`':
*result = mulhi(left, right);
return true;
case '/':
if(right)
{
*result = left / right;
return true;
}
return false;
case '%':
if(right)
{
*result = left % right;
return true;
}
return false;
case '+':
*result = left + right;
return true;
case '-':
*result = left - right;
return true;
case '<':
*result = left << right;
return true;
case '>':
*result = left >> right;
return true;
case '&':
*result = left & right;
return true;
case '^':
*result = left ^ right;
return true;
case '|':
*result = left | right;
return true;
}
return false;
} }
void fillpair(EXPRESSION* expstruct, int pos, int layer) void fillpair(EXPRESSION* expstruct, int pos, int layer)
{ {
for(int i = 0; i < expstruct->total_pairs; i++) for(int i = 0; i < expstruct->total_pairs; i++)
{ {
if(!expstruct->pairs[i].isset) if(expstruct->pairs[i].isset == BRACKET_FREE)
{ {
expstruct->pairs[i].layer = layer; expstruct->pairs[i].layer = layer;
expstruct->pairs[i].openpos = pos; expstruct->pairs[i].openpos = pos;
expstruct->pairs[i].isset = BRACKET_OPEN; expstruct->pairs[i].isset = BRACKET_OPEN;
break; break;
} }
else if(expstruct->pairs[i].layer == layer and expstruct->pairs[i].isset == 1) else if(expstruct->pairs[i].layer == layer && expstruct->pairs[i].isset == BRACKET_OPEN)
{ {
expstruct->pairs[i].closepos = pos; expstruct->pairs[i].closepos = pos;
expstruct->pairs[i].isset = BRACKET_CLOSE; expstruct->pairs[i].isset = BRACKET_CLOSE;
break; break;
} }
} }
} }
int matchpairs(EXPRESSION* expstruct, char* expression, int endlayer) int matchpairs(EXPRESSION* expstruct, char* expression, int endlayer)
{ {
int layer = endlayer; int layer = endlayer;
@ -298,6 +272,7 @@ void adjustpairs(EXPRESSION* exps, int cur_open, int cur_close, int cur_len, int
{ {
if(exps->pairs[i].openpos > cur_open) if(exps->pairs[i].openpos > cur_open)
exps->pairs[i].openpos += new_len - cur_len; exps->pairs[i].openpos += new_len - cur_len;
if(exps->pairs[i].closepos > cur_close) if(exps->pairs[i].closepos > cur_close)
exps->pairs[i].closepos += new_len - cur_len; exps->pairs[i].closepos += new_len - cur_len;
} }
@ -309,18 +284,18 @@ bool printlayer(char* exp, EXPRESSION* exps, int layer, bool silent, bool baseon
{ {
if(exps->pairs[i].layer == layer) if(exps->pairs[i].layer == layer)
{ {
char temp[256] = ""; int open = exps->pairs[i].openpos;
char backup[256] = ""; int close = exps->pairs[i].closepos;
int len = close - open;
int open = exps->pairs[i].openpos; char temp[256];
int close = exps->pairs[i].closepos;
int len = close - open;
strncpy(temp, exp + open + 1, len - 1); strncpy(temp, exp + open + 1, len - 1);
char backup[256];
strcpy_s(backup, exp + open + len + 1); strcpy_s(backup, exp + open + len + 1);
uint value; uint value;
if(!mathfromstring(temp, &value, silent, baseonly, 0, 0)) if(!mathfromstring(temp, &value, silent, baseonly, nullptr, nullptr))
return false; return false;
adjustpairs(exps, open, close, len + 1, sprintf(exp + open, "%"fext"X", value)); adjustpairs(exps, open, close, len + 1, sprintf(exp + open, "%"fext"X", value));
@ -330,32 +305,41 @@ bool printlayer(char* exp, EXPRESSION* exps, int layer, bool silent, bool baseon
} }
} }
return true; return true;
} }
bool mathhandlebrackets(char* expression, bool silent, bool baseonly) bool mathhandlebrackets(char* expression, bool silent, bool baseonly)
{ {
EXPRESSION expstruct; int totalPairs = expressionformat(expression);
expstruct.expression = expression;
int total_pairs = expressionformat(expression); if(totalPairs == -1)
if(total_pairs == -1)
return false; return false;
else if(!total_pairs) else if(!totalPairs)
return true; return true;
expstruct.total_pairs = total_pairs;
Memory<BRACKET_PAIR*> pairs(expstruct.total_pairs * sizeof(BRACKET_PAIR), "mathhandlebrackets:expstruct.pairs"); Memory<BRACKET_PAIR*> pairs(totalPairs * sizeof(BRACKET_PAIR), "mathhandlebrackets:pairs");
expstruct.pairs = pairs;
memset(expstruct.pairs, 0, expstruct.total_pairs * sizeof(BRACKET_PAIR)); EXPRESSION expStruct;
matchpairs(&expstruct, expression, 0); expStruct.expression = expression;
expStruct.total_pairs = totalPairs;
expStruct.pairs = pairs;
matchpairs(&expStruct, expression, 0);
int deepest = 0; int deepest = 0;
for(int i = 0; i < expstruct.total_pairs; i++) for (int i = 0; i < expStruct.total_pairs; i++)
if(expstruct.pairs[i].layer > deepest) {
deepest = expstruct.pairs[i].layer; if (expStruct.pairs[i].layer > deepest)
deepest = expStruct.pairs[i].layer;
}
for (int i = deepest; i > 0; i--)
{
if (!printlayer(expression, &expStruct, i, silent, baseonly))
return false;
}
for(int i = deepest; i > 0; i--)
if(!printlayer(expression, &expstruct, i, silent, baseonly))
return false;
return true; return true;
} }
@ -386,8 +370,6 @@ bool mathfromstring(const char* string, uint* value, bool silent, bool baseonly,
return valfromstring(string, value, silent, baseonly, value_size, isvar, 0); return valfromstring(string, value, silent, baseonly, value_size, isvar, 0);
Memory<char*> strleft(len + 1 + negative, "mathfromstring:strleft"); Memory<char*> strleft(len + 1 + negative, "mathfromstring:strleft");
Memory<char*> strright(len + 1, "mathfromstring:strright"); Memory<char*> strright(len + 1, "mathfromstring:strright");
memset(strleft, 0, len + 1);
memset(strright, 0, len + 1);
strncpy(strleft, string - negative, highestop_pos + negative); strncpy(strleft, string - negative, highestop_pos + negative);
strcpy(strright, string + highestop_pos + 1); strcpy(strright, string + highestop_pos + 1);
strcpy(strleft, StringUtils::Trim(strleft).c_str()); strcpy(strleft, StringUtils::Trim(strleft).c_str());