diff --git a/src/bootstrap.zig b/src/bootstrap.zig index a1b3eac..5296927 100644 --- a/src/bootstrap.zig +++ b/src/bootstrap.zig @@ -107,6 +107,14 @@ fn is_decimal_ch(ch: u8) bool { return ch >= '0' and ch <= '9'; } +fn is_octal_ch(ch: u8) bool { + return ch >= '0' and ch <= '7'; +} + +fn is_binary_ch(ch: u8) bool { + return ch == '0' or ch == '1'; +} + fn is_identifier_ch(ch: u8) bool { return is_identifier_start_ch(ch) or is_decimal_ch(ch); } @@ -1173,6 +1181,36 @@ pub const Module = struct { return value; } + fn parse_octal(noalias module: *Module) u64 { + var value: u64 = 0; + while (true) { + const ch = module.content[module.offset]; + if (!is_octal_ch(ch)) { + break; + } + + module.offset += 1; + value = lib.parse.accumulate_octal(value, ch); + } + + return value; + } + + fn parse_binary(noalias module: *Module) u64 { + var value: u64 = 0; + while (true) { + const ch = module.content[module.offset]; + if (!is_binary_ch(ch)) { + break; + } + + module.offset += 1; + value = lib.parse.accumulate_binary(value, ch); + } + + return value; + } + const AttributeBuildOptions = struct { return_type_abi: Abi.Information, abi_argument_types: []const *Type, @@ -2023,16 +2061,32 @@ pub const Module = struct { 'x' => .hexadecimal, 'o' => .octal, 'b' => .binary, + 'd' => .decimal, else => .decimal, }; const value: u64 = switch (token_integer_kind) { - .binary => @trap(), - .octal => @trap(), + .binary => b: { + module.offset += 2; + const v = module.parse_binary(); + break :b v; + }, + .octal => b: { + module.offset += 2; + const v = module.parse_octal(); + break :b v; + }, .decimal => switch (next_ch) { 0...9 => module.report_error(), - else => b: { - module.offset += 1; - break :b 0; + else => switch (next_ch) { + 'd' => b: { + module.offset += 2; + const v = module.parse_decimal(); + break :b v; + }, + else => b: { + module.offset += 1; + break :b 0; + }, }, }, .hexadecimal => b: { @@ -4087,13 +4141,17 @@ pub const Module = struct { module.offset += 1; break :b module.parse_hexadecimal(); }, - 'o' => { - // TODO: parse octal - module.report_error(); + 'd' => b: { + module.offset += 1; + break :b module.parse_decimal(); }, - 'b' => { - // TODO: parse binary - module.report_error(); + 'o' => b: { + module.offset += 1; + break :b module.parse_octal(); + }, + 'b' => b: { + module.offset += 1; + break :b module.parse_binary(); }, '0'...'9' => { module.report_error(); diff --git a/src/compiler.bbb b/src/compiler.bbb index 4882790..52f2bac 100644 --- a/src/compiler.bbb +++ b/src/compiler.bbb @@ -174,6 +174,7 @@ os_commit = fn (address: u64, size: u64, protection: OS_ProtectionFlags) void os_make_directory = fn (path: &u8) void { + >result = mkdir(path, 0o755); } Arena = struct diff --git a/src/lib.zig b/src/lib.zig index 0d7115e..8957823 100644 --- a/src/lib.zig +++ b/src/lib.zig @@ -2865,6 +2865,14 @@ pub const parse = struct { pub fn accumulate_decimal(accumulator: u64, ch: u8) u64 { return (accumulator * 10) + (ch - '0'); } + + pub fn accumulate_octal(accumulator: u64, ch: u8) u64 { + return (accumulator * 8) + (ch - '0'); + } + + pub fn accumulate_binary(accumulator: u64, ch: u8) u64 { + return (accumulator * 2) + (ch - '0'); + } }; test "parse integer decimal" { diff --git a/src/main.zig b/src/main.zig index 1480e53..4a25e2f 100644 --- a/src/main.zig +++ b/src/main.zig @@ -320,4 +320,6 @@ const names = &[_][]const u8{ "pointer_decay", "enum_name", "slice_of_slices", + "type_alias", + "integer_formats", }; diff --git a/tests/integer_formats.bbb b/tests/integer_formats.bbb new file mode 100644 index 0000000..88c6bc1 --- /dev/null +++ b/tests/integer_formats.bbb @@ -0,0 +1,7 @@ +[export] main = fn [cc(c)] () s32 +{ + >a: s32 = 0o10; + >b: s32 = 0b1000; + >c: s32 = 0d0; + return a - b + c; +}