尝试使用 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 的一个大进步!