Hejsil / mecha

A parser combinator library for Zig
MIT License
473 stars 21 forks source link

Checking the result of many{ .collect = true }.asStr() #66

Closed joelreymont closed 3 weeks ago

joelreymont commented 4 weeks ago

I tried to extend the asStr test like this

    const parser3 = comptime ascii.range('a', 'z').many(.{}).asStr();
    try expectResult([]const u8, .{ .value = "ad" }, parser3.parse(allocator, "ad"));

It's failing, though. What am I doing wrong?

joelreymont commented 4 weeks ago

Full build error

❯ zig build test --summary all
test
└─ run test 22/23 passed, 1 failed
error: 'mecha.test.asStr' failed: /usr/local/lib/zig/std/mem/Allocator.zig:225:89: 0x10030bdff in allocBytesWithAlignment__anon_10338 (test)
    const byte_ptr = self.rawAlloc(byte_count, log2a(alignment), return_address) orelse return Error.OutOfMemory;
                                                                                        ^
/usr/local/lib/zig/std/mem/Allocator.zig:211:5: 0x1002e03cf in allocWithSizeAndAlignment__anon_7113 (test)
    return self.allocBytesWithAlignment(alignment, byte_count, return_address);
    ^
/usr/local/lib/zig/std/mem/Allocator.zig:193:5: 0x100361407 in alignedAlloc__anon_20442 (test)
    return self.allocAdvancedWithRetAddr(T, alignment, n, @returnAddress());
    ^
/usr/local/lib/zig/std/array_list.zig:475:36: 0x100360af7 in ensureTotalCapacityPrecise (test)
                const new_memory = try self.allocator.alignedAlloc(T, alignment, new_capacity);
                                   ^
/usr/local/lib/zig/std/array_list.zig:452:13: 0x1003616ff in ensureTotalCapacity (test)
            return self.ensureTotalCapacityPrecise(better_capacity);
            ^
/usr/local/lib/zig/std/array_list.zig:501:13: 0x100360ff3 in addOne (test)
            try self.ensureTotalCapacity(newlen);
            ^
/usr/local/lib/zig/std/array_list.zig:262:34: 0x1003605d3 in append (test)
            const new_item_ptr = try self.addOne();
                                 ^
/Users/joelr/Work/Zig/mecha/mecha.zig:237:21: 0x100360247 in parse (test)
                    try res.append(r.value);
                    ^
/Users/joelr/Work/Zig/mecha/mecha.zig:453:23: 0x10035fbc7 in parse (test)
            const r = try parser.parse(allocator, str);
                      ^
/Users/joelr/Work/Zig/mecha/mecha.zig:966:20: 0x10033807b in expectResult__anon_14676 (test)
    const actual = try m_actual;
                   ^
/Users/joelr/Work/Zig/mecha/mecha.zig:476:5: 0x10035f6fb in test.asStr (test)
    try expectResult([]const u8, .{ .value = "ad" }, parser3.parse(allocator, "ad"));
    ^
error: while executing test 'src.utf8.test.not', the following test command failed:
/Users/joelr/Work/Zig/mecha/.zig-cache/o/0d25412f33b31d993c451e30fc0308b2/test --seed=0x81b34b68 --cache-dir=/Users/joelr/Work/Zig/mecha/.zig-cache --listen=-
Build Summary: 5/7 steps succeeded; 1 failed; 344/347 tests passed; 2 skipped; 1 failed
test transitive failure
├─ run test 22/23 passed, 1 failed
│  └─ zig test Debug native success 2s MaxRSS:362M
├─ run test 1 passed 308ms MaxRSS:2M
│  └─ zig test Debug native success 1s MaxRSS:275M
└─ run test 321 passed 2 skipped 234ms MaxRSS:2M
   └─ zig test Debug native success 1s MaxRSS:301M
error: the following build command failed with exit code 1:
/Users/joelr/Work/Zig/mecha/.zig-cache/o/cfa96da071d62655097a34de3361d84d/build /usr/local/bin/zig /usr/local/lib/zig /Users/joelr/Work/Zig/mecha /Users/joelr/Work/Zig/mecha/.zig-cache /Users/joelr/.cache/zig --seed 0x81b34b68 -Z48516667f5743783 test --summary all
Hejsil commented 3 weeks ago

What allocator are you using here?

joelreymont commented 3 weeks ago

I'm extending the asStr test In mecha.zig so

test "asStr" {
    const allocator = testing.failing_allocator;
...
}
Hejsil commented 3 weeks ago

Aah, i see. It fails because the call to many tried to allocate. You need to set collect = false to prevent many from doing that

joelreymont commented 3 weeks ago

In what circumstances would I set collect = true, though?

I understand that it's set by default.

Hejsil commented 3 weeks ago

In what circumstances would I set collect = true, though?

I understand that it's set by default.

many can only collect the result of the underlying parser when collect = true (Aka returning []T). When set to false, many will always return the parsed string (aka []const u8)