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 + -
显示快捷键?