📄 symbol.c
字号:
sym1 = sym1->next;
sym2 = sym2->next;
}
if(sym2||sym1)//not end at the same time
return 2;
break;
case bt_pointer:
if(t1->array_vol != t2->array_vol)
return 1;
if(checkTypeSame(t1->subtype, t2->subtype))
return 1;
else return 0;
case bt_typedef:
if(t1->tname&&t2->tname
&&strcmp(t1->tname,t2->tname))
return 2; //with the same name
}
return 0;
}
//only const string
int add_const(char *string)
{
static int total, size;
char *str;
if(!string)
debug("[add_const] null pointer input\n");
total += size;
size = strlen(string)+1;
str = dmalloc(size, false);
memcpy(str, string, size);
push_List(&const_list, str);
return total;
}
void *value_init(struct _expnode *exp)
{
//now just this, lack stuct or array init
if(exp != NULL)
return &(exp->val);
else
return NULL;
}
int global_define(
struct _supertype *prefix,
struct _sym *var
)
{
Type *tmptype;
HashNode *hashnode;
if(!prefix)
{
debug("[global_define]null pointer input\n");
return -1;
}
if(!var)
{
if(prefix->sc == sc_typedef)
generror(ERR_SYNTAX_ERROR, "no target type name");
// else
// generror(ERR_SYNTAX_ERROR, "can not specify a type with storage class");
return -1;
}
if(prefix->sc == sc_auto || prefix->sc == sc_register)
{
generror(ERR_STORAGE_CLASS, "register/auto in global area");
return -1;
}
//??the name of array/function is const pointer
for(;var;var = var->next)
{
if(prefix->sc == sc_typedef)
{
tmptype = newType(var->name, bt_typedef, NULL);
tmptype->subtype = compoundType(var->datatype, prefix->datatype);
checkTypeSize(tmptype);//may be of no use
add_newType(tmptype);
continue;
}
////??????????
var->init = value_init(var->init);
var->datatype = compoundType(var->datatype, prefix->datatype);
checkTypeSize(var->datatype);
hashnode= add_node(symtab, SYMTABSIZE, var->name, var);
var->value.linkname = var->name;
if(var->datatype->basic_type != bt_func)
{
if(prefix->sc == UNKNOWN)
var->storage_class = sc_global;
else
var->storage_class = prefix->sc;
if(var->datatype->array_vol != 0)
var->const_flag = true;
if(hashnode)
generror(ERR_REDEF_VAR, var->name);
else if(var->storage_class == sc_external)
push_List(&extern_list, var);
else
{
if(var->storage_class == sc_global)
push_List(&extern_list, var);
if(var->init)
push_List(&data_list, var);
else
push_List(&bss_list, var);
}
}
else
{
if(prefix->sc == UNKNOWN)
var->storage_class = sc_external;
else
var->storage_class = prefix->sc;
//function name is a constant function pointer
var->datatype->basic_type = bt_funcptr;
var->datatype->size = 4;
var->const_flag = true;
var->value.localdata =0;
if(hashnode)
{
if(checkTypeSame(((Symbol*)hashnode->val)->datatype, var->datatype)>1)
generror(ERR_DECL_CONFLICT, var->name);
}
else
push_List(&extern_list, var);
}
}
return 0;
}
int add_local_sym(Symbol *sym)
{
HashNode *hashnode;
Symbol *tmp;
ListNode *item;
hashnode = add_node(symtab, SYMTABSIZE, sym->name, sym);
if(hashnode)
{
do{
for(item = current_block->add.head;item;item=item->next)
{
tmp = item->content;
if(!strcmp(tmp->name, sym->name))
break;
}
if(item)break;
for(item=current_block->dup.head;item;item= item->next)
{
tmp = item->content;
if(!strcmp(tmp->name, sym->name))
break;
}
}while(0);
if(item)
return -1;
else
{
push_List(¤t_block->dup, hashnode->val);
hashnode->val = sym;
}
}
else
{
push_List(¤t_block->add, sym);
}
return 0;
}
struct _stmtnode *local_define(
struct _supertype *prefix,
struct _sym *var
)
{
char buf[64];
ExpNode *left, *init = NULL;
if(!prefix)
{
debug("[local_define]null pointer input\n");
return NULL;
}
if(prefix->sc == UNKNOWN || prefix->sc == sc_register)
prefix->sc = sc_auto;
for(;var;var = var->next)
{
var->storage_class = prefix->sc;
var->datatype = compoundType(var->datatype, prefix->datatype);
checkTypeSize(var->datatype);
if(var->datatype->array_vol != 0)
var->const_flag = true;
if(add_local_sym(var))
{
generror(ERR_REDEF_VAR, var->name);
continue;
}
if(var->storage_class == sc_external)
{
debug("You had better to declare a external variable in a local area");
/*pre= hashnode->val;
if(checkTypeSame(pre->datatype, var->datatype))
generror(ERR_DECL_CONFLICT, var->name);
*/
}
else if(var->storage_class == sc_static)
{
sprintf(buf, "%s@%s@l%d", var->name, current_func->name, lineno);
var->value.linkname = newstrcpy(buf, UNKNOWN);
push_List(&bss_list, var);
}
else //assume no func decl here
{
current_func->value.localdata = align_add(
current_func->value.localdata, var->datatype->size);
var->value.offset = -current_func->value.localdata;
}
//check
if(var->init)
{
left = evaluate_id_exp(var->name);
appendObject(&init, evaluate_assign_exp(exp_assign, left, var->init));
}
}
if(init)
return newCalcStmt(stmt_exp, init, NULL, NULL, NULL, currentfile, lineno);
else
return NULL;
}
//log out all the symbols from the symbol table
//recover all the symbols in dup list
void enter_block()
{
current_block = dmalloc(sizeof(LocalDefines), false);
push_List(&block_list, current_block);
}
//log out all the symbols from the symbol table
//recover all the symbols in dup list
void leave_block()
{
ListNode *add=current_block->add.head, *dup=current_block->dup.head;
Symbol *sym;
HashNode *hashnode;
for(;add;add=add->next)
{
sym = add->content;
remove_node(symtab,SYMTABSIZE, sym->name);
}
for(;dup;dup= dup->next)
{
sym = dup->content;
hashnode = lookup_node(symtab,SYMTABSIZE, sym->name);
hashnode->val = sym;
}
popback_List(&block_list);
}
//the parameter and return value to ready
//call asm_func_begin
int blocklevel;
void prepare_local(
struct _sym *func
)
{
Symbol *para;
int paraoffset = 8;
HashNode *hashnode = lookup_node(symtab, SYMTABSIZE, func->name);
//check redefine
para = hashnode->val;
if(para->storage_class ==sc_global)
generror(ERR_REDEF_FUNC, para->name);
func->storage_class = sc_global;
current_func = func;
enter_block();
blocklevel=0;
para = func->datatype->arglist;
if(para->datatype->basic_type == bt_void)
return;
while(para&¶->datatype->basic_type != bt_ellipsis)
{
para->storage_class = sc_auto;
para->datatype->array_vol=0;//array parameter is pointer
checkTypeSize(para->datatype);
if(add_local_sym(para))
{
generror(ERR_REDEF_VAR, para->name);
}
else
{
para->value.offset = paraoffset;
paraoffset += (para->datatype->size+3)&~3;//in stack there are only times of dword
}
para =para->next;
}
}
void exit_local()
{
Symbol *func = current_func;
clean_named_label();
leave_block();
current_func = NULL;
//release_local();
}
struct _datatype *add_newType(
struct _datatype *newtype
)
{
HashNode *hash;
Type *pre;
if(!newtype->tname||!newtype->tname[0])
{
debug("can not define a type without a name\n");
return newtype;
}
hash = add_node(typetab, TYPETABSIZE, newtype->tname, newtype);
if(hash)
{
pre = hash->val;
if(checkTypeSame(pre, newtype))
generror(ERR_REDEF_TYPE, newtype->tname);
newtype = pre;
}
else
{
//port to global memory management
//hash->val = new_sameType(newtype, false);
}
return newtype;
}
//get out of a function, remember to clean this list
void clean_named_label()
{
Symbol *label;
while(label = popfront_List(&label_list))
{
remove_node(symtab, SYMTABSIZE, label->name);
}
}
struct _sym *add_named_label(
char *labelname,
int labelno
)
{
Symbol *asym = newSymbol(labelname, sc_label, NULL), *pre;
HashNode *hashnode = add_node(symtab, SYMTABSIZE, labelname, asym);
if(hashnode)
{
pre = hashnode->val;
if(pre->storage_class == sc_label)
{
if(labelno != UNKNOWN)
{
if(pre->value.labelno != UNKNOWN)
generror(ERR_REDEF_LABEL, labelname);
else pre->value.labelno = labelno;
}
return pre;
}
else
{
generror(ERR_REDEF_VAR, labelname);
return NULL;
}
}
else
{
asym->value.labelno = labelno;
push_List(&label_list, asym);
return asym;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -