authorchloe caruso <git@paperclover.net> 2025-02-22 17:26:13-08:00
committerchloe caruso <git@paperclover.net> 2025-02-22 18:30:48-08:00
log79de6d7ec05e2811a2acc459ed5f28d4cf454348
treeddf4e5227a44edc0c4d323de27f076584bee8a11
parent2bcfa5e47db1ba080d7add7d2cd7a59e0e249bd1

upgrade zig


17 files changed, 86 insertions(+), 77 deletions(-)

build.zig+16-3
......@@ -236,9 +236,8 @@ fn createModuleTests(module: *Build.Module, options: Options) *Build.Step.Compil
236236}
237237
238238pub fn build(b: *Build) !void {
239 b.reference_trace = 32;
240
241 const target = b.standardTargetOptions(.{});
239 var target = b.standardTargetOptions(.{});
240 var host = b.graph.host;
242241
243242 // I disagree with how the standard optimize flag works
244243 const optimize_fallback = switch (b.release_mode) {
......@@ -272,6 +271,12 @@ pub fn build(b: *Build) !void {
272271 "Experiment with the Zig self-hosted backends",
273272 ) orelse false;
274273
274 if (no_llvm) {
275 if (b.user_input_options.getPtr("target") == null)
276 target = mapTargetForSelfHosted(target);
277 host = mapTargetForSelfHosted(host);
278 }
279
275280 const have_embedded_quickjs = b.option(
276281 bool,
277282 "quickjs",
......@@ -599,6 +604,14 @@ fn crossTarget(cpu_arch: std.Target.Cpu.Arch, os_tag: std.Target.Os.Tag) Build.R
599604 };
600605}
601606
607fn mapTargetForSelfHosted(target: Build.ResolvedTarget) Build.ResolvedTarget {
608 if (target.result.os.tag == .macos and target.result.cpu.arch == .aarch64) {
609 var mut = target;
610 mut.result.cpu = std.Target.Cpu.baseline(.x86_64, target.result.os);
611 }
612 return target;
613}
614
602615pub const PathOrString = union(enum) {
603616 path: LazyPath,
604617 string: []const u8,
build.zig.zon+2-2
......@@ -7,8 +7,8 @@
77 .dependencies = .{
88 // Used to determine unicode properties to tokenize identifiers
99 .zg = .{
10 .url = "https://codeberg.org/dude_the_builder/zg/archive/c425c9c8511bf92e14b8b612d1d16e774b186f2e.tar.gz",
11 .hash = "1220c79009f1e443b015db4de6e5319432538ead2fea10d271f3f35d3ae83c996789",
10 .url = "https://codeberg.org/atman/zg/archive/4a002763419a34d61dcbb1f415821b83b9bf8ddc.tar.gz",
11 .hash = "1220f3e29bc40856bfc06e0ee133f814b0011c76de987d8a6a458c2f34d82708899a",
1212 },
1313 // Optional: Used for tracing
1414 .tracer = .{
doc/language-manual.md+1-2
......@@ -1,7 +1,6 @@
11# Ix Programming Language
22
3Ix (**I**nferable E**x**pression) is a high-level programming language for
4developing web applications and games.
3Ix (**I**nferable E**x**pression) is an experimental programming language.
54
65Key goals of this project are:
76
src/Cli.zig+10-10
......@@ -5,6 +5,8 @@
55//!
66//! See `fn main` for a basic usage example. Parsing subcommands is done in
77//! `main.zig`, utilizing a different `Cli` for each option set.
8const Cli = @This();
9
810options: []const Option,
911positionals: Positionals,
1012help: HelpConfig = .{},
......@@ -57,14 +59,15 @@ pub const Positionals = union(enum) {
5759 /// Store the start and count of positionals. Call
5860 /// 'parsed.positionals.iterator(args)' with the
5961 /// original argument array to read positionals.
60 unlimited,
61 /// Same strategy as .unlimited, with a limit
6262 limited: usize,
6363 /// Use a bounded array to store positionals, using
6464 /// a stack allocated buffer that can hold enough
6565 /// '[]const u8's as allowed by the bound.
6666 bounded: usize,
6767
68 /// Shorthand for an unlimited amount of positionals.
69 const unlimited: Positionals = .{ .limited = std.math.maxInt(usize) };
70
6871 pub fn Type(p: Positionals) type {
6972 return switch (p) {
7073 .none => void,
......@@ -73,7 +76,6 @@ pub const Positionals = union(enum) {
7376 0 => void,
7477 else => Multi,
7578 },
76 .unlimited => Multi,
7779 .bounded => |n| std.BoundedArray([]const u8, n),
7880 };
7981 }
......@@ -83,7 +85,6 @@ pub const Positionals = union(enum) {
8385 .none => 0,
8486 .single => 1,
8587 inline .limited, .bounded => |limit| limit,
86 .unlimited => std.math.maxInt(usize),
8788 };
8889 }
8990
......@@ -188,7 +189,7 @@ pub fn Parsed(p: Cli) type {
188189 field.* = .{
189190 .name = fieldName(def.name),
190191 .alignment = @alignOf(Wrapped),
191 .default_value = &@as(Wrapped, null),
192 .default_value_ptr = &@as(Wrapped, null),
192193 .is_comptime = false,
193194 .type = Wrapped,
194195 };
......@@ -199,10 +200,10 @@ pub fn Parsed(p: Cli) type {
199200 .name = "positionals",
200201 .alignment = @alignOf(Pos),
201202 .type = Pos,
202 .default_value = &@as(Pos, switch (p.positionals) {
203 .default_value_ptr = &@as(Pos, switch (p.positionals) {
203204 .none => {},
204205 .single => null,
205 .limited, .unlimited => .empty,
206 .limited => .empty,
206207 .bounded => .{},
207208 }),
208209 .is_comptime = false,
......@@ -466,7 +467,7 @@ pub fn parseWithErrorWriter(
466467 else
467468 null,
468469 .bounded => out.positionals, // already correct
469 .unlimited, .limited => if (max_positionals > 0) .{
470 .limited => if (max_positionals > 0) .{
470471 .first = first_positional,
471472 .len = positionals_counted,
472473 .first_is_after_double_dash = if (double_dash) |dd|
......@@ -662,7 +663,7 @@ pub fn main() !void {
662663 std.debug.print("--enum: {any}\n", .{parsed.@"enum"});
663664 std.debug.print("positionals({d}):\n", .{parsed.positionals.len});
664665
665 // if using '.positionals = .unlimited'
666 // if using '.positionals = .limited'
666667 // var it = parsed.positionals.iterator(args[1..]);
667668 // while (it.next()) |item| {
668669 // std.debug.print(" - {s}\n", .{item});
......@@ -673,7 +674,6 @@ pub fn main() !void {
673674 }
674675}
675676
676const Cli = @This();
677677const std = @import("std");
678678const mem = std.mem;
679679const Type = std.builtin.Type;
src/core/Ast.zig+1-1
......@@ -351,7 +351,7 @@ pub const Node = struct {
351351 });
352352
353353 pub const Data = union {
354 none: struct { Unused = .zero, Unused = .zero },
354 none: struct { a: Unused = .zero, b: Unused = .zero },
355355 function: struct {
356356 /// A `Fn`
357357 extra: ExtraIndex,
src/core/Comp.zig+3-6
......@@ -322,8 +322,9 @@ pub const File = struct {
322322 return source;
323323 }
324324
325 // Keep track of inode, file size, mtime, hash so we can detect which files
326 // have been modified when an incremental update is requested.
325 // Keep track of inode, file size, mtime, hash so the incremental
326 // compiler can detect which files have been modified when an
327 // incremental update is requested.
327328 var f = try std.fs.openFileAbsolute(file.file_path, .{});
328329 defer f.close();
329330
......@@ -338,10 +339,6 @@ pub const File = struct {
338339 if (amt != stat.size)
339340 return error.UnexpectedEndOfFile;
340341
341 // Here we do not modify stat fields because this function is the one
342 // used for error reporting. We need to keep the stat fields stale so that
343 // transformFile can know to regenerate Hir.
344
345342 const loaded_source: Source = .{
346343 .code = source,
347344 .stat = .{
src/core/InternPool.zig+8-7
......@@ -25,10 +25,10 @@ map: std.AutoArrayHashMapUnmanaged(void, void) = .empty,
2525items: std.MultiArrayList(Item) = .empty,
2626extra: Extra = .empty,
2727
28/// In order to store references to strings in fewer bytes, we copy all
29/// string bytes into here. String bytes can be null. It is up to whoever
30/// is referencing the data here whether they want to store both index and length,
31/// thus allowing null bytes, or store only index, and use null-termination. The
28/// In order to store references to strings in fewer bytes, all string bytes are
29/// placed here. String bytes can be null. It is up to whoever is referencing
30/// the data here whether they want to store both index and length, thus
31/// allowing null bytes, or store only index, and use null-termination. The
3232/// `string_bytes` array is agnostic to either usage.
3333string_bytes: std.ArrayListUnmanaged(u8) = .empty,
3434
......@@ -451,6 +451,7 @@ pub const Type = enum(u32) {
451451 };
452452
453453 pub const Slice = Extra.Slice(Type);
454 const y = Slice{};
454455
455456 pub fn value(ty: Type) Value {
456457 return @enumFromInt(@intFromEnum(ty));
......@@ -1712,7 +1713,7 @@ pub fn addDependency(ip: *InternPool, gpa: Allocator, depender: AnalysisUnit, de
17121713 }
17131714
17141715 // Prepend a new dependency.
1715 const new_index: DepEntry.Index, const ptr = if (ip.free_dep_entries.popOrNull()) |new_index| new: {
1716 const new_index: DepEntry.Index, const ptr = if (ip.free_dep_entries.pop()) |new_index| new: {
17161717 break :new .{ new_index, &ip.dep_entries.items[@intFromEnum(new_index)] };
17171718 } else .{ @enumFromInt(ip.dep_entries.items.len), ip.dep_entries.addOneAssumeCapacity() };
17181719 ptr.next = if (gop.found_existing) gop.value_ptr.*.toOptional() else .none;
......@@ -1751,7 +1752,7 @@ pub fn createDecl(
17511752 const t = tracer.trace(@src());
17521753 defer t.end();
17531754
1754 if (ip.decls_free_list.popOrNull()) |index| {
1755 if (ip.decls_free_list.pop()) |index| {
17551756 ip.allocated_decls.at(@intFromEnum(index)).* = initialization;
17561757 return index;
17571758 }
......@@ -1779,7 +1780,7 @@ pub fn createNamespace(
17791780 const t = tracer.trace(@src());
17801781 defer t.end();
17811782
1782 if (ip.namespaces_free_list.popOrNull()) |index| {
1783 if (ip.namespaces_free_list.pop()) |index| {
17831784 ip.allocated_namespaces.at(@intFromEnum(index)).* = initialization;
17841785 return index;
17851786 }
src/core/Sema.zig+3-3
......@@ -172,7 +172,7 @@ const Frame = struct {
172172 data: Data,
173173
174174 const Data = union {
175 pub const none = .{ .undefined = {} };
175 pub const none: Data = .{ .undefined = {} };
176176
177177 undefined: void,
178178 conditional: Conditional,
......@@ -961,7 +961,7 @@ fn stepInner(s: *Sema, comptime tag: Hir.Tag) Error!InstructionKind.fromTag(tag)
961961 const data: Hir.Func = s.frame.currentPayload(.func);
962962 const reserve = try s.scratch.reserveMulti(
963963 s.arena(),
964 .{ .params = Type, .captures = Air.Inst.Ref },
964 FunctionReserve.reserve_types,
965965 .{ data.params.len, data.captures.len },
966966 );
967967 if (data.captures.len > 0) @panic("TODO: captures");
......@@ -2453,7 +2453,7 @@ fn pushFrame(s: *Sema) !void {
24532453}
24542454
24552455fn popFrame(s: *Sema) void {
2456 s.frame = s.frame_stack.pop();
2456 s.frame = s.frame_stack.pop() orelse unreachable;
24572457}
24582458
24592459fn addIndexUntracked(s: *Sema, comptime tag: Air.Inst.Tag, data: tag.Data()) !Air.Inst.Index {
src/core/Tokenizer.zig+2-2
......@@ -275,8 +275,8 @@ pub const Token = struct {
275275 }
276276 };
277277
278 /// Instead of storing the length of a token, we can recompute this
279 /// information on demand, as it is not often needed.
278 /// Instead of storing the length of a token, it's recomputed on demand by
279 /// tokenizing the text. This trade-off was done to preserve memory.
280280 ///
281281 /// When computing the length of something that can be known without
282282 /// the source code, use token.tag.staticLen() instead.
src/core/Transform.zig+12-13
......@@ -369,18 +369,18 @@ const BuiltIn = struct {
369369};
370370
371371const built_in_ids = std.StaticStringMap(BuiltIn).initComptime(.{
372 .{ "void", .{ .value = .void, .type = .void } },
373 .{ "true", .{ .value = .bool_true, .type = .bool_type } },
374 .{ "false", .{ .value = .bool_false, .type = .bool_type } },
375 .{ "int", .{ .value = .int32_type, .type = .type_type } },
376 .{ "float", .{ .value = .float_type, .type = .type_type } },
377 .{ "string", .{ .value = .string_type, .type = .type_type } },
378 .{ "opaque", .{ .value = .opaque_type, .type = .type_type } },
379 // .{ "bigint", .{ .value = .bigint_type, .type = .type_type } },
380 .{ "bool", .{ .value = .bool_type, .type = .type_type } },
381 .{ "never", .{ .value = .never_type, .type = .type_type } },
382 .{ "type", .{ .value = .type_type, .type = .type_type } },
383 // .{ "std", .{ .value = .standard_library, .type = ... } },
372 .{ "void", BuiltIn{ .value = .void, .type = .void } },
373 .{ "true", BuiltIn{ .value = .bool_true, .type = .bool_type } },
374 .{ "false", BuiltIn{ .value = .bool_false, .type = .bool_type } },
375 .{ "int", BuiltIn{ .value = .int32_type, .type = .type_type } },
376 .{ "float", BuiltIn{ .value = .float_type, .type = .type_type } },
377 .{ "string", BuiltIn{ .value = .string_type, .type = .type_type } },
378 .{ "opaque", BuiltIn{ .value = .opaque_type, .type = .type_type } },
379 // .{ "bigint", BuiltIn{ .value = .bigint_type, .type = .type_type } },
380 .{ "bool", BuiltIn{ .value = .bool_type, .type = .type_type } },
381 .{ "never", BuiltIn{ .value = .never_type, .type = .type_type } },
382 .{ "type", BuiltIn{ .value = .type_type, .type = .type_type } },
383 // .{ "std", BuiltIn{ .value = .standard_library, .type = ... } },
384384});
385385
386386fn transformModule(t: *Transform, module_node: NodeIndex) Allocator.Error!Inst.Index {
......@@ -412,7 +412,6 @@ fn transformModule(t: *Transform, module_node: NodeIndex) Allocator.Error!Inst.I
412412 defer t.gpa.free(decls);
413413
414414 {
415 // `transformDecl` is not allowed to mutate symbols as we rely on the stable value.
416415 s.symbols.lockPointers();
417416 defer s.symbols.unlockPointers();
418417
src/core/array.zig+14-16
......@@ -90,7 +90,7 @@ pub const StoreKind = enum {
9090
9191 pub fn ResolvedStore(kind: StoreKind, Owner: type) type {
9292 const ptr = @typeInfo(Owner).pointer;
93 assert(ptr.size == .One);
93 assert(ptr.size == .one);
9494 const mutability = brk: for (@typeInfo(ptr.child).@"struct".fields) |field| {
9595 if (std.mem.eql(u8, field.name, "extra")) {
9696 break :brk field.type.mutability;
......@@ -100,7 +100,7 @@ pub const StoreKind = enum {
100100 }
101101
102102 pub fn ResolvedStorePtr(kind: StoreKind, Owner: type) type {
103 return kind.ItemPointer(Owner, .One, kind.ResolvedStore(Owner));
103 return kind.ItemPointer(Owner, .one, kind.ResolvedStore(Owner));
104104 }
105105
106106 pub fn ItemPointer(
......@@ -110,18 +110,16 @@ pub const StoreKind = enum {
110110 child: type,
111111 ) type {
112112 const ptr = @typeInfo(Owner).pointer;
113 return @Type(.{
114 .pointer = .{
115 .size = size,
116 .is_const = ptr.is_const or ResolvedStore(kind, Owner).mutability == .@"const",
117 .is_volatile = false,
118 .is_allowzero = false,
119 .alignment = @alignOf(child),
120 .address_space = .generic,
121 .child = child,
122 .sentinel = null,
123 },
124 });
113 return @Type(.{ .pointer = .{
114 .size = size,
115 .is_const = ptr.is_const or ResolvedStore(kind, Owner).mutability == .@"const",
116 .is_volatile = false,
117 .is_allowzero = false,
118 .alignment = @alignOf(child),
119 .address_space = .generic,
120 .child = child,
121 .sentinel_ptr = null,
122 } });
125123 }
126124};
127125
......@@ -264,7 +262,7 @@ pub fn Store(set_kind: StoreKind, set_mutability: Mutability) type {
264262 .len = 0,
265263 };
266264
267 pub fn get(slice: @This(), owner: anytype) kind.ItemPointer(@TypeOf(owner), .Slice, T) {
265 pub fn get(slice: @This(), owner: anytype) kind.ItemPointer(@TypeOf(owner), .slice, T) {
268266 return @ptrCast(kind.resolveStore(owner).list.items[slice.start..][0..slice.len]);
269267 }
270268
......@@ -448,7 +446,7 @@ pub fn Store(set_kind: StoreKind, set_mutability: Mutability) type {
448446
449447 pub fn appendSlice(store: *Self, gpa: Allocator, data: anytype) !Slice(std.meta.Child(@TypeOf(data))) {
450448 const idx = store.list.items.len;
451 comptime assert(@typeInfo(@TypeOf(data)).pointer.size == .Slice);
449 comptime assert(@typeInfo(@TypeOf(data)).pointer.size == .slice);
452450 comptime assert(@typeInfo(@TypeOf(data)).pointer.alignment == @alignOf(u32));
453451 comptime assert(@sizeOf(@TypeOf(data[0])) == @sizeOf(u32));
454452 comptime assert(@alignOf(@TypeOf(data[0])) == @alignOf(u32));
src/core/js/Link.zig+4-4
......@@ -677,10 +677,10 @@ fn writeString(decoded: []const u8, writer: Writer) !void {
677677 text = text[width..];
678678
679679 switch (c) {
680 // Special-case the bell character since it may cause dumping this file to
681 // the terminal to make a sound, which is undesirable. Note that we can't
682 // use an octal literal to print this shorter since octal literals are not
683 // allowed in strict mode (or in template strings).
680 // Special-case the bell character since it may cause dumping this
681 // file to the terminal to make a sound, which is undesirable. Note
682 // that an octal literal to print this shorter since octal literals
683 // are not allowed in strict mode (or in template strings).
684684 0x07 => {
685685 try writer.writeAll("\\x07");
686686 },
src/core/js/NodeGen.zig+1-1
......@@ -456,7 +456,7 @@ fn codeGenInst(c: *NodeGen, inst: Air.Inst.Index) Error!void {
456456 // of a block.
457457 //
458458 // This is also required for the main function, which cannot return
459 // anything. We don't want to emit return instructions here.
459 // anything, so this prevents that invalid codegen.
460460 const main_insts = c.air.instData(.block, .main_block).get(&c.air);
461461 if (main_insts[main_insts.len - 1] == inst) {
462462 return;
src/core/stack.zig+4-2
......@@ -104,6 +104,8 @@ pub fn Stack(comptime Base: type) type {
104104 starts: [fields.len]u32,
105105 lengths: [fields.len]u32,
106106
107 pub const reserve_types = types;
108
107109 fn Type(comptime field: FieldEnum) type {
108110 return @field(types, @tagName(field));
109111 }
......@@ -156,10 +158,10 @@ pub fn Stack(comptime Base: type) type {
156158 stack: *Self,
157159 allocator: Allocator,
158160 comptime types: anytype,
159 lengths: [std.meta.fields(@TypeOf(types)).len]u32,
161 lengths: [@typeInfo(@TypeOf(types)).@"struct".fields.len]u32,
160162 ) !ReserveMulti(types) {
161163 var all_lengths: usize = 0;
162 var starts: [std.meta.fields(@TypeOf(types)).len]u32 = undefined;
164 var starts: [@typeInfo(@TypeOf(types)).@"struct".fields.len]u32 = undefined;
163165 const start = stack.list.items.len;
164166 inline for (lengths, &starts) |len, *slice_start| {
165167 slice_start.* = @intCast(start + all_lengths);
src/core/unicode_props.zig+3-3
......@@ -6,7 +6,7 @@ const tracer = @import("tracer");
66var props: ?PropsData = undefined;
77var props_memory: []u8 = undefined;
88
9const raw_allocator = if (@import("builtin").target.isWasm())
9const raw_allocator = if (@import("builtin").target.cpu.arch.isWasm())
1010 std.heap.wasm_allocator
1111else
1212 std.heap.page_allocator;
......@@ -17,9 +17,9 @@ pub fn init() !void {
1717 const trace = tracer.trace(@src());
1818 defer trace.end();
1919
20 // We know exactly how much this uses, so let's preallocate these pages and use a FBA.
20 // The uncompressed unicode data has a fixed size allocated on startup.
21 // In practice, it is never freed.
2122 const allocation_size = 8704 + 34560 + 8704 + 17664 + 8704 + 25856;
22
2323 if (allocation_size == 0) {
2424 var logging_alloc = std.heap.loggingAllocator(std.heap.page_allocator);
2525 props = try PropsData.init(logging_alloc.allocator());
src/deps/quickjs/build.zig+1-1
......@@ -163,7 +163,7 @@ fn runQjsc(b: *Build, qjsc: *Build.Step.Compile, in: Build.LazyPath) Build.LazyP
163163 return out;
164164}
165165
166/// Zig doesnt include winpthreads, so we build it from source. This helper
166/// Zig doesnt include winpthreads, so it's built from source. This helper
167167/// decides if it is needed, and provides a no-op `configure` function if it is
168168/// not actually needed. Call .configure on any object files you need.
169169const WinPthreads = struct {
src/main.zig+1-1
......@@ -41,7 +41,7 @@ const top_level_commands: []const Command.ListItem = &.{
4141 .name = "run",
4242 .description = "Create executable and run with QuickJS",
4343 .cli = .{
44 .options = general_compiler_options ++ .{
44 .options = general_compiler_options ++ [_]Cli.Option{
4545 .{ .name = "--dump-code", .desc = "Dump compiled JavaScript to standard out" },
4646 },
4747 .positionals = .single,