From 9244bd106d72ac365e037a52b8a5deff4d29e88e Mon Sep 17 00:00:00 2001 From: David Gonzalez Martin Date: Mon, 8 Apr 2024 19:45:13 -0600 Subject: [PATCH] Basic polymorphic function --- bootstrap/Compilation.zig | 19 +++++++++++++++++++ lib/std/data_structures/pinned_array.nat | 10 ++++++++++ test/standalone/pinned_array/main.nat | 8 ++++---- test/standalone/sliceable/main.nat | 1 + test/standalone/sliceable_simple/main.nat | 17 +++++++++++++++++ 5 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 test/standalone/sliceable_simple/main.nat diff --git a/bootstrap/Compilation.zig b/bootstrap/Compilation.zig index 5c61d44..c489d1c 100644 --- a/bootstrap/Compilation.zig +++ b/bootstrap/Compilation.zig @@ -6625,6 +6625,8 @@ pub const Builder = struct { _ = &scope; const type_index = global_scope.type; assert(type_index != .null); + const ty = unit.types.get(type_index); + assert(ty.* != .polymorphic); return type_index; } }, @@ -10920,6 +10922,20 @@ pub const Builder = struct { else => |t| @panic(@tagName(t)), }, }, + .@"struct" => |struct_index| switch (unit.structs.get(struct_index).kind) { + .@"struct" => |*struct_type| if (struct_type.options.sliceable) |sliceable| b: { + const field_index = struct_type.fields.slice()[sliceable.pointer]; + const field = unit.struct_fields.get(field_index); + const child_pointer_type = field.type; + const pointer_type = unit.types.get(field.type).pointer; + const child_base_type = pointer_type.type; + const v = try builder.build_slice_indexed_access(unit, context, array_like_expression, pointer.type, child_pointer_type, child_base_type, pointer_type.mutability, sliceable, index); + break :b v; + } else { + unreachable; + }, + else => |t| @panic(@tagName(t)), + }, else => |t| @panic(@tagName(t)), }, }, @@ -12056,6 +12072,7 @@ pub const Builder = struct { } } else { const look_in_parent_scopes = false; + if (struct_type.scope.scope.lookupDeclaration(right_identifier_hash, look_in_parent_scopes)) |lookup| { const right_symbol = try builder.referenceGlobalDeclaration(unit, context, lookup.scope, lookup.declaration, .{}, &.{}); switch (right_symbol.initial_value) { @@ -12116,6 +12133,8 @@ pub const Builder = struct { else => |t| @panic(@tagName(t)), } } else { + const id = unit.getIdentifier( struct_type.scope.scope.declarations.key_pointer[0]); + _ = id; // autofix unreachable; } } diff --git a/lib/std/data_structures/pinned_array.nat b/lib/std/data_structures/pinned_array.nat index 993ed30..8c59613 100644 --- a/lib/std/data_structures/pinned_array.nat +++ b/lib/std/data_structures/pinned_array.nat @@ -1,5 +1,15 @@ +const std = #import("std"); +const assert = std.assert; + const PinnedArray = struct(.{ .sliceable = true }, $T) { pointer: [&]T = #cast(0), length: u32 = 0, capacity: u32 = 0, + + const append_with_capacity = fn (pinned_array: &Self, item: T) void { + const index = pinned_array.length; + assert(index < pinned_array.capacity); + pinned_array.length += 1; + pinned_array[index] = item; + } }; diff --git a/test/standalone/pinned_array/main.nat b/test/standalone/pinned_array/main.nat index 03c6c4c..5013d48 100644 --- a/test/standalone/pinned_array/main.nat +++ b/test/standalone/pinned_array/main.nat @@ -9,8 +9,8 @@ const main = fn () *!void { .length = 0, .capacity = 1, }; - //const n = 5; - //pinned_array.append_with_capacity(n); - //try expect(pinned_array.length == 1); - //try expect(pinned_array[0] == n); + const n = 5; + pinned_array.append_with_capacity(n); + try expect(pinned_array.length == 1); + try expect(pinned_array[0] == n); } diff --git a/test/standalone/sliceable/main.nat b/test/standalone/sliceable/main.nat index 936bcc8..19d1349 100644 --- a/test/standalone/sliceable/main.nat +++ b/test/standalone/sliceable/main.nat @@ -27,4 +27,5 @@ const main = fn () *!void { try expect(s.length == 1); try expect(foo[0] == 5); + try expect(s[0] == 5); } diff --git a/test/standalone/sliceable_simple/main.nat b/test/standalone/sliceable_simple/main.nat new file mode 100644 index 0000000..fc2e1a6 --- /dev/null +++ b/test/standalone/sliceable_simple/main.nat @@ -0,0 +1,17 @@ +const std = #import("std"); +const assert = std.assert; +const expect = std.testing.expect; + +const Foo = struct(.{ .sliceable = true }) { + pointer: [&]u32, + length: u32, +}; + +const main = fn () *!void { + var foo = [1]u32{123}; + var f = Foo{ + .pointer = foo.&, + .length = foo.length, + }; + try expect(f[0] == foo[0]); +}