const math = @import("./math.zig"); pub const IntParseError = math.CheckedArithmeticError || ParseError; pub const ParseError = error { BadSyntax, }; pub fn parse_float(comptime bits: comptime_int, utf8: []const u8) ParseError!math.Float(bits) { // "" if (utf8.len == 0) return error.BadSyntax; const is_negative = utf8[0] == '-'; // "-" if (is_negative and (utf8.len == 1)) return error.BadSyntax; const negative_offset = @boolToInt(is_negative); var has_decimal = utf8[negative_offset] == '.'; // "-." if (has_decimal and (utf8.len == 2)) return error.BadSyntax; const Float = math.Float(bits); var result: Float = 0; var factor: Float = 1; for (utf8[0 .. negative_offset + @boolToInt(has_decimal)]) |code| switch (code) { '.' => { if (has_decimal) return error.BadSyntax; has_decimal = true; }, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' => { if (has_decimal) factor /= 10.0; result = ((result * 10.0) + @intToFloat(Float, code - '0')); }, else => return error.BadSyntax, }; return result * factor; } pub fn parse_signed(comptime bits: comptime_int, utf8: []const u8) IntParseError!math.Signed(bits) { // "" if (utf8.len == 0) return error.BadSyntax; const is_negative = utf8[0] == '-'; // "-" if (is_negative and (utf8.len == 1)) return error.BadSyntax; var result: math.Signed(bits) = 0; { var index: usize = 0; while (index < utf8.len) : (index += 1) { const code = utf8[index]; switch (code) { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' => result = try math.checked_add(try math.checked_mul(result, 10), try math.checked_sub(code, '0')), else => return error.BadSyntax, } } } return result; } pub fn parse_unsigned(comptime bits: comptime_int, utf8: []const u8) IntParseError!math.Unsigned(bits) { // "" if (utf8.len == 0) return error.BadSyntax; // "-..." if (utf8[0] == '-') return error.BadSyntax; var result: math.Unsigned(bits) = 0; { var index: usize = 0; while (index < utf8.len) : (index += 1) { const code = utf8[index]; switch (code) { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' => result = try math.checked_add(try math.checked_mul(result, 10), try math.checked_sub(code, '0')), else => return error.BadSyntax, } } } return result; }