?? symtab.h
字號:
#ifndef _C_SYMTAB_H_
#define _C_SYMTAB_H_
#include "Common.h"
// for string tab
#include "GBStrTab.h"
// the first three char must be this
#define _GLOBE_VAL_NAME "mm_%s"
// struct _specifier_
#define SPEC_UNKNOW 0 // only for function return value
// noun
#define SPEC_VOID 1 // only for function return value
#define SPEC_CHAR 2
#define SPEC_INT 3
#define SPEC_FLOAT 4 // can be ingored in gen code
#define SPEC_DOUBLE 5 // can be ingored in gen code
#define SPEC_LABEL 6
// sclass
#define SPEC_AUTO 1
#define SPEC_REGISTER 2
#define SPEC_CONSTANT 3
#define SPEC_TYPEDEF 4
#define _MAIN_FUNC_NAME "main"
// const value
typedef union _const_value_
{
char v_c;
unsigned char v_uc;
int v_i;
unsigned int v_ui;
float f; // never used
double lf; // never used
const_string *v_str; // pointer to the string in table
} const_value;
typedef struct _specifier_
{
unsigned noun; // CHAR INT FLOAT DOUBLE STRING LABEL
unsigned sclass; // REGISTER AUTO CONSTANT TYPEDEF
unsigned is_long; // 1 = long , 0 = short , can be ingore in code gen
unsigned is_unsigned;// 1 = unsigned, 0 = signed
unsigned is_static; // 1 = static keyword found in declaration
unsigned is_extern; // 1 = extern keyword found in declaration
const_value v; // const value
} specifier;
typedef struct _symbol_
{
char name[NAME_LEN]; // Input name of symbol
char rname[LABEL_LEN]; // Output name of symbol in .asm
unsigned is_symtab; // 1 == symtab ; means is tab head
unsigned is_function; // 1 == the symbol is function
unsigned is_declaration; // 1 == the function is only declaration, not defined
// or the label only declaration
unsigned is_array; // 1 == the symbol is array
unsigned is_argument; // 1 == the symbol is argument in function declaration
unsigned is_assign; // 1 == the symbol is var and be assigned
unsigned is_cl; // 1 == the symbol is const value, not var
unsigned is_rvalue; // 1 == the symbol is a rvalue
unsigned is_pushed; // 1 == the symbol has push itself
int num_ele; // if is array use this field to show element number
specifier basetype; // if func, is fun's return value
int offset; // Offset of variable , if var
struct _symbol_ *next; // Next symbol in the table
// if is args, use this to link next args symbol
struct _symbol_ *args; // if the symbol stand for function
// use this to link args
// if the symbol is not function, it has initalizer
// use this pointer reference to initalizer
// if the symbol is array in expression, use this
// to refer to index expression
struct _symbol_ *lchild,*rchild;// 二叉樹組織
} symbol;
#define NOUN basetype.noun
#define SCLASS basetype.sclass
#define IS_LONG basetype.is_long
#define IS_UNSIGNED basetype.is_unsigned
#define IS_STATIC basetype.is_static
#define IS_EXTERN basetype.is_extern
#define V_C basetype.v.v_c
#define V_UC basetype.v.v_uc
#define V_I basetype.v.v_i
#define V_UI basetype.v.v_ui
#define V_F basetype.v.f
#define V_LF basetype.v.lf
#define V_STR basetype.v.v_str
#define IS_SYMTAB(x) ( (x)->is_symtab )
#define IS_FUNCTION(x) ( (x)->is_function )
#define IS_FUNC_DECL(x) ( IS_FUNCTION(x) && (x)->is_declaration )
#define IS_ARGUMENT(x) ( (x)->is_argument )
#define IS_ASSIGN(x) ( (x)->is_assign )
#define IS_ARRAY(x) ( (x)->is_array )
#define IS_LABEL(x) ( (x)->NOUN == SPEC_LABEL )
#define IS_CL(x) ( (x)->is_cl )
#define IS_RVALUE(x) ( (x)->is_rvalue )
#define IS_PUSHED(x) ( (x)->is_pushed )
#define IS_LAB_DECL(x) ( (x)->NOUN == SPEC_LABEL && (x)->is_declaration )
#define IS_LOCAL_VAR(x) ( !IS_FUNCTION(x) && \
!IS_SYMTAB(x) && \
!IS_ARGUMENT(x) && \
!IS_TYPEDEF(x) && \
!IS_CL(x) && \
!IS_RVALUE(x) && \
!IS_LABEL(x) )
#define IS_VAR(x) ( !IS_FUNCTION(x) && \
!IS_SYMTAB(x) && \
!IS_TYPEDEF(x) && \
!IS_CL(x) && \
!IS_RVALUE(x) && \
!IS_LABEL(x) )
// tmp array symbol has index expression
#define IS_ARRAY_HAS_INDEX(x) ( IS_ARRAY(x) && (x)->args )
#define IS_LVALUE(x) ( ( IS_VAR(x) && !IS_ARRAY(x) ) || \
IS_ARRAY_HAS_INDEX(x) )
#define IS_GLOBE(x) ( !strncmp((x)->rname,_GLOBE_VAL_NAME, 3) )
#define IS_AUTO(x) ( (x)->SCLASS == SPEC_AUTO )
#define IS_REGISTER(x) ( (x)->SCLASS == SPEC_REGISTER )
#define IS_CONSTANT(x) ( (x)->SCLASS == SPEC_CONSTANT )
#define IS_TYPEDEF(x) ( (x)->SCLASS == SPEC_TYPEDEF )
#define IS_MAIN_FUNC(x) ( IS_FUNCTION(x) && \
!strcmp(_MAIN_FUNC_NAME, (x)->name) )
#define _CL_SINGLE_OPERATION(x, o) \
switch((x)->NOUN) \
{ \
case SPEC_CHAR: \
(x)->V_C = (o((x)->V_C)); \
break; \
case SPEC_INT: \
(x)->V_I = (o((x)->V_I)); \
break; \
case SPEC_DOUBLE: \
(x)->V_LF = (o((x)->V_LF)); \
break; \
case SPEC_FLOAT: \
(x)->V_F = (o((x)->V_F)); \
break; \
default: \
yyerror("can't do cl operator"); \
user_exit(1); \
}
#define _CL_SINGLE_BIT_OPERATION(x, o) \
switch((x)->NOUN) \
{ \
case SPEC_CHAR: \
(x)->V_C = (o((x)->V_C)); \
break; \
case SPEC_INT: \
(x)->V_I = (o((x)->V_I)); \
break; \
default: \
yyerror("can't do cl bit operator"); \
user_exit(1); \
}
#define _CL_DOUBLE_OPERATION(x,y,o) \
switch((x)->NOUN) \
{ \
case SPEC_CHAR: \
(x)->V_C = ((x)->V_C o ((y)->V_C)); \
break; \
case SPEC_INT: \
(x)->V_I = ((x)->V_I o ((y)->V_I)); \
break; \
case SPEC_DOUBLE: \
(x)->V_LF = ((x)->V_LF o ((y)->V_LF)); \
break; \
case SPEC_FLOAT: \
(x)->V_F = ((x)->V_F o ((y)->V_F)); \
break; \
default: \
yyerror("can't do cl operator"); \
user_exit(1); \
}
#define _CL_DOUBLE_BIT_OPERATION(x,y,o) \
switch((x)->NOUN) \
{ \
case SPEC_CHAR: \
(x)->V_C = ((x)->V_C o ((y)->V_C)); \
break; \
case SPEC_INT: \
(x)->V_I = ((x)->V_I o ((y)->V_I)); \
break; \
default: \
yyerror("can't do cl bit operator"); \
user_exit(1); \
}
#define CHECK_BIT_OP_TYPE(x) \
if ( (x)->NOUN == SPEC_DOUBLE || (x)->NOUN == SPEC_FLOAT ) \
{ \
yyerror("illegal on operands of type 'float ' or 'double'"); \
user_exit(1); \
}
// globe value
// for symtab
symbol *new_symbol();
void del_symbol(symbol *p);
void remove_symtab(symbol *head);
// delete a symtab except function args
void remove_symtab_except_args(symbol *head);
// delete a function symtab include function args
void remove_function_symtab_include_args(symbol *func);
// remove the linked symbol
// eg. not use declaration list
void remove_symbol_list(symbol *p);
symbol *create_symtab(const char *name);
// return NULL means not found
symbol *search_symbol_in_symtab(symbol *tab, char *name);
// return NULL means not found
symbol *search_symbol_to_top(char *name);
int add_symbol_to_symtab(symbol *tab, symbol *p);
// add symbol to current symtab
// return 0 means ok, otherwise return 1 means already exist
int add_symbol_to_current_symtab(symbol *p);
// add symbol list to symtab, use ->next to link
int add_symbol_list_to_current_symtab(symbol *p);
// link two symbol list to one list
// link p2 at ->next of p1's last symbol
symbol *link_symbol_list(symbol *p1, symbol *p2);
// union the specifier symbol
// change p1
void union_specifier_symbol(symbol *p1, symbol *p2);
// check declarator
void check_var_declarator(symbol *decl);
// union the specifier to declarator
// at same time check declarator , not be void
void unoin_specifier_to_declarator(symbol *spec, symbol *decl);
// union the specifier to declarator list
void unoin_specifier_to_declarator_list(symbol *spec, symbol *decl_list);
// new symbol from a typedef symbol
symbol *new_symbol_from_typedef(symbol *def_sym);
// search for typedef name
// return not NULL means found
symbol *find_symtab_typedef(char *name);
// create compound symtab , and push it
symbol *new_compound_symtab();
// pop a compound symtab, and destory it
void del_compound_symtab();
// check args type in function call
int check_args_type_in_function_call(symbol *p1,symbol *p2);
// check args type
int check_args_type(symbol *p1,symbol *p2);
// check the function parameter and return type
int check_func_args_type(symbol *func,symbol *decl);
// add function definition to function tab
// if declaration if exist, check parameter type,
// and overwrite parameter's name
// actual delete the declaration list
// and add itself to function symtab
symbol *add_function_def_to_functab(symbol *func);
// only declaration
// add or only check parameter type
// not overwrite parameter's type
void add_function_decl_to_functab(symbol *decl);
// check function return value
// array can't be return value
void check_function_retval(symbol *func);
// get symbol 's size
int get_symbol_size(symbol *p);
// set local value or args rname
void set_local_or_args_rname(symbol *p);
// get local value or args asm attrib "word ptr [bp-%d]" or "byte ptr [bp-%d]"
// or "word ptr [bp+%d]" or "byte ptr [bp+%d]"
char *get_asm_attri(symbol *p);
// assign parameters rname
void assign_parameters_rname(symbol *args_list);
// assign symbol a unused name
void assign_symbol_unusedname(symbol *p);
// set function 's offset to sub sp, offset
void set_func_offset(symbol *func);
// change cl value if necessary
void cast_cl_type(symbol *c1, symbol *c2);
// get symbol value as int
int get_sym_value(symbol *c);
// clone a symbol with symbol
symbol *clone_symbol(symbol *p);
// calcu function argument size
int get_function_args_size(symbol *func);
// create goto label symtab
void create_goto_label_symtab();
// destory goto label symtab
void destory_goto_label_symtab();
// found the goto label in goto label symtab
symbol *search_goto_label(char *name);
// add goto label to goto label symtab
void add_goto_label(symbol *lb);
void InitSymTab();
void DestorySymTab();
// dump symbol for debug
void dump_symbol(symbol *p);
void dump_function(symbol *func);
void dump_current_symtab();
void dump_function_symtab();
#endif
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -