017 expr evaluator

✓ Passing This code compiles and runs correctly.

Code

// Test: Expression Evaluator Standard Library
// Tests the Value and Bindings types compile and work correctly
// Note: Direct module import not yet supported, so we test via inline Zig

~import "$std/runtime"
~import "$std/build"
~import "$std/eval"

const std = @import("std");

// Re-implement Value and Bindings locally to test the concepts
// The actual $std/eval has these - this validates the design

pub const Value = union(enum) {
    bool_val: bool,
    int_val: i64,
    float_val: f64,
    string_val: []const u8,
    null_val: void,

    pub fn isTruthy(self: Value) bool {
        return switch (self) {
            .bool_val => |b| b,
            .int_val => |n| n != 0,
            .float_val => |f| f != 0.0,
            .string_val => |s| s.len > 0,
            .null_val => false,
        };
    }
};

pub const Bindings = struct {
    values: std.StringHashMap(Value),
    allocator: std.mem.Allocator,

    pub fn init(allocator: std.mem.Allocator) Bindings {
        return .{
            .values = std.StringHashMap(Value).init(allocator),
            .allocator = allocator,
        };
    }

    pub fn deinit(self: *Bindings) void {
        self.values.deinit();
    }

    pub fn set(self: *Bindings, name: []const u8, value: Value) !void {
        try self.values.put(name, value);
    }

    pub fn get(self: *const Bindings, name: []const u8) ?Value {
        return self.values.get(name);
    }

    pub fn setAuto(self: *Bindings, name: []const u8, str_value: []const u8) !void {
        if (std.mem.eql(u8, str_value, "true")) {
            try self.set(name, .{ .bool_val = true });
            return;
        }
        if (std.mem.eql(u8, str_value, "false")) {
            try self.set(name, .{ .bool_val = false });
            return;
        }
        if (std.fmt.parseInt(i64, str_value, 10)) |n| {
            try self.set(name, .{ .int_val = n });
            return;
        } else |_| {}
        if (std.fmt.parseFloat(f64, str_value)) |f| {
            try self.set(name, .{ .float_val = f });
            return;
        } else |_| {}
        try self.set(name, .{ .string_val = str_value });
    }
};

