Files
c_soft/create_lambda_fun.py

126 lines
3.3 KiB
Python
Raw Permalink Normal View History

2025-06-20 15:50:39 +08:00
import os
import sys
import dataclasses
LAMBDA_INDEX=0
TMP_DIR="build"
@dataclasses.dataclass
class fun_name_t:
name:str
return_type:str
params:list
body:str
# 判断是否需要重新生成
def check_rebuild(dst:str,src:list):
if(not os.path.exists(dst)):
return True
dst_time=os.path.getmtime(dst)
src_time=[]
for i in src:
src_time.append(os.path.getmtime(i))
src_time.sort()
if(src_time[-1]>dst_time):
return True
return False
def find_closed(text:str,par:tuple=('(',')')):
count_left=0
count_right=0
for i in range(len(text)):
if(text[i]==par[0]):
count_left+=1
elif(text[i]==par[1]):
count_right+=1
if(count_left==0):
continue
if(count_left==count_right):
# print(f"count_left={count_left} count_right={count_right}")
return i+1
# print(f"count_left={count_left} count_right={count_right}")
return 0
# 找到lambda字符
def calc_lambda_text(text:str):
lambda_list=[]
while True:
index=text.find("lambda(")
if(index==-1):
break
# print(f"index={index}")
lenght=find_closed(text[index:])
if(lenght>0):
lambda_list.append(text[index:index+lenght])
text=text[index+lenght:]
else:
break
return lambda_list
# 根据lambda字符生成函数名
def create_lambda(text:str):
global LAMBDA_INDEX
text=text.replace("lambda(","")[:-1] # 去掉lambda和首末括号
2025-06-20 17:26:36 +08:00
fun_name=f"__lambda_{LAMBDA_INDEX}"
2025-06-20 15:50:39 +08:00
LAMBDA_INDEX+=1
return_type=text[:text.find("(")]
# 有","则至少有两个参数否则可能有一个参数,可能没有
param_str=text[text.find("(")+1:text.find(")")]
params=[]
if(param_str.count(',')>0):
params=param_str.split(',')
for i in range(len(params)):
params[i]=params[i].strip()
else:
t_str=param_str.strip()
if(len(t_str)>0)and(t_str!="void"):
params.append(t_str)
body_start=text.find("{")+1
body_end=find_closed(text,('{','}'))-1
return fun_name_t(fun_name,return_type,params,text[body_start:body_end])
# 生成lambda展开后的文件 返回新的源文件列表
def search_lambda(src_list:list) -> list:
for index,item in enumerate(src_list):
with open(item,encoding='utf-8') as f:
d=f.read()
if(d.count("lambda_use")!=1):
continue
lam_index=d.find("lambda_use")
# 如果标签不在一行的开头 视为不使用lambda
if(lam_index!=0 and d[lam_index-1]!='\n'):
continue
# 获取lambda文件名
2025-06-26 17:41:33 +08:00
base_path=os.path.join(TMP_DIR,os.path.dirname(item))
if not os.path.exists(base_path):
os.makedirs(base_path)
dst_file_name=os.path.join(base_path, os.path.basename(item))
src_list[index]=dst_file_name
2025-06-20 15:50:39 +08:00
# 不需要重新生成lambda文件
2025-06-26 17:41:33 +08:00
if(not check_rebuild(dst_file_name,[item])):
2025-06-20 15:50:39 +08:00
continue
lam_list=calc_lambda_text(d)
lambda_funs=[]
for lam in lam_list:
lambda_funs.append(create_lambda(lam))
2025-06-26 17:41:33 +08:00
print(f"生成 {dst_file_name}")
with open(dst_file_name,mode='w+',encoding='utf-8') as f:
2025-06-20 15:50:39 +08:00
lambda_funs_text=""
for lam,fun in zip(lam_list,lambda_funs):
lambda_funs_text+=f"static {fun.return_type} {fun.name}({','.join(fun.params)}){'{'}{fun.body}{'}'}\n"
d=d.replace(lam,fun.name)
d=d.replace("lambda_use",lambda_funs_text)
f.write(d)
return src_list
if __name__=="__main__":
t=search_lambda(sys.argv[1:])
print(t)