fpc.zig
· 2.5 KiB · Zig
Raw
Playground
const std = @import("std");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}).init;
defer _ = gpa.deinit();
const alloc = gpa.allocator();
// Using this for cross-platform suitability
const argv = try std.process.argsAlloc(alloc);
defer std.process.argsFree(alloc, argv);
try stkEval(alloc, argv[1..]);
}
const eql = std.mem.eql;
const parseFloat = std.fmt.parseFloat;
const StkEvalError = error{
StackUnderflow,
UnrecognizedOperation,
};
fn Stack(comptime T: type) type {
return struct {
const Self = @This();
storage: std.ArrayList(T),
alloc: std.mem.Allocator,
pub fn init(alloc: std.mem.Allocator) !Self {
const list = try std.ArrayList(T).initCapacity(alloc, 8);
return Self{
.storage = list,
.alloc = alloc,
};
}
pub fn items(self: Self) []T {
return self.storage.items;
}
pub fn deinit(self: *Self) void {
self.storage.deinit(self.alloc);
}
pub fn pop(self: *Self) StkEvalError!T {
return self.storage.pop() orelse StkEvalError.StackUnderflow;
}
pub fn push(self: *Self, item: T) !void {
try self.storage.append(self.alloc, item);
}
};
}
pub fn stkEval(alloc: std.mem.Allocator, tokens: [][:0]u8) !void {
var dataStack = try Stack(f64).init(alloc);
defer dataStack.deinit();
for (tokens) |token| {
if (parseFloat(f64, token) catch null) |num| {
try dataStack.push(num);
} else if (eql(u8, token, "+")) {
const a = try dataStack.pop();
const b = try dataStack.pop();
try dataStack.push(a+b);
} else if (eql(u8, token, "-")) {
const a = try dataStack.pop();
const b = try dataStack.pop();
try dataStack.push(b-a);
} else if (eql(u8, token, "x")) {
const a = try dataStack.pop();
const b = try dataStack.pop();
try dataStack.push(a*b);
} else if (eql(u8, token, "div")) {
const a = try dataStack.pop();
const b = try dataStack.pop();
try dataStack.push(b/a);
} else {
std.debug.print("UNHANDLED {s}\n", .{token});
return StkEvalError.UnrecognizedOperation;
}
}
for (dataStack.items()) |item| {
std.debug.print("{} ", .{item});
}
std.debug.print("\n", .{});
}
| 1 | const std = @import("std"); |
| 2 | |
| 3 | pub fn main() !void { |
| 4 | var gpa = std.heap.GeneralPurposeAllocator(.{}).init; |
| 5 | defer _ = gpa.deinit(); |
| 6 | const alloc = gpa.allocator(); |
| 7 | |
| 8 | // Using this for cross-platform suitability |
| 9 | const argv = try std.process.argsAlloc(alloc); |
| 10 | defer std.process.argsFree(alloc, argv); |
| 11 | |
| 12 | try stkEval(alloc, argv[1..]); |
| 13 | } |
| 14 | |
| 15 | const eql = std.mem.eql; |
| 16 | const parseFloat = std.fmt.parseFloat; |
| 17 | |
| 18 | const StkEvalError = error{ |
| 19 | StackUnderflow, |
| 20 | UnrecognizedOperation, |
| 21 | }; |
| 22 | |
| 23 | fn Stack(comptime T: type) type { |
| 24 | return struct { |
| 25 | const Self = @This(); |
| 26 | |
| 27 | storage: std.ArrayList(T), |
| 28 | alloc: std.mem.Allocator, |
| 29 | pub fn init(alloc: std.mem.Allocator) !Self { |
| 30 | const list = try std.ArrayList(T).initCapacity(alloc, 8); |
| 31 | return Self{ |
| 32 | .storage = list, |
| 33 | .alloc = alloc, |
| 34 | }; |
| 35 | } |
| 36 | pub fn items(self: Self) []T { |
| 37 | return self.storage.items; |
| 38 | } |
| 39 | pub fn deinit(self: *Self) void { |
| 40 | self.storage.deinit(self.alloc); |
| 41 | } |
| 42 | pub fn pop(self: *Self) StkEvalError!T { |
| 43 | return self.storage.pop() orelse StkEvalError.StackUnderflow; |
| 44 | } |
| 45 | pub fn push(self: *Self, item: T) !void { |
| 46 | try self.storage.append(self.alloc, item); |
| 47 | } |
| 48 | }; |
| 49 | } |
| 50 | |
| 51 | |
| 52 | pub fn stkEval(alloc: std.mem.Allocator, tokens: [][:0]u8) !void { |
| 53 | var dataStack = try Stack(f64).init(alloc); |
| 54 | defer dataStack.deinit(); |
| 55 | |
| 56 | for (tokens) |token| { |
| 57 | if (parseFloat(f64, token) catch null) |num| { |
| 58 | try dataStack.push(num); |
| 59 | } else if (eql(u8, token, "+")) { |
| 60 | const a = try dataStack.pop(); |
| 61 | const b = try dataStack.pop(); |
| 62 | try dataStack.push(a+b); |
| 63 | } else if (eql(u8, token, "-")) { |
| 64 | const a = try dataStack.pop(); |
| 65 | const b = try dataStack.pop(); |
| 66 | try dataStack.push(b-a); |
| 67 | } else if (eql(u8, token, "x")) { |
| 68 | const a = try dataStack.pop(); |
| 69 | const b = try dataStack.pop(); |
| 70 | try dataStack.push(a*b); |
| 71 | } else if (eql(u8, token, "div")) { |
| 72 | const a = try dataStack.pop(); |
| 73 | const b = try dataStack.pop(); |
| 74 | try dataStack.push(b/a); |
| 75 | } else { |
| 76 | std.debug.print("UNHANDLED {s}\n", .{token}); |
| 77 | return StkEvalError.UnrecognizedOperation; |
| 78 | } |
| 79 | } |
| 80 | |
| 81 | for (dataStack.items()) |item| { |
| 82 | std.debug.print("{} ", .{item}); |
| 83 | } |
| 84 | std.debug.print("\n", .{}); |
| 85 | } |
| 86 |