#recursive struct parsing

1 messages · Page 1 of 1 (latest)

empty wraith
#

how could I implement this?

    const Operand = union(enum) {
        bool: bool,
        int: i32,
        float: f32,
        string: []const u8,
        @"struct",

        fn initContextValue(key: []const u8, ctx: anytype) !Operand {
            switch (@typeInfo(@TypeOf(ctx))) {
                .Struct => |@"struct"| {
                    inline for (@"struct".fields) |field| if (mem.eql(u8, field.name, key)) {
                        switch (@typeInfo(field.type)) {
                            .Struct => return .@"struct",
                            else => {
                                log.err("`ctx.{s}`: unsupported type {s}", .{ key, @typeName(field.type) });
                                return error.Context;
                            },
                        }
                    };

                    log.err("`ctx` does not have field '{s}'", .{key});
                    return error.Context;
                },

                else => unreachable,
            }
        }
    };
};

elsewhere, passing in this value as ctx: .{ .foo = .{ .bar = "Hello" } }.

    fn evalIdentifierNode(self: *Interpreter, node: Ast.Node, stack_top: usize, ctx: anytype) anyerror!Operand {
        const value = self.ast.tokenValue(node.token);
        var lhs = try Operand.initContextValue(value, ctx);
        // first we init an Operand.struct with `foo` value

        while (stack.popOrNull()) |rhs| {
                .field_access => switch (lhs) {
                    .@"struct" => {
                    // TODO this attempts to search for `ctx.bar`, but needs to search for `ctx.foo.bar`. can infinitely recurse
                        return try Operand.initContextValue(self.ast.tokenValue(rhs.data.rhs), ctx)
                    },
                    else => {
                        log.err("Unexpected {s} node", .{@tagName(rhs.type)});
                        return error.UnexpectedNode;
                    },
                },
        }
}
empty wraith
#

any helpers? what context do I need to provide

#

I cnt use @field because value isnt comptime-known

worthy marlin
#

Wait so what exactly is the problem?