1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
|
// builtin demo
const std = @import("std");
const warn = std.debug.warn;
fn add_integers(x: i78, y: i78) i78 {
var res: i78 = undefined;
if (@addWithOverflow(i78, x, y, &res)) {
warn("overflow detected!\n", .{});
return 0;
}
return res;
}
test "add_integers" {
warn("{}\n", .{add_integers(123, 171781717)});
warn("{}\n", .{add_integers(97239729372893729998991, 99900091788888881781717)});
}
// demo of real numbers
const std = @import("std");
const warn = std.debug.warn;
fn add_floats(x: f128, y: f128) f128 {
return x + y;
}
test "add_floats" {
const x = 1.23;
const y = -.0019;
warn("{} + {} = {}\n", .{x, y, add_floats(x, y)});
}
// unions and enums demo - a simple arithmetic expression evaluator
const std = @import("std");
const warn = std.debug.warn;
/// this expresses the variants that an arithmetic expression can take
const Expr = union(enum) {
Val: i32,
Add: Payload,
Div: Payload,
Sub: Payload,
Mul: Payload,
};
const Payload = struct {
left: *const Expr,
right: *const Expr,
};
fn show_helper(expr: *const Payload, expr_name: []const u8, stdout: *const @TypeOf(std.io.getStdOut().outStream())) anyerror!void {
try stdout.print("{}", .{expr_name});
try show(expr.left, stdout);
try stdout.print(", ", .{});
try show(expr.right, stdout);
try stdout.print(")", .{});
}
fn show(e: *const Expr, stdout: *const @TypeOf(std.io.getStdOut().outStream())) anyerror!void {
switch (e.*) {
Expr.Val => |n| try stdout.print("Val {}", .{n}),
Expr.Add => |a| try show_helper(&a, "Add (", stdout),
Expr.Sub => |s| try show_helper(&s, "Sub (", stdout),
Expr.Mul => |m| try show_helper(&m, "Mul (", stdout),
Expr.Div => |d| try show_helper(&d, "Div (", stdout),
else => unreachable,
}
}
fn eval(e: *const Expr) i32 {
return switch (e.*) {
Expr.Val => |v| v,
Expr.Add => |a| eval(a.left) + eval(a.right),
Expr.Sub => |s| eval(s.left) - eval(s.right),
Expr.Mul => |m| eval(m.left) * eval(m.right),
Expr.Div => |d| return if (eval(d.right) == 0) eval(d.left) else @divTrunc(eval(d.left), eval(d.right)),
else => unreachable,
};
}
pub fn main() !void {
const stdout = std.io.getStdOut().outStream();
const e1 = Expr{ .Val = 100 };
try show(&e1, &stdout);
try stdout.print(" = {}\n", .{eval(&e1)});
const e2 = Expr{ .Div = .{ .left = &Expr{ .Val = 10 }, .right = &Expr{ .Val = 2 } } };
try show(&e2, &stdout);
try stdout.print(" = {}\n", .{eval(&e2)});
const e3 = Expr{
.Div = .{
.left = &Expr{
.Mul = .{
.left = &Expr{ .Val = 5 },
.right = &Expr{ .Val = 4 },
},
},
.right = &Expr{ .Val = 2 },
},
};
try show(&e3, &stdout);
try stdout.print(" = {}\n", .{eval(&e3)});
const e4 = Expr{
.Add = .{
.left = &Expr{
.Mul = .{
.left = &Expr{ .Val = 5 },
.right = &Expr{ .Val = 4 },
},
},
.right = &Expr{
.Sub = .{
.left = &Expr{ .Val = 100 },
.right = &Expr{
.Div = .{
.left = &Expr{ .Val = 12 },
.right = &Expr{ .Val = 4 },
},
},
},
},
},
};
try show(&e4, &stdout);
try stdout.print(" = {}\n", .{eval(&e4)});
const e5 = Expr{ .Div = .{ .left = &Expr{ .Val = 100 }, .right = &Expr{ .Val = 0 } } };
try show(&e5, &stdout);
try stdout.print(" = {}\n", .{eval(&e5)});
}
|