mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
This use case is handled by ArrayListUnmanaged via the "...Bounded" method variants, and it's more optimal to share machine code, versus generating multiple versions of each function for differing array lengths.
40 lines
1,009 B
Zig
40 lines
1,009 B
Zig
const std = @import("std");
|
|
const expectEqual = std.testing.expectEqual;
|
|
|
|
const Instruction = enum {
|
|
add,
|
|
mul,
|
|
end,
|
|
};
|
|
|
|
fn evaluate(initial_stack: []const i32, code: []const Instruction) !i32 {
|
|
var buffer: [8]i32 = undefined;
|
|
var stack = std.ArrayListUnmanaged(i32).initBuffer(&buffer);
|
|
try stack.appendSliceBounded(initial_stack);
|
|
var ip: usize = 0;
|
|
|
|
return vm: switch (code[ip]) {
|
|
// Because all code after `continue` is unreachable, this branch does
|
|
// not provide a result.
|
|
.add => {
|
|
try stack.appendBounded(stack.pop().? + stack.pop().?);
|
|
|
|
ip += 1;
|
|
continue :vm code[ip];
|
|
},
|
|
.mul => {
|
|
try stack.appendBounded(stack.pop().? * stack.pop().?);
|
|
|
|
ip += 1;
|
|
continue :vm code[ip];
|
|
},
|
|
.end => stack.pop().?,
|
|
};
|
|
}
|
|
|
|
test "evaluate" {
|
|
const result = try evaluate(&.{ 7, 2, -3 }, &.{ .mul, .add, .end });
|
|
try expectEqual(1, result);
|
|
}
|
|
|
|
// test
|