#dynamic dispatch, interface etc.

1 messages · Page 1 of 1 (latest)

split galleon
#
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.

split galleon
#

I do not expect you do it for me, I would like a heads-up in case I am going completely the wrong way.

split galleon
#

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()});
}