From 7ab94d4ed5e4a8fb21434d3d28cd4ab0e845d995 Mon Sep 17 00:00:00 2001 From: Slendi Date: Wed, 28 Feb 2024 16:34:40 +0200 Subject: [PATCH] Implement binary in the lexer Signed-off-by: Slendi --- src/lexer.odin | 27 ++++++++++++++++++++++++++- src/type.odin | 29 +++++++++++++++++++++++++++++ src/type_checker.odin | 2 +- test_type_checker.cat | 4 ++-- 4 files changed, 58 insertions(+), 4 deletions(-) diff --git a/src/lexer.odin b/src/lexer.odin index e25300e..67cd78c 100644 --- a/src/lexer.odin +++ b/src/lexer.odin @@ -369,10 +369,10 @@ lexer_read_number :: proc(lexer: ^Lexer) -> Token { end = lexer.position, } - // FIXME: Implement binary ReadMode :: enum { Normal, Hex, + Binary, } read_mode := ReadMode.Normal @@ -381,6 +381,11 @@ lexer_read_number :: proc(lexer: ^Lexer) -> Token { lexer_advance(lexer) crange.end = lexer.position lexer_advance(lexer) + } else if lexer.char == '0' && lexer.next == 'b' { + read_mode = .Binary + lexer_advance(lexer) + crange.end = lexer.position + lexer_advance(lexer) } whole_part: u64 = 0 @@ -402,6 +407,12 @@ lexer_read_number :: proc(lexer: ^Lexer) -> Token { lexer_advance(lexer) } whole_part = whole_part >> 4 + } else if read_mode == .Binary { + for lexer.char == '0' || lexer.char == '1' { + whole_part = (whole_part << 1) + u64(lexer.char) - '0' + crange.end = lexer.position + lexer_advance(lexer) + } } if lexer.char == '.' { @@ -435,6 +446,20 @@ lexer_read_number :: proc(lexer: ^Lexer) -> Token { lexer_advance(lexer) } fractional_part = fractional_part / 16 + } else if read_mode == .Binary { + append( + &g_message_list, + message_create( + .Error, + "Binary floating point numbers are not supported yet", + crange, + ), + ) + for lexer.char == '0' || lexer.char == '1' { + fractional_part = (fractional_part << 1) + u64(lexer.char) - '0' + crange.end = lexer.position + lexer_advance(lexer) + } } fractional_part_clone := fractional_part diff --git a/src/type.odin b/src/type.odin index 56a1fd1..c10091a 100644 --- a/src/type.odin +++ b/src/type.odin @@ -3,12 +3,17 @@ package main TypeKind :: enum { Integer, Float, + Pointer, + Array, } Type :: struct { kind: TypeKind, bit_size: u8, is_signed: bool, + pointer_to: ^Type, + array_of: ^Type, + array_size: u64, } FunctionType :: struct { @@ -19,6 +24,15 @@ FunctionType :: struct { compare_types :: proc(a: ^Type, b: ^Type) -> (ret: bool) { ret = a != nil && b != nil && a.kind == b.kind && a.bit_size == b.bit_size && a.is_signed == b.is_signed + if ret == false { + return + } + + if a.kind == .Pointer { + ret = compare_types(a.pointer_to, b.pointer_to) + } else if a.kind == .Array { + ret = a.array_size == b.array_size && compare_types(a.array_of, b.array_of) + } return } @@ -55,3 +69,18 @@ type_create_float :: proc(bit_size: u8) -> (ret: ^Type) { ret.is_signed = true return } + +type_create_pointer :: proc(to: ^Type) -> (ret: ^Type) { + ret = new(Type) + ret.kind = .Pointer + ret.pointer_to = to + return +} + +type_create_array :: proc(of: ^Type, size: u64) -> (ret: ^Type) { + ret = new(Type) + ret.kind = .Array + ret.array_of = of + ret.array_size = size + return +} diff --git a/src/type_checker.odin b/src/type_checker.odin index b4fa205..b4920f7 100644 --- a/src/type_checker.odin +++ b/src/type_checker.odin @@ -16,7 +16,7 @@ infer_type :: proc(parent: ^Node, child: ^Node) { #partial switch child.kind { case .Integer: child.return_type = type_create_integer(32, true) case .Float: child.return_type = type_create_float(32) - case .String: panic("FIXME: Add support for arrays") + case .String: child.return_type = type_create_array(type_create_integer(32, false), 0) case .Character: child.return_type = type_create_integer(32, false) } } else { diff --git a/test_type_checker.cat b/test_type_checker.cat index 45d3557..05f93c3 100644 --- a/test_type_checker.cat +++ b/test_type_checker.cat @@ -1,8 +1,8 @@ -let asdf := 123.0 +let asdf := 0b1101 as f32 let poop :: 12.0 + 2.0 * asdf fn name(a b: f32) i32 { ret (a + b) as i32 } -name 123 456.0 +name 123.0 456.0