diff options
-rw-r--r-- | src/include/util_Expression.h | 64 | ||||
-rw-r--r-- | src/include/utili_Expression.h | 82 | ||||
-rw-r--r-- | src/util/Expression.c | 186 |
3 files changed, 183 insertions, 149 deletions
diff --git a/src/include/util_Expression.h b/src/include/util_Expression.h index 85ead356..c8b524c4 100644 --- a/src/include/util_Expression.h +++ b/src/include/util_Expression.h @@ -16,66 +16,6 @@ extern "C" { #endif - /* These data types are for internal use only. */ - - /* Defined operators */ -typedef enum {OP_NONE, - OP_EQUALS, - OP_LESS_THAN, - OP_GREATER_THAN, - OP_LEQUALS, - OP_GEQUALS, - OP_AND, - OP_OR, - OP_PLUS, - OP_MINUS, - OP_DIV, - OP_TIMES, - OP_POWER, - OP_ACOS, - OP_ASIN, - OP_ATAN, - OP_CEIL, - OP_COS, - OP_COSH, - OP_EXP, - OP_FABS, - OP_FLOOR, - OP_LOG, - OP_LOG10, - OP_SIN, - OP_SINH, - OP_SQRT, - OP_TAN, - OP_TANH} - uExpressionOpcode; - - /* What sort of expression types we have. */ -typedef enum {val,unary,binary} uExpressionType; - - /* RPN object. */ -typedef struct -{ - uExpressionType type; - - union - { - uExpressionOpcode opcode; - int varnum; - } token; -} uExpressionToken; - - /* Parsed expression object. */ -typedef struct -{ - int ntokens; - uExpressionToken *tokens; - int nvars; - const char **vars; -} uExpressionInternals; - -/* Beginning of externally useable objects. */ - /* Structure to hold values. */ typedef struct { @@ -88,8 +28,10 @@ typedef struct } value; } uExpressionValue; +#ifndef __UTILI_EXPRESSION_H__ /* Externally visible representation of the expression. */ -typedef uExpressionInternals *uExpression; +typedef void *uExpression; +#endif /*__UTIL_EXPRESSION_H__ */ uExpression Util_ExpressionParse(const char *expression); diff --git a/src/include/utili_Expression.h b/src/include/utili_Expression.h new file mode 100644 index 00000000..b501ebad --- /dev/null +++ b/src/include/utili_Expression.h @@ -0,0 +1,82 @@ + /*@@ + @header utili_Expression.h + @date Wed Nov 7 00:39:24 2001 + @author Tom Goodale + @desc + Internal definitions for the expression parser. + @enddesc + @version $Header$ + @@*/ + +#ifndef __UTILI_EXPRESSION_H__ +#define __UTILI_EXPRESSION_H__ 1 + +#ifdef __cplusplus +extern "C" +{ +#endif + + /* Defined operators */ +typedef enum {OP_NONE, + OP_EQUALS, + OP_LESS_THAN, + OP_GREATER_THAN, + OP_LEQUALS, + OP_GEQUALS, + OP_AND, + OP_OR, + OP_PLUS, + OP_MINUS, + OP_DIV, + OP_TIMES, + OP_POWER, + OP_ACOS, + OP_ASIN, + OP_ATAN, + OP_CEIL, + OP_COS, + OP_COSH, + OP_EXP, + OP_FABS, + OP_FLOOR, + OP_LOG, + OP_LOG10, + OP_SIN, + OP_SINH, + OP_SQRT, + OP_TAN, + OP_TANH} + uExpressionOpcode; + + /* What sort of expression types we have. */ +typedef enum {val,unary,binary} uExpressionType; + + /* RPN object. */ +typedef struct +{ + uExpressionType type; + + union + { + uExpressionOpcode opcode; + int varnum; + } token; +} uExpressionToken; + + /* Parsed expression object. */ +typedef struct +{ + int ntokens; + uExpressionToken *tokens; + int nvars; + char **vars; +} uExpressionInternals; + + /* Internal representation of the expression. */ +typedef uExpressionInternals *uExpression; + +#ifdef __cplusplus +} +#endif + +#endif /* __UTIL_EXPRESSION_H__ */ diff --git a/src/util/Expression.c b/src/util/Expression.c index b79b4706..ed881d69 100644 --- a/src/util/Expression.c +++ b/src/util/Expression.c @@ -20,6 +20,7 @@ #include <math.h> +#include "utili_Expression.h" #include "util_Expression.h" static const char *rcsid = "$Header$"; @@ -254,10 +255,7 @@ uExpression Util_ExpressionParse(const char *expression) @returntype int @returndesc 0 - success - The below used to be returned, but now expression is pre-verified. - +ve - success but there were this number of remaining operation on the stack. - -ve - the number of remaining items on the expression stack when an error was - encountered + -1 - memory allocation failure @endreturndesc @@*/ @@ -279,98 +277,102 @@ int Util_ExpressionEvaluate(const uExpression buffer, /* Assign memory for array to contain all variable values */ varvals = (uExpressionValue *)malloc(buffer->nvars*sizeof(uExpressionValue)); - if(varvals) + if(varvals || ! buffer->nvars) { /* Evaluate the variables in one go to help people doing parallel ops. */ eval(buffer->nvars, buffer->vars, varvals, data); - } - - /* Tokens are seperated by @ signs */ - for(position = 0; position < buffer->ntokens; position++) - { - if(buffer->tokens[position].type == val) - { - /* Put value on stack */ - stack[stackpointer] = varvals[buffer->tokens[position].token.varnum]; - stackpointer++; - } - else + /* Tokens are seperated by @ signs */ + for(position = 0; position < buffer->ntokens; position++) { + if(buffer->tokens[position].type == val) + { + /* Put value on stack */ + stack[stackpointer] = varvals[buffer->tokens[position].token.varnum]; + + stackpointer++; + } + else + { #ifdef TEST_EXPRESSION_PARSER - printf("Stackpointer is %d, ", stackpointer); - if(buffer->tokens[position].type == binary) - { - switch(stack[stackpointer-2].type) + printf("Stackpointer is %d, ", stackpointer); + if(buffer->tokens[position].type == binary) + { + switch(stack[stackpointer-2].type) + { + case ival: + printf("%d " ,stack[stackpointer-2].value.ival); break; + case rval: + printf("%f " ,stack[stackpointer-2].value.rval); break; + default: + ; + } + } + + printf("%s ", opname(buffer->tokens[position].token.opcode)); + switch(stack[stackpointer-1].type) { case ival: - printf("%d " ,stack[stackpointer-2].value.ival); break; + printf("%d " ,stack[stackpointer-1].value.ival); break; case rval: - printf("%f " ,stack[stackpointer-2].value.rval); break; + printf("%f " ,stack[stackpointer-1].value.rval); break; default: ; } - } - - printf("%s ", opname(buffer->tokens[position].token.opcode)); - switch(stack[stackpointer-1].type) - { - case ival: - printf("%d " ,stack[stackpointer-1].value.ival); break; - case rval: - printf("%f " ,stack[stackpointer-1].value.rval); break; - default: - ; - } - printf(" = "); - fflush(stdout); + printf(" = "); + fflush(stdout); #endif - /* Evaluate operation, clear operands from stack and add the result to the stack. */ - switch(buffer->tokens[position].type) - { - case binary: - EvaluateBinary(&(stack[stackpointer-2]), - &(stack[stackpointer-2]), - buffer->tokens[position].token.opcode, - &(stack[stackpointer-1])); - stackpointer--; - break; - case unary: + /* Evaluate operation, clear operands from stack and add the result to the stack. */ + switch(buffer->tokens[position].type) + { + case binary: + EvaluateBinary(&(stack[stackpointer-2]), + &(stack[stackpointer-2]), + buffer->tokens[position].token.opcode, + &(stack[stackpointer-1])); + stackpointer--; + break; + case unary: EvaluateUnary(&(stack[stackpointer-1]), buffer->tokens[position].token.opcode, &(stack[stackpointer-1])); - break; - default : - ; - } - + break; + default : + ; + } + #ifdef TEST_EXPRESSION_PARSER - switch(stack[stackpointer-1].type) - { - case ival: - printf("%d\n" ,stack[stackpointer-1].value.ival); break; - case rval: - printf("%f\n" ,stack[stackpointer-1].value.rval); break; - default: - ; - } + switch(stack[stackpointer-1].type) + { + case ival: + printf("%d\n" ,stack[stackpointer-1].value.ival); break; + case rval: + printf("%f\n" ,stack[stackpointer-1].value.rval); break; + default: + ; + } #endif + } + } + if(varvals) + { + free(varvals); } - } - - if(varvals) - { - free(varvals); - } - *retval=stack[0]; + *retval=stack[0]; + /* stackpointer should be 1 at this point if VerifyExpression + * was called on the expression. + */ - /* stackpointer should be 1 at this point if VerifyExpression - * was called on the expression. - */ + retcode = stackpointer-1; + } + else + { + /* memory failure */ - retcode = stackpointer-1; + retcode = -1; + } return retcode; } @@ -406,7 +408,7 @@ void Util_ExpressionFree(uExpression buffer) for(i = 0; i < buffer->nvars; i++) { - free((char *)(buffer->vars[i])); + free(buffer->vars[i]); } free(buffer->vars); } @@ -541,25 +543,33 @@ static pToken *Tokenise(const char *expression) /* Create a new token */ new = newtoken(tokenstart, tokenend); - /* Insert on list */ - if(current) - { - insertafter(current, new); - } - current = new; - - if(!start) + if(new) { - start = current; - } + /* Insert on list */ + if(current) + { + insertafter(current, new); + } + current = new; + + if(!start) + { + start = current; + } - if(*tokenend) - { - tokenstart = tokenend+1; + if(*tokenend) + { + tokenstart = tokenend+1; + } + else + { + break; + } } else { - break; + fprintf(stderr, "Unable to allocate memory for new token !\n"); + abort(); } } |