From 63367550df238ebbd06fdef3c183c607238b0a26 Mon Sep 17 00:00:00 2001 From: Jon Lewis Date: Wed, 27 Jun 2018 15:26:32 -0500 Subject: [PATCH] Major overhaul. Using pointer arithmetic and strtod now --- ee.c | 222 ++++++++++++++++++++++++++++++++++++++++++++++++----- ee.h | 172 +++++------------------------------------ ee_stack.h | 39 ---------- 3 files changed, 222 insertions(+), 211 deletions(-) delete mode 100644 ee_stack.h diff --git a/ee.c b/ee.c index b84f9fa..e89616b 100644 --- a/ee.c +++ b/ee.c @@ -1,27 +1,207 @@ - #include "ee.h" +int error = 0; int main (int argc, const char* argv[]){ - STACK ee_stack = NULL; - int iter = 1; - while (iter < argc){ - if (isNum(argv[iter])){ - ee_stack = push(strtod(argv[iter],NULL), ee_stack); - }else if (isOperator(argv[iter][0])){ - ee_stack = push(evaluate(&ee_stack, argv[iter][0]), ee_stack); - } else{ - ERR_INVALID_INPUT = 1; - } - iter++; + + STACK expr = NULL; + const char** endPtr = argv+argc, + ** arg = argv+1 ; + + while ((arg < endPtr) && (!error)){ + + if (arrity(**arg)) + expr = push(evaluate(&expr, **arg), expr); + + else if(isNum(*arg)) + expr = push(strtod(*arg,NULL), expr); + + else + error |= ERR_INVALID_INPUT; + + arg++; } - if (ee_stack == NULL){ - ERR_NS_OPERANDS = 1; - } else if (ee_stack->tail!=NULL){ - ERR_NS_OPERATORS = 1; - } - if (!reportErrors()){ - printf("%f\n", peek(ee_stack)); - } - return 0; + + if (expr == NULL) + error |= ERR_NS_OPERANDS; + + else if (expr->tail!=NULL) + error |= ERR_NS_OPERATORS; + + report(expr); + + return error; +} + +int // Dependency of main() +isNum(const char* query){ + + /* + * If query is a string, isNum(query) iff query represents a number. + */ + + char* alphas; + strtod(query, &alphas); + return !strcmp(alphas,""); + +} + +int // Dependency of main() +arrity(const char query){ + /* + * If query is a string, isOperator iff query is a + * supported operator. + */ + return (query == '+')? 2: + (query == 'x')? 2: + (query == '/')? 2: + (query == '^')? 2: + (query == '!')? 1: + 0; +} + + +double // Dependency of main() +evaluate(STACK* target_stack, int operator){ + /* + * if target_stack is a pointer to a STACK and operator is + * an integer corresponding to the ascii value of a supported + * operator, evaluate(target_stack,operator) is the result of + * applying the given operator to the appropriate number of + * operands from target_stack. + */ + double value = 0, + a = 0, + b = 0; + + double *_operands = operands(target_stack, arrity(operator)); + + switch (operator){ + + case '+' : + value = _operands[1] + _operands[0]; + break; + + case '-' : + value = _operands[1] - _operands[0]; + break; + + case 'x' : + value = _operands[1] * _operands[0]; + break; + + case '/' : + value = _operands[1] / _operands[0]; + break; + + case '^' : + value = pow(_operands[1],_operands[0]); + break; + + case '!' : + if ( (*_operands != floor(*_operands)) || (*_operands < 0)) + error |= ERR_INVALID_FACTORIAL; + + else + value = fact(*_operands); + + break; + + default : + break; + } + return value; +} +double* // Dependency of evaluate() +operands(STACK* target_stack, int size){ + /* + * if target_stack is a pointer to a STACK, and size is an integer + * corresponding to the number of operands desired, + * getOperands(target_stack,size) returns an array of operands and + * pops them off *target_stack. + */ + double * const _operands = (double*)malloc(size*sizeof(double)); + + if ((*target_stack) == NULL) + error |= ERR_NS_OPERANDS; + + double * tPtr = _operands; + double * endPtr = _operands + size; + while ((tPtr < endPtr) && !error) + { + *tPtr = peek((*target_stack)); + (*target_stack) = pop(*target_stack); + + tPtr += 1; + } + return _operands; +} + +double // Dependency of evaluate() +fact(int n){ + /* + * if n is an integer, fact(n) is 'n factorial'. + */ + return (n==0)? 1 : n*fact(n-1); +} + +void // Dependency of main() +report(STACK expr){ + /* + * reportErrors() returns an integer corresponding to + * the number of discrete error types noted in global + * variables ERR_NS_OPERANDS, ERR_NS_OPERATORS, and + * ERR_INVALID_INPUT. + */ + + if (error & ERR_INVALID_INPUT) + printf("Error: Unexpected input.\n"); + + else if (error & ERR_NS_OPERATORS) + printf("Error: insufficient operators.\n"); + + else if (error & ERR_NS_OPERANDS) + printf("Error: insufficient operands.\n"); + + else if (error & ERR_INVALID_FACTORIAL) + printf("Error: Factorials are only supported for positive integers.\n"); + + else + printf("%g\n", peek(expr)); +} + +STACK +push(double datum, STACK tail){ + /* Given a double value (datum), and a STACK (tail), + * push(datum,tail) is the STACK resulting from + * prepending datum to the STACK tail. + */ + NODE* new_node = (NODE*)malloc(sizeof(NODE)); + (*new_node).datum = datum; + (*new_node).tail = tail; + return new_node; +} + +STACK +pop(STACK target_stack){ + /* Given a STACK (target_stack), pop(target_stack) + * is the STACK resulting from the removal of the first + * item in target_stack; + */ + + STACK tail = NULL; + + if (target_stack != NULL){ + tail = (*target_stack).tail; + free(target_stack); + } + return tail; +} + +double +peek(STACK target_stack){ + /* Given a STACK (target_stack), peek(STACK) + * is the first element's datum. + */ + return (target_stack)? (*target_stack).datum : 0; } diff --git a/ee.h b/ee.h index 10d30f7..e689802 100644 --- a/ee.h +++ b/ee.h @@ -2,165 +2,35 @@ #include #include #include -#include "ee_stack.h" +#include -int ERR_NS_OPERANDS = 0; -int ERR_NS_OPERATORS = 0; -int ERR_INVALID_INPUT = 0; -int ERR_INVALID_FACTORIAL = 0; -// Summary +const int ERR_NS_OPERANDS = 1; +const int ERR_NS_OPERATORS = 2; +const int ERR_INVALID_INPUT = 4; +const int ERR_INVALID_FACTORIAL = 8; + + +struct EE_STACK_NODE { + double datum; + struct EE_STACK_NODE* tail; +}; +typedef struct EE_STACK_NODE NODE; +typedef struct EE_STACK_NODE* STACK; + +STACK push(double,STACK); +STACK pop(STACK); +double peek(STACK); + int isNum(const char*); -int isOperator(const char); +int arrity(const char); double evaluate(STACK*, int); -double* getOperands(STACK*, int); +double* operands(STACK*, int); double fact(int n); -int reportErrors(); +void report(); -int // Dependency of main() -isNum(const char* query){ - /* - * If query is a string, isNum(query) iff query represents a number. - */ - int foundDecimal = 0; int foundSign = 0; int noDigits = 1; - int ch=0; int issues = 0; int i = 0; - while (!issues && ( ( ch = query[i] ) != '\0') ){ - ch = query[i]; - if (isdigit(ch)){ - noDigits = 0; - }else { - if (ch == '-' || ch == '+'){ - if (foundSign){ issues = 1; } - else {foundSign = 1;} - } - else if (ch == '.'){ - if (foundDecimal) { issues = 1; } - else { foundDecimal = 1; } - } - else { issues = 1; } - } - i++; - } - if (noDigits) { issues = 1; } - return !issues; -} -int // Dependency of main() -isOperator(const char query){ - /* - * If query is a string, isOperator iff query is a - * supported operator. - */ - switch (query){ - case '+': - return 1; break; - case '-': - return 1; break; - case 'x': - return 1; break; - case '/': - return 1; break; - case '^': - return 1; break; - case '!': - return 1; break; - default: - return 0; break; - } -} -double // Dependency of main() -evaluate(STACK* target_stack, int operator){ - /* - * if target_stack is a pointer to a STACK and operator is - * an integer corresponding to the ascii value of a supported - * operator, evaluate(target_stack,operator) is the result of - * applying the given operator to the appropriate number of - * operands from target_stack. - */ - double value = 0; - double a,b; a=b=0; - double* operands; - switch (operator){ - case '+' : - operands = getOperands(target_stack, 2); - value = operands[1] + operands[0]; - break; - case '-' : - operands = getOperands(target_stack, 2); - value = operands[1] - operands[0]; - break; - case 'x' : - operands = getOperands(target_stack, 2); - value = operands[1] * operands[0]; - break; - case '/' : - operands = getOperands(target_stack, 2); - value = operands[1] / operands[0]; - break; - case '^' : - operands = getOperands(target_stack, 2); - value = pow(operands[1],operands[0]); - break; - case '!' : - operands = getOperands(target_stack, 1); - if ( (operands[0] != floor(operands[0])) || (operands[0] < 0)) - { ERR_INVALID_FACTORIAL = 1; } - else{ - value = fact((int)operands[0]); - } - break; - default : - break; - } - return value; -} -double* // Dependency of evaluate() -getOperands(STACK* target_stack, int size){ - /* - * if target_stack is a pointer to a STACK, and size is an integer - * corresponding to the number of operands desired, - * getOperands(target_stack,size) returns an array of operands and - * pops them off *target_stack. - */ - double* operands = (double*)malloc(size*sizeof(double)); - int i = 0; - for (i=0; i