Skip to content

Commit

Permalink
simple inheritance with base: ParentClass,
Browse files Browse the repository at this point in the history
  • Loading branch information
lassade committed Jun 9, 2023
1 parent 8602815 commit a8c0ad6
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 8 deletions.
6 changes: 2 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@ inspeired by this [article](https://floooh.github.io/2020/08/23/sokol-bindgen.ht

`zig cc -x c++ -std=c++11 -Xclang -ast-dump=json {input_file}`

- use `[*c]` for pointers
- parse fn ptr
- function pointers should be decorated with `callconv(.C)`
- parse fn ptr function pointers should be decorated with `callconv(.C)`
- write opaques if they didn't get defined at the end of the file
- use `@compileError` for objects that couldn't be transpiled
- hireitance using `base: ParentClass,`
- virtual functions and vtable
- peform layout validation

test with: other libraries from: https://github.com/godotengine/godot/tree/master/modules
Expand Down
28 changes: 24 additions & 4 deletions src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -139,19 +139,30 @@ const Transpiler = struct {
return;
}

var inner = value.*.object.get("inner");
if (inner == null) {
var ov_inner = value.*.object.get("inner");
if (ov_inner == null) {
log.warn("opaque `{s}`", .{name});
// try self.out.print("pub const {s} = anyopaque;\n", .{name});
return;
}

try self.out.print("pub const {s} = extern struct {{\n", .{name});

if (value.*.object.get("bases")) |v_bases| {
if (v_bases.array.items.len > 1) {
log.warn("multiple inheritance in `{s}`", .{name});
}
for (v_bases.array.items, 0..) |v_base, i| {
const parent_type = try self.transpileType(typeQualifier(&v_base).?);
defer self.allocator.free(parent_type);
try self.out.print(" base{d}: {s},\n\n", .{ i, parent_type });
}
}

var declbuf = std.ArrayList(u8).init(self.allocator);
defer declbuf.deinit();

for (inner.?.array.items) |inner_item| {
for (ov_inner.?.array.items) |inner_item| {
if (inner_item.object.get("isImplicit")) |implicit| {
if (implicit.bool) {
self.visited += nodeCount(&inner_item);
Expand All @@ -172,10 +183,17 @@ const Transpiler = struct {
}
}

var field_type = try self.transpileType(typeQualifier(&inner_item).?);
const field_type = try self.transpileType(typeQualifier(&inner_item).?);
defer self.allocator.free(field_type);
try self.out.print(" {s}: {s},\n", .{ field_name, field_type });
} else if (mem.eql(u8, kind_tag, "CXXMethodDecl")) {
if (inner_item.object.get("virtual")) |virtual| {
if (virtual.bool) {
// todo: handle virtual methods, add a `vtable: *const anyopaque,` in every other struct connected to this one
log.err("unhandleded vtable of virtual method in struct `{s}`", .{name});
}
}

const tmp = self.out;
self.out = declbuf.writer();
try self.visitCXXMethodDecl(&inner_item, name);
Expand Down Expand Up @@ -269,6 +287,8 @@ const Transpiler = struct {
}
}

// note: if the function has a `= 0` at the end it will have "pure" = true attribute

// todo: deal with inlined methods
// var inlined = false;
// if (value.*.object.get("inline")) |v_inline| {
Expand Down
22 changes: 22 additions & 0 deletions use_cases/common_cases/c005_inheritance.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
pub const vec2_t = extern struct {
x: f32,
y: f32,
};

pub const shape_t = extern struct {
vtable: *const anyopaque, // manually added

aabb: vec2_t,

extern fn _ZNK7shape_t4areaEv(self: *const shape_t) f32;
pub const area = _ZNK7shape_t4areaEv;
};

pub const circle_t = extern struct {
base0: shape_t,

radius: f32,

extern fn _ZNK8circle_t4areaEv(self: *const circle_t) f32;
pub const area = _ZNK8circle_t4areaEv;
};
18 changes: 18 additions & 0 deletions use_cases/common_cases/include/c005_inheritance.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
struct vec2_t {
float x;
float y;
};

class shape_t {
public:
vec2_t aabb;
virtual float area() const = 0;
};

class circle_t: public shape_t {
public:
virtual float area() const = 0;

private:
float radius;
};

0 comments on commit a8c0ad6

Please sign in to comment.