321 lines
12 KiB
Python
321 lines
12 KiB
Python
from copy import deepcopy
|
||
from cpu import cpu
|
||
from io import StringIO as string
|
||
|
||
|
||
|
||
|
||
|
||
class variable_type(object):
|
||
def __init__(self,attr:list[str],size:int,limit:tuple[int,int]=None):
|
||
# 对于函数 attr就是返回值类型 attr中包含 '()' 则表示函数
|
||
self.attr=attr
|
||
self.size=size
|
||
self.pack=4 # 默认4字节对齐
|
||
self.member:list[tuple[variable_type,str]]=[]
|
||
if not (limit is None):
|
||
self.min=limit[0]
|
||
self.max=limit[1]
|
||
if(self.min>self.max):
|
||
raise Exception(f"{self.attr} 最小值大于最大值 {limit}")
|
||
self.enum_types={}
|
||
# 对于函数 member就是形式参数
|
||
def add_member(self,member,name:str):
|
||
if(isinstance(member,(variable_type))):
|
||
self.member.append((member,name))
|
||
else:
|
||
raise Exception(f"参数类型不对 {type(member)}")
|
||
def add_enum_item(self,key:str,index:int):
|
||
if (not key in self.enum_types.keys()) and (not index in self.enum_types.values()):
|
||
self.enum_types[key]=index
|
||
return
|
||
print(self.enum_types.keys(),self.enum_types.values())
|
||
raise Exception(f"枚举类型键或值已存在 {key} {index}")
|
||
def get_enum_value(self,key:str):
|
||
return self.enum_types.get(key,None)
|
||
def eq(self,attr:list[str]):
|
||
attr.sort()
|
||
self.attr.sort()
|
||
if(len(self.attr) != len(attr)):
|
||
return False
|
||
for item1,item2 in zip(self.attr,attr):
|
||
if(item1 != item2):
|
||
return False
|
||
return True
|
||
def get_size(self):
|
||
if("struct" in self.attr):
|
||
size=0
|
||
for item in self.member:
|
||
item_size=((item[0].get_size()+(self.pack-1))//self.pack)*self.pack
|
||
size+=item_size
|
||
return size
|
||
elif("union" in self.attr):
|
||
size=0
|
||
for item in self.member:
|
||
item_size=item[0].get_size()
|
||
if(size<item_size):
|
||
size=item_size
|
||
return size
|
||
elif("enum" in self.attr):
|
||
return 4
|
||
else:
|
||
return self.size
|
||
|
||
class variable(object):
|
||
def __init__(self,name:str,attr:variable_type,value:int):
|
||
self.name=name
|
||
self.value_=value # 这个值是变量在内存中的首地址
|
||
self.attr=attr
|
||
def set_value(self,value):
|
||
if("const" in self.attr):
|
||
raise Exception(f"变量 {self.name} 不可写")
|
||
self.value_=value
|
||
def size(self):
|
||
return self.attr.get_size()
|
||
def value(self):
|
||
return self.value_,self.attr.get_size()
|
||
def member_value(self,member_stack:list[str]=[]):
|
||
off=0
|
||
deep=len(member_stack)
|
||
member=self.attr.member
|
||
index=0
|
||
member_index=0
|
||
member_len=len(member)
|
||
while index < deep:
|
||
while(member_index < member_len):
|
||
if(member[member_index][1]!=member_stack[index]):
|
||
off+=member[member_index][0].get_size()
|
||
member_index+=1
|
||
else:
|
||
index+=1
|
||
if(index==deep):
|
||
return self.value_+off,member[member_index][0].get_size()
|
||
member=member[member_index][0].member
|
||
member_index=0
|
||
member_len=len(member)
|
||
raise Exception(f"{self.name} 中不存在指定成员 {member_stack}")
|
||
return self.value()
|
||
|
||
|
||
class variable_alias(object):
|
||
def __init__(self,alias:str,attr:variable_type):
|
||
self.attr=attr
|
||
self.alias=alias
|
||
|
||
class run(object):
|
||
def __init__(self):
|
||
self.variable_type_list:list[variable_type]=[
|
||
variable_type(["char"],1,(-128,127)),
|
||
variable_type(["short"],2,(-32768,32767)),
|
||
variable_type(["int"],4,(-2147483648,2147483647)),
|
||
variable_type(["long"],4,(-2147483648,2147483647)),
|
||
variable_type(["long","long"],8,(-9223372036854775808,9223372036854775807)),
|
||
variable_type(["float"],4),
|
||
variable_type(["double"],8),
|
||
variable_type(["unsigned","char"],1,(0,0xff)),
|
||
variable_type(["unsigned","short"],2,(0,0xffff)),
|
||
variable_type(["unsigned","int"],4,(0,0xffffffff)),
|
||
variable_type(["unsigned","long"],4,(0,0xffffffff)),
|
||
variable_type(["unsigned","long","long"],8,(0,0xffffffff_ffffffff)),
|
||
]
|
||
variable_list_len=len(self.variable_type_list)
|
||
for i in range(variable_list_len):
|
||
item=deepcopy(self.variable_type_list[i])
|
||
item2=deepcopy(self.variable_type_list[i])
|
||
item3=deepcopy(self.variable_type_list[i])
|
||
item.attr.insert(0,"static")
|
||
self.variable_type_list.append(item)
|
||
item2.attr.insert(0,"const")
|
||
self.variable_type_list.append(item2)
|
||
item3.attr.insert(0,"static")
|
||
item3.attr.insert(1,"const")
|
||
self.variable_type_list.append(item3)
|
||
self.variable_type_alias:list[variable_alias]=[]
|
||
self.unname_struct_index=0
|
||
self.unname_union_index=0
|
||
self.unname_enum_index=0
|
||
self.cpu=cpu(0x1000_0000,1*1024*1024,0x2000_0000,1*1024*1024)
|
||
self.stack:list[variable]=[]
|
||
def variable_type_check(self,attr:list[str]):
|
||
'''
|
||
校验变量类型
|
||
attr:变量属性
|
||
如果该变量类型已存在 则返回True 否则返回False
|
||
'''
|
||
for item in self.variable_type_list:
|
||
if(item.eq(attr)):
|
||
return True
|
||
return False
|
||
def enum_type_check(self,key):
|
||
'''
|
||
校验枚举类型
|
||
key:枚举的名称
|
||
如果枚举名称已存在 则返回True 否则返回False
|
||
'''
|
||
for item in self.variable_type_list:
|
||
if("enum" in item.attr):
|
||
if item.get_enum_value(key):
|
||
return True
|
||
return False
|
||
def get_variable_type(self,attr:list[str]):
|
||
'''
|
||
根据变量属性列表返回变量类
|
||
attr:属性列表
|
||
'''
|
||
if(len(attr)==1):
|
||
for item in self.variable_type_alias:
|
||
if(item.alias==attr[0]):
|
||
return item.attr
|
||
for item in self.variable_type_list:
|
||
if(item.eq(attr)):
|
||
return item
|
||
raise Exception(f"变量类型不存在 {attr}")
|
||
def add_struct_type(self,pack:int,type_name:str,member:list[tuple[variable_type,str]]):
|
||
'''
|
||
添加一个结构体类型
|
||
pack:按pack字节对齐
|
||
type_name:类型名,如果为None则生成匿名结构体类型
|
||
member:成员类型和成员名称
|
||
'''
|
||
if(type_name is None):
|
||
type_name=f"unname_struct{self.unname_struct_index}"
|
||
self.unname_struct_index+=1
|
||
attr=["struct",type_name]
|
||
if(self.variable_type_check(attr)):
|
||
raise Exception(f"类型已存在 {attr}")
|
||
vt=variable_type(attr,0,None)
|
||
vt.pack=pack
|
||
for item in member:
|
||
if("static" in item[0].attr):
|
||
raise Exception(f"结构体成员不能包含 static 属性 {item[0].attr}")
|
||
vt.add_member(item[0],item[1])
|
||
self.variable_type_list.append(vt)
|
||
def add_union_type(self,type_name:str,member:list[tuple[variable_type,str]]):
|
||
'''
|
||
添加一个联合体类型
|
||
pack:按pack字节对齐
|
||
type_name:类型名,如果为None则生成匿名联合体类型
|
||
member:成员类型和成员名称
|
||
'''
|
||
if(type_name is None):
|
||
type_name=f"unname_union{self.unname_union_index}"
|
||
self.unname_union_index+=1
|
||
attr=["union",type_name]
|
||
if(self.variable_type_check(attr)):
|
||
raise Exception(f"类型已存在 {attr}")
|
||
vt=variable_type(attr,0,None)
|
||
for item in member:
|
||
if("static" in item[0].attr):
|
||
raise Exception(f"结构体成员不能包含 static 属性 {item[0].attr}")
|
||
vt.add_member(item[0],item[1])
|
||
self.variable_type_list.append(vt)
|
||
def add_enum_type(self,type_name:str,member:list[tuple[str,int]]):
|
||
'''
|
||
添加一个枚举类型
|
||
type_name:类型名,如果为None则生成匿名结构体类型
|
||
member:枚举名称和枚举值
|
||
'''
|
||
if(type_name is None):
|
||
type_name=f"unname_enum{self.unname_union_index}"
|
||
self.unname_enum_index+=1
|
||
attr=["enum",type_name]
|
||
if(self.variable_type_check(attr)):
|
||
raise Exception(f"类型已存在 {attr}")
|
||
vt=variable_type(attr,4,None)
|
||
for item in member:
|
||
if(self.enum_type_check(item[0])):
|
||
raise Exception(f"枚举键已存在 {member}")
|
||
vt.add_enum_item(item[0],item[1])
|
||
self.variable_type_list.append(vt)
|
||
def add_type_alias(self,attr:list[str],new_name:str):
|
||
'''
|
||
添加一个类型别名
|
||
attr:类型的属性列表,
|
||
member:成员类型和成员名称
|
||
'''
|
||
if(len(attr)==1):
|
||
for item in self.variable_type_alias:
|
||
if(item.alias==attr[0]):
|
||
self.variable_type_alias.append(variable_alias(new_name,item.attr))
|
||
return
|
||
for item in self.variable_type_list:
|
||
if(item.eq(attr)):
|
||
self.variable_type_alias.append(variable_alias(new_name,item))
|
||
def add_variable(self,attr:list[str],name:str,value=None):
|
||
'''
|
||
添加一个变量
|
||
attr:变量类型的属性列表
|
||
name:变量名称
|
||
value:变量值 为None时不设置初值 这个参数暂时没有使用
|
||
'''
|
||
for item in self.stack:
|
||
if(item.name==name):
|
||
raise Exception(f"符号名称已存在 {name}")
|
||
if(len(attr)==1):
|
||
for item in self.variable_type_alias:
|
||
if(item.alias==attr[0]):
|
||
addr=self.cpu.create_var(item.attr.get_size())
|
||
self.stack.append(variable(name,item.attr,addr))
|
||
return
|
||
for item in self.variable_type_list:
|
||
if(item.eq(attr)):
|
||
addr=self.cpu.create_var(item.get_size())
|
||
self.stack.append(variable(name,item,addr))
|
||
def set_variable(self,name:str,value,member_stack:list[str]=[]):
|
||
'''
|
||
设置变量值
|
||
name:要设置的变量名称
|
||
value:变量值
|
||
member_stack:变量的成员
|
||
'''
|
||
for item in self.stack:
|
||
if(item.name==name):
|
||
addr,size=item.member_value(member_stack)
|
||
self.cpu.set_value(addr,size,value)
|
||
return
|
||
raise Exception(f"符号名称不存在 {name}")
|
||
def get_variable(self,name:str,member_stack:list[str]=[]):
|
||
'''
|
||
获取变量的值
|
||
name:变量名
|
||
member_stack:变量成员,成员的成员
|
||
'''
|
||
for item in self.stack:
|
||
if(item.name==name):
|
||
addr,size=item.member_value(member_stack)
|
||
print(f"addr={addr},size={size}")
|
||
return self.cpu.get_value(addr,size)
|
||
|
||
def __str__(self) -> str:
|
||
ret=string()
|
||
ret.write("变量类型\n")
|
||
for item in self.variable_type_list:
|
||
ret.write(f"\t{item.attr}\n")
|
||
ret.write("变量别名\n")
|
||
for item in self.variable_type_alias:
|
||
ret.write(f"\t{item.attr.attr} eq {item.alias}\n")
|
||
ret.write("变量栈\n")
|
||
for item in self.stack:
|
||
addr,size=item.value()
|
||
ret.write(f"\t{item.attr.attr} {item.name}={hex(addr)},{size}\n")
|
||
ret_str=ret.getvalue()
|
||
ret.close()
|
||
return ret_str
|
||
|
||
if __name__ == "__main__":
|
||
f=run()
|
||
f.add_enum_type("enum1",[("ENUM0",0),("ENUM1",1)])
|
||
f.add_struct_type(4,"struct1",[
|
||
(f.get_variable_type(['int']),'a'),
|
||
(f.get_variable_type(['int']),'b'),
|
||
])
|
||
f.add_type_alias(['unsigned','char'],'uint8_t')
|
||
f.add_type_alias(['struct','struct1'],'struct1_def')
|
||
f.add_type_alias(['struct1_def'],'struct1_def_def')
|
||
f.add_variable(['unsigned','char'],'char_a',120)
|
||
f.add_variable(['uint8_t'],'char_b',100)
|
||
f.add_variable(['struct',"struct1"],'struct_a')
|
||
f.get_variable("struct_a")
|
||
f.get_variable("struct_a",['a'])
|
||
f.get_variable("struct_a",['b'])
|
||
print(f) |