Skip to content

Instantly share code, notes, and snippets.

@metaleap
Last active January 18, 2020 10:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save metaleap/57ce1abacb28ac755d891b9df0ee2f9f to your computer and use it in GitHub Desktop.
Save metaleap/57ce1abacb28ac755d891b9df0ee2f9f to your computer and use it in GitHub Desktop.
pub fn exprNumListToBytes(mem: *std.mem.Allocator, maybeNumList: ?[]const Expr) !?[]const u8 {
if (maybeNumList) |it| {
const bytes = try mem.alloc(u8, it.len);
for (it) |expr, i|
if (expr.is(.NumInt)) |n| { // .is() expands to: switch(expr) { .NumInt => |n| ..., else => ... }
if (n >= 0 and n <= 255)
bytes[i] = @intCast(u8, n)
else {
mem.free(bytes);
return null;
}
} else {
mem.free(bytes);
return null;
};
return bytes;
}
return null;
}
@metaleap
Copy link
Author

metaleap commented Jan 18, 2020

With goto could do instead:

pub fn exprNumListToBytes(mem: *std.mem.Allocator, maybeNumList: ?[]const Expr) !?[]const u8 {
    if (maybeNumList) |it| {
        const bytes = try mem.alloc(u8, it.len);
        for (it) |expr, i|
            if (expr.is(.NumInt)) |n| { // .is() expands to: switch(expr) { .NumInt => |n| ..., else => ... }
                if (n >= 0 and n <= 255)
                    bytes[i] = @intCast(u8, n)
                else
                    goto nope;
            } else
                goto nope;
        return bytes;
        nope:
            mem.free(bytes);
    }
    return null;
}

@metaleap
Copy link
Author

metaleap commented Jan 18, 2020

With defer it becomes more bearable indeed, thx @daurnimator ! The 2 extra line costs of var ok and ok = true come out for the current example to the same overall LoC (-1) but at least if additional elses were to come into play it would amortize decently.

pub fn listToBytes(mem: *std.mem.Allocator, maybeNumList: ?[]const Expr) !?[]const u8 {
    if (maybeNumList) |it| {
        var ok = false;
        const bytes = try mem.alloc(u8, it.len);
        defer if (!ok) mem.free(bytes);
        for (it) |expr, i|
            if (expr.is(.NumInt)) |n| { // .is() expands to: switch(expr) { .NumInt => |n| ..., else => ... }
                if (n >= 0 and n <= 255)
                    bytes[i] = @intCast(u8, n)
                else
                    return null;
            } else
                return null;
        ok = true;
        return bytes;
    }
    return null;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment