...
This commit is contained in:
@@ -81,7 +81,7 @@ filename = sys.argv[1]
|
|||||||
|
|
||||||
index = clang.cindex.Index.create()
|
index = clang.cindex.Index.create()
|
||||||
|
|
||||||
tu = index.parse(filename, ["-x", "c"])
|
tu = index.parse(filename, ["-x", "c", "-std=c23"])
|
||||||
|
|
||||||
if tu.diagnostics:
|
if tu.diagnostics:
|
||||||
for diag in tu.diagnostics:
|
for diag in tu.diagnostics:
|
||||||
|
|||||||
134
examples/raylib/generate.py
Normal file
134
examples/raylib/generate.py
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import clang.cindex
|
||||||
|
from clang.cindex import CursorKind, TypeKind, Type
|
||||||
|
|
||||||
|
|
||||||
|
def map_type(clang_type: Type):
|
||||||
|
canonical = clang_type.get_canonical()
|
||||||
|
kind = canonical.kind
|
||||||
|
spelling = (
|
||||||
|
canonical.spelling.replace("const ", "")
|
||||||
|
.replace("volatile ", "")
|
||||||
|
.replace("restrict ", "")
|
||||||
|
)
|
||||||
|
|
||||||
|
if kind == TypeKind.POINTER:
|
||||||
|
pointee = canonical.get_pointee()
|
||||||
|
if pointee.kind == TypeKind.CHAR_S or pointee.kind == TypeKind.CHAR_U:
|
||||||
|
return "cstring"
|
||||||
|
|
||||||
|
if pointee.kind == TypeKind.FUNCTIONPROTO:
|
||||||
|
arg_types = []
|
||||||
|
|
||||||
|
for arg in pointee.get_canonical().argument_types():
|
||||||
|
arg_types.append(map_type(arg))
|
||||||
|
|
||||||
|
mapped_return = map_type(pointee.get_canonical().get_result())
|
||||||
|
args_str = ", ".join(arg_types)
|
||||||
|
|
||||||
|
return f"func({args_str}): {mapped_return}"
|
||||||
|
|
||||||
|
return f"^{map_type(pointee)}"
|
||||||
|
|
||||||
|
if kind == TypeKind.CONSTANTARRAY:
|
||||||
|
element_type = canonical.get_array_element_type()
|
||||||
|
size = canonical.get_array_size()
|
||||||
|
return f"[{size}]{map_type(element_type)}"
|
||||||
|
|
||||||
|
if kind == TypeKind.FUNCTIONPROTO or kind == TypeKind.FUNCTIONNOPROTO:
|
||||||
|
arg_types = []
|
||||||
|
|
||||||
|
for arg in canonical.argument_types():
|
||||||
|
arg_types.append(map_type(arg))
|
||||||
|
|
||||||
|
mapped_return = map_type(canonical.get_result())
|
||||||
|
args_str = ", ".join(arg_types)
|
||||||
|
|
||||||
|
return f"func({args_str}): {mapped_return}"
|
||||||
|
|
||||||
|
if kind == TypeKind.VOID:
|
||||||
|
return "void"
|
||||||
|
|
||||||
|
if kind == TypeKind.BOOL:
|
||||||
|
return "bool"
|
||||||
|
|
||||||
|
if kind in [TypeKind.CHAR_S, TypeKind.SCHAR]:
|
||||||
|
return "i8"
|
||||||
|
if kind == TypeKind.CHAR_U or kind == TypeKind.UCHAR:
|
||||||
|
return "u8"
|
||||||
|
if kind == TypeKind.SHORT:
|
||||||
|
return "i16"
|
||||||
|
if kind == TypeKind.USHORT:
|
||||||
|
return "u16"
|
||||||
|
if kind == TypeKind.INT:
|
||||||
|
return "i32"
|
||||||
|
if kind == TypeKind.UINT:
|
||||||
|
return "u32"
|
||||||
|
if kind in [TypeKind.LONG, TypeKind.LONGLONG]:
|
||||||
|
return "i64"
|
||||||
|
if kind in [TypeKind.ULONG, TypeKind.ULONGLONG]:
|
||||||
|
return "u64"
|
||||||
|
|
||||||
|
if kind == TypeKind.FLOAT:
|
||||||
|
return "f32"
|
||||||
|
if kind == TypeKind.DOUBLE or kind == TypeKind.LONGDOUBLE:
|
||||||
|
return "f64"
|
||||||
|
|
||||||
|
if kind == TypeKind.RECORD:
|
||||||
|
if not spelling.startswith("struct "):
|
||||||
|
raise Exception(f"Unknown custom type: {spelling}")
|
||||||
|
|
||||||
|
return spelling.replace("struct ", "")
|
||||||
|
|
||||||
|
raise Exception(f"Unresolved type: {spelling}")
|
||||||
|
|
||||||
|
|
||||||
|
if len(sys.argv) != 2:
|
||||||
|
print("Usage: python3 generate.py [path to header]", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
filename = sys.argv[1]
|
||||||
|
|
||||||
|
index = clang.cindex.Index.create()
|
||||||
|
|
||||||
|
tu = index.parse(filename, ["-x", "c", "-std=c23"])
|
||||||
|
|
||||||
|
if tu.diagnostics:
|
||||||
|
for diag in tu.diagnostics:
|
||||||
|
if diag.severity >= clang.cindex.Diagnostic.Error:
|
||||||
|
print(f"Error: {diag.spelling}", file=sys.stderr)
|
||||||
|
|
||||||
|
print(f'module "{os.path.basename(filename).split(".")[0]}"')
|
||||||
|
print()
|
||||||
|
|
||||||
|
for cursor in tu.cursor.walk_preorder():
|
||||||
|
if cursor.location.file and cursor.location.file.name != filename:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if cursor.kind == CursorKind.FUNCTION_DECL:
|
||||||
|
name = cursor.spelling
|
||||||
|
return_type = map_type(cursor.result_type)
|
||||||
|
|
||||||
|
params = []
|
||||||
|
for arg in cursor.get_arguments():
|
||||||
|
param_name = arg.spelling
|
||||||
|
param_type = map_type(arg.type)
|
||||||
|
params.append(f"{param_name}: {param_type}")
|
||||||
|
|
||||||
|
params_str = ", ".join(params)
|
||||||
|
|
||||||
|
print(f'export extern "{name}" func {name}({params_str}): {return_type}')
|
||||||
|
|
||||||
|
elif cursor.kind == CursorKind.STRUCT_DECL:
|
||||||
|
name = cursor.spelling
|
||||||
|
print(f"export struct {name}")
|
||||||
|
print("{")
|
||||||
|
for field in cursor.get_children():
|
||||||
|
if field.kind == CursorKind.FIELD_DECL:
|
||||||
|
field_name = field.spelling
|
||||||
|
field_type = map_type(field.type)
|
||||||
|
print(f" {field_name}: {field_type}")
|
||||||
|
else:
|
||||||
|
raise Exception(f"Unsupported child of struct: {field.spelling}")
|
||||||
|
print("}")
|
||||||
@@ -4,7 +4,7 @@ module "main"
|
|||||||
|
|
||||||
extern "main" func main(args: []cstring): i64
|
extern "main" func main(args: []cstring): i64
|
||||||
{
|
{
|
||||||
raylib::SetConfigFlags(raylib::FLAG_VSYNC_HINT | raylib::FLAG_WINDOW_RESIZABLE)
|
raylib::SetConfigFlags(4 | 64)
|
||||||
raylib::InitWindow(1600, 900, "Hi from nub-lang")
|
raylib::InitWindow(1600, 900, "Hi from nub-lang")
|
||||||
raylib::SetTargetFPS(240)
|
raylib::SetTargetFPS(240)
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ NUBC = ../../compiler/NubLang.CLI/bin/Debug/net9.0/nubc
|
|||||||
out: .build/out.o
|
out: .build/out.o
|
||||||
gcc -nostartfiles -lm -o out x86_64.s .build/out.o raylib-5.5_linux_amd64/lib/libraylib.a
|
gcc -nostartfiles -lm -o out x86_64.s .build/out.o raylib-5.5_linux_amd64/lib/libraylib.a
|
||||||
|
|
||||||
# .build/out.o: $(NUBC) main.nub raylib.nub
|
.build/out.o: $(NUBC) main.nub raylib.nub
|
||||||
# $(NUBC) main.nub raylib.nub
|
$(NUBC) main.nub raylib.nub
|
||||||
|
|
||||||
.build/out.o: $(NUBC) main.nub
|
raylib.nub:
|
||||||
$(NUBC) main.nub -h raylib-5.5_linux_amd64/include/raylib.h
|
python3 generate.py raylib-5.5_linux_amd64/include/raylib.h > raylib.nub
|
||||||
|
|
||||||
.PHONY: $(NUBC)
|
.PHONY: $(NUBC)
|
||||||
$(NUBC):
|
$(NUBC):
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user