int expr_compare( struct expr *a, struct expr *b ) { if ((!a) && (!b)) return 1; if (!a) return 0; if (!b) return 0; if (a->kind != b->kind) return 0; if (!expr_compare(a->left, b->left)) return 0; if (!expr_compare(a->right, b->right)) return 0; if (!expr_compare(a->next, b->next)) return 0; if (a->literal_value != b->literal_value) return 0; return 1; }
int stmt_compare(struct stmt * a, struct stmt * b) { if (!a && !b) { return 1; } else if ((!a || !b)) { return 0; } else { return (a->kind==b->kind) && decl_compare(a->decl, b->decl) && expr_compare(a->init_expr, b->init_expr) && expr_compare(a->expr, b->expr) && expr_compare(a->next_expr, b->next_expr) && stmt_compare(a->body, b->body) && stmt_compare(a->else_body, b->else_body) && stmt_compare(a->next, b->next); } }
// compare two types int type_compare( struct type *a, struct type *b ){ if(!a && !b) return 1; if(!a || !b) return 0; return (a->kind == b->kind && param_list_compare(a->params, b->params) && type_compare(a->subtype, b->subtype) && expr_compare(a->opt_expr, b->opt_expr)); }
/* * Flatten an equality expression `x = y'. Assumes x and y are already * flattened. */ static expr_t flatten_eq_to_builtin(exprop_t op, expr_t x, expr_t y, bool toplevel, context_t cxt) { if (expr_gettype(x) == EXPRTYPE_VAR && expr_gettype(y) == EXPRTYPE_VAR) return expr_make(op, x, y); if (expr_gettype(y) == EXPRTYPE_VAR) { expr_t t = x; x = y; y = t; } if (expr_gettype(x) != EXPRTYPE_VAR) x = context_update(cxt, x); if (!toplevel) y = context_update(cxt, y); // Special-case handling of constants and variables: switch (expr_gettype(y)) { case EXPRTYPE_VAR: if (expr_compare(x, y) < 0) return expr_make(op, x, y); else return expr_make(op, y, x); case EXPRTYPE_NUM: return expr_make(exprop_atom_make(ATOM_INT_EQ_C), x, y); case EXPRTYPE_NIL: return expr_make(exprop_atom_make(ATOM_NIL_EQ_C), x, y); case EXPRTYPE_STR: return expr_make(exprop_atom_make(ATOM_STR_EQ_C), x, y); case EXPRTYPE_ATOM: return expr_make(exprop_atom_make(ATOM_ATOM_EQ_C), x, y); case EXPRTYPE_OP: break; default: panic("unexpected expr type (%d)", expr_gettype(y)); } // Special-case handling of add/mul: exprop_t fop = expr_op(y); switch (fop) { case EXPROP_ADD: { expr_t a = expr_arg(y, 0); expr_t b = expr_arg(y, 1); if (expr_gettype(a) == EXPRTYPE_NUM) { expr_t t = a; a = b; b = t; } if (expr_gettype(b) == EXPRTYPE_NUM) { num_t c = expr_getnum(b); if (c < 0) return expr_make(exprop_atom_make(ATOM_INT_EQ_PLUS_C), a, x, expr_num(-c)); else return expr_make(exprop_atom_make(ATOM_INT_EQ_PLUS_C), x, a, b); } else return expr_make(exprop_atom_make(ATOM_INT_EQ_PLUS), x, a, b); } case EXPROP_MUL: { expr_t a = expr_arg(y, 0); expr_t b = expr_arg(y, 1); if (expr_gettype(a) == EXPRTYPE_NUM) { expr_t t = a; a = b; b = t; } if (expr_gettype(b) == EXPRTYPE_NUM) return expr_make(exprop_atom_make(ATOM_INT_EQ_MUL_C), x, a, b); else return expr_make(exprop_atom_make(ATOM_INT_EQ_MUL), x, a, b); } case EXPROP_POW: { expr_t a = expr_arg(y, 0); expr_t b = expr_arg(y, 1); return expr_make(exprop_atom_make(ATOM_INT_EQ_POW_C), x, a, b); } default: break; } // Generic function calls: atom_t atom = expr_sym(y); const char *name = atom_name(atom); size_t arity = atom_arity(atom); size_t len = strlen(name); char buf[len + 32]; typesig_t sig = typeinst_lookup_typesig(atom); typeinst_t type = (sig == TYPESIG_DEFAULT? TYPEINST_NUM: typeinst_make_ground(sig->type)); const char *type_name = typeinst_show(type); int r = snprintf(buf, sizeof(buf)-1, "%s_eq_call_%s", type_name, name); if (r <= 0 || r >= sizeof(buf)-1) panic("failed to create function constraint name"); op = exprop_make(buf, arity+1); expr_t args[arity+1]; expr_args(y, args+1); args[0] = x; expr_t e = expr(op, args); if (sig == TYPESIG_DEFAULT) return e; atom = expr_sym(e); typeinst_t sig_args[arity+1]; memcpy(sig_args+1, sig->args, arity * sizeof(typeinst_t)); sig_args[0] = typeinst_make_var(sig->type); sig = typeinst_make_typesig(arity+1, TYPEINST_BOOL, sig_args); if (!typeinst_declare(atom, sig)) { error("(%s: %zu) failed to declare implied type for %s/%zu", cxt->file, cxt->line, atom_name(atom), atom_arity(arity)); cxt->error = true; } return e; }