bool check_exp(const node* p, int rr_level) { if (!p || p->t == nt_num) return true; // rrlvl1: 交换率,以下两个判断保证了A+B+C+...+Z这种形式下,只选择A>B>C>...>Z这一种组合 if (rr_level >= 1) { if (commulative(p->op)) { double v1 = p->l_child->val(); double v2 = p->r_child->val(); if (v1 < v2) return false; if (double_equ(v1, v2) && shape_less(p->l_child, p->r_child)) return false; } if (p->l_child->t == nt_op && p->l_child->op == p->op && associative(p->op)) { double v1 = p->l_child->r_child->val(); double v2 = p->r_child->val(); if (v1 < v2) return false; if (double_equ(v1, v2) && shape_less(p->l_child->r_child, p->r_child)) return false; } } // rrlvl2: 去除/1和-0。/1可以用*1替换,-0可以用+0替换。 if (rr_level >= 2) { if (p->op == L'/' && double_equ(p->r_child->val(), 1)) return false; if (p->op == L'-' && double_equ(p->r_child->val(), 0)) return false; } if (!check_exp(p->l_child, rr_level)) return false; if (!check_exp(p->r_child, rr_level)) return false; return true; }
void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { lua_assert(!hasjumps(t)); t->u.ind.t = t->u.info; t->u.ind.idx = luaK_exp2RK(fs, k); t->u.ind.vt = (t->k == VUPVAL) ? VUPVAL : check_exp(vkisinreg(t->k), VLOCAL); t->k = VINDEXED; }
void check_command(SymTab *st, Command* c) { if(!c) return; switch(c->tag) { case COMMAND_IF: { check_exp(st, c->u.cif.exp); check_type_int(c->u.cif.exp); check_command(st, c->u.cif.comm); check_command(st, c->u.cif.celse); break; } case COMMAND_WHILE: { check_exp(st, c->u.cwhile.exp); check_type_int(c->u.cwhile.exp); check_command(st, c->u.cwhile.comm); break; } case COMMAND_ATTR: { check_var(st, c->u.attr.lvalue); check_exp(st, c->u.attr.rvalue); check_type_compatible(c->u.attr.lvalue->type, &(c->u.attr.rvalue), c->line); break; } case COMMAND_RET: { if(c->u.ret) { check_exp(st, c->u.ret); check_type_compatible(return_type, &(c->u.ret), c->line); } break; } case COMMAND_FUNCALL: { check_exp(st, c->u.funcall); break; } case COMMAND_BLOCK: { check_block(st, c->u.block); break; } } }
// Your job: void check_stm (Stm_t stm) { switch (stm->kind) { case STM_ASSIGN:{ Stm_Assign s = (Stm_Assign)stm; Type_t t1 = Table_lookup(s->id); Type_t t2 = check_exp(s->exp); if (t1 != t2) exit(0); break; } case STM_PRINTB: { Stm_Printb s = (Stm_Printb)stm; Type_t t1 = check_exp(s->exp); if (t1 == -1 && s->exp->kind == EXP_ID) { fprintf(stdout, "%s is not defined yet!\n", ((Exp_Id)s->exp)->id); exit(0); } else if (t1 != TYPE_BOOL) { fprintf(stdout, "Printb's argument is not a bool!\n"); exit(0); } break; } case STM_PRINTI: { Stm_Printi s = (Stm_Printi)stm; Type_t t1 = check_exp(s->exp); if (t1 == -1 && s->exp->kind == EXP_ID) { fprintf(stdout, "%s is not defined yet!\n", ((Exp_Id)s->exp)->id); exit(0); } else if (t1 != TYPE_INT) { fprintf(stdout, "Printi's argument is not a int!\n"); exit(0); } break; } } }
t_bool check_background(t_token *token_lst) { if (token_lst->type == bg) { if (token_lst->next) return (check_exp(token_lst->next)); return (TRUE); } return (parse_error(token_lst->str)); }
t_command *parser(char *str) { t_token *token_lst; t_command *command_lst; command_lst = NULL; token_lst = get_token_lst(str); if (check_exp(token_lst)) command_lst = make_command_lst(token_lst); token_lst_free(&token_lst); return (command_lst); }
t_bool check_logical(t_token *token_lst) { if (token_lst->type == log_and \ || token_lst->type == log_or) { if (token_lst->next) return (check_exp(token_lst->next)); else return (parse_error(token_lst->str)); } return (parse_error(token_lst->str)); }
void *rstack_alloc (lua_State *L, size_t size) { RStack *rs = rstack(L); Region *r = check_exp(rs->cregnum > 0, rs->creg); RObject *top = r->top; if (top == rs->rbuf.last) { RObject *ohead = rs->rbuf.head; buf_resize(L, rs, rs->rbuf.size * 2); buf_fix(rs, ohead); top = r->top; } top->body = luaM_malloc(L, size); ++r->top; return top->body; }
void iterate_num_permutation(node* exp, node** num_nodes, double* nums, int num_count, double result, int rr_level) { do { for (int i = 0; i < num_count; i++) num_nodes[i]->num = nums[i]; if (check_exp(exp, rr_level)) { if (g_debug) { std::wcout << get_exp(exp) << " = " << exp->val() << std::endl; } if (double_equ(exp->val(), result)) { std::wcout << get_exp(exp) << " = " << result << std::endl; } } }while (std::next_permutation(nums, nums + num_count)); }
void check_var(SymTab *st, Var* v) { Declr *d; int dim; ExpListNode *eln; d = symtab_find(st, v->name); if(!d) print_error("variable is not declared" , v->line); if(d->tag == DECLR_FUNC) print_error("illegal use of a function", v->line); v->var = d; dim = d->type->dimensions; eln = v->idxs; while(eln) { if(!dim) print_error("tried to index a value that is not an array", v->line); check_exp(st, eln->exp); check_type_int(eln->exp); dim--; eln = eln->next; } ALLOC(v->type, Type); v->type->type = d->type->type; v->type->dimensions = dim; v->type->sizes = NULL; }
static const char *upvalname (Proto *p, int uv) { TString *s = check_exp(uv < p->sizeupvalues, p->upvalues[uv].name); if (s == NULL) return "?"; else return getstr(s); }
void check_exp(SymTab *st, Exp* e) { switch(e->tag) { case EXP_INT: e->type = ∭ break; case EXP_FLOAT: e->type = &tfloat; break; case EXP_STRING: e->type = &tstring; break; case EXP_VAR: check_var(st, e->u.var); e->type = (e->u.var)->type; break; case EXP_BINOP: { check_exp(st, e->u.binop.e1); if((e->u.binop.e1)->type->type == TK_TCHAR) insert_conv(&(e->u.binop.e1), TK_TINT); check_exp(st, e->u.binop.e2); if((e->u.binop.e2)->type->type == TK_TCHAR) insert_conv(&(e->u.binop.e2), TK_TINT); switch(e->u.binop.op) { case TK_EQ: case TK_LEQ: case TK_GEQ: case TK_NEQ: case '<': case '>': { check_type_relational(e); break; } case TK_AND: case TK_OR: { check_type_int(e->u.binop.e1); check_type_int(e->u.binop.e2); e->type = ∭ break; } case '+': case '-': case '*': case '/': { check_type_arith(e); break; } default: print_error("Bug in the compiler!", e->line); } break; } case EXP_NEG: { check_exp(st, e->u.exp); if((e->u.exp)->type->type == TK_TCHAR) insert_conv(&(e->u.exp), TK_TINT); if((e->u.exp)->type->dimensions != 0) print_error("cannot negate an array", e->line); e->type = (e->u.exp)->type; break; } case EXP_LNEG: { check_exp(st, e->u.exp); check_type_int(e->u.exp); e->type = ∭ break; } case EXP_FUNCALL: { Declr *func; ExpListNode *eln; DeclrListNode *pln; func = symtab_find(st, e->u.funcall.name); if(!func) print_error("calling undeclared function", e->line); eln = e->u.funcall.expl; pln = func->u.func.params; while(eln) { if(!pln) print_error("excess arguments in function call", e->line); check_exp(st, eln->exp); if(pln->declr != NULL) { check_type_compatible(pln->declr->type, &(eln->exp), e->line); pln = pln->next; } eln = eln->next; } if(pln && pln->declr) print_error("missing arguments in function call", e->line); e->u.funcall.func = func; e->type = func->type; break; } } }
static const char *localname (Proto *p, int lv) { TString *s = check_exp(lv < p->sizelocvars, p->locvars[lv].varname); if (s == NULL) return "?"; else return getstr(s); }
// Your job: Type_t check_exp (Exp_t exp) { Type_t t1, t2; switch (exp->kind) { case EXP_INT: return TYPE_INT; case EXP_TRUE: case EXP_FALSE: return TYPE_BOOL; case EXP_AND: { Exp_And e = (Exp_And)exp; t1 = check_exp(e->left); t2 = check_exp(e->right); if (t1 != TYPE_BOOL || t2 != TYPE_BOOL) { fprintf(stdout, "Error: variable is not a bool!\n"); exit(0); } return TYPE_BOOL; } case EXP_OR: { Exp_Or e = (Exp_Or)exp; t1 = check_exp(e->left); t2 = check_exp(e->right); if (t1 != TYPE_BOOL || t2 != TYPE_BOOL) { fprintf(stdout, "Error: variable is not a bool!\n"); exit(0); } return TYPE_BOOL; } case EXP_ADD: { Exp_Add e = (Exp_Add)exp; t1 = check_exp(e->left); t2 = check_exp(e->right); if (t1 != TYPE_INT || t2 != TYPE_INT) { fprintf(stderr, "Error: variable is not a int.\n"); exit(0); } return TYPE_INT; } case EXP_SUB: { Exp_Sub e = (Exp_Sub)exp; t1 = check_exp(e->left); t2 = check_exp(e->right); if (t1 != TYPE_INT || t2 != TYPE_INT) { fprintf(stderr, "Error: variable is not a int.\n"); exit(0); } return TYPE_INT; } case EXP_TIMES: { Exp_Times e = (Exp_Times)exp; t1 = check_exp(e->left); t2 = check_exp(e->right); if (t1 != TYPE_INT || t2 != TYPE_INT) { fprintf(stderr, "Error: variable is not a int.\n"); exit(0); } return TYPE_INT; } case EXP_DIVIDE: { Exp_Divide e = (Exp_Divide)exp; t1 = check_exp(e->left); t2 = check_exp(e->right); if (t1 != TYPE_INT || t2 != TYPE_INT) { fprintf (stderr, "Error: variable is not a int.\n"); exit(0); } return TYPE_INT; } case EXP_ID: { Exp_Id e = (Exp_Id)exp; return Table_lookup(e->id); } default:{ fprintf(stderr, "not support yet!\n"); exit(0); } } }