/* subst_imp - return result of substituting vars into pat */ char* subst_imp(char* pat, char** vars) { static char errormsg[80]; static char lin[MAXLINE]; char num[30]; char *s, *start = pat; int i; i = 0; for (;;) { if (pat[0] == '%' && pat[1] == '%') { if (i < MAXLINE) { lin[i] = '%'; ++i; } pat += 2; } else if (pat[0] == '%' && pat[1] >= FIRSTLAB && pat[1] <= LASTLAB) { int il = pat[1] - FIRSTLAB; if (!labnum[il]) labnum[il] = nextlab++; sprintf(num, "%d", labnum[il]); for (s = num; i < MAXLINE && (lin[i] = *s++) != 0; ++i) ; pat += 2; } else if (pat[0] == '%' && strncmp(pat,"%eval(", 6) == 0 ) { char expr[1024]; int x = 0; int r; pat += 6; while (*pat != ')') { expr[x++] = *pat++; } expr[x] = 0; pat++; sprintf(expr, "%d", rpn_eval(expr, vars)); for ( s = expr; i <MAXLINE && *s; i++ ) lin[i] = *s++; } else if (pat[0] == '%' && isdigit(pat[1])) { if (vars[pat[1] - '0'] == 0) { sprintf(errormsg, "error: variable %c is not set in \"%s\"", pat[1], start); error(errormsg); } for (s = vars[pat[1] - '0']; i < MAXLINE && (lin[i] = *s++) != 0; i++) ; pat += 2; } else if (i >= MAXLINE) error("line too long\n"); else if (!(lin[i++] = *pat++)) return &lin[0]; } }
int check_eval(char* pat, char** vars) { char expr[1024]; int expected, result, x; char v1, v2; x = sscanf(pat, "%d = %[^\n]s", &expected, expr); if (x != 2) { fprintf(stderr, "warning: invalid use of '%%check_eval' in \"%s\"\n", pat); fprintf(stderr, "format is '%%check_eval result = expr"); return 0; } return expected == rpn_eval(expr, vars); }
double in_eval(char *exp) { int exp_length = strlen(exp), numOfVars = 0; struct operator_stack *os = create_operator_stack(exp_length / 2); char *token, *copy, *vars[10] = {NULL}, rpn_exp[1024] = ""; double value = 0; copy = (char *) malloc(sizeof(char) * exp_length); strcpy(copy, exp); token = strtok(copy, " "); bool previousIsOperator = false, previousIsLeftParenthese = false, varsSet = false; while (token != NULL) { errorOccurs = true; varsSet = false; if (isNumeric(token) && sscanf(token, "%lf", &value) > 0) { if (!(strlen(rpn_exp) == 0 || previousIsOperator || previousIsLeftParenthese)) return value; for (int i = 0; i < numOfVars; i++) { setVariable(vars[i], value); vars[i] = NULL; varsSet = true; } numOfVars = 0; errorOccurs = false; previousIsOperator = false; previousIsLeftParenthese = false; concat_double(rpn_exp, value); } else if (variableValid(token)) { if (!(strlen(rpn_exp) == 0 || previousIsOperator || previousIsLeftParenthese)) return value; char operator = *(token + strlen(token) + 1); if (operator == '=') { vars[numOfVars++] = token; errorOccurs = false; } else { value = getVariable(token); errorOccurs = !variableExists(token); concat_double(rpn_exp, value); } previousIsOperator = false; previousIsLeftParenthese = false; } else if (isOperator(token) || isParenthese(token)) { if ((isOperator(token) && previousIsOperator) || (strcmp(token, ")") == 0 && strlen(rpn_exp) == 0)) return value; if (numOfVars > 0) return value; char *op = NULL; if (strcmp(token, "(") == 0) { push_operator(os, token); previousIsLeftParenthese = true; } else if (strcmp(token, ")") == 0) { op = peek_operator(os); if (strcmp(op, "(") == 0) return value; op = pop_operator(os); while (strcmp(op, "(") != 0) { if (strcmp(op, ")") == 0) return value; concat_operator(rpn_exp, op); op = pop_operator(os); } previousIsLeftParenthese = false; } else { int pre1 = -1, pre2 = getOperatorPrecedence(token); if (os->top > -1) pre1 = getOperatorPrecedence(peek_operator(os)); while (pre2 > pre1 && pre1 > 0 && os->top > -1) { concat_operator(rpn_exp, pop_operator(os)); if (os->top > -1) pre1 = getOperatorPrecedence(peek_operator(os)); } push_operator(os, token); previousIsOperator = true; previousIsLeftParenthese = false; } errorOccurs = false; } else if (strcmp(token, "=") == 0) { errorOccurs = false; } else { return value; } if (errorOccurs) return value; token = strtok(NULL, " "); } while (os->top > -1) concat_operator(rpn_exp, pop_operator(os)); free(copy); free_operator_stack(os); if (!(varsSet || errorOccurs)) value = rpn_eval(rpn_exp); return value; }
void createPlot( char * funcFile, double minX, double maxX) { int nvals = MAXCOLS; double yy[MAXCOLS]; clearPlot(); // Evaluate function and store in vector yy double n; //for (int i = minX; i <= maxX * (80 / (2.0 * maxX)); i++) { int count = 0; double step = (maxX - minX) / MAXCOLS; //printf("%lf\n" , step); for (double i = minX; count < 80; i = (i + step)) { //printf("Step %lf\n", i); yy[count] = rpn_eval(funcFile, i); count++; //printf("count: %d x: %lf y: %lf\n", count, i, yy[count - 1]); } //Compute maximum and minimum y in vector yy double maxY = yy[0]; for (int i = 1; i < MAXCOLS; i++) { if (yy[i] > maxY) maxY = yy[i]; } //printf("%lf\n", maxY); double minY = yy[0]; for (int i = 1; i < MAXCOLS; i++) { if (yy[i] < minY) minY = yy[i]; } //printf("%lf\n", minY); for (int i = 0; i < MAXCOLS; i++) { yy[i] = (yy[i] - minY) * (MAXROWS / (maxY - minY)); //printf("x: %d y: %lf\n", i, yy[i]); } //Plot x axis //Plot y axis if (minY >= 0) { for (int i = 0; i < MAXROWS; i++) { for (int j = 0; j < MAXCOLS; j++) { if (i == 39) { plot[i][j] = '_'; } else if (j == 40) { plot[i][j] = '|'; } } } } else { for (int i = 0; i < MAXROWS; i++) { for (int j = 0; j < MAXCOLS; j++) { if (i == 19) { plot[i][j] = '_'; } else if (j == 40) { plot[i][j] = '|'; } } } } int yVal; for (int i = 0; i < 80; i++) { yVal = (int) yy[i]; //printf("x: %d y: %d\n", i, yVal); if (yVal < 0) { yVal = yVal * -1; plot[yVal][i] = '*'; } else { plot[39 - yVal][i] = '*'; } } // minX is plotted at column 0 and maxX is plotted ar MAXCOLS-1 // minY is plotted at row 0 and maxY is plotted at MAXROWS-1 printPlot(); }
int main (int argc, char *argv[]) { int length = 1024, option; char str[length]; bool batchOn, echoOn, invalid, isRPN, isIn; batchOn = false; echoOn = false; invalid = false; while ((option = getopt(argc - 1, argv, "be")) != -1) { switch(option) { case 'b': batchOn = true; break; case 'e': echoOn = true; break; default: invalid = true; break; } } if (invalid || argc == 1 || (argc == 2 && !(strcmp(argv[1], "--rpn") == 0 || strcmp(argv[1], "--in") == 0)) || (argc == 3 && !(strcmp(argv[2], "--rpn") == 0 || strcmp(argv[2], "--in") == 0)) || (argc == 4 && !(strcmp(argv[3], "--rpn") == 0 || strcmp(argv[3], "--in") == 0)) || argc > 4) { printf("Usage: calc [options] --rpn|--in\n"); printf("\nCalculator modes:\n"); printf(" --rpn\tReverse polish notation\n"); printf(" --in\tInorder\n"); printf("\nOptions:\n"); printf(" -b\tBatch mode: No prompt will be printed\n"); printf(" -e\tEcho mode: Input will be printed immediately after read\n"); } else { isRPN = strcmp(argv[argc - 1], "--rpn") == 0; isIn = strcmp(argv[argc - 1], "--in") == 0; while (1) { if (batchOn && isatty(STDIN_FILENO)) printf("s3255350>>> "); char *input = fgets(str, length, stdin); if (input == NULL || input == (char *) EOF) break; if (!(strlen(str) == 0 || strcmp(str, "\n") == 0 || strcmp(str, "\r\n") == 0)) { if (strlen(str) > 0) { if (str[strlen(str) - 2] == '\r') str[strlen(str) - 2] = '\0'; if (str[strlen(str) - 1] == '\n') str[strlen(str) - 1] = '\0'; if (batchOn) { printf("s3255350>>> "); } double value = 0; if (isRPN) { value = rpn_eval(str); } else if (isIn) { value = in_eval(str); } if (errorOccurs) { if (isRPN) { printf("Invalid RPN expression!\n"); } else if (isIn) { printf("Invalid Inorder expression!\n"); } } else { if (echoOn) printf("%s = ", str); printf("%lf\n", value); } } } } } return EXIT_SUCCESS; }