-
zhaochaoyi authoredzhaochaoyi authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
symbol.c 18.85 KiB
#include "data.h"
#include "debug.h"
typedef SymbolInfoList_t list_t;
typedef struct SymbolStack_ele_t stack_ele_t;
//都应该使用static
static void node_init(unit_t * cur,int argc,...);
static void node_delete(void * cur,int mode);
static bool struct_node_equal(unit_t*,unit_t*);
static struct Info_Node_Ops InfoNodeOp = {
.init = node_init,
.delete = node_delete,
.equal = struct_node_equal,
};
struct Info_Node_Ops * nodeop = &InfoNodeOp;
static void SymbolInfoList_insert(list_t * list,unit_t * cur,unit_t * new);
static void SymbolInfoList_remove(list_t * list,unit_t * cur);
static void SymbolInfoList_init(list_t * list);
static void SymbolInfoList_delete(list_t * list);
static unit_t * SymbolInfoList_find(list_t * list,char * name);
static list_t * SymbolInfoList_alloc();
static struct Hash_List_Ops {
void (*insert)(list_t * list,unit_t * cur,unit_t * new); //在list链表节点cur之后插入新节点new !!!注意插入节点前要先malloc一个节点
void (*remove)(list_t * list,unit_t * cur); //在list链表中删除cur节点, !!!注意:删除节点时候不free,在stack中pop的时候free;
void (*init)(list_t * list); //初始化
void (*delete)(list_t * list);
unit_t * (* find)(list_t * list,char * name);
list_t * (*alloc)();
}listop = {
.insert = SymbolInfoList_insert,
.remove = SymbolInfoList_remove,
.init = SymbolInfoList_init,
.find = SymbolInfoList_find,
.alloc = SymbolInfoList_alloc,
.delete = SymbolInfoList_delete,
};
//hash table list 接口
static unit_t * SymbolTable_node_alloc();
static void SymbolTable_init(int size);
static int SymbolTable_insert(unit_t * cur);
static int SymbolTable_remove(unit_t * cur);
static unit_t * SymbolTable_find(char *);
static void SymbolTable_node_init(unit_t * cur,char * name);
static void SymbolTable_rehash();
static void SymbolTable_display_node(unit_t *);
//SymbolTable API
MODULE_DEF(SymbolTable_t,symbol_table) = {
.node_alloc = SymbolTable_node_alloc,
.node_init = SymbolTable_node_init,
.init = SymbolTable_init,
.insert = SymbolTable_insert,
.remove = SymbolTable_remove,
.find = SymbolTable_find,
.rehash = SymbolTable_rehash,
.display_node = SymbolTable_display_node,
};
static stack_ele_t * SymbolStack_node_alloc(); //分配栈中的节点,由于也是链表,需要分配两个head和tail
static void SymbolStack_init(); //初始化栈
static void SymbolStack_push(stack_ele_t * ); //在push前应调用stack的node_alloc来分配栈中的节点
static void SymbolStack_pop(); //在pop时free掉所有这一层作用域申请的节点
static stack_ele_t * SymbolStack_top();
static bool SymbolStack_empty();
MODULE_DEF(SymbolStack_t,symbol_stack) = {
.node_alloc = SymbolStack_node_alloc,
.init = SymbolStack_init,
.push = SymbolStack_push,
.pop = SymbolStack_pop,
.top = SymbolStack_top,
.empty = SymbolStack_empty,
};
//Symbol Table
static void SymbolTable_display_node(unit_t * cur) {
printf("Name: %s, deep: %d\n",cur->name,cur->deep);
type_ops->print_type(cur->type,0);
}
static int SymbolTable_hashFun(char * name) {
int val = 0,i;
for(; *name; ++name) {
val = (val << 2) + *name;
if ((i = val & symbol_table->table_size)) {
val = (val ^ (i >> 12)) & symbol_table->table_size;
}
}
return val;
}
static void SymbolTable_init(int size) {
symbol_table->table_size = size;
symbol_table->hash = SymbolTable_hashFun;
symbol_table->table = (list_t **)malloc(sizeof(list_t*) * size);
for(int i = 0;i < size;i++) {
symbol_table->table[i] = NULL;
}
symbol_table->cnt = 0;
}
static unit_t * SymbolTable_node_alloc() {
unit_t * ans = (unit_t *) malloc(sizeof(unit_t));
return ans;
}
static void SymbolTable_node_init(unit_t * cur,char * name) {
nodeop->init(cur,3,name,symbol_stack->stack_size,INFONODE);
}
static int SymbolTable_insert(unit_t * cur) {
int id = symbol_table->hash(cur->name);
list_t * list = symbol_table->table[id];
if(symbol_table->table[id] != NULL) {
unit_t * find = symbol_table->find(cur->name);
if(find && find->deep == cur->deep) {
return 0;
} else {
listop.insert(list,&list->head,cur);
}
} else {
list = listop.alloc();
listop.init(list);
symbol_table->table[id] = list;
listop.insert(list,&list->head,cur);
}
symbol_table->cnt += 1;
//printf("---\nSymbol Table Insert: %s ,deep: %d ,line: %d\n",cur->name,cur->deep,cur->line);
//type_ops->print_type(cur->type,0);
//还需在纵向的十字链表插入头部
unit_t * scope = &symbol_stack->top()->head;
unit_t * next = scope->scope_next;
assert(scope->node_type == STACKNODE);
scope->scope_next = cur;
cur->scope_next = next;
next->scope_prev = cur;
cur->scope_prev = scope;
return 1;
}
//插入失败不会删除
static int SymbolTable_remove(unit_t * cur) {
int id = symbol_table->hash(cur->name);
list_t * list = symbol_table->table[id];
assert(list != NULL);
listop.remove(list,cur);
symbol_table->cnt--;
//printf("---\nSymbol Table remove: %s ,deep: %d ,line: %d\n",cur->name,cur->deep,cur->line);
//type_ops->print_type(cur->type,0);
return 1;
}//说明见最后,这里不free
//Symbol Table
static unit_t * SymbolTable_find(char * name) {
int id = symbol_table->hash(name);
list_t * list = symbol_table->table[id];
if(list == NULL) {
return NULL;
} else {
return listop.find(list,name);
}
}
static void SymbolTable_rehash() {
panic("Not implemented");
}
/*
* 在stack中,unit_t *的指针作用
* scope,用于纵向连接hash table中元素
* hash,用于在stack中连接栈中的元素
*/
//Symbol Stack
static stack_ele_t * SymbolStack_node_alloc(int field_type) {
stack_ele_t * node = (stack_ele_t *) malloc(sizeof(stack_ele_t));
node->field_type = field_type;
node->prev = node->next = NULL;
unit_t * head = &node->head;
unit_t * tail = &node->tail;
nodeop->init(head,3,"Stack node head",symbol_stack->stack_size + 1,STACKNODE);
nodeop->init(tail,3,"Stack node tail",symbol_stack->stack_size + 1,STACKNODE);
head->hash_prev = head->hash_next = tail->hash_prev = tail->hash_next = NULL;
head->scope_prev = NULL,tail->scope_next = NULL;
head->scope_next = tail;
tail->scope_prev = head;
return node;
}//分配两个节点,连接两个节点
static void SymbolStack_init() {
symbol_stack->stack_size = 0;
stack_ele_t * first = &symbol_stack->first;
stack_ele_t * last = &symbol_stack->last;
first->prev = last->next = NULL;
first->next = last;
last->prev = first;
}//初始化栈中的两个节点
static void SymbolStack_push(stack_ele_t * item) {
stack_ele_t * first = &symbol_stack->first, * next = first->next;
first->next = item;
item->next = next;
next->prev = item;
item->prev = first;
symbol_stack->stack_size++;
item->head.type = next->head.type;
}
static void SymbolStack_pop() {
stack_ele_t * top = symbol_stack->top();
unit_t * cur = top->head.scope_next, * temp;
while (cur != &top->tail) {
temp = cur->scope_next;
assert(cur->deep == top->head.deep);
symbol_table->remove(cur);
nodeop->delete(cur,INFONODE);
cur = temp;
}
stack_ele_t * head = &symbol_stack->first, * next = top->next;
head->next = next;
next->prev = head;
nodeop->delete(top,STACKNODE);
symbol_stack->stack_size--;
}
static stack_ele_t * SymbolStack_top() {
if(symbol_stack->first.next != &symbol_stack->last) {
return symbol_stack->first.next;
} else {
Log("The Symbol Stack is empty!");
assert(0);
}
}
static bool SymbolStack_empty() {
if(symbol_stack->stack_size == 0) return true;
else return false;
}
//Symbol Stack
//Symbol List
static void SymbolInfoList_insert(list_t * list,unit_t * cur,unit_t * new) {
unit_t * next = cur->hash_next;
cur->hash_next = new;
new->hash_next = next;
next->hash_prev = new;
new->hash_prev = cur;
list->list_cnt++;
}
static void SymbolInfoList_init(list_t * list) {
nodeop->init(&list->head,1,"HASH LIST HEAD");
nodeop->init(&list->tail,1,"HASH LIST TAIL");
list->list_cnt = 0;
list->head.hash_next = &list->tail;
list->tail.hash_prev = &list->head;
list->head.hash_prev = list->tail.hash_next = NULL;
list->head.node_type = list->tail.node_type = HASHLIST;
}
static void SymbolInfoList_remove(list_t * list,unit_t * cur) {
unit_t * prev = cur->hash_prev, * next = cur->hash_next;
assert(prev != NULL && next != NULL);
prev->hash_next = next;
next->hash_prev = prev;
list->list_cnt--;
//在这里不删除分配的内存,最后统一删除
}
static void SymbolInfoList_delete(list_t * list) {
panic("Not implemented");
}
static unit_t * SymbolInfoList_find(list_t * list,char * name) {
unit_t * cur = list->head.hash_next;
while (cur != &list->tail) {
if(strcmp(name,cur->name) == 0) {
return cur;
}
cur = cur->hash_next;
}
return NULL;
}
static list_t * SymbolInfoList_alloc() {
list_t * list = (list_t *)malloc(sizeof(list_t));
return list;
}
//Symbol List
//Symbol Info node ops
//argc,char * name,deep,Type
static void node_init(unit_t * cur,int argc,...) {
//argc,char * name,deep,Type
va_list ap;
va_start(ap,argc);
if(argc >= 1) {
char * name = va_arg(ap,char *);
assert(NAME_LENGTH > strlen(name));
strcpy(cur->name,name);
}
if(argc >= 2) {
int deep = va_arg(ap,int);
cur->deep = deep;
}
if(argc >= 3) {
cur->node_type = va_arg(ap,int );
}
va_end(ap);
//初始化目前仅涉及了
cur->hash_next = cur->hash_prev = cur->scope_next = cur->scope_prev = NULL;
}
static void node_delete(void * cur,int mode) {
unit_t * info_node = (unit_t*) cur;
SymbolStack_ele_t * stack_node = (SymbolStack_ele_t *) cur;
switch (mode) {
case INFONODE:
type_ops->type_delete(info_node->type);
free(info_node);
//存实际信息的节点
break;
case HASHLIST:
panic("Delete hash list node not allowed!");
//不允许通过该API删除
//hash table中每个链表的头尾节点
break;
case STACKNODE:
free(stack_node);
break;
case STACKLIST:
panic("Delete stack list node not allowed!");
//不允许通过该API删除
//stack中的
break;
default:
panic("Wrong mode");
}
}
static bool struct_node_equal(unit_t* n1,unit_t* n2) {
if(strcmp(n1->name,n2->name) != 0) return false;
if(!type_ops->type_equal(n1->type,n2->type)) return false;
return true;
}
//Symbol Info node
/*
每次向散列表中插入元素时,总是将新插入的元素放到该槽下挂的链表以及该层
所对应的链表的表头。每次查表时如果定位到某个槽,则按顺序遍历这个槽下挂的链表并返回
这个槽中符合条件的第一个变量
stack: | 1 | 2 | 3 |
| | -> List : | 31 | 21 | 11 |
| |
| |
| | -> List : | 32 | 22 | 12 |
| |
| |
| | -> List : | 13 |
| |
stack中构成的链表:
1 : 11 -> 12 -> 13
2 : 21 -> 22
3 : 31 -> 32
以stack中开头的链表:纵向链表
以hashtable中开头的链表:横向链表
插入删除流程:
插入:
在当前作用域插入: 不需要处理stack,调用SymbolTable中的insert,insert进行hash,(分配链表,如果slot没有链表),从头部插入hash表中的链表,也从头部插入对应作用域的纵向链表
插入新的作用域: stack申请新的节点(是两个节点),将head节点push进去
删除:
通常是以作用域为单位删除:找到栈顶的作用域,沿着链表删除,先使用SymbolList中的remove删除hash table slot中的节点(这个节点不会free),
然后free当前节点,然后删除下一个节点,知道end,最后只剩下push时申请的head和end,在stack的链表中删除并free
*/
/*
* 一个类型表
* 类型表的复制、删除(删除暂时不用实现,struct的定义一定是全局定义)
* 类型表的查询
* 类型表的插入
*/
//需要的接口
static void print_field(const FieldList *,int);
static void print_type(const Type *,int);
static Type * Type_Ops_Type_copy(const Type *);
static FieldList * Type_Ops_Field_Copy(const FieldList *);
static void Type_Ops_Type_delete(Type *);
static void Type_Ops_Field_delete(FieldList *);
static Type * Type_Ops_Type_alloc_init(int kind);
static FieldList * Type_Ops_Field_alloc_init(char *,int,const Type*);
static bool Type_Ops_Type_Equal(const Type *,const Type *);
static bool Type_Ops_Field_Equal(const FieldList *,const FieldList *);
MODULE_DEF(Type_Ops_t,type_ops) = {
.print_field = print_field,
.print_type = print_type,
.type_copy = Type_Ops_Type_copy,
.field_copy = Type_Ops_Field_Copy,
.type_delete = Type_Ops_Type_delete,
.field_delete = Type_Ops_Field_delete,
.type_alloc_init = Type_Ops_Type_alloc_init,
.field_alloc_init = Type_Ops_Field_alloc_init,
.type_equal = Type_Ops_Type_Equal,
.field_equal = Type_Ops_Field_Equal,
};
static void print_field(const FieldList * field,int deep) {
if(field == NULL) return;
for (int i = 0;i < deep;i++) {
printf(" ");
}
printf("%s line:%d\n",field->name,field->line);
print_type(field->type,deep + 1);
if(field->tail) {
print_field(field->tail,deep);
}
}
static void print_type(const Type * type,int deep) {
if(type == NULL) return;
for (int i = 0;i < deep;i++) {
printf(" ");
}
printf("Type : %d ",type->kind);
if(type->kind == BASIC) {
printf("BASIC : %d\n",type->u.basic);
} else if(type->kind == ARRAY) {
printf("Array : size=%d ->",type->u.array.size);
print_type(type->u.array.elem,deep + 1);
} else if(type->kind == STRUCTURE){
printf("\n");
print_field(type->u.structure,deep + 1);
} else if(type->kind == FUNC_DECL || type->kind == FUNC_IMPL ) {
printf("return type:\n");
print_type(type->u.func.ret_type,deep + 1);
printf("var type:\n");
print_field(type->u.func.var_list,deep + 1);
} else if(type->kind) {
printf("Wrong type\n");
} else if(type->kind == REMAINED) {
panic("Wrong Remained Modified Type");
}
}
static Type * Type_Ops_Type_copy(const Type * type) {
if(!type) return NULL;
Type * ret = new(Type);
ret->kind = type->kind;
switch (type->kind) {
case BASIC:
ret->u.basic = type->u.basic;
break;
case ARRAY:
ret->u.array.size = type->u.array.size;
break;
case STRUCTURE:
ret->u.structure = Type_Ops_Field_Copy(type->u.structure);
break;
case FUNC_IMPL:
case FUNC_DECL:
panic("Not Implemented");
break;
case REMAINED:
panic("Wrong Remained Modified Type");
case WRONG:
break;
default:
panic("Wrong");
}
return ret;
}
static FieldList * Type_Ops_Field_Copy(const FieldList * field) {
if(!field) return NULL;
FieldList * ret = new(FieldList);
strcpy(ret->name,field->name);
ret->type = type_ops->type_copy(field->type);
ret->line = field->line;
if(field->tail) {
ret->tail = type_ops->field_copy(field->tail);
} else {
ret->tail = NULL;
}
return ret;
}
static void Type_Ops_Type_delete(Type * type) {
if(type == NULL) return;
else {
switch (type->kind) {
case BASIC:
//do nothing
break;
case ARRAY:
Type_Ops_Type_delete(type->u.array.elem);
break;
case STRUCTURE:
Type_Ops_Field_delete(type->u.structure);
break;
case FUNC_DECL:
case FUNC_IMPL:
Type_Ops_Type_delete(type->u.func.ret_type);
Type_Ops_Field_delete(type->u.func.var_list);
break;
case REMAINED:
panic("Wrong Remained Modified Type");
case WRONG:
break;
default:
panic("Wrong");
}
free(type);
}
}
static void Type_Ops_Field_delete(FieldList * field) {
if(field == NULL) return;
Type_Ops_Type_delete(field->type);
if(field->tail != NULL) {
Type_Ops_Field_delete(field->tail);
}
free(field);
}
static Type * Type_Ops_Type_alloc_init(int kind) {
Type * ret = new(Type);
memset(ret,0, sizeof(Type));
ret->kind = kind;
return ret;
}
static FieldList * Type_Ops_Field_alloc_init(char * name,int line,const Type * type) {
FieldList * ret = new(FieldList);
memset(ret,0, sizeof(FieldList));
strcpy(ret->name,name);
ret->line = line;
ret->tail = NULL;
ret->type = type_ops->type_copy(type);
return ret;
}
static bool Type_Ops_Type_Equal(const Type * t1,const Type * t2) {
if(t1 == t2) return true;
if(t1 == NULL && t2 == NULL) return true;
if(t1 && !t2 ) return false;
if(!t1 && t2 ) return false;
if(t1->kind != t2->kind) {
if((t1->kind != FUNC_IMPL && t1->kind != FUNC_DECL ) && (t2->kind != FUNC_IMPL && t2->kind != FUNC_DECL )) {
return false;
}
}
switch (t1->kind) {
case REMAINED:
panic("Wrong");
case WRONG:
return true;
case BASIC:
return t1->u.basic == t2->u.basic;
case ARRAY:
//if(t1->u.array.size != t2->u.array.size) return false;
return Type_Ops_Type_Equal(t1->u.array.elem,t2->u.array.elem);
case STRUCTURE:
return Type_Ops_Field_Equal(t1->u.structure,t2->u.structure);
case FUNC_DECL:
case FUNC_IMPL:
if(!Type_Ops_Type_Equal(t1->u.func.ret_type,t2->u.func.ret_type)) return false;
return Type_Ops_Field_Equal(t1->u.func.var_list,t2->u.func.var_list);
}
}
static bool Type_Ops_Field_Equal(const FieldList * f1,const FieldList * f2) {
if(f1 == NULL && f2 == NULL) return true;
if(f1 && !f2 ) return false;
if(!f1 && f2 ) return false;
/*
if(strcmp(f1->name,f2->name) != 0 ) {
if(!(f1->type->kind == STRUCTURE && f2->type->kind == STRUCTURE)) {
return false;
}
}*/
if(!Type_Ops_Type_Equal(f1->type,f2->type)) return false;
if(!Type_Ops_Field_Equal(f1->tail,f2->tail)) return false;
return true;
}