Integer hex parsing
This commit is contained in:
parent
3c7fea2526
commit
1599a78d03
@ -703,6 +703,21 @@ const Converter = struct {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_hexadecimal(noalias converter: *Converter) u64 {
|
||||||
|
var value: u64 = 0;
|
||||||
|
while (true) {
|
||||||
|
const ch = converter.content[converter.offset];
|
||||||
|
if (!lib.is_hex_digit(ch)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
converter.offset += 1;
|
||||||
|
value = lib.parse.accumulate_hexadecimal(value, ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_integer(noalias converter: *Converter, noalias module: *Module, expected_type: *Type, sign: bool) *Value {
|
fn parse_integer(noalias converter: *Converter, noalias module: *Module, expected_type: *Type, sign: bool) *Value {
|
||||||
const start = converter.offset;
|
const start = converter.offset;
|
||||||
const integer_start_ch = converter.content[start];
|
const integer_start_ch = converter.content[start];
|
||||||
@ -716,9 +731,9 @@ const Converter = struct {
|
|||||||
const next_ch = converter.content[converter.offset];
|
const next_ch = converter.content[converter.offset];
|
||||||
break :blk switch (sign) {
|
break :blk switch (sign) {
|
||||||
false => switch (next_ch) {
|
false => switch (next_ch) {
|
||||||
'x' => {
|
'x' => b: {
|
||||||
// TODO: parse hexadecimal
|
converter.offset += 1;
|
||||||
converter.report_error();
|
break :b converter.parse_hexadecimal();
|
||||||
},
|
},
|
||||||
'o' => {
|
'o' => {
|
||||||
// TODO: parse octal
|
// TODO: parse octal
|
||||||
|
72
src/lib.zig
72
src/lib.zig
@ -2365,8 +2365,36 @@ pub const string_format = struct {
|
|||||||
// zig fmt: on
|
// zig fmt: on
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub fn and_bool_branchless(a: bool, b: bool) bool {
|
||||||
|
return (@intFromBool(a) & @intFromBool(b)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn or_bool_branchless(a: bool, b: bool) bool {
|
||||||
|
return (@intFromBool(a) | @intFromBool(b)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_character_between_ranges(ch: u8, start: u8, end: u8) bool {
|
||||||
|
return and_bool_branchless(ch >= start, ch <= end);
|
||||||
|
}
|
||||||
|
|
||||||
fn is_decimal_digit(ch: u8) bool {
|
fn is_decimal_digit(ch: u8) bool {
|
||||||
return ch >= '0' and ch <= '9';
|
return is_character_between_ranges(ch, '0', '9');
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_hex_digit_alpha_lower(ch: u8) bool {
|
||||||
|
return is_character_between_ranges(ch, 'a', 'f');
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_hex_digit_alpha_upper(ch: u8) bool {
|
||||||
|
return is_character_between_ranges(ch, 'A', 'F');
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_hex_digit_alpha(ch: u8) bool {
|
||||||
|
return or_bool_branchless(is_hex_digit_alpha_lower(ch), is_hex_digit_alpha_upper(ch));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_hex_digit(ch: u8) bool {
|
||||||
|
return or_bool_branchless(is_decimal_digit(ch), is_hex_digit_alpha(ch));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fn log2_int(v: anytype) u8 {
|
inline fn log2_int(v: anytype) u8 {
|
||||||
@ -2558,6 +2586,27 @@ pub const GlobalState = struct {
|
|||||||
pub var global: GlobalState = undefined;
|
pub var global: GlobalState = undefined;
|
||||||
|
|
||||||
pub const parse = struct {
|
pub const parse = struct {
|
||||||
|
pub fn integer_hexadecimal(str: []const u8) u64 {
|
||||||
|
var value: u64 = 0;
|
||||||
|
|
||||||
|
for (str) |ch| {
|
||||||
|
assert(is_hex_digit(ch));
|
||||||
|
value = accumulate_hexadecimal(value, ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn accumulate_hexadecimal(accumulator: u64, ch: u8) u64 {
|
||||||
|
const value_to_add: u64 = if (is_decimal_digit(ch)) ch - '0' else if (is_hex_digit_alpha_upper(ch))
|
||||||
|
ch - 'A' + 10
|
||||||
|
else if (is_hex_digit_alpha_lower(ch))
|
||||||
|
ch - 'a' + 10
|
||||||
|
else
|
||||||
|
unreachable;
|
||||||
|
return (accumulator * 16) + value_to_add;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn integer_decimal(str: []const u8) u64 {
|
pub fn integer_decimal(str: []const u8) u64 {
|
||||||
var value: u64 = 0;
|
var value: u64 = 0;
|
||||||
|
|
||||||
@ -2574,6 +2623,27 @@ pub const parse = struct {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
test "parse integer decimal" {
|
||||||
|
const std = @import("std");
|
||||||
|
const expect = std.testing.expect;
|
||||||
|
try expect(parse.integer_decimal("0") == 0);
|
||||||
|
try expect(parse.integer_decimal("5") == 5);
|
||||||
|
try expect(parse.integer_decimal("10") == 10);
|
||||||
|
try expect(parse.integer_decimal("901283") == 901283);
|
||||||
|
try expect(parse.integer_decimal("189234819023129038") == 189234819023129038);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "parse integer hexadecimal" {
|
||||||
|
const std = @import("std");
|
||||||
|
const expect = std.testing.expect;
|
||||||
|
try expect(parse.integer_hexadecimal("0") == 0);
|
||||||
|
try expect(parse.integer_hexadecimal("5") == 5);
|
||||||
|
try expect(parse.integer_hexadecimal("10") == 0x10);
|
||||||
|
try expect(parse.integer_hexadecimal("901283") == 0x901283);
|
||||||
|
try expect(parse.integer_hexadecimal("1892348190231290") == 0x1892348190231290);
|
||||||
|
try expect(parse.integer_hexadecimal("1b92a48c90d3e2f0") == 0x1b92a48c90d3e2f0);
|
||||||
|
}
|
||||||
|
|
||||||
fn vprint(format_string: [*:0]const u8, args: *VariableArguments) void {
|
fn vprint(format_string: [*:0]const u8, args: *VariableArguments) void {
|
||||||
var buffer: [16 * 1024]u8 = undefined;
|
var buffer: [16 * 1024]u8 = undefined;
|
||||||
const slice = format_va(&buffer, format_string, args);
|
const slice = format_va(&buffer, format_string, args);
|
||||||
|
5
tests/integer_hex.bbb
Normal file
5
tests/integer_hex.bbb
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
[export] main = fn [cc(c)] () s32
|
||||||
|
{
|
||||||
|
>result: s32 = 0x0;
|
||||||
|
return result;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user