diff --git a/.gitignore b/.gitignore index 2e51a97..56cd31c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ build/ -output/ \ No newline at end of file +output/ +__pycache__/ \ No newline at end of file diff --git a/cpu/riscv.c b/cpu/riscv.c index c0ecfc0..32c892e 100644 --- a/cpu/riscv.c +++ b/cpu/riscv.c @@ -856,7 +856,7 @@ long get_file_size(FILE *stream) riscv_t riscv = { 0 }; -int thread_fun(void* t) +int thread_fun_r(void* t) { int argc; char** argv; diff --git a/create_lambda_fun.py b/create_lambda_fun.py new file mode 100644 index 0000000..eddc1ce --- /dev/null +++ b/create_lambda_fun.py @@ -0,0 +1,124 @@ +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和首末括号 + fun_name=f"lambda_{LAMBDA_INDEX}" + 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: + file_index=0 + 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文件名 + dst_file_name=f"lambda_{file_index}_"+ os.path.basename(item) + file_index+=1 + dst_path=os.path.join(TMP_DIR,dst_file_name) + src_list[index]=dst_path + # 不需要重新生成lambda文件 + if(not check_rebuild(dst_path,[item])): + continue + lam_list=calc_lambda_text(d) + lambda_funs=[] + for lam in lam_list: + lambda_funs.append(create_lambda(lam)) + with open(dst_path,mode='w+',encoding='utf-8') as f: + 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) diff --git a/make.py b/make.py index 9bdb96c..3f62965 100644 --- a/make.py +++ b/make.py @@ -6,6 +6,7 @@ import os import sys import time +from create_lambda_fun import search_lambda ''' @@ -23,9 +24,9 @@ CC = 'gcc' # HEX = 'C:\\ARM_GCC\\bin\\arm-none-eabi-objcopy' + ' -O ihex' # BIN = 'C:\\ARM_GCC\\bin\\arm-none-eabi-objcopy' + ' -O binary -S' -CSRC = ["main.c"] +CSRC = ["main.c","test/lambda_test.c"] -CINC = ['-Isoft',"-Icpu"] +CINC = ['-Isoft',"-Icpu", "-I./"] CDEF = ["-DTEST","-DLINUX"] @@ -186,6 +187,7 @@ def main(): global ASRC CSRC+=find_type('soft',['c','C']) CSRC+=find_type('cpu',['c','C']) + CSRC=search_lambda(CSRC) # ASRC+=find_type('./',['s','S','asm','ASM']) if(not os.path.exists(BUILD_DIR)): diff --git a/soft/lambda.h b/soft/lambda.h new file mode 100644 index 0000000..33bb0d4 --- /dev/null +++ b/soft/lambda.h @@ -0,0 +1,26 @@ +#ifndef lambda_h__ +#define lambda_h__ + +#include "stdint.h" + +#define lambda(...) 0 +#define lambda_use + +/* + +使用方法 + +在c文件开头添加 +lambda_use + + +然后在需要使用lambda的地方添加 +lambda( + void (int a, int b){ + printf("%d + %d = %d\n", a, b, a+b); + } + ) + +*/ + +#endif diff --git a/cmdline_test.c b/test/cmdline_test.c similarity index 100% rename from cmdline_test.c rename to test/cmdline_test.c diff --git a/test/lambda_test.c b/test/lambda_test.c new file mode 100644 index 0000000..4d95db4 --- /dev/null +++ b/test/lambda_test.c @@ -0,0 +1,72 @@ + + +#include "stdio.h" +#include "stdlib.h" +#include "stdint.h" +#include "string.h" +#include "main.h" +#include "lambda.h" + +lambda_use + + + + + + +void run_callback(int (*fun)(int a, int b)) { + int a = fun(1, 2); + printf("a = %d\n", a); +} + + + + + + + + +int thread_fun(void* t) +{ + void (*fun1)(int a, int b); + fun1 = lambda(void(int a, int b) { + printf("a = %d, b = %d\n", a, b); + }); + fun1(1, 2); + void (*fun2)(int a, int b); + fun2 = lambda(void(int a, int b) { + printf("a = %d, b = %d a*b=%d\n", a, b, a * b); + }); + fun2(3, 4); + void (*fun3)(void); + fun3 = lambda(void(void) { + int a = 3; + int b = 4; + printf("a = %d, b = %d a*b=%d\n", a, b, a * b); + }); + fun3(); + void (*fun4)(); + fun4 = lambda(void() { + int a = 5, b = 6; + printf("a = %d, b = %d a*b=%d\n", a, b, a * b); + }); + fun4(); + unsigned int (*fun5)(int a, int b); + fun5 = lambda(unsigned int (int a,int b) { + printf("a = %d, b = %d a*b=%d\n", a, b, a * b); + return 6; + }); + fun5(3, 4); + + run_callback(lambda(int(int a, int b) { + return a * b; + })); + run_callback(lambda(int(int a, int b) { + return a * b * 10; + })); + + return 0; +} + + + diff --git a/test_fun.c b/test/test_fun.c similarity index 100% rename from test_fun.c rename to test/test_fun.c diff --git a/test_fun2.c b/test/test_fun2.c similarity index 100% rename from test_fun2.c rename to test/test_fun2.c