Add support for array.len pseudo-field

This commit is contained in:
jaina heartles 2022-12-14 02:57:27 -08:00
parent 73ba42d2d5
commit 27ee0ecd5d
1 changed files with 15 additions and 4 deletions

View File

@ -215,6 +215,17 @@ fn print(writer: anytype, arg: anytype) !void {
const ExpressionError = error{ IndexOutOfBounds, NullOptional };
fn Deref(comptime T: type, comptime field: []const u8) type {
if (std.meta.trait.isIndexable(T) and std.mem.eql(u8, field, "len")) return usize;
switch (@typeInfo(T)) {
.Pointer => return Deref(std.meta.Child(T), field),
.Struct => |info| for (info.fields) |f| {
if (std.mem.eql(u8, field, f.name)) return f.field_type;
} else @compileError("Field " ++ field ++ " does not exist on type " ++ @typeName(T)),
else => @compileError("Cannot retrieve field " ++ field ++ " from type " ++ @typeName(T)),
}
}
fn EvaluateExpression(
comptime expression: Expression,
comptime Args: type,
@ -227,9 +238,7 @@ fn EvaluateExpression(
.context => Context,
.deref => |expr| {
const T = EvaluateExpression(expr.container, Args, Captures, Context);
for (@typeInfo(T).Struct.fields) |f| {
if (std.mem.eql(u8, expr.field, f.name)) return f.field_type;
} else @compileError("Field " ++ expr.field ++ " does not exist on type " ++ @typeName(T));
return Deref(T, expr.field);
},
.equals => bool,
.builtin => |call| switch (call.*) {
@ -300,12 +309,14 @@ fn AddCapture(comptime Root: type, comptime name: []const u8, comptime Val: type
.alignment = @alignOf(Val),
}};
return @Type(.{ .Struct = .{
const Result = @Type(.{ .Struct = .{
.layout = .Auto,
.fields = fields,
.decls = &.{},
.is_tuple = false,
} });
return Result;
}
fn addCapture(root: anytype, comptime name: []const u8, val: anytype) AddCapture(@TypeOf(root), name, @TypeOf(val)) {