goomsl_yacc.c
来自「linux下的MPEG1」· C语言 代码 · 共 1,746 行 · 第 1/5 页
C
1,746 行
else { /* type is a struct_id */ fprintf(stderr, "ERROR: Line %d, Could not negate struct '%s'\n", expr->line_number, expr->str); exit(1); } } return new_expr2("sub", OPR_SUB, zeroConst, expr); } /* }}} */ /* MUL */ static NodeType *new_mul(NodeType *expr1, NodeType *expr2) { /* {{{ */ return new_expr2("mul", OPR_MUL, expr1, expr2); } static void precommit_mul(NodeType *mul) { precommit_expr(mul,"mul",INSTR_MUL); } /* }}} */ /* DIV */ static NodeType *new_div(NodeType *expr1, NodeType *expr2) { /* {{{ */ return new_expr2("div", OPR_DIV, expr1, expr2); } static void precommit_div(NodeType *mul) { precommit_expr(mul,"div",INSTR_DIV); } /* }}} */ /* CALL EXPRESSION */ static NodeType *new_call_expr(const char *name, NodeType *affect_list) { /* {{{ */ NodeType *call = new_call(name,affect_list); NodeType *node = new_expr1(name, OPR_CALL_EXPR, call); node->vnamespace = gsl_find_namespace(name); if (node->vnamespace == NULL) fprintf(stderr, "ERROR: Line %d, No return type for: '%s'\n", currentGoomSL->num_lines, name); return node; } static void precommit_call_expr(NodeType *call) { char stmp[256]; NodeType *tmp,*tmpcpy; int type = gsl_type_of_var(call->vnamespace, call->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", call->line_number, call->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,call->line_number); commit_node(call->unode.opr.op[0],0); tmpcpy = nodeClone(tmp); commit_node(new_set(tmp,new_var(call->str,call->line_number)),0); nodeFreeInternals(call); *call = *tmpcpy; free(tmpcpy); } /* }}} */ static void commit_test2(NodeType *set,const char *type, int instr) { /* {{{ */ NodeType *tmp; char stmp[256]; precommit_node(set->unode.opr.op[0]); precommit_node(set->unode.opr.op[1]); tmp = set->unode.opr.op[0]; stmp[0] = 0; if (set->unode.opr.op[0]->type == CONST_INT_NODE) { sprintf(stmp,"_i_tmp_%i",allocateTemp()); gsl_int_decl_global(stmp); } else if (set->unode.opr.op[0]->type == CONST_FLOAT_NODE) { sprintf(stmp,"_f_tmp%i",allocateTemp()); gsl_float_decl_global(stmp); } else if (set->unode.opr.op[0]->type == CONST_PTR_NODE) { sprintf(stmp,"_p_tmp%i",allocateTemp()); gsl_ptr_decl_global(stmp); } if (stmp[0]) { NodeType *tmpcpy; tmp = new_var(stmp, set->line_number); tmpcpy = nodeClone(tmp); commit_node(new_set(tmp,set->unode.opr.op[0]),0); tmp = tmpcpy; }#ifdef VERBOSE printf("%s %s %s\n", type, tmp->str, set->unode.opr.op[1]->str);#endif currentGoomSL->instr = gsl_instr_init(currentGoomSL, type, instr, 2, set->line_number); commit_node(tmp,instr!=INSTR_SET); commit_node(set->unode.opr.op[1],1); } /* }}} */ /* NOT */ static NodeType *new_not(NodeType *expr1) { /* {{{ */ return new_expr1("not", OPR_NOT, expr1); } static void commit_not(NodeType *set) { commit_node(set->unode.opr.op[0],0);#ifdef VERBOSE printf("not\n");#endif currentGoomSL->instr = gsl_instr_init(currentGoomSL, "not", INSTR_NOT, 1, set->line_number); gsl_instr_add_param(currentGoomSL->instr, "|dummy|", TYPE_LABEL); } /* }}} */ /* EQU */ static NodeType *new_equ(NodeType *expr1, NodeType *expr2) { /* {{{ */ return new_expr2("isequal", OPR_EQU, expr1, expr2); } static void commit_equ(NodeType *mul) { commit_test2(mul,"isequal",INSTR_ISEQUAL); } /* }}} */ /* INF */ static NodeType *new_low(NodeType *expr1, NodeType *expr2) { /* {{{ */ return new_expr2("islower", OPR_LOW, expr1, expr2); } static void commit_low(NodeType *mul) { commit_test2(mul,"islower",INSTR_ISLOWER); } /* }}} */ /* WHILE */ static NodeType *new_while(NodeType *expression, NodeType *instr) { /* {{{ */ NodeType *node = new_op("while", OPR_WHILE, 2); node->unode.opr.op[0] = expression; node->unode.opr.op[1] = instr; return node; } static void commit_while(NodeType *node) { int lbl = allocateLabel(); char start_while[1024], test_while[1024]; sprintf(start_while, "|start_while_%d|", lbl); sprintf(test_while, "|test_while_%d|", lbl); GSL_PUT_JUMP(test_while,node->line_number); GSL_PUT_LABEL(start_while,node->line_number); /* code */ commit_node(node->unode.opr.op[1],0); GSL_PUT_LABEL(test_while,node->line_number); commit_node(node->unode.opr.op[0],0); GSL_PUT_JNZERO(start_while,node->line_number); } /* }}} */ /* FOR EACH */ static NodeType *new_static_foreach(NodeType *var, NodeType *var_list, NodeType *instr) { /* {{{ */ NodeType *node = new_op("for", OPR_FOREACH, 3); node->unode.opr.op[0] = var; node->unode.opr.op[1] = var_list; node->unode.opr.op[2] = instr; node->line_number = currentGoomSL->num_lines; return node; } static void commit_foreach(NodeType *node) { NodeType *cur = node->unode.opr.op[1]; char tmp_func[256], tmp_loop[256]; int lbl = allocateLabel(); sprintf(tmp_func, "|foreach_func_%d|", lbl); sprintf(tmp_loop, "|foreach_loop_%d|", lbl); GSL_PUT_JUMP(tmp_loop, node->line_number); GSL_PUT_LABEL(tmp_func, node->line_number); precommit_node(node->unode.opr.op[2]); commit_node(node->unode.opr.op[2], 0); currentGoomSL->instr = gsl_instr_init(currentGoomSL, "ret", INSTR_RET, 1, node->line_number); gsl_instr_add_param(currentGoomSL->instr, "|dummy|", TYPE_LABEL);#ifdef VERBOSE printf("ret\n");#endif GSL_PUT_LABEL(tmp_loop, node->line_number); while (cur != NULL) { NodeType *x, *var; /* 1: x=var */ x = nodeClone(node->unode.opr.op[0]); var = nodeClone(cur->unode.opr.op[0]); commit_node(new_set(x, var),0); /* 2: instr */ currentGoomSL->instr = gsl_instr_init(currentGoomSL, "call", INSTR_CALL, 1, node->line_number); gsl_instr_add_param(currentGoomSL->instr, tmp_func, TYPE_LABEL);#ifdef VERBOSE printf("call %s\n", tmp_func);#endif /* 3: var=x */ x = nodeClone(node->unode.opr.op[0]); var = cur->unode.opr.op[0]; commit_node(new_set(var, x),0); cur = cur->unode.opr.op[1]; } nodeFree(node->unode.opr.op[0]); } /* }}} */ /* IF */ static NodeType *new_if(NodeType *expression, NodeType *instr) { /* {{{ */ NodeType *node = new_op("if", OPR_IF, 2); node->unode.opr.op[0] = expression; node->unode.opr.op[1] = instr; return node; } static void commit_if(NodeType *node) { char slab[1024]; sprintf(slab, "|eif%d|", allocateLabel()); commit_node(node->unode.opr.op[0],0); GSL_PUT_JZERO(slab,node->line_number); /* code */ commit_node(node->unode.opr.op[1],0); GSL_PUT_LABEL(slab,node->line_number); } /* }}} */ /* BLOCK */ static NodeType *new_block(NodeType *lastNode) { /* {{{ */ NodeType *blk = new_op("block", OPR_BLOCK, 2); blk->unode.opr.op[0] = new_nop("start_of_block"); blk->unode.opr.op[1] = lastNode; return blk; } static void commit_block(NodeType *node) { commit_node(node->unode.opr.op[0]->unode.opr.next,0); } /* }}} */ /* FUNCTION INTRO */ static NodeType *new_function_intro(const char *name) { /* {{{ */ char stmp[256]; if (strlen(name) < 200) { sprintf(stmp, "|__func_%s|", name); } return new_op(stmp, OPR_FUNC_INTRO, 0); } static void commit_function_intro(NodeType *node) { currentGoomSL->instr = gsl_instr_init(currentGoomSL, "label", INSTR_LABEL, 1, node->line_number); gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_LABEL);#ifdef VERBOSE printf("label %s\n", node->str);#endif } /* }}} */ /* FUNCTION OUTRO */ static NodeType *new_function_outro() { /* {{{ */ return new_op("ret", OPR_FUNC_OUTRO, 0); } static void commit_function_outro(NodeType *node) { currentGoomSL->instr = gsl_instr_init(currentGoomSL, "ret", INSTR_RET, 1, node->line_number); gsl_instr_add_param(currentGoomSL->instr, "|dummy|", TYPE_LABEL); releaseAllTemps();#ifdef VERBOSE printf("ret\n");#endif } /* }}} */ /* AFFECTATION LIST */ static NodeType *new_affec_list(NodeType *set, NodeType *next) /* {{{ */ { NodeType *node = new_op("affect_list", OPR_AFFECT_LIST, 2); node->unode.opr.op[0] = set; node->unode.opr.op[1] = next; return node; } static NodeType *new_affect_list_after(NodeType *affect_list) { NodeType *ret = NULL; NodeType *cur = affect_list; while(cur != NULL) { NodeType *set = cur->unode.opr.op[0]; NodeType *next = cur->unode.opr.op[1]; NodeType *lvalue = set->unode.opr.op[0]; NodeType *expression = set->unode.opr.op[1]; if ((lvalue->str[0] == '&') && (expression->type == VAR_NODE)) { NodeType *nset = new_set(nodeClone(expression), nodeClone(lvalue)); ret = new_affec_list(nset, ret); } cur = next; } return ret; } static void commit_affect_list(NodeType *node) { NodeType *cur = node; while(cur != NULL) { NodeType *set = cur->unode.opr.op[0]; precommit_node(set->unode.opr.op[0]); precommit_node(set->unode.opr.op[1]); cur = cur->unode.opr.op[1]; } cur = node; while(cur != NULL) { NodeType *set = cur->unode.opr.op[0]; commit_node(set,0); cur = cur->unode.opr.op[1]; } } /* }}} */ /* VAR LIST */ static NodeType *new_var_list(NodeType *var, NodeType *next) /* {{{ */ { NodeType *node = new_op("var_list", OPR_VAR_LIST, 2); node->unode.opr.op[0] = var; node->unode.opr.op[1] = next; return node; } static void commit_var_list(NodeType *node) { } /* }}} */ /* FUNCTION CALL */ static NodeType *new_call(const char *name, NodeType *affect_list) { /* {{{ */ HashValue *fval; fval = goom_hash_get(currentGoomSL->functions, name); if (!fval) { gsl_declare_task(name); fval = goom_hash_get(currentGoomSL->functions, name); } if (!fval) { fprintf(stderr, "ERROR: Line %d, Could not find function %s\n", currentGoomSL->num_lines, name); exit(1); return NULL; } else { ExternalFunctionStruct *gef = (ExternalFunctionStruct*)fval->ptr; if (gef->is_extern) { NodeType *node = new_op(name, OPR_EXT_CALL, 1); node->unode.opr.op[0] = affect_list; return node;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?