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;
 | 
						|
}
 |