void ofold(oast_t *ast) { switch (ast->token) { case tok_com: case tok_plus: case tok_neg: case tok_not: case tok_integer_p: case tok_rational_p: case tok_float_p: case tok_real_p: case tok_complex_p: case tok_number_p: case tok_finite_p: case tok_inf_p: case tok_nan_p: case tok_num: case tok_den: case tok_real: case tok_imag: case tok_signbit: case tok_abs: case tok_signum: case tok_rational: case tok_arg: case tok_conj: case tok_floor: case tok_trunc: case tok_round: case tok_ceil: case tok_sqrt: case tok_cbrt: case tok_sin: case tok_cos: case tok_tan: case tok_asin: case tok_acos: case tok_atan: case tok_sinh: case tok_cosh: case tok_tanh: case tok_asinh: case tok_acosh: case tok_atanh: case tok_proj: case tok_exp: case tok_log: case tok_log2: case tok_log10: eval_unary(ast); break; case tok_andand: case tok_oror: eval_boolean(ast); break; case tok_ne: case tok_lt: case tok_le: case tok_eq: case tok_ge: case tok_gt: case tok_and: case tok_or: case tok_xor: case tok_mul2: case tok_div2: case tok_shl: case tok_shr: case tok_add: case tok_sub: case tok_mul: case tok_div: case tok_trunc2: case tok_rem: case tok_complex: case tok_atan2: case tok_pow: case tok_hypot: eval_binary(ast); break; default: #if DEBUG oparse_warn(ast, "fold: not handling %s", otoken_to_charp(ast->token)); #endif break; } }
static Eina_Bool eval_exp(const Eolian_Expression *expr, Eolian_Expression_Mask mask, Eolian_Expression *out) { switch (expr->type) { case EOLIAN_EXPR_INT: case EOLIAN_EXPR_LONG: case EOLIAN_EXPR_LLONG: { if (!(mask & EOLIAN_MASK_SINT)) return expr_type_error(expr, EOLIAN_MASK_SINT, mask); *out = *expr; return EINA_TRUE; } case EOLIAN_EXPR_UINT: case EOLIAN_EXPR_ULONG: case EOLIAN_EXPR_ULLONG: { if (!(mask & EOLIAN_MASK_UINT)) return expr_type_error(expr, EOLIAN_MASK_UINT, mask); *out = *expr; return EINA_TRUE; } case EOLIAN_EXPR_FLOAT: case EOLIAN_EXPR_DOUBLE: { if (!(mask & EOLIAN_MASK_FLOAT)) return expr_type_error(expr, EOLIAN_MASK_FLOAT, mask); *out = *expr; return EINA_TRUE; } case EOLIAN_EXPR_STRING: { if (!(mask & EOLIAN_MASK_STRING)) return expr_type_error(expr, EOLIAN_MASK_STRING, mask); *out = *expr; return EINA_TRUE; } case EOLIAN_EXPR_NULL: { if (!(mask & EOLIAN_MASK_NULL)) return expr_type_error(expr, EOLIAN_MASK_NULL, mask); *out = *expr; return EINA_TRUE; } case EOLIAN_EXPR_CHAR: { if (!(mask & EOLIAN_MASK_CHAR)) return expr_type_error(expr, EOLIAN_MASK_CHAR, mask); *out = *expr; return EINA_TRUE; } case EOLIAN_EXPR_BOOL: { if (!(mask & EOLIAN_MASK_BOOL)) return expr_type_error(expr, EOLIAN_MASK_BOOL, mask); *out = *expr; return EINA_TRUE; } case EOLIAN_EXPR_NAME: { const Eolian_Variable *var = eolian_variable_constant_get_by_name (expr->value.s); const Eolian_Expression *exp = NULL; if (!var) { const Eolian_Type *etp; const Eolian_Enum_Type_Field *fl; /* try aliases, hoping it'll be enum */ char *fulln = NULL, *memb = NULL; if (!split_enum_name(expr->value.s, &fulln, &memb)) return expr_error(expr, "undefined variable"); /* assert int here, as we're clearly dealing with enum */ if (!(mask & EOLIAN_MASK_INT)) return expr_type_error(expr, EOLIAN_MASK_INT, mask); etp = eolian_type_alias_get_by_name(fulln); while (etp && (etp->type == EOLIAN_TYPE_ALIAS || etp->type == EOLIAN_TYPE_REGULAR)) etp = eolian_type_base_type_get(etp); if (!etp) etp = eolian_type_enum_get_by_name(fulln); if (!etp || etp->type != EOLIAN_TYPE_ENUM) { free(fulln); return expr_error(expr, "undefined variable"); } fl = eolian_type_enum_field_get(etp, memb); if (fl) exp = eolian_type_enum_field_value_get(fl, EINA_TRUE); free(fulln); if (!exp) return expr_error(expr, "invalid enum field"); } else exp = var->value; if (!exp) return expr_error(expr, "undefined variable"); return eval_exp(exp, mask, out); } case EOLIAN_EXPR_UNARY: return eval_unary(expr, mask, out); case EOLIAN_EXPR_BINARY: return eval_binary(expr, mask, out); default: assert(EINA_FALSE); return EINA_FALSE; } return EINA_TRUE; }
static void eval_expr(m1_expression *e) { if (e == NULL) return; switch (e->type) { case EXPR_NUMBER: eval_number(e->expr.l->value.fval); break; case EXPR_INT: eval_int(e->expr.l->value.ival); break; case EXPR_BINARY: eval_binary(e->expr.b); break; case EXPR_UNARY: eval_unary(e->expr.u); break; case EXPR_FUNCALL: eval_funcall(e->expr.f); break; case EXPR_ASSIGN: eval_assign(e->expr.a); break; case EXPR_IF: eval_if(e->expr.i); break; case EXPR_WHILE: eval_while(e->expr.w); break; case EXPR_DOWHILE: eval_dowhile(e->expr.w); break; case EXPR_FOR: eval_for(e->expr.o); break; case EXPR_RETURN: eval_return(e->expr.e); break; case EXPR_NULL: eval_null(); break; case EXPR_DEREF: eval_deref(e->expr.t); break; case EXPR_ADDRESS: eval_address(e->expr.t); break; case EXPR_OBJECT: eval_obj(e->expr.t); break; case EXPR_BREAK: eval_break(); break; case EXPR_CONTINUE: eval_continue(); break; case EXPR_CONSTDECL: case EXPR_VARDECL: break; default: fprintf(stderr, "unknown expr type"); exit(EXIT_FAILURE); } }