int Formula::eval_atom(char *&s, Args *args, bool *vars) const { while (*s) { if (myisspace(*s)) { ++s; } else if (*s == '(') { int res = eval_neq(++s, args, vars); if (*s == ')') ++s; return res; } else if ((*s == '+') || (*s == '-')) { int sign = 1; if (*s == '-') sign = -1; return sign * eval_neq(++s, args, vars); } else if (*s == '!') { return !eval_neq(++s, args, vars); } else if ((*s >= '0') && (*s <= '9')) { int res = 0; while ((*s >= '0') && (*s <= '9')) res = res * 10 + *s++ - '0'; return res; } else { if (!args) return 0; char buf[1024]; char *bufptr = buf; while (((*s >= '0') && (*s <= '9')) || ((*s >= 'a') && (*s <= 'z')) || ((*s >= 'A') && (*s <= 'A')) || (*s == '_') || (*s == '.')) *bufptr++ = *s++; *bufptr = 0; int res = args->get(buf); if (vars) *vars = true; return res; } } return 0; }
int Formula::eval(Args *args, bool *vars) const { if (vars) *vars = false; char *s = m_str; int res = eval_neq(s, args, vars); return res; }
ast_t* eval_expression(env_t* env, ast_t* ast) { switch(ast->type) { /* valid */ case at_call: return eval_call(env,ast); case at_identifier: return get_ast_by_id(env, ast->data.id); case at_expression: { ast_t* result = NULL; ast_t* left = eval_expression(env, ast->data.expression.left); ast_t* right = eval_expression(env, ast->data.expression.right); inc_ref(left); inc_ref(right); switch(ast->data.expression.op) { case op_add: result = eval_add(env, left, right); break; case op_mul: result = eval_mul(env, left, right); break; case op_div: result = eval_div(env, left, right); break; case op_sub: result = eval_sub(env, left, right); break; case op_mod: result = eval_mod(env, left, right); break; case op_and: result = eval_and(env, left, right); break; case op_or: result = eval_or(env, left, right); break; case op_gt: result = eval_gt(env, left, right); break; case op_ge: result = eval_ge(env, left, right); break; case op_lt: result = eval_lt(env, left, right); break; case op_le: result = eval_le(env, left, right); break; case op_eq: result = eval_eq(env, left, right); break; case op_neq: result = eval_neq(env, left, right); break; case op_cat: result = eval_cat(env, left, right); break; case op_deref: { ast_t* index = eval_expression(env, right); if (index->type != at_integer) { // TODO: error -> index must be an integer! } else { switch(left->type) { case at_list: result = left->data.list.elements[index->data.i]; } } } } result->ref_count = 0; dec_ref(left); dec_ref(right); return result; } /* no need to evaluate */ case at_integer: case at_bool: case at_double: case at_string: case at_function: case at_statements: case at_list: return ast; /* invalid */ case at_assignment: case at_callargs: case at_conditional: case at_dowhile: case at_elif: case at_if: case at_params: case at_while: case at_builtin: error_expected(NULL,"expression",get_ast_type_name(ast->type)); } return NULL; /* this should never happen */ }