102 lines
2.3 KiB
Zig
Executable File
102 lines
2.3 KiB
Zig
Executable File
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;
|
|
}
|