From c613ec4abb31983babb6c87e637624a13ee60bd6 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Tue, 3 Apr 2007 03:43:22 +0000 Subject: Deleted the egg example...it was annoying me. --- parex/eval.c | 651 ----------------------------------------------------------- 1 file changed, 651 deletions(-) delete mode 100644 parex/eval.c (limited to 'parex/eval.c') diff --git a/parex/eval.c b/parex/eval.c deleted file mode 100644 index 7eb9607..0000000 --- a/parex/eval.c +++ /dev/null @@ -1,651 +0,0 @@ -/* - * EVAL.C - part of the EGG system. - * - * Helper routine for evaluating arithmetic expressions. - * - * By Shawn Hargreaves. - */ - - -#include -#include -#include -#include -#include - -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - -#ifndef M_E -#define M_E 2.7182818284590452354 -#endif - -#include "egg.h" - - - -/* convert radians <-> degrees */ -#define DEG2RAD(x) ((x)*M_PI/180.0) -#define RAD2DEG(x) ((x)*180.0/M_PI) - - - -/* internal state information */ -static int evaluate_error; - -static char operator_stack[256]; -static double value_stack[256]; - -static int stack_depth; - -static double current_val; - -static int current_valid; - - - -/* operator tokens */ -#define OP_OPEN_PAREN '(' -#define OP_CLOSE_PAREN ')' -#define OP_PLUS '+' -#define OP_MINUS '-' -#define OP_MUL '*' -#define OP_DIV '/' -#define OP_POWER '^' -#define OP_NEGATE '~' -#define OP_SQRT 'q' -#define OP_SIN 's' -#define OP_COS 'c' -#define OP_TAN 't' -#define OP_ASIN 'S' -#define OP_ACOS 'C' -#define OP_ATAN 'T' -#define OP_LOG 'l' -#define OP_LN 'L' -#define OP_CEIL 'e' -#define OP_FLOOR 'f' -#define OP_ROUND 'r' -#define OP_ABS 'a' -#define OP_MOD '%' -#define OP_EQUALS '=' -#define OP_NOT_EQUALS '#' -#define OP_LESS '<' -#define OP_GREATER '>' -#define OP_LESS_EQUALS '{' -#define OP_GREATER_EQUALS '}' -#define OP_OR '|' -#define OP_AND '&' -#define OP_NOT '!' -#define OP_TERMINATOR ' ' - - - -/* precedence: - * Returns the precedence of the specified operator. - */ -static int precedence(char op) -{ - switch (op) { - - case OP_OPEN_PAREN: - case OP_CLOSE_PAREN: - return 1; - - case OP_TERMINATOR: - return 2; - - case OP_OR: - case OP_AND: - return 3; - - case OP_EQUALS: - case OP_NOT_EQUALS: - case OP_LESS: - case OP_GREATER: - case OP_LESS_EQUALS: - case OP_GREATER_EQUALS: - return 4; - - case OP_PLUS: - case OP_MINUS: - return 5; - - case OP_MUL: - case OP_DIV: - case OP_MOD: - return 6; - - case OP_POWER: - return 7; - - case OP_NEGATE: - case OP_NOT: - case OP_SQRT: - case OP_SIN: - case OP_COS: - case OP_TAN: - case OP_ASIN: - case OP_ACOS: - case OP_ATAN: - case OP_LOG: - case OP_LN: - case OP_CEIL: - case OP_FLOOR: - case OP_ROUND: - case OP_ABS: - return 8; - - default: - return -1; - } -} - - - -/* is_unary: - * Checks whether an operator is unary. - */ -static int is_unary(char op) -{ - if ((op == OP_NEGATE) || (op == OP_SQRT) || (op == OP_SIN) || - (op == OP_COS) || (op == OP_TAN) || (op == OP_ASIN) || - (op == OP_ACOS) || (op == OP_ATAN) || (op == OP_LOG) || - (op == OP_LN) || (op == OP_CEIL) || (op == OP_FLOOR) || - (op == OP_ROUND) || (op == OP_ABS) || (op == OP_NOT)) - return TRUE; - - return FALSE; -} - - - -/* add_value: - * Processes a new numeric value from the input string. - */ -static void add_value(double val) -{ - if (current_valid) { - evaluate_error = TRUE; - return; - } - - current_val = val; - current_valid = TRUE; -} - - - -/* add_operator: - * Processes a new operator from the input string. - */ -static void add_operator(char op) -{ - /* bodge for unary negation */ - if ((op == OP_MINUS) && (!current_valid)) - op = OP_NEGATE; - - /* check validity */ - if ((op == OP_PLUS) || (op == OP_MINUS) || - (op == OP_MUL) || (op == OP_DIV) || - (op == OP_POWER) || (op == OP_MOD) || - (op == OP_EQUALS) || (op == OP_NOT_EQUALS) || - (op == OP_LESS) || (op == OP_GREATER) || - (op == OP_LESS_EQUALS) || (op == OP_GREATER_EQUALS) || - (op == OP_OR) || (op == OP_AND)) { - - if (!current_valid) { - evaluate_error = TRUE; - return; - } - } - - /* evaluate */ - if (op != OP_OPEN_PAREN) { - while ((stack_depth > 0) && - ((precedence(op) <= precedence(operator_stack[stack_depth-1]) && (!is_unary(operator_stack[stack_depth-1]))) || - (precedence(op) < precedence(operator_stack[stack_depth-1]) && (is_unary(operator_stack[stack_depth-1]))))) { - - stack_depth--; - - switch (operator_stack[stack_depth]) { - - case OP_PLUS: - current_val = value_stack[stack_depth] + current_val; - break; - - case OP_MINUS: - current_val = value_stack[stack_depth] - current_val; - break; - - case OP_MUL: - current_val = value_stack[stack_depth] * current_val; - break; - - case OP_DIV: - if (current_val != 0) - current_val = value_stack[stack_depth] / current_val; - else - current_val = 0; - break; - - case OP_POWER: - current_val = pow(value_stack[stack_depth], current_val); - break; - - case OP_NEGATE: - current_val = -current_val; - break; - - case OP_SQRT: - if (current_val >= 0) - current_val = sqrt(current_val); - else - current_val = 0; - break; - - case OP_SIN: - current_val = sin(DEG2RAD(current_val)); - break; - - case OP_COS: - current_val = cos(DEG2RAD(current_val)); - break; - - case OP_TAN: - current_val = tan(DEG2RAD(current_val)); - break; - - case OP_ASIN: - if ((current_val >= -1) && (current_val <= 1)) - current_val = RAD2DEG(asin(current_val)); - else - current_val = 0; - break; - - case OP_ACOS: - if ((current_val >= -1) && (current_val <= 1)) - current_val = RAD2DEG(acos(current_val)); - else - current_val = 0; - break; - - case OP_ATAN: - current_val = RAD2DEG(atan(current_val)); - break; - - case OP_LOG: - if (current_val > 0) - current_val = log10(current_val); - else - current_val = 0; - break; - - case OP_LN: - if (current_val > 0) - current_val = log(current_val); - else - current_val = 0; - break; - - case OP_CEIL: - current_val = ceil(current_val); - break; - - case OP_FLOOR: - current_val = floor(current_val); - break; - - case OP_ROUND: - if (current_val < 0) - current_val = (int)(current_val - 0.5); - else - current_val = (int)(current_val + 0.5); - break; - - case OP_ABS: - current_val = fabs(current_val); - break; - - case OP_MOD: - if (current_val >= 1) - current_val = fmod(value_stack[stack_depth], current_val); - else - current_val = 0; - break; - - case OP_EQUALS: - current_val = (value_stack[stack_depth] == current_val); - break; - - case OP_NOT_EQUALS: - current_val = (value_stack[stack_depth] != current_val); - break; - - case OP_LESS: - current_val = (value_stack[stack_depth] < current_val); - break; - - case OP_GREATER: - current_val = (value_stack[stack_depth] > current_val); - break; - - case OP_LESS_EQUALS: - current_val = (value_stack[stack_depth] <= current_val); - break; - - case OP_GREATER_EQUALS: - current_val = (value_stack[stack_depth] >= current_val); - break; - - case OP_OR: - current_val = ((int)value_stack[stack_depth] || (int)current_val); - break; - - case OP_AND: - current_val = ((int)value_stack[stack_depth] && (int)current_val); - break; - - case OP_NOT: - current_val = !(int)current_val; - break; - - case OP_OPEN_PAREN: - if (op == OP_CLOSE_PAREN) - return; - break; - } - } - } - - /* push onto the stack */ - if (op != OP_CLOSE_PAREN) { - operator_stack[stack_depth] = op; - value_stack[stack_depth] = current_val; - stack_depth++; - current_val = 0; - current_valid = FALSE; - } - else { - if (stack_depth <= 0) - evaluate_error = TRUE; - } -} - - - -/* evaluate: - * Top level evaluation function. - */ -double evaluate(char *equation, int *error, double (*variable)(char *name)) -{ - char buf[256]; - double val; - int i; - - stack_depth = 0; - current_val = 0; - current_valid = FALSE; - evaluate_error = FALSE; - - while ((*equation) && (!evaluate_error)) { - /* skip whitespace */ - while (isspace(*equation)) - equation++; - - switch (*equation) { - - case '+': - /* addition */ - add_operator(OP_PLUS); - equation++; - break; - - case '-': - /* subtraction */ - add_operator(OP_MINUS); - equation++; - break; - - case '*': - /* multiplication */ - add_operator(OP_MUL); - equation++; - break; - - case '/': - /* division */ - add_operator(OP_DIV); - equation++; - break; - - case '^': - /* rasing to a power (_not_ XOR!) */ - add_operator(OP_POWER); - equation++; - break; - - case '%': - /* modulus */ - add_operator(OP_MOD); - equation++; - break; - - case '|': - /* logical or */ - add_operator(OP_OR); - equation++; - break; - - case '&': - /* logical and */ - add_operator(OP_AND); - equation++; - break; - - case '=': - /* equality test (requires dual ==) */ - if (equation[1] == '=') { - add_operator(OP_EQUALS); - equation += 2; - } - else - evaluate_error = TRUE; - break; - - case '!': - /* could be inequality test or logical not */ - if (equation[1] == '=') { - add_operator(OP_NOT_EQUALS); - equation += 2; - } - else { - add_operator(OP_NOT); - equation++; - } - break; - - case '<': - /* could be less than or less/equal test */ - if (equation[1] == '=') { - add_operator(OP_LESS_EQUALS); - equation += 2; - } - else { - add_operator(OP_LESS); - equation++; - } - break; - - case '>': - /* could be greater than or greater/equal test */ - if (equation[1] == '=') { - add_operator(OP_GREATER_EQUALS); - equation += 2; - } - else { - add_operator(OP_GREATER); - equation++; - } - break; - - case '(': - /* open bracket */ - add_operator(OP_OPEN_PAREN); - equation++; - break; - - case ')': - /* close bracket */ - add_operator(OP_CLOSE_PAREN); - equation++; - break; - - case '0': - /* special case for hex constants (0x prefix) */ - if (equation[1] == 'x') { - equation += 2; - - for (i=0; isxdigit(equation[i]); i++) - buf[i] = equation[i]; - - buf[i] = 0; - equation += i; - - val = strtol(buf, NULL, 16); - add_value(val); - break; - } - /* else fall through */ - - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - /* floating point constant */ - for (i=0; isdigit(equation[i]) || (equation[i] == '.'); i++) - buf[i] = equation[i]; - - buf[i] = 0; - equation += i; - - val = atof(buf); - add_value(val); - break; - - default: - /* this is a string, could be a variable or function */ - for (i=0; (isalpha(equation[i])) || (equation[i] == '_'); i++) - buf[i] = tolower(equation[i]); - - buf[i] = 0; - equation += i; - - if (strcmp(buf, "pi") == 0) { - /* pi (built in constant) */ - add_value(M_PI); - } - else if (strcmp(buf, "e") == 0) { - /* e (built in constant) */ - add_value(M_E); - } - else if (strcmp(buf, "sqrt") == 0) { - /* square root function */ - add_operator(OP_SQRT); - } - else if (strcmp(buf, "sin") == 0) { - /* sin function */ - add_operator(OP_SIN); - } - else if (strcmp(buf, "cos") == 0) { - /* cos function */ - add_operator(OP_COS); - } - else if (strcmp(buf, "tan") == 0) { - /* tan function */ - add_operator(OP_TAN); - } - else if (strcmp(buf, "asin") == 0) { - /* inverse sin function */ - add_operator(OP_ASIN); - } - else if (strcmp(buf, "acos") == 0) { - /* inverse cos function */ - add_operator(OP_ACOS); - } - else if (strcmp(buf, "atan") == 0) { - /* inverse tan function */ - add_operator(OP_ATAN); - } - else if (strcmp(buf, "log") == 0) { - /* base 10 logarithm function */ - add_operator(OP_LOG); - } - else if (strcmp(buf, "ln") == 0) { - /* natural logarithm function */ - add_operator(OP_LN); - } - else if (strcmp(buf, "ceil") == 0) { - /* round upwards function */ - add_operator(OP_CEIL); - } - else if (strcmp(buf, "floor") == 0) { - /* round downwards function */ - add_operator(OP_FLOOR); - } - else if (strcmp(buf, "round") == 0) { - /* round to nearest integer function */ - add_operator(OP_ROUND); - } - else if (strcmp(buf, "abs") == 0) { - /* absolute value function */ - add_operator(OP_ABS); - } - else if (strcmp(buf, "rand") == 0) { - /* random number between 0 and 1 */ - add_value((rand()&32767)/32767.0); - } - else { - /* user-supplied callback for looking up variables */ - if ((buf[0]) && (variable)) { - add_value(variable(buf)); - } - else { - if (error) - *error = TRUE; - - return 0; - } - } - break; - } - } - - if ((evaluate_error) || (!current_valid)) { - if (error) - *error = TRUE; - - return 0; - } - - /* force a stack flush */ - add_operator(OP_TERMINATOR); - - if (stack_depth != 1) { - if (error) - *error = TRUE; - - return 0; - } - - if (error) - *error = FALSE; - - return value_stack[0]; -} - -- cgit v1.2.3