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