Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}