24a's blog
0x24a's personal blog website.
首页
关于
文章分类
按月归档
常用标签
友情链接
记给SBLang2C实现跨文件导入的过程
2023-08-20 |0x24a | 默认分类

尝试使用 extern

  尽管我没学过 C ++, 但我知道有 extern 这个关键字,可以让编译器从其他文件找到变量的内容。
一开始试图采用import {} from {}的语法,即为将其他的 SBLang 文件编译为头文件后,在 g ++ 编译最终文件时链接起来。
经过测试,无论怎么修改,结果只有两种:访问的是无效变量或报错。
由于 extern 太复杂,我尝试通过将其他 SBLang 转换为 C ++ 头文件后,在主程序内 include。
实现代码如下:

def fromimport(runtime,line):
    runtime.externs.add(line[1])

然后在编译器 (sblang2c.py) 中:

print('-| Resolving externs')
links=[]
mapping={}
if len(runtime.externs) == 0:
    print("-| No externs")
else:
    runtime.externs=list(runtime.externs)
    print(f"-| Compiling {len(runtime.externs)} head(s)")
    for count in range(1,len(runtime.externs)+1):
        print(f"- -|{count}/{len(runtime.externs)}: {runtime.externs[count-1]}")
        filename=f"_sblang_header_{secrets.token_hex(16)}.h"
        temps.append(filename)
        with open(runtime.externs[count-1],"r",encoding="utf-8") as f:
            modcode=f.read()
        with open(filename,"w+") as f:
            rt=converter.Runtime()
            try:
                for i in modcode.splitlines():
                    rt.translate(i)
            except BaseException as e:
                print(f"\n! Error when converting: {e}")
                from traceback import print_exc
                print_exc()
                exit(1)
            rt.heads=[]
            f.write(rt.export_final())
            if rt.externs != []:
                print("WARN: Multi-layer extern is not supported yet, ignoring.")
        mapping.update({runtime.externs[count-1]:filename})
        print(f"- -|{count}/{len(runtime.externs)}: {runtime.externs[count-1]}: Success")
new=[]
for i in runtime.externs:
    data=mapping.get(i,i)
    if data != i:
        data=os.getcwd()+"/"+data
    runtime.heads.add(data)

注:这里os.getcwd()+"/"+data是因为经过测试,只有使用绝对路径 G ++ 才能正确的同时编译头文件。

开始跑测试。
import.sbl

main
    import import_head.sbl
    output "1+1="
    output plusOne(1)
end

import_head.sbl

define plusOne num
    return (1+num)
define end
python3 sblang2c.py --gcc-binary=/opt/homebrew/bin/g++-13 --debug import.sbl
SBLang2C Compiler and converter v0.0.2-dev-2
-| Reading File 0.13995 ms
-| Converting to C++
- -| Creating Runtime 0.0031 ms
- -| Converting
DEBUG:root:Running Dynamic Command: main
DEBUG:root:Running Dynamic Command: import
DEBUG:root:Running Dynamic Command: output
DEBUG:root:Running Dynamic Command: output

 0.09823 ms
-| Resolving externs
-| Compiling 1 head(s)
- -|1/1: import_head.sbl
DEBUG:root:Running Dynamic Command: define
DEBUG:root:Function Info:
DEBUG:root:Running Checker:return (1+num)
DEBUG:root:{'DEFINEING': True, 'DEFINE_DATA': {'name': 'plusOne', 'args': ['auto num'], 'lines': []}}
DEBUG:root:Running Dynamic Command: return
DEBUG:root:Added: {'name': 'plusOne', 'args': ['auto num'], 'lines': ['return (1+num);']}
DEBUG:root:Stopped by Global-Checker
DEBUG:root:Running Checker:define end
DEBUG:root:Generated Program:auto plusOne(auto num){
return (1+num);}
DEBUG:root:Stopped by Global-Checker
DEBUG:root:Exporting....
DEBUG:root:Headers: []
- -|1/1: import_head.sbl: Success
- -| Writing to temp file
DEBUG:root:Exporting....
DEBUG:root:Headers: {'/Users/0x24a/Desktop/Projects/SBLang2C/tests/_sblang_header_720038921a2546135b37567b58b5aae4.h', 'bits/stdc++.h'}

 0.09298 ms
-| Compiling with g++
- -| Awaiting G++ execute 1371.68694 ms
-| Removeing Tempfile
-| Exiting Compile.
➜  tests git:(main) ✗ ./import
1+1=2

这里虽然仅仅输出了“1+1=2”, 但这个 "2" 是从其他文件获得的,这是 SBLang2C 的一个大进步!

技术
Python
respond-post-6

添加新评论

请填写称呼
请填写合法的电子邮箱地址
请填写合法的网站地址
请填写内容