static bool execution_order(const TCHAR *input, double *outval) { const TCHAR *strpos = input, *strend = input + _tcslen(input); TCHAR c, res[4]; unsigned int sl = 0, rn = 0; struct calcstack stack[STACK_SIZE] = { {0, .0} }, *sc, *sc2; double val = 0; int i; bool ok = false; // While there are input tokens left while(strpos < strend) { if (sl >= STACK_SIZE) return false; // Read the next token from input. c = *strpos; // If the token is a value or identifier if(is_ident(c)) { // Push it onto the stack. stack[sl].s = chartostack (c); ++sl; } // Otherwise, the token is an operator (operator here includes both operators, and functions). else if(is_operator(c) || is_function(c)) { _stprintf(res, _T("_%02d"), rn); calc_log ((_T("%s = "), res)); ++rn; // It is known a priori that the operator takes n arguments. unsigned int nargs = op_arg_count(c); // If there are fewer than n values on the stack if(sl < nargs) { // (Error) The user has not input sufficient values in the expression. return false; } // Else, Pop the top n values from the stack. // Evaluate the operator, with the values as arguments. if(is_function(c)) { calc_log ((_T("%c("), c)); while(nargs > 0){ sc = &stack[sl - nargs]; // to remove reverse order of arguments if(nargs > 1) { calc_log ((_T("%s, "), sc)); } else { calc_log ((_T("%s)\n"), sc)); } --nargs; } sl-=op_arg_count(c); } else { if(nargs == 1) { sc = &stack[sl - 1]; sl--; val = docalc1 (c, sc, val); calc_log ((_T("%c %s = %f;\n"), c, stacktostr(sc), val)); } else { sc = &stack[sl - 2]; calc_log ((_T("%s %c "), stacktostr(sc), c)); sc2 = &stack[sl - 1]; val = docalc2 (c, sc, sc2); sl--;sl--; calc_log ((_T("%s = %f;\n"), stacktostr(sc2), val)); } } // Push the returned results, if any, back onto the stack. stack[sl].val = val; stack[sl].s = NULL; ++sl; } ++strpos; } // If there is only one value in the stack // That value is the result of the calculation. if(sl == 1) { sc = &stack[sl - 1]; sl--; calc_log ((_T("result = %f\n"), val)); if (outval) *outval = val; ok = true; } for (i = 0; i < STACK_SIZE; i++) xfree (stack[i].s); // If there are more values in the stack // (Error) The user input has too many values. return ok; }
bool execution_order(const char *input) { printf("order: (arguments in reverse order)\n"); const char *strpos = input, *strend = input + strlen(input); char c, res[4]; unsigned int sl = 0, sc, stack[32], rn = 0; // While there are input tokens left while(strpos < strend) { // Read the next token from input. c = *strpos; // If the token is a value or identifier if(is_ident(c)) { // Push it onto the stack. stack[sl] = c; ++sl; } // Otherwise, the token is an operator (operator here includes both operators, and functions). else if(is_operator(c) || is_function(c)) { sprintf(res, "_%02d", rn); printf("%s = ", res); ++rn; // It is known a priori that the operator takes n arguments. unsigned int nargs = op_arg_count(c); // If there are fewer than n values on the stack if(sl < nargs) { // (Error) The user has not input sufficient values in the expression. return false; } // Else, Pop the top n values from the stack. // Evaluate the operator, with the values as arguments. if(is_function(c)) { printf("%c(", c); while(nargs > 0) { sc = stack[sl - 1]; sl--; if(nargs > 1) { printf("%s, ", &sc); } else { printf("%s)\n", &sc); } --nargs; } } else { if(nargs == 1) { sc = stack[sl - 1]; sl--; printf("%c %s;\n", c, &sc); } else { sc = stack[sl - 1]; sl--; printf("%s %c ", &sc, c); sc = stack[sl - 1]; sl--; printf("%s;\n",&sc); } } // Push the returned results, if any, back onto the stack. stack[sl] = *(unsigned int*)res; ++sl; } ++strpos; } // If there is only one value in the stack // That value is the result of the calculation. if(sl == 1) { sc = stack[sl - 1]; sl--; printf("%s is a result\n", &sc); return true; } // If there are more values in the stack // (Error) The user input has too many values. return false; }