Skip to content

Commit d318d98

Browse files
committed
fix: Use unmanaged ArrayList and HashMaps everywhere
1 parent 8847af1 commit d318d98

28 files changed

+556
-419
lines changed

CRUSH.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
CRUSH.md
2+
3+
Build, lint, test
4+
- Build: zig build
5+
- Run REPL: zig build run
6+
- Run file: zig build run -- path/to/file.buzz
7+
- Install (user): zig build -Doptimize=ReleaseSafe install -p ~/.local
8+
- Install (system): sudo zig build -Doptimize=ReleaseSafe install -p /usr/local
9+
- Clean: rm -rf .zig-cache zig-out
10+
- Typecheck/lsp: zls (use your editor’s Zig LSP); no separate typecheck script
11+
- Format Zig: zig fmt .
12+
- Web WASM tooling: npm install; node src/wasm.ts (uses esbuild+ts)
13+
- Run single test: zig build run -- tests/068-testing.buzz --name "<test_name>" (tests are Buzz scripts; prefer targeted script runs)
14+
- Example single test: zig build run -- tests/023-std.buzz
15+
16+
Project conventions
17+
- Language: Zig 0.15.x; entry in src/main.zig; build via build.zig; vendor deps under vendors/
18+
- Buzz tests: each .buzz file in tests/ acts as an executable scenario; keep them self-contained
19+
- Imports: Zig uses relative imports (const x = @import("file.zig")); keep import blocks at top, grouped std, vendors, local
20+
- Formatting: run zig fmt before commits; keep line width conventional (~100) and avoid trailing spaces
21+
- Types: prefer explicit types in public APIs; use var/const deliberately; avoid anyopaque unless necessary
22+
- Naming: snake_case for Zig functions/vars, TitleCase for types, SCREAMING_SNAKE for compile-time consts
23+
- Errors: use Zig error sets; return !T and propagate with try/errdefer; avoid panic except unrecoverable
24+
- Memory: use provided allocators; pair alloc/free; errdefer for cleanup; avoid leaks in hot paths
25+
- Concurrency: fibers exist at Buzz level; in Zig keep APIs non-blocking where possible
26+
- Logging/Reporting: use Reporter.zig utilities; avoid printing in libraries
27+
- Performance: prefer slices over arrays; minimize copies; use inline and comptime judiciously
28+
29+
Notes
30+
- No .cursor or Copilot rules found
31+
- VS Code: install Buzz extension and Zig LSP for best experience
32+
- Security: never commit secrets; do not log keys or tokens

out.txt

Whitespace-only changes.

