goomsl_yacc.c
来自「linux下的MPEG1」· C语言 代码 · 共 1,746 行 · 第 1/5 页
C
1,746 行
} else { NodeType *node; char stmp[256]; if (strlen(name) < 200) { sprintf(stmp, "|__func_%s|", name); } node = new_op(stmp, OPR_CALL, 1); node->unode.opr.op[0] = affect_list; return node; } } } static void commit_ext_call(NodeType *node) { NodeType *alafter = new_affect_list_after(node->unode.opr.op[0]); commit_node(node->unode.opr.op[0],0); currentGoomSL->instr = gsl_instr_init(currentGoomSL, "extcall", INSTR_EXT_CALL, 1, node->line_number); gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_VAR);#ifdef VERBOSE printf("extcall %s\n", node->str);#endif commit_node(alafter,0); } static void commit_call(NodeType *node) { NodeType *alafter = new_affect_list_after(node->unode.opr.op[0]); commit_node(node->unode.opr.op[0],0); currentGoomSL->instr = gsl_instr_init(currentGoomSL, "call", INSTR_CALL, 1, node->line_number); gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_LABEL);#ifdef VERBOSE printf("call %s\n", node->str);#endif commit_node(alafter,0); } /* }}} */ /** **/ static NodeType *rootNode = 0; /* TODO: reinitialiser a chaque compilation. */ static NodeType *lastNode = 0; static NodeType *gsl_append(NodeType *curNode) { if (curNode == 0) return 0; /* {{{ */ if (lastNode) lastNode->unode.opr.next = curNode; lastNode = curNode; while(lastNode->unode.opr.next) lastNode = lastNode->unode.opr.next; if (rootNode == 0) rootNode = curNode; return curNode; } /* }}} */#if 1 int allocateTemp() { return allocateLabel(); } void releaseAllTemps() {} void releaseTemp(int n) {}#else static int nbTemp = 0; static int *tempArray = 0; static int tempArraySize = 0; int allocateTemp() { /* TODO: allocateITemp, allocateFTemp */ int i = 0; /* {{{ */ if (tempArray == 0) { tempArraySize = 256; tempArray = (int*)malloc(tempArraySize * sizeof(int)); } while (1) { int j; for (j=0;j<nbTemp;++j) { if (tempArray[j] == i) break; } if (j == nbTemp) { if (nbTemp == tempArraySize) { tempArraySize *= 2; tempArray = (int*)realloc(tempArray,tempArraySize * sizeof(int)); } tempArray[nbTemp++] = i; return i; } i++; } } /* }}} */ void releaseAllTemps() { nbTemp = 0; /* {{{ */ } /* }}} */ void releaseTemp(int n) { int j; /* {{{ */ for (j=0;j<nbTemp;++j) { if (tempArray[j] == n) { tempArray[j] = tempArray[--nbTemp]; break; } } } /* }}} */#endif static int lastLabel = 0; int allocateLabel() { return ++lastLabel; /* {{{ */ } /* }}} */ void gsl_commit_compilation() { /* {{{ */ commit_node(rootNode,0); rootNode = 0; lastNode = 0; } /* }}} */ void precommit_node(NodeType *node) { /* {{{ */ /* do here stuff for expression.. for exemple */ if (node->type == OPR_NODE) switch(node->unode.opr.type) { case OPR_ADD: precommit_add(node); break; case OPR_SUB: precommit_sub(node); break; case OPR_MUL: precommit_mul(node); break; case OPR_DIV: precommit_div(node); break; case OPR_CALL_EXPR: precommit_call_expr(node); break; } } /* }}} */ void commit_node(NodeType *node, int releaseIfTmp) { /* {{{ */ if (node == 0) return; switch(node->type) { case OPR_NODE: switch(node->unode.opr.type) { case OPR_SET: commit_set(node); break; case OPR_PLUS_EQ: commit_plus_eq(node); break; case OPR_SUB_EQ: commit_sub_eq(node); break; case OPR_MUL_EQ: commit_mul_eq(node); break; case OPR_DIV_EQ: commit_div_eq(node); break; case OPR_IF: commit_if(node); break; case OPR_WHILE: commit_while(node); break; case OPR_BLOCK: commit_block(node); break; case OPR_FUNC_INTRO: commit_function_intro(node); break; case OPR_FUNC_OUTRO: commit_function_outro(node); break; case OPR_CALL: commit_call(node); break; case OPR_EXT_CALL: commit_ext_call(node); break; case OPR_EQU: commit_equ(node); break; case OPR_LOW: commit_low(node); break; case OPR_NOT: commit_not(node); break; case OPR_AFFECT_LIST: commit_affect_list(node); break; case OPR_FOREACH: commit_foreach(node); break; case OPR_VAR_LIST: commit_var_list(node); break;#ifdef VERBOSE case EMPTY_NODE: printf("NOP\n"); break;#endif } commit_node(node->unode.opr.next,0); /* recursive for the moment, maybe better to do something iterative? */ break; case VAR_NODE: gsl_instr_set_namespace(currentGoomSL->instr, node->vnamespace); gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_VAR); break; case CONST_INT_NODE: gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_INTEGER); break; case CONST_FLOAT_NODE: gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_FLOAT); break; case CONST_PTR_NODE: gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_PTR); break; } if (releaseIfTmp && is_tmp_expr(node)) releaseTemp(get_tmp_id(node)); nodeFree(node); } /* }}} */ NodeType *nodeNew(const char *str, int type, int line_number) { NodeType *node = (NodeType*)malloc(sizeof(NodeType)); /* {{{ */ node->type = type; node->str = (char*)malloc(strlen(str)+1); node->vnamespace = NULL; node->line_number = line_number; strcpy(node->str, str); return node; } /* }}} */ static NodeType *nodeClone(NodeType *node) { NodeType *ret = nodeNew(node->str, node->type, node->line_number); /* {{{ */ ret->vnamespace = node->vnamespace; ret->unode = node->unode; return ret; } /* }}} */ void nodeFreeInternals(NodeType *node) { free(node->str); /* {{{ */ } /* }}} */ void nodeFree(NodeType *node) { nodeFreeInternals(node); /* {{{ */ free(node); } /* }}} */ NodeType *new_constInt(const char *str, int line_number) { NodeType *node = nodeNew(str, CONST_INT_NODE, line_number); /* {{{ */ node->unode.constInt.val = atoi(str); return node; } /* }}} */ NodeType *new_constPtr(const char *str, int line_number) { NodeType *node = nodeNew(str, CONST_PTR_NODE, line_number); /* {{{ */ node->unode.constPtr.id = strtol(str,NULL,0); return node; } /* }}} */ NodeType *new_constFloat(const char *str, int line_number) { NodeType *node = nodeNew(str, CONST_FLOAT_NODE, line_number); /* {{{ */ node->unode.constFloat.val = atof(str); return node; } /* }}} */ NodeType *new_var(const char *str, int line_number) { NodeType *node = nodeNew(str, VAR_NODE, line_number); /* {{{ */ node->vnamespace = gsl_find_namespace(str); if (node->vnamespace == 0) { fprintf(stderr, "ERROR: Line %d, Variable not found: '%s'\n", line_number, str); exit(1); } return node; } /* }}} */ NodeType *new_nop(const char *str) { NodeType *node = new_op(str, EMPTY_NODE, 0); /* {{{ */ return node; } /* }}} */ NodeType *new_op(const char *str, int type, int nbOp) { int i; /* {{{ */ NodeType *node = nodeNew(str, OPR_NODE, currentGoomSL->num_lines); node->unode.opr.next = 0; node->unode.opr.type = type; node->unode.opr.nbOp = nbOp; for (i=0;i<nbOp;++i) node->unode.opr.op[i] = 0; return node; } /* }}} */ void gsl_declare_global_variable(int type, char *name) { switch(type){ case -1: break; case FLOAT_TK:gsl_float_decl_global(name);break; case INT_TK: gsl_int_decl_global(name);break; case PTR_TK: gsl_ptr_decl_global(name);break; default: { int id = type - 1000; gsl_struct_decl_global_from_id(name,id); } } }/* Enabling traces. */#ifndef YYDEBUG# define YYDEBUG 0#endif/* Enabling verbose error messages. */#ifdef YYERROR_VERBOSE# undef YYERROR_VERBOSE# define YYERROR_VERBOSE 1#else# define YYERROR_VERBOSE 0#endif#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)#line 1199 "goomsl_yacc.y"typedef union YYSTYPE { int intValue; float floatValue; char charValue; char strValue[2048]; NodeType *nPtr; GoomHash *namespace; GSL_Struct *gsl_struct; GSL_StructField *gsl_struct_field; } YYSTYPE;/* Line 191 of yacc.c. */#line 1327 "goomsl_yacc.c"# define yystype YYSTYPE /* obsolescent; will be withdrawn */# define YYSTYPE_IS_DECLARED 1# define YYSTYPE_IS_TRIVIAL 1#endif/* Copy the second part of user declarations. *//* Line 214 of yacc.c. */#line 1339 "goomsl_yacc.c"#if ! defined (yyoverflow) || YYERROR_VERBOSE/* The parser invokes alloca or malloc; define the necessary symbols. */# if YYSTACK_USE_ALLOCA# define YYSTACK_ALLOC alloca# else# ifndef YYSTACK_USE_ALLOCA# if defined (alloca) || defined (_ALLOCA_H)# define YYSTACK_ALLOC alloca# else# ifdef __GNUC__# define YYSTACK_ALLOC __builtin_alloca# endif# endif# endif# endif# ifdef YYSTACK_ALLOC /* Pacify GCC's `empty if-body' warning. */# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)# else# if defined (__STDC__) || defined (__cplusplus)# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */# define YYSIZE_T size_t# endif# define YYSTACK_ALLOC malloc# define YYSTACK_FREE free# endif#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */#if (! defined (yyoverflow) \ && (! defined (__cplusplus) \ || (YYSTYPE_IS_TRIVIAL)))/* A type that is properly aligned for any stack member. */union yyalloc{ short yyss; YYSTYPE yyvs; };/* The size of the maximum gap between one aligned stack and the next. */# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)/* The size of an array large to enough to hold all stacks, each with N elements. */# define YYSTACK_BYTES(N) \ ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM)/* Copy COUNT objects from FROM to TO. The source and destination do not overlap. */# ifndef YYCOPY# if 1 < __GNUC__# define YYCOPY(To, From, Count) \ __builtin_memcpy (To, From, (Count) * sizeof (*(From)))# else# define YYCOPY(To, From, Count) \
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?