// Solves the equation within a set of parenthesis // returns SUCCESS or FAIL int satisfy_paren() { char op; int larg; int rarg; int answer; int ret; ret = peek_op(&op); while (op != '(' && ret == SUCCESS) { // evaluate everything inside of the parens if (pop_num(&rarg) != SUCCESS) return FAIL; if (pop_num(&larg) != SUCCESS) return FAIL; if (pop_op(&op) != SUCCESS) return FAIL; if (evaluate(larg, op, rarg, &answer) != SUCCESS) return FAIL; debug_print("inside paren loop: @d@c@d=@d\n", larg, op, rarg, answer); push_num(answer); ret = peek_op(&op); } if (op == '(') { pop_op(&op); // consume the open paren } return ret; }
void Expressions::calc(void) { tecoInt result; tecoInt vright; Operator op; tecoInt vleft; if (!operators.items() || operators.peek() != OP_NUMBER) throw Error("Missing right operand"); vright = pop_num(); op = pop_op(); if (!operators.items() || operators.peek() != OP_NUMBER) throw Error("Missing left operand"); vleft = pop_num(); switch (op) { case OP_POW: for (result = 1; vright--; result *= vleft); break; case OP_MUL: result = vleft * vright; break; case OP_DIV: if (!vright) throw Error("Division by zero"); result = vleft / vright; break; case OP_MOD: if (!vright) throw Error("Remainder of division by zero"); result = vleft % vright; break; case OP_ADD: result = vleft + vright; break; case OP_SUB: result = vleft - vright; break; case OP_AND: result = vleft & vright; break; case OP_XOR: result = vleft ^ vright; break; case OP_OR: result = vleft | vright; break; default: /* shouldn't happen */ g_assert_not_reached(); } push(result); }
static int do_expr( void ) { long arg1; long arg2; int op; if( not_ok == pop_op( &op ) ) { return( not_ok ); } if( not_ok == pop_val( &arg1 ) ) { return( not_ok ); } pop_val( &arg2 ); switch( op ) { case '+': push_val( arg2 + arg1 ); break; case '-': push_val( arg2 - arg1 ); break; case '*': push_val( arg2 * arg1 ); break; case '/': if( 0 == arg1 ) { return( not_ok ); } push_val( arg2 / arg1 ); break; case '(': cvalue += 2; break; default: return( not_ok ); } if( 1 > cvalue ) { return( not_ok ); } else { return( op ); } }
tecoInt Expressions::pop_num(guint index) { tecoInt n = 0; Operator op = pop_op(); g_assert(op == OP_NUMBER); if (numbers.items()) { n = numbers.pop(index); NumberStack::undo_push<numbers>(n, index); } return n; }
tecoInt Expressions::push(tecoInt number) { while (operators.items() && operators.peek() == OP_NEW) pop_op(); push(OP_NUMBER); if (num_sign < 0) { set_num_sign(1); number *= -1; } NumberStack::undo_pop<numbers>(); return numbers.push(number); }
void Expressions::eval(bool pop_brace) { for (;;) { gint n = first_op(); Operator op; if (n < 0) break; op = operators.peek(n); if (op == OP_BRACE) { if (pop_brace) pop_op(n); break; } if (n < 1) break; calc(); } }
static bool execute(char *buffer, bool *data) { char *token, **ops, *o1, *o2; bool *output, res; int n_o, n_q, sz_o, sz_q;; sz_o = 8192; sz_q = 8192; ops = malloc(sz_q * sizeof(char *)); output = malloc(sz_o * sizeof(bool)); n_o = n_q = 0; for (token = strtok(buffer, " "); token; token = strtok(NULL, " ")) { if (strncmp(token, "b", 1) == 0) { push_bit(data[atoi(token + 1)], &output, &n_o, &sz_o); } else if (is_function(token)) { push_op(token, &ops, &n_q, &sz_q); } else if (strncmp(token, ",", 1) == 0) { while (strncmp(peek_op(ops, n_q), "(", 1) != 0) { token = pop_op(ops, &n_q); if (is_operator(token)) { push_bit(operator(token, pop_bit(output, &n_o), pop_bit(output, &n_o)), &output, &n_o, &sz_o); } else { push_bit(function(token, output, &n_o), &output, &n_o, &sz_o); } } } else if (is_operator(token)) { o1 = token; while (peek_op(ops, n_q) && is_operator(peek_op(ops, n_q))) { o2 = peek_op(ops, n_q); if (operator_precedence(o1) <= operator_precedence(o2)) { push_bit(operator(pop_op(ops, &n_q), pop_bit(output, &n_o), pop_bit(output, &n_o)), &output, &n_o, &sz_o); } else { break; } } push_op(o1, &ops, &n_q, &sz_q); } else if (strncmp(token, "(", 1) == 0) { push_op(token, &ops, &n_q, &sz_q); } else if (strncmp(token, ")", 1) == 0) { while (strncmp(peek_op(ops, n_q), "(", 1) != 0) { token = pop_op(ops, &n_q); if (is_operator(token)) { push_bit(operator(token, pop_bit(output, &n_o), pop_bit(output, &n_o)), &output, &n_o, &sz_o); } else { push_bit(function(token, output, &n_o), &output, &n_o, &sz_o); } } token = pop_op(ops, &n_q); /* pop the left bracket */ if (peek_op(ops, n_q) && is_function(peek_op(ops, n_q))) { push_bit(function(pop_op(ops, &n_q), output, &n_o), &output, &n_o, &sz_o); } } else { fprintf(stderr, "ERROR: unknown symbol: %s\n", token); exit(EXIT_FAILURE); } } while ((token = pop_op(ops, &n_q))) { if (is_operator(token)) { push_bit(operator(token, pop_bit(output, &n_o), pop_bit(output, &n_o)), &output, &n_o, &sz_o); } else { push_bit(function(token, output, &n_o), &output, &n_o, &sz_o); } } res = output[0]; free(output); free(ops); return res; }
void *bank_server(void *args) { OpQueue queue; init_opqueue(&queue); int balance = 0; int locked_by = -1; while(1) { Operation *op = NULL; if(operation.status == 1) { pthread_mutex_lock(&operation.mutex); op = clone_op(&operation); operation.status = 0; pthread_mutex_unlock(&operation.mutex); fprintf(stderr, "[Thread %d], operation %s, new op", op->client_id, code_to_text(op->code)); } else if(locked_by == -1) { op = pop_op(&queue); if(op != NULL) { fprintf(stderr, "[Thread %d], operation %s, popped op", op->client_id, code_to_text(op->code)); } } else { continue; } if(op == NULL) { continue; } int is_performable = can_perform_op(op->code, op->client_id, locked_by); if(is_performable != 0) { pthread_mutex_lock(&op->put_answer_to->mutex); if(is_performable == 1) { switch(op->code) { case OP_LOOK: op->put_answer_to->comment = ""; break; case OP_LOCK: op->put_answer_to->comment = "successfully locked"; locked_by = op->client_id; break; case OP_UNLOCK: op->put_answer_to->comment = "successfully unlocked"; locked_by = -1; break; case OP_INC: balance += op->value; op->put_answer_to->comment = "successfuly added"; break; case OP_DEC: balance -= op->value; op->put_answer_to->comment = "successfully withdrawed"; break; } fprintf(stderr, " - completed\n"); } else { op->put_answer_to->comment = "balance not locked"; fprintf(stderr, " - declined\n"); } op->put_answer_to->status = is_performable; op->put_answer_to->value = balance; // free(op); pthread_cond_signal(&op->put_answer_to->cond); pthread_mutex_unlock(&op->put_answer_to->mutex); } else { push_op(&queue, op); fprintf(stderr, " - pushed to queue\n"); } } return NULL; }
/* Evaluate stacked arguments and operands */ static int do_op(void) { double arg1, arg2; int op; if (E_ERROR == pop_op(&op)) return E_ERROR; pop_arg(&arg1); pop_arg(&arg2); switch (op) { case '+': push_arg(arg2 + arg1); break; case '-': push_arg(arg2 - arg1); break; case '*': push_arg(arg2 * arg1); break; case '/': if (0.0 == arg1) return(DIV_ZERO); push_arg(arg2 / arg1); break; case '\\': if (0.0 == arg1) return R_ERROR; push_arg(fmod(arg2, arg1)); break; case '^': push_arg(pow(arg2, arg1)); break; case 't': ++arg_sptr; push_arg(atan(arg1)); break; case 'S': ++arg_sptr; push_arg(sin(arg1)); break; case 's': if (0.0 > arg2) return R_ERROR; ++arg_sptr; push_arg(sqrt(arg1)); break; case 'C': ++arg_sptr; push_arg(cos(arg1)); break; case 'A': ++arg_sptr; push_arg(fabs(arg1)); break; case 'L': if (0.0 < arg1) { ++arg_sptr; push_arg(log(arg1)); break; } else return R_ERROR; case 'E': ++arg_sptr; push_arg(exp(arg1)); break; case '(': arg_sptr += 2; break; default: return E_ERROR; } if (1 > arg_sptr) return E_ERROR; else return op; }
/* Calcola e restituisce il risultato di un'espressione in forma infissa */ double EvalInfix(const char *strExpression, char * strError) { Token tok; Token tok_temp; double left, right; double dblRet; strcpy(strError, ""); tok_temp.Type = EOL; tok_temp.str[0] = '@'; tok_temp.str[1] = '\0'; push_op(tok_temp, strError); if ( strError[0] != '\0' ) return 0.0; left = right = 0.0; while ( (PreviousTokenType = GetNextToken(strExpression, &tok, TRUE)) != EOL ) { if ( tok.Type == UNKNOWN ) { sprintf(strError, "Error: invalid token: %s\n", tok.str); return 0.0; } else if ( tok.Type == VALUE ) { push_val(tok.Value, strError); if ( strError[0] != '\0' ) return 0.0; } else if ( tok.Type == OPAREN || tok.Type == UMINUS || tok.Type == UPLUS ) { push_op(tok, strError); if ( strError[0] != '\0' ) return 0.0; } else if ( tok.Type == CPAREN ) { while ( top_op(strError).Type != OPAREN ) { if ( strError[0] != '\0' ) return 0.0; tok_temp = pop_op(strError); if ( strError[0] != '\0' ) return 0.0; if ( (tok_temp.Type == EOL) || (is_empty_op()) ) { sprintf(strError, "Error: unbalanced brackets.\n"); return 0.0; } right = pop_val(strError); if ( strError[0] != '\0' ) return 0.0; if ( tok_temp.Type != UMINUS ) { left = pop_val(strError); if ( strError[0] != '\0' ) return 0.0; dblRet = BinaryOperation(left, right, tok_temp.str[0], strError); if ( strError[0] != '\0' ) return 0.0; push_val(dblRet, strError); if ( strError[0] != '\0' ) return 0.0; } else { push_val( -1 * right, strError ); if ( strError[0] != '\0' ) return 0.0; } } pop_op(strError); if ( strError[0] != '\0' ) return 0.0; } else { while ( PREC_TABLE[ top_op(strError).Type ].topOfStack >= PREC_TABLE[ tok.Type ].inputSymbol ) { if ( strError[0] != '\0' ) return 0.0; if ( top_op(strError).Type != UMINUS && top_op(strError).Type != UPLUS ) { if ( strError[0] != '\0' ) return 0.0; right = pop_val(strError); if ( strError[0] != '\0' ) return 0.0; left = pop_val(strError); if ( strError[0] != '\0' ) return 0.0; tok_temp = pop_op(strError); if ( strError[0] != '\0' ) return 0.0; dblRet = BinaryOperation(left, right, tok_temp.str[0], strError); if ( strError[0] != '\0' ) return 0.0; push_val(dblRet, strError); if ( strError[0] != '\0' ) return 0.0; } else { if ( top_op(strError).Type == UMINUS ) { if ( strError[0] != '\0' ) return 0.0; right = pop_val(strError); if ( strError[0] != '\0' ) return 0.0; pop_op(strError); if ( strError[0] != '\0' ) return 0.0; push_val(-1 * right, strError); if ( strError[0] != '\0' ) return 0.0; } else { pop_op(strError); if ( strError[0] != '\0' ) return 0.0; } } } if ( tok.Type != EOL ) { push_op(tok, strError); if ( strError[0] != '\0' ) return 0.0; } } } while ( 1 ) { tok_temp = pop_op(strError); if ( strError[0] != '\0' ) return 0.0; if ( tok_temp.Type == EOL ) break; if ( tok_temp.Type != UPLUS ) { right = pop_val(strError); if ( strError[0] != '\0' ) return 0.0; } if ( tok_temp.Type != UMINUS && tok_temp.Type != UPLUS ) { left = pop_val(strError); if ( strError[0] != '\0' ) return 0.0; dblRet = BinaryOperation(left, right, tok_temp.str[0], strError); if ( strError[0] != '\0' ) return 0.0; push_val(dblRet, strError); if ( strError[0] != '\0' ) return 0.0; } else { push_val( -1 * right, strError ); if ( strError[0] != '\0' ) return 0.0; } } dblRet = pop_val(strError); if ( strError[0] != '\0' ) return 0.0; if ( is_empty_val() ) { return dblRet; } else { sprintf(strError, "Error: malformed expression.\n"); return 0.0; } }
// Solves the equation in 'str' // returns SUCCESS if equation was solved // returns FAIL if equation couldn't be solved // Solution returned in 'answer' int solve_equation(char* str, int *answer) { int j = 0; int ret; char curr; // intialize stack curr_num_stack = -1; curr_op_stack = -1; while (str[j] != 0) { curr = str[j]; // walk through the equation if (curr <= '9' && curr >= '0') { char t; int is_neg = 0; int val; // get the number (could be any number of spots) // this is a number, push it on the stack ret = peek_op(&t); if (ret == SUCCESS && t == '-') { if(pop_op(&t) != SUCCESS) return FAIL; push_op('+'); is_neg = 1; } int moved = 0; val = stoi(str+j, &moved); if (is_neg) val *= -1; is_neg = 0; push_num(val); //tmp = get_str_end(str+j); j += moved; continue; } if (curr == '(') { push_op(str[j]); j++; continue; } if (curr == ')') { if (satisfy_paren() != SUCCESS) return FAIL; j++; continue; } if (curr == '+' || curr == '-') { char p_op; ret = peek_op(&p_op); if (ret == SUCCESS && (p_op == '+' || p_op == '-' || p_op == '*' || p_op == '/')) { char prev_op; int larg, rarg, answer = 0; if (pop_num(&rarg)!= SUCCESS) return FAIL; if (pop_num(&larg)!= SUCCESS) return FAIL; if (pop_op(&prev_op)!= SUCCESS) return FAIL; if (evaluate(larg, prev_op, rarg, &answer) != SUCCESS) return FAIL; push_num(answer); } push_op(str[j]); j++; continue; } if (curr == '*' || curr == '/') { char prev_op; ret = peek_op(&prev_op); if (ret == SUCCESS && (prev_op == '*' || prev_op == '/')) { int larg, rarg, answer = 0; if (pop_num(&rarg)!= SUCCESS) return FAIL; if (pop_num(&larg)!= SUCCESS) return FAIL; if (pop_op(&prev_op)!= SUCCESS) return FAIL; if (evaluate(larg, prev_op, rarg, &answer) != SUCCESS) return FAIL; push_num(answer); } push_op(str[j]); j++; continue; } return FAIL; // Invalid input. } int b,a, tmp; pop_num(&b); while(curr_op_stack != -1) { if (pop_num(&a)!= SUCCESS) return FAIL; if (pop_op(&curr)!= SUCCESS) return FAIL; if (evaluate(a,curr,b, &tmp)!= SUCCESS) return FAIL; b = tmp; } *answer = b; return SUCCESS; }