src/Ast.zig

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -625,11 +625,11 @@ pub const Slice = struct {
625625
const left_map = if (left.isObj()) obj.ObjMap.cast(left.obj()) else null;
626626

627627
if (right_string) |rs| {
628-
var new_string = std.array_list.Managed(u8).init(gc.allocator);
629-
try new_string.appendSlice(left_string.?.string);
630-
try new_string.appendSlice(rs.string);
628+
var new_string = std.ArrayList(u8).empty;
629+
try new_string.appendSlice(gc.allocator, left_string.?.string);
630+
try new_string.appendSlice(gc.allocator, rs.string);
631631

632-
return (try gc.copyString(try new_string.toOwnedSlice())).toValue();
632+
return (try gc.copyString(try new_string.toOwnedSlice(gc.allocator))).toValue();
633633
} else if (right_float) |rf| {
634634
return Value.fromDouble(rf + left_float.?);
635635
} else if (right_integer) |ri| {
@@ -819,13 +819,13 @@ pub const Slice = struct {
819819
.String => string: {
820820
const elements = self.nodes.items(.components)[node].String;
821821

822-
var string = std.array_list.Managed(u8).init(gc.allocator);
823-
const writer = &string.writer();
822+
var string = std.ArrayList(u8).empty;
823+
const writer = &string.writer(gc.allocator);
824824
for (elements) |element| {
825825
try (try self.toValue(element, gc)).toString(writer);
826826
}
827827

828-
break :string (try gc.copyString(try string.toOwnedSlice())).toValue();
828+
break :string (try gc.copyString(try string.toOwnedSlice(gc.allocator))).toValue();
829829
},
830830
.Subscript => subscript: {
831831
const components = self.nodes.items(.components)[node].Subscript;

src/Codegen.zig

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,10 +1142,14 @@ fn generateCall(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj
11421142
const arg_keys = args.keys();
11431143
const arg_count = arg_keys.len;
11441144

1145-
var missing_arguments = std.StringArrayHashMap(usize).init(self.gc.allocator);
1146-
defer missing_arguments.deinit();
1145+
var missing_arguments = std.StringArrayHashMapUnmanaged(usize).empty;
1146+
defer missing_arguments.deinit(self.gc.allocator);
11471147
for (arg_keys, 0..) |arg_name, pindex| {
1148-
try missing_arguments.put(arg_name.string, pindex);
1148+
try missing_arguments.put(
1149+
self.gc.allocator,
1150+
arg_name.string,
1151+
pindex,
1152+
);
11491153
}
11501154

11511155
if (components.arguments.len > args.count()) {
@@ -1211,10 +1215,11 @@ fn generateCall(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj
12111215
}
12121216

12131217
// Argument order reference
1214-
var arguments_order_ref = std.array_list.Managed([]const u8).init(self.gc.allocator);
1215-
defer arguments_order_ref.deinit();
1218+
var arguments_order_ref = std.ArrayList([]const u8).empty;
1219+
defer arguments_order_ref.deinit(self.gc.allocator);
12161220
for (components.arguments) |arg| {
12171221
try arguments_order_ref.append(
1222+
self.gc.allocator,
12181223
if (arg.name) |name|
12191224
lexemes[name]
12201225
else
@@ -1224,25 +1229,25 @@ fn generateCall(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj
12241229

12251230
// Push default arguments
12261231
if (missing_arguments.count() > 0) {
1227-
var tmp_missing_arguments = try missing_arguments.clone();
1228-
defer tmp_missing_arguments.deinit();
1232+
var tmp_missing_arguments = try missing_arguments.clone(self.gc.allocator);
1233+
defer tmp_missing_arguments.deinit(self.gc.allocator);
12291234
const missing_keys = tmp_missing_arguments.keys();
12301235
for (missing_keys) |missing_key| {
12311236
if (defaults.get(try self.gc.copyString(missing_key))) |default| {
12321237
// TODO: like ObjTypeDef, avoid generating constants multiple time for the same value
12331238
try self.emitConstant(locations[node], default);
12341239
try self.OP_CLONE(locations[node]);
12351240

1236-
try arguments_order_ref.append(missing_key);
1241+
try arguments_order_ref.append(self.gc.allocator, missing_key);
12371242
_ = missing_arguments.orderedRemove(missing_key);
12381243
needs_reorder = true;
12391244
}
12401245
}
12411246
}
12421247

12431248
if (missing_arguments.count() > 0) {
1244-
var missing = std.array_list.Managed(u8).init(self.gc.allocator);
1245-
const missing_writer = missing.writer();
1249+
var missing = std.ArrayList(u8).empty;
1250+
const missing_writer = missing.writer(self.gc.allocator);
12461251
for (missing_arguments.keys(), 0..) |key, i| {
12471252
try missing_writer.print(
12481253
"{s}{s}",
@@ -1255,7 +1260,7 @@ fn generateCall(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj
12551260
},
12561261
);
12571262
}
1258-
defer missing.deinit();
1263+
defer missing.deinit(self.gc.allocator);
12591264
self.reporter.reportErrorFmt(
12601265
.call_arguments,
12611266
self.ast.tokens.get(locations[node]),
@@ -1342,8 +1347,8 @@ fn generateCall(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj
13421347
} else if (error_types) |errors| {
13431348
if (self.current.?.enclosing != null and self.current.?.function.?.type_def.resolved_type.?.Function.function_type != .Test) {
13441349
var handles_any = false;
1345-
var not_handled = std.array_list.Managed(*obj.ObjTypeDef).init(self.gc.allocator);
1346-
defer not_handled.deinit();
1350+
var not_handled = std.ArrayList(*obj.ObjTypeDef).empty;
1351+
defer not_handled.deinit(self.gc.allocator);
13471352
for (errors) |error_type| {
13481353
if (error_type.def_type == .Void) {
13491354
continue;
@@ -1373,12 +1378,12 @@ fn generateCall(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj
13731378
locations[components.callee],
13741379
);
13751380
} else {
1376-
try not_handled.append(error_type);
1381+
try not_handled.append(self.gc.allocator, error_type);
13771382
}
13781383
}
13791384

13801385
if (handles_any) {
1381-
not_handled.clearAndFree();
1386+
not_handled.clearAndFree(self.gc.allocator);
13821387
break;
13831388
}
13841389
}
@@ -3621,10 +3626,11 @@ fn generateObjectInit(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error
36213626

36223627
var fields = if (node_type_def.def_type == .ObjectInstance) inst: {
36233628
const fields = node_type_def.resolved_type.?.ObjectInstance.of.resolved_type.?.Object.fields;
3624-
var fields_type_defs = std.StringArrayHashMap(*obj.ObjTypeDef).init(self.gc.allocator);
3629+
var fields_type_defs = std.StringArrayHashMapUnmanaged(*obj.ObjTypeDef).empty;
36253630
var it = fields.iterator();
36263631
while (it.next()) |kv| {
36273632
try fields_type_defs.put(
3633+
self.gc.allocator,
36283634
kv.value_ptr.*.name,
36293635
kv.value_ptr.*.type_def,
36303636
);
@@ -3633,7 +3639,7 @@ fn generateObjectInit(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error
36333639
} else node_type_def.resolved_type.?.ForeignContainer.buzz_type;
36343640

36353641
defer if (node_type_def.def_type == .ObjectInstance) {
3636-
fields.deinit();
3642+
fields.deinit(self.gc.allocator);
36373643
};
36383644

36393645
const object_location = if (node_type_def.def_type == .ObjectInstance)
@@ -3642,8 +3648,8 @@ fn generateObjectInit(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error
36423648
node_type_def.resolved_type.?.ForeignContainer.location;
36433649

36443650
// Keep track of what's been initialized or not by this statement
3645-
var init_properties = std.StringHashMap(void).init(self.gc.allocator);
3646-
defer init_properties.deinit();
3651+
var init_properties = std.StringHashMapUnmanaged(void).empty;
3652+
defer init_properties.deinit(self.gc.allocator);
36473653

36483654
for (components.properties) |property| {
36493655
const property_name = lexemes[property.name];
@@ -3701,7 +3707,7 @@ fn generateObjectInit(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error
37013707

37023708
_ = try self.generateNode(property.value, breaks);
37033709

3704-
try init_properties.put(property_name, {});
3710+
try init_properties.put(self.gc.allocator, property_name, {});
37053711

37063712
try self.emitCodeArg(
37073713
location,
@@ -4185,8 +4191,8 @@ fn generateTry(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.
41854191
// Jump reached if no error was raised
41864192
const no_error_jump = try self.OP_JUMP(self.ast.nodes.items(.end_location)[components.body]);
41874193

4188-
var exit_jumps = std.array_list.Managed(usize).init(self.gc.allocator);
4189-
defer exit_jumps.deinit();
4194+
var exit_jumps = std.ArrayList(usize).empty;
4195+
defer exit_jumps.deinit(self.gc.allocator);
41904196

41914197
self.patchTryOrJit(try_jump);
41924198
var has_unconditional = components.unconditional_clause != null;
@@ -4214,7 +4220,10 @@ fn generateTry(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.
42144220
self.current.?.try_should_handle = previous;
42154221

42164222
// After handling the error, jump over next clauses
4217-
try exit_jumps.append(try self.emitJump(location, .OP_JUMP));
4223+
try exit_jumps.append(
4224+
self.gc.allocator,
4225+
try self.emitJump(location, .OP_JUMP),
4226+
);
42184227

42194228
self.patchJump(next_clause_jump);
42204229
// Pop `is` result
@@ -4230,7 +4239,10 @@ fn generateTry(self: *Self, node: Ast.Node.Index, breaks: ?*Breaks) Error!?*obj.
42304239
_ = try self.generateNode(unconditional_clause, breaks);
42314240
self.current.?.try_should_handle = previous;
42324241

4233-
try exit_jumps.append(try self.emitJump(location, .OP_JUMP));
4242+
try exit_jumps.append(
4243+
self.gc.allocator,
4244+
try self.emitJump(location, .OP_JUMP),
4245+
);
42344246
}
42354247

42364248
// Tell runtime we're not in a try block anymore

0 commit comments

Comments
 (0)