pub fn main() void {
    std.debug.print("\n", .{});
    std.debug.print("╔══════════════════════════════════════════════════════════════╗\n", .{});
    std.debug.print("║           EXPRESSION EVALUATOR TEST                          ║\n", .{});
    std.debug.print("╚══════════════════════════════════════════════════════════════╝\n\n", .{});

    var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
    defer arena.deinit();
    const allocator = arena.allocator();

    // ========================================================================
    // Test 1: Create bindings and evaluate literals
    // ========================================================================
    std.debug.print("Test 1: Bindings and Value types\n", .{});
    {
        var bindings = Bindings.init(allocator);
        defer bindings.deinit();

        // Set some bindings
        bindings.set("score", .{ .int_val = 75 }) catch unreachable;
        bindings.set("name", .{ .string_val = "Alice" }) catch unreachable;
        bindings.set("active", .{ .bool_val = true }) catch unreachable;

        // Check retrieval
        if (bindings.get("score")) |val| {
            std.debug.print("  score = {d}\n", .{val.int_val});
        }
        if (bindings.get("name")) |val| {
            std.debug.print("  name = {s}\n", .{val.string_val});
        }
        if (bindings.get("active")) |val| {
            std.debug.print("  active = {}\n", .{val.bool_val});
        }

        std.debug.print("  ✓ TEST 1 PASSED\n\n", .{});
    }

    // ========================================================================
    // Test 2: Value truthiness
    // ========================================================================
    std.debug.print("Test 2: Value truthiness\n", .{});
    {
        const true_val = Value{ .bool_val = true };
        const false_val = Value{ .bool_val = false };
        const int_zero = Value{ .int_val = 0 };
        const int_nonzero = Value{ .int_val = 42 };
        const empty_str = Value{ .string_val = "" };
        const nonempty_str = Value{ .string_val = "hello" };
        const null_val = Value{ .null_val = {} };

        std.debug.print("  true.isTruthy() = {}\n", .{true_val.isTruthy()});
        std.debug.print("  false.isTruthy() = {}\n", .{false_val.isTruthy()});
        std.debug.print("  0.isTruthy() = {}\n", .{int_zero.isTruthy()});
        std.debug.print("  42.isTruthy() = {}\n", .{int_nonzero.isTruthy()});
        std.debug.print("  \"\".isTruthy() = {}\n", .{empty_str.isTruthy()});
        std.debug.print("  \"hello\".isTruthy() = {}\n", .{nonempty_str.isTruthy()});
        std.debug.print("  null.isTruthy() = {}\n", .{null_val.isTruthy()});

        // Verify expectations
        if (true_val.isTruthy() and !false_val.isTruthy() and
            !int_zero.isTruthy() and int_nonzero.isTruthy() and
            !empty_str.isTruthy() and nonempty_str.isTruthy() and
            !null_val.isTruthy())
        {
            std.debug.print("  ✓ TEST 2 PASSED\n\n", .{});
        } else {
            std.debug.print("  ✗ TEST 2 FAILED\n\n", .{});
        }
    }

    // ========================================================================
    // Test 3: setAuto type detection
    // ========================================================================
    std.debug.print("Test 3: setAuto type detection\n", .{});
    {
        var bindings = Bindings.init(allocator);
        defer bindings.deinit();

        bindings.setAuto("bool_true", "true") catch unreachable;
        bindings.setAuto("bool_false", "false") catch unreachable;
        bindings.setAuto("int_val", "123") catch unreachable;
        bindings.setAuto("float_val", "3.14") catch unreachable;
        bindings.setAuto("str_val", "hello") catch unreachable;

        if (bindings.get("bool_true")) |val| {
            std.debug.print("  'true' -> {s} = {}\n", .{ @tagName(val), val.bool_val });
        }
        if (bindings.get("int_val")) |val| {
            std.debug.print("  '123' -> {s} = {d}\n", .{ @tagName(val), val.int_val });
        }
        if (bindings.get("float_val")) |val| {
            std.debug.print("  '3.14' -> {s} = {d}\n", .{ @tagName(val), val.float_val });
        }
        if (bindings.get("str_val")) |val| {
            std.debug.print("  'hello' -> {s} = {s}\n", .{ @tagName(val), val.string_val });
        }

        std.debug.print("  ✓ TEST 3 PASSED\n\n", .{});
    }

    std.debug.print("╔══════════════════════════════════════════════════════════════╗\n", .{});
    std.debug.print("║           EXPRESSION EVALUATOR TESTS COMPLETE                ║\n", .{});
    std.debug.print("╚══════════════════════════════════════════════════════════════╝\n", .{});
}
input.kz

Expected Output


╔══════════════════════════════════════════════════════════════╗
║           EXPRESSION EVALUATOR TEST                          ║
╚══════════════════════════════════════════════════════════════╝

Test 1: Bindings and Value types
  score = 75
  name = Alice
  active = true
  ✓ TEST 1 PASSED

Test 2: Value truthiness
  true.isTruthy() = true
  false.isTruthy() = false
  0.isTruthy() = false
  42.isTruthy() = true
  "".isTruthy() = false
  "hello".isTruthy() = true
  null.isTruthy() = false
  ✓ TEST 2 PASSED

Test 3: setAuto type detection
  'true' -> bool_val = true
  '123' -> int_val = 123
  '3.14' -> float_val = 3.14
  'hello' -> string_val = hello
  ✓ TEST 3 PASSED

╔══════════════════════════════════════════════════════════════╗
║           EXPRESSION EVALUATOR TESTS COMPLETE                ║
╚══════════════════════════════════════════════════════════════╝

Test Configuration

MUST_RUN