hi I am have a go background and struggling quite hard on interface in zig,
but I found a blog that is pretty close to what I am trying to do.
https://revivalizer.xyz/post/the-missing-zig-polymorphism-reference/
the issue is that it does not work , not with recent version of zig.
I changed ptrToInt to -> intFromPtr some var to const etc.
#dynamic dispatch, interface etc.
1 messages · Page 1 of 1 (latest)
const std = @import("std");
const int_ptr = usize;
const node = struct {
Object: int_ptr = undefined,
VirtualTable: *const virtual_table = undefined,
const virtual_table = struct {
Compute: fn(self: *node) i32,
};
pub fn Compute(self: *node) i32 {
return self.VirtualTable.Compute(self);
}
pub fn make(Object: anytype) node {
const ObjectPtrType = @TypeOf(Object);
return node {
.Object = @intFromPtr(Object),
.VirtualTable = &.{
.Compute = struct {
fn Compute(self: *node) i32 {
const TypedObject:ObjectPtrType = @ptrFromInt(self.Object);
return TypedObject.Compute();
}
}.Compute,
}
};
}
};
const operator_plus = struct {
Input1: *node = undefined,
Input2: *node = undefined,
pub fn Compute(self: *operator_plus) i32 {
return self.Input1.Compute() + self.Input2.Compute();
}
};
const operator_multiply = struct {
Input1: *node = undefined,
Input2: *node = undefined,
pub fn Compute(self: *operator_multiply) i32 {
return self.Input1.Compute() * self.Input2.Compute();
}
};
const literal_value = struct {
Value: i32 = undefined,
pub fn Compute(self: *literal_value) i32 {
return self.Value;
}
};
const square = struct {
Input: *node = undefined,
pub fn Compute(self: *square) i32 {
const Val = self.Input.Compute();
return Val*Val;
}
};
test "(2+3)*(4*5) == 100" {
const LiteralTwo = literal_value{ .Value = 2 };
const LiteralThree = literal_value{ .Value = 3 };
const LiteralFour = literal_value{ .Value = 4 };
const LiteralFive = literal_value{ .Value = 5 };
var NodeLiteralTwo = node.make(&LiteralTwo);
var NodeLiteralThree = node.make(&LiteralThree);
var NodeLiteralFour = node.make(&LiteralFour);
var NodeLiteralFive = node.make(&LiteralFive);
var Plus = operator_plus { .Input1 = &NodeLiteralTwo, .Input2 = &NodeLiteralThree };
var NodePlus = node.make(&Plus);
var Multiply = operator_multiply { .Input1 = &NodeLiteralFour, .Input2 = &NodeLiteralFive };
var NodeMultiply = node.make(&Multiply);
var Result = operator_multiply { .Input1 = &NodePlus, .Input2 = &NodeMultiply };
var NodeResult = node.make(&Result);
try std.testing.expectEqual(@as(i32, 100), NodeResult.Compute());
}
but it still refuses to run/test
dispatch.zig:20:35: error: expected pointer, found 'dispatch.literal_value'
~~ .Object = @intFromPtr(Object),~~
nvm I did a typo
My plan was to start from a working example and go into , tweak it to understand the "gears" but then I am bit stuck.
Is fixing the code a few little changes away at least ? or I just picked the wrong example ?
Thanks.
I do not expect you do it for me, I would like a heads-up in case I am going completely the wrong way.
did it, I do not know what I actually did but it works now :
const node = struct {
to_sub_node: To_opaque = undefined,
to_vtable: *const virtual_table = undefined,
const virtual_table = struct {
compute: fn(self: *const node) i32,
};
pub fn compute(self: *const node) i32 {
return self.to_vtable.compute(self);
}
pub fn make(to_sub_node: anytype) node {
// pub fn make(to_sub_node: *const anyopaque) node {
const To_sub_node= @TypeOf(to_sub_node);
return node {
.to_sub_node = @ptrCast(@alignCast(to_sub_node)),
.to_vtable = &.{ // a lambda function that
.compute = struct {
fn compute(self: *const node) i32 {
const to_typed_sub_node:To_sub_node= @ptrCast(@alignCast(self.to_sub_node));
return to_typed_sub_node.compute();
}
}.compute,
}
};
}
};
const operator_plus = struct {
Input1: *const node = undefined,
Input2: *const node = undefined,
pub fn compute(self: *const operator_plus) i32 {
return self.Input1.compute() + self.Input2.compute();
}
};
const operator_multiply = struct {
Input1: *const node = undefined,
Input2: *const node = undefined,
pub fn compute(self: *const operator_multiply) i32 {
return self.Input1.compute() * self.Input2.compute();
}
};
const literal_value = struct {
Value: i32 = undefined,
pub fn compute(self: *const literal_value) i32 {
return self.Value;
}
};
const square = struct {
Input: *const node = undefined,
pub fn compute(self: *square) i32 {
const Val = self.Input.compute();
return Val*Val;
}
};
// test "(2+3)*(4*5) == 100" {
pub fn main() !void {
const LiteralTwo = literal_value{ .Value = 2 };
const LiteralThree = literal_value{ .Value = 3 };
const LiteralFour = literal_value{ .Value = 4 };
const LiteralFive = literal_value{ .Value = 5 };
const NodeLiteralTwo = node.make(&LiteralTwo);
const NodeLiteralThree = node.make(&LiteralThree);
const NodeLiteralFour = node.make(&LiteralFour);
const NodeLiteralFive = node.make(&LiteralFive);
const Plus = operator_plus { .Input1 = &NodeLiteralTwo, .Input2 = &NodeLiteralThree };
const NodePlus = node.make(&Plus);
const Multiply = operator_multiply { .Input1 = &NodeLiteralFour, .Input2 = &NodeLiteralFive };
const NodeMultiply = node.make(&Multiply);
const Result = operator_multiply { .Input1 = &NodePlus, .Input2 = &NodeMultiply };
const NodeResult = node.make(&Result);
try std.testing.expectEqual(@as(i32, 100), NodeResult.compute());
std.debug.print("{}",.{NodeResult.compute()});
}