minor refactoring

This commit is contained in:
2026-07-25 00:23:52 +02:00
parent ad54a00893
commit c7f527e3c3
5 changed files with 49 additions and 40 deletions
+16 -9
View File
@@ -5,7 +5,7 @@ import "@std/strmap"
import "@source/strpool" import "@source/strpool"
keywords std.StaticStringMap(TokenKind) :: strmap.init([ keywords std.StringMap(TokenKind) :: strmap.init([
{ "proc", .proc }, { "proc", .proc },
{ "return", .return }, { "return", .return },
{ "if", .if }, { "if", .if },
@@ -58,6 +58,9 @@ scan proc(state @mut State, input []u8) void ! (mem.AllocError | strpool.InternE
# comments # comments
if char == '#' { if char == '#' {
# fixme(brolang): while currently requires curly braces but this should be legal
#while (cursor < input.len and input[cursor] != '\n') cursor += 1
while cursor < input.len and input[cursor] != '\n' : cursor += 1 {} while cursor < input.len and input[cursor] != '\n' : cursor += 1 {}
continue continue
} }
@@ -96,9 +99,7 @@ scan proc(state @mut State, input []u8) void ! (mem.AllocError | strpool.InternE
has_decimal bool = false has_decimal bool = false
# scan integer part # scan integer part
while cursor < input.len and is_digit(input[cursor]) { while cursor < input.len and is_digit(input[cursor]) : cursor += 1 {}
cursor += 1
}
# check for decimal point # check for decimal point
if cursor < input.len and input[cursor] == '.' { if cursor < input.len and input[cursor] == '.' {
@@ -110,18 +111,21 @@ scan proc(state @mut State, input []u8) void ! (mem.AllocError | strpool.InternE
if has_decimal and (cursor >= input.len or !is_digit(input[cursor])) { if has_decimal and (cursor >= input.len or !is_digit(input[cursor])) {
token :: tokens.items.len token :: tokens.items.len
try arraylist.append(tokens, Token{ kind = .invalid, start = start }) try arraylist.append(tokens, Token{ kind = .invalid, start = start })
try arraylist.append(diagnostics, ScanDiagnostic{ token = token, message = "float must end with a digit" }) try arraylist.append(diagnostics, ScanDiagnostic{
token = token,
message = "float must end with a digit",
})
continue continue
} }
# scan decimal part # scan decimal part
while cursor < input.len and is_digit(input[cursor]) : cursor += 1 {} while cursor < input.len and is_digit(input[cursor]) : cursor += 1 {}
if has_decimal { if (has_decimal)
try arraylist.append(tokens, Token{ kind = .float, start = start }) try arraylist.append(tokens, Token{ kind = .float, start = start })
} else { else
try arraylist.append(tokens, Token{ kind = .int, start = start }) try arraylist.append(tokens, Token{ kind = .int, start = start })
}
continue continue
} }
@@ -184,7 +188,10 @@ scan proc(state @mut State, input []u8) void ! (mem.AllocError | strpool.InternE
# invalid character # invalid character
token :: tokens.items.len token :: tokens.items.len
try arraylist.append(tokens, Token{ kind = .invalid, start = cursor }) try arraylist.append(tokens, Token{ kind = .invalid, start = cursor })
try arraylist.append(diagnostics, ScanDiagnostic{ token = token, message = "invalid character" }) try arraylist.append(diagnostics, ScanDiagnostic{
token = token,
message = "invalid character",
})
cursor += 1 cursor += 1
} }
-23
View File
@@ -1,7 +1,6 @@
import "@std/mem" import "@std/mem"
import "@std/arraylist" import "@std/arraylist"
import "@std/hashmap" import "@std/hashmap"
import "@std/testing"
# cross-cutting concern, hence global singleton (owned by main.hon) # cross-cutting concern, hence global singleton (owned by main.hon)
strings StringPool = undefined strings StringPool = undefined
@@ -64,25 +63,3 @@ get_str proc(pool @StringPool, id StringId) ?[]u8 {
get_id proc(pool @StringPool, str []u8) ?StringId { get_id proc(pool @StringPool, str []u8) ?StringId {
return hashmap.get(&pool.ids, str) return hashmap.get(&pool.ids, str)
} }
handles_intern test {
pool StringPool = init(mem.c_allocator)
defer deinit(&pool)
input [5]mut u8 = ['h', 'e', 'l', 'l', 'o']
id :: try intern(&pool, input[..])
duplicate :: try intern(&pool, "hello")
input[0] = 'j'
same_id :: get_id(&pool, "hello")
mutated_id :: get_id(&pool, input[..])
hello_str :: get_str(&pool, id)
invalid_str :: get_str(&pool, id + 1)
try testing.expect_equal(0, id)
try testing.expect_equal(id, duplicate)
try testing.expect_equal(id, same_id?)
try testing.expect_equal(null, mutated_id)
try testing.expect_equal(null, invalid_str)
try testing.expect_equal("hello", hello_str?)
}
+24
View File
@@ -0,0 +1,24 @@
import "@std/mem"
import "@std/testing"
handles_intern test {
pool StringPool = init(mem.c_allocator)
defer deinit(&pool)
input [5]mut u8 = ['h', 'e', 'l', 'l', 'o']
id :: try intern(&pool, input[..])
duplicate :: try intern(&pool, "hello")
input[0] = 'j'
same_id :: get_id(&pool, "hello")
mutated_id :: get_id(&pool, input[..])
hello_str :: get_str(&pool, id)
invalid_str :: get_str(&pool, id + 1)
try testing.expect_equal(0, id)
try testing.expect_equal(id, duplicate)
try testing.expect_equal(id, same_id?)
try testing.expect_equal(null, mutated_id)
try testing.expect_equal(null, invalid_str)
try testing.expect_equal("hello", hello_str?)
}
+1 -1
View File
@@ -8,4 +8,4 @@ Io :: alias io.Io
EnumMap :: alias enums.EnumMap EnumMap :: alias enums.EnumMap
ArrayList :: alias arraylist.ArrayList ArrayList :: alias arraylist.ArrayList
StringHashMap :: alias hashmap.StringHashMap StringHashMap :: alias hashmap.StringHashMap
StaticStringMap :: alias strmap.StaticStringMap StringMap :: alias strmap.StringMap
+8 -7
View File
@@ -1,6 +1,6 @@
import "@std/mem" import "@std/mem"
StaticStringMap proc($V type) type { StringMap proc($V type) type {
return struct { return struct {
keys [][]u8 keys [][]u8
values []V values []V
@@ -14,7 +14,8 @@ hide Pair proc($V type) type {
return struct { []u8, V } return struct { []u8, V }
} }
init proc($V type, $N usize, $entries [N]Pair(V)) StaticStringMap(V) { #! initializes a static string map from a list of key-value pairs (constructed at compile-time).
init proc($V type, $N usize, $entries [N]Pair(V)) StringMap(V) {
if N > usize(maxval!(u32)) { if N > usize(maxval!(u32)) {
compile_error!("static string map has too many entries") compile_error!("static string map has too many entries")
} }
@@ -38,7 +39,7 @@ init proc($V type, $N usize, $entries [N]Pair(V)) StaticStringMap(V) {
if N == 0 { if N == 0 {
len_indexes [0]u32 = undefined len_indexes [0]u32 = undefined
return StaticStringMap(V){ return StringMap(V){
keys = keys[..], keys = keys[..],
values = values[..], values = values[..],
len_indexes = len_indexes[..], len_indexes = len_indexes[..],
@@ -47,7 +48,7 @@ init proc($V type, $N usize, $entries [N]Pair(V)) StaticStringMap(V) {
} }
} }
# fixme: insertion sort is compile-time O(N^2); replace if large maps affect builds # fixme: insertion sort is compile-time O(N²); replace if large maps affect builds
for 1..N |i| { for 1..N |i| {
key :: keys[i] key :: keys[i]
value :: values[i] value :: values[i]
@@ -69,7 +70,7 @@ init proc($V type, $N usize, $entries [N]Pair(V)) StaticStringMap(V) {
len_indexes[length] = u32(entry_index) len_indexes[length] = u32(entry_index)
} }
return StaticStringMap(V) { return StringMap(V) {
keys = keys[..], keys = keys[..],
values = values[..], values = values[..],
len_indexes = len_indexes[..], len_indexes = len_indexes[..],
@@ -78,7 +79,7 @@ init proc($V type, $N usize, $entries [N]Pair(V)) StaticStringMap(V) {
} }
} }
get proc($V type, map @StaticStringMap(V), key []u8) ?V { get proc($V type, map @StringMap(V), key []u8) ?V {
if (map.keys.len == 0 or key.len > maxval!(u32)) return null if (map.keys.len == 0 or key.len > maxval!(u32)) return null
length u32 = u32(key.len) length u32 = u32(key.len)
@@ -87,7 +88,7 @@ get proc($V type, map @StaticStringMap(V), key []u8) ?V {
idx usize = usize(map.len_indexes[usize(length)]) idx usize = usize(map.len_indexes[usize(length)])
while idx < map.keys.len : idx += 1 { while idx < map.keys.len : idx += 1 {
candidate :: map.keys[idx] candidate :: map.keys[idx]
if (candidate.len != key.len) return null if (candidate.len != key.len) return null # key not found
if mem.eql(u8, candidate, key) return map.values[idx] if mem.eql(u8, candidate, key) return map.values[idx]
} }
return null return null