#Defining strings in function parameters

1 messages · Page 1 of 1 (latest)

tulip carbon
#

I'm trying to write a toy parser in Zig, capable of parsing literals from some input string.
I'm unable to figure out how to define the function (and testing it tbh) to account for this.

So here's what I want:

/// Attempt to parse a literal from the text,
/// returning the length of the literal on success,
/// otherwise 0.
fn parseLiteral(literal: *const []u8, text: []u8) usize {
  // ...
}

This doesn't work for literal: *const []u8, as the following test fails:

test "parseLiteral: del -> 3" {
    var data = "del";
    const results = parseLiteral("del", &data);
    try std.testing.expectEqual(3, results);
}

Error:

error: expected type '*const []u8', found '*const [3:0]u8'
    const results = parseLiteral("del", &data);
                                 ^~~~~
note: pointer type child 'u8' cannot cast into pointer type child '[]u8'
note: parameter type declared here
fn parseLiteral(literal: *const []u8, data: []u8) usize {

Since the literals will not all be the same length, is there some way to be generic over the length of the constant, or what is the best way to work with constant literals of varying lengths in function parameters?

feral linden
#

*const []u8 is a const pointer to a slice of characters. Slices are pointer/length pairs. So it's double indirection and not a string type you'd use unless you wanted to modify the slice (which is actually reasonable, especially for parsers, but not what you want here)

#

here's a contrived example of a parsing function with a comptime parameter:

fn parseLiteral(comptime needle: []const u8, haystack: []const u8) ?[]const u8 {
    if (haystack.len < needle.len) return null;
    inline for (needle, 0..) |c, i| {
        if (haystack[i] != c) return null;
    }
    return haystack[needle.len..];
}

pub fn main() u8 {
    if (parseLiteral("ex(", "ex(ample)")) |rest| {
        return rest[0];
    }
    return 1;
}
#

you can read about comptime in the langref if that's not clear. It's essentially expanded to a function call where needle.len is constant and the for loop is expanded to a series of tests against the individual characters of needle