goomsl_yacc.c
来自「linux下的MPEG1」· C语言 代码 · 共 1,746 行 · 第 1/5 页
C
1,746 行
} /* Adds a field to a struct */ void gsl_add_struct_field(GSL_Struct *s, GSL_StructField *field) { s->fields[s->nbFields++] = field; } int gsl_type_of_var(GoomHash *ns, const char *name) { char type_of[256]; HashValue *hv; sprintf(type_of, "__type_of_%s", name); hv = goom_hash_get(ns, type_of); if (hv != NULL) return hv->i; fprintf(stderr, "ERROR: Unknown variable type: '%s'\n", name); return -1; } static void gsl_declare_var(GoomHash *ns, const char *name, int type, void *space) { char type_of[256]; if (name[0] == '@') { ns = currentGoomSL->vars; } if (space == NULL) { switch (type) { case INSTR_INT: case INSTR_FLOAT: case INSTR_PTR: space = goom_heap_malloc_with_alignment(currentGoomSL->data_heap, sizeof(int), sizeof(int)); break; case -1: fprintf(stderr, "What the fuck!\n"); exit(1); default: /* On a un struct_id */ space = goom_heap_malloc_with_alignment_prefixed(currentGoomSL->data_heap, currentGoomSL->gsl_struct[type]->size, STRUCT_ALIGNMENT, sizeof(int)); } } goom_hash_put_ptr(ns, name, (void*)space); sprintf(type_of, "__type_of_%s", name); goom_hash_put_int(ns, type_of, type); /* Ensuite le hack: on ajoute les champs en tant que variables. */ if (type < FIRST_RESERVED) { int i; GSL_Struct *gsl_struct = currentGoomSL->gsl_struct[type]; ((int*)space)[-1] = type; /* stockage du type dans le prefixe de structure */ for (i = 0; i < gsl_struct->nbFields; ++i) { char full_name[256]; char *cspace = (char*)space + gsl_struct->fields[i]->offsetInStruct; sprintf(full_name, "%s.%s", name, gsl_struct->fields[i]->name); gsl_declare_var(ns, full_name, gsl_struct->fields[i]->type, cspace); } } } /* Declare a variable which will be a struct */ static void gsl_struct_decl(GoomHash *namespace, const char *struct_name, const char *name) { int struct_id = gsl_get_struct_id(struct_name); gsl_declare_var(namespace, name, struct_id, NULL); } static void gsl_float_decl_global(const char *name) { gsl_declare_var(currentGoomSL->vars, name, INSTR_FLOAT, NULL); } static void gsl_int_decl_global(const char *name) { gsl_declare_var(currentGoomSL->vars, name, INSTR_INT, NULL); } static void gsl_ptr_decl_global(const char *name) { gsl_declare_var(currentGoomSL->vars, name, INSTR_PTR, NULL); } static void gsl_struct_decl_global_from_id(const char *name, int id) { gsl_declare_var(currentGoomSL->vars, name, id, NULL); } /* FLOAT */ static void gsl_float_decl_local(const char *name) { gsl_declare_var(currentGoomSL->namespaces[currentGoomSL->currentNS], name, INSTR_FLOAT, NULL); } /* INT */ static void gsl_int_decl_local(const char *name) { gsl_declare_var(currentGoomSL->namespaces[currentGoomSL->currentNS], name, INSTR_INT, NULL); } /* PTR */ static void gsl_ptr_decl_local(const char *name) { gsl_declare_var(currentGoomSL->namespaces[currentGoomSL->currentNS], name, INSTR_PTR, NULL); } /* STRUCT */ static void gsl_struct_decl_local(const char *struct_name, const char *name) { gsl_struct_decl(currentGoomSL->namespaces[currentGoomSL->currentNS],struct_name,name); } static void commit_test2(NodeType *set,const char *type, int instr); static NodeType *new_call(const char *name, NodeType *affect_list); /* SETTER */ static NodeType *new_set(NodeType *lvalue, NodeType *expression) { /* {{{ */ NodeType *set = new_op("set", OPR_SET, 2); set->unode.opr.op[0] = lvalue; set->unode.opr.op[1] = expression; return set; } /* }}} */ static void commit_set(NodeType *set) { /* {{{ */ commit_test2(set,"set",INSTR_SET); } /* }}} */ /* PLUS_EQ */ static NodeType *new_plus_eq(NodeType *lvalue, NodeType *expression) /* {{{ */ { NodeType *set = new_op("plus_eq", OPR_PLUS_EQ, 2); set->unode.opr.op[0] = lvalue; set->unode.opr.op[1] = expression; return set; } static void commit_plus_eq(NodeType *set) { precommit_node(set->unode.opr.op[1]);#ifdef VERBOSE printf("add %s %s\n", set->unode.opr.op[0]->str, set->unode.opr.op[1]->str);#endif currentGoomSL->instr = gsl_instr_init(currentGoomSL, "add", INSTR_ADD, 2, set->line_number); commit_node(set->unode.opr.op[0],0); commit_node(set->unode.opr.op[1],1); } /* }}} */ /* SUB_EQ */ static NodeType *new_sub_eq(NodeType *lvalue, NodeType *expression) /* {{{ */ { NodeType *set = new_op("sub_eq", OPR_SUB_EQ, 2); set->unode.opr.op[0] = lvalue; set->unode.opr.op[1] = expression; return set; } static void commit_sub_eq(NodeType *set) { precommit_node(set->unode.opr.op[1]);#ifdef VERBOSE printf("sub %s %s\n", set->unode.opr.op[0]->str, set->unode.opr.op[1]->str);#endif currentGoomSL->instr = gsl_instr_init(currentGoomSL, "sub", INSTR_SUB, 2, set->line_number); commit_node(set->unode.opr.op[0],0); commit_node(set->unode.opr.op[1],1); } /* }}} */ /* MUL_EQ */ static NodeType *new_mul_eq(NodeType *lvalue, NodeType *expression) /* {{{ */ { NodeType *set = new_op("mul_eq", OPR_MUL_EQ, 2); set->unode.opr.op[0] = lvalue; set->unode.opr.op[1] = expression; return set; } static void commit_mul_eq(NodeType *set) { precommit_node(set->unode.opr.op[1]);#ifdef VERBOSE printf("mul %s %s\n", set->unode.opr.op[0]->str, set->unode.opr.op[1]->str);#endif currentGoomSL->instr = gsl_instr_init(currentGoomSL, "mul", INSTR_MUL, 2, set->line_number); commit_node(set->unode.opr.op[0],0); commit_node(set->unode.opr.op[1],1); } /* }}} */ /* DIV_EQ */ static NodeType *new_div_eq(NodeType *lvalue, NodeType *expression) /* {{{ */ { NodeType *set = new_op("div_eq", OPR_DIV_EQ, 2); set->unode.opr.op[0] = lvalue; set->unode.opr.op[1] = expression; return set; } static void commit_div_eq(NodeType *set) { precommit_node(set->unode.opr.op[1]);#ifdef VERBOSE printf("div %s %s\n", set->unode.opr.op[0]->str, set->unode.opr.op[1]->str);#endif currentGoomSL->instr = gsl_instr_init(currentGoomSL, "div", INSTR_DIV, 2, set->line_number); commit_node(set->unode.opr.op[0],0); commit_node(set->unode.opr.op[1],1); } /* }}} */ /* commodity method for add, mult, ... */ static void precommit_expr(NodeType *expr, const char *type, int instr_id) { /* {{{ */ NodeType *tmp, *tmpcpy; int toAdd; /* compute "left" and "right" */ switch (expr->unode.opr.nbOp) { case 2: precommit_node(expr->unode.opr.op[1]); case 1: precommit_node(expr->unode.opr.op[0]); } if (is_tmp_expr(expr->unode.opr.op[0])) { tmp = expr->unode.opr.op[0]; toAdd = 1; } else if (is_commutative_expr(instr_id) && (expr->unode.opr.nbOp==2) && is_tmp_expr(expr->unode.opr.op[1])) { tmp = expr->unode.opr.op[1]; toAdd = 0; } else { char stmp[256]; /* declare a temporary variable to store the result */ if (expr->unode.opr.op[0]->type == CONST_INT_NODE) { sprintf(stmp,"_i_tmp_%i",allocateTemp()); gsl_int_decl_global(stmp); } else if (expr->unode.opr.op[0]->type == CONST_FLOAT_NODE) { sprintf(stmp,"_f_tmp%i",allocateTemp()); gsl_float_decl_global(stmp); } else if (expr->unode.opr.op[0]->type == CONST_PTR_NODE) { sprintf(stmp,"_p_tmp%i",allocateTemp()); gsl_ptr_decl_global(stmp); } else { int type = gsl_type_of_var(expr->unode.opr.op[0]->vnamespace, expr->unode.opr.op[0]->str); if (type == INSTR_FLOAT) { sprintf(stmp,"_f_tmp_%i",allocateTemp()); gsl_float_decl_global(stmp); } else if (type == INSTR_PTR) { sprintf(stmp,"_p_tmp_%i",allocateTemp()); gsl_ptr_decl_global(stmp); } else if (type == INSTR_INT) { sprintf(stmp,"_i_tmp_%i",allocateTemp()); gsl_int_decl_global(stmp); } else if (type == -1) { fprintf(stderr, "ERROR: Line %d, Could not find variable '%s'\n", expr->line_number, expr->unode.opr.op[0]->str); exit(1); } else { /* type is a struct_id */ sprintf(stmp,"_s_tmp_%i",allocateTemp()); gsl_struct_decl_global_from_id(stmp,type); } } tmp = new_var(stmp,expr->line_number); /* set the tmp to the value of "op1" */ tmpcpy = nodeClone(tmp); commit_node(new_set(tmp,expr->unode.opr.op[0]),0); toAdd = 1; tmp = tmpcpy; } /* add op2 to tmp */#ifdef VERBOSE if (expr->unode.opr.nbOp == 2) printf("%s %s %s\n", type, tmp->str, expr->unode.opr.op[toAdd]->str); else printf("%s %s\n", type, tmp->str);#endif currentGoomSL->instr = gsl_instr_init(currentGoomSL, type, instr_id, expr->unode.opr.nbOp, expr->line_number); tmpcpy = nodeClone(tmp); commit_node(tmp,0); if (expr->unode.opr.nbOp == 2) { commit_node(expr->unode.opr.op[toAdd],1); } /* redefine the ADD node now as the computed variable */ nodeFreeInternals(expr); *expr = *tmpcpy; free(tmpcpy); } /* }}} */ static NodeType *new_expr1(const char *name, int id, NodeType *expr1) { /* {{{ */ NodeType *add = new_op(name, id, 1); add->unode.opr.op[0] = expr1; return add; } /* }}} */ static NodeType *new_expr2(const char *name, int id, NodeType *expr1, NodeType *expr2) { /* {{{ */ NodeType *add = new_op(name, id, 2); add->unode.opr.op[0] = expr1; add->unode.opr.op[1] = expr2; return add; } /* }}} */ /* ADD */ static NodeType *new_add(NodeType *expr1, NodeType *expr2) { /* {{{ */ return new_expr2("add", OPR_ADD, expr1, expr2); } static void precommit_add(NodeType *add) { precommit_expr(add,"add",INSTR_ADD); } /* }}} */ /* SUB */ static NodeType *new_sub(NodeType *expr1, NodeType *expr2) { /* {{{ */ return new_expr2("sub", OPR_SUB, expr1, expr2); } static void precommit_sub(NodeType *sub) { precommit_expr(sub,"sub",INSTR_SUB); } /* }}} */ /* NEG */ static NodeType *new_neg(NodeType *expr) { /* {{{ */ NodeType *zeroConst = NULL; if (expr->type == CONST_INT_NODE) zeroConst = new_constInt("0", currentGoomSL->num_lines); else if (expr->type == CONST_FLOAT_NODE) zeroConst = new_constFloat("0.0", currentGoomSL->num_lines); else if (expr->type == CONST_PTR_NODE) { fprintf(stderr, "ERROR: Line %d, Could not negate const pointer.\n", currentGoomSL->num_lines); exit(1); } else { int type = gsl_type_of_var(expr->vnamespace, expr->str); if (type == INSTR_FLOAT) zeroConst = new_constFloat("0.0", currentGoomSL->num_lines); else if (type == INSTR_PTR) { fprintf(stderr, "ERROR: Line %d, Could not negate pointer.\n", currentGoomSL->num_lines); exit(1); } else if (type == INSTR_INT) zeroConst = new_constInt("0", currentGoomSL->num_lines); else if (type == -1) { fprintf(stderr, "ERROR: Line %d, Could not find variable '%s'\n", expr->line_number, expr->unode.opr.op[0]->str); exit(1); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?