GOAL P3-5: StrId 를 키로 -- 별도 IntMap 은 필요 없다

std.map 은 바이트 열을 키로 받는다. 이름의 번호를 네 바이트로 써 내려놓으면
그대로 심볼 표가 된다. 감사가 권한 IntMap(V) 를 따로 만들 이유가 없고, 그
쪽이 trait 없는 v0.1 과도 덜 싸운다.

intern.key_of 가 그 네 바이트를 써준다. 리졸버가 스코프마다 할 일이라
손으로 풀게 두지 않았다.

  scope x 10 y 20 of 2

245/245, 38/38.
This commit is contained in:
2026-08-17 16:28:47 +09:00
parent b7ce16f65e
commit b0cc737c6b
2 changed files with 22 additions and 0 deletions
+11
View File
@@ -28,6 +28,17 @@ pub struct StrId {
/// No name. /// No name.
pub const NONE: u32 = 4294967295; pub const NONE: u32 = 4294967295;
/// A name written out as map key bytes. `std.map` keys on bytes, so a name
/// used as a key is just its number -- four of them, and nothing allocated.
/// A symbol table is `Map(V)` keyed on this.
pub fn key_of(id: StrId, out: []mut u8) -> []u8 {
out[0] = (id.raw % 256) as u8;
out[1] = ((id.raw / 256) % 256) as u8;
out[2] = ((id.raw / 65536) % 256) as u8;
out[3] = ((id.raw / 16777216) % 256) as u8;
return out[0..4];
}
struct Entry { struct Entry {
at: usize, at: usize,
len: usize, len: usize,
+11
View File
@@ -5,12 +5,14 @@
// OUTPUT:find 1 missing yes // OUTPUT:find 1 missing yes
// OUTPUT:hash steady yes apart yes // OUTPUT:hash steady yes apart yes
// OUTPUT:copied unit 4 // OUTPUT:copied unit 4
// OUTPUT:scope x 10 y 20 of 2
// OUTPUT:balanced // OUTPUT:balanced
unit interns; unit interns;
import std.io; import std.io;
import std.sys; import std.sys;
import std.intern; import std.intern;
import std.map;
// One copy of every distinct name, and a number that stands for it. Comparing // One copy of every distinct name, and a number that stands for it. Comparing
// two names is comparing two integers; storing one costs four bytes and no // two names is comparing two integers; storing one costs four bytes and no
@@ -46,6 +48,15 @@ fn run() -> !void {
var buf: [8]u8 = undefined; var buf: [8]u8 = undefined;
let n: usize = t.copy_into(a, buf[..]); let n: usize = t.copy_into(a, buf[..]);
@print("copied {} {}\n", buf[0..n], n); @print("copied {} {}\n", buf[0..n], n);
// A symbol table is a Map keyed on the name's number. std.map keys on
// bytes, so no separate integer-keyed map is needed.
var scope: map.Map(i32) = try map.Map(i32).with_capacity(8);
var key: [4]u8 = undefined;
try scope.put(intern.key_of(a, key[..]), 10);
try scope.put(intern.key_of(b, key[..]), 20);
@print("scope x {} y {} of {}\n", scope.get(intern.key_of(a, key[..]), -1),
scope.get(intern.key_of(b, key[..]), -1), scope.count_of());
return; return;
} }