From b0cc737c6be87180c9dc0a78334a1b8126560028 Mon Sep 17 00:00:00 2001 From: Sebastian Jeong Date: Mon, 17 Aug 2026 16:28:47 +0900 Subject: [PATCH] =?UTF-8?q?GOAL=20P3-5:=20StrId=20=EB=A5=BC=20=ED=82=A4?= =?UTF-8?q?=EB=A1=9C=20--=20=EB=B3=84=EB=8F=84=20IntMap=20=EC=9D=80=20?= =?UTF-8?q?=ED=95=84=EC=9A=94=20=EC=97=86=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit std.map 은 바이트 열을 키로 받는다. 이름의 번호를 네 바이트로 써 내려놓으면 그대로 심볼 표가 된다. 감사가 권한 IntMap(V) 를 따로 만들 이유가 없고, 그 쪽이 trait 없는 v0.1 과도 덜 싸운다. intern.key_of 가 그 네 바이트를 써준다. 리졸버가 스코프마다 할 일이라 손으로 풀게 두지 않았다. scope x 10 y 20 of 2 245/245, 38/38. --- fec/std/intern.fe | 11 +++++++++++ fec/tests/exec/interns.fe | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/fec/std/intern.fe b/fec/std/intern.fe index 03ddba8..613b9b1 100644 --- a/fec/std/intern.fe +++ b/fec/std/intern.fe @@ -28,6 +28,17 @@ pub struct StrId { /// No name. 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 { at: usize, len: usize, diff --git a/fec/tests/exec/interns.fe b/fec/tests/exec/interns.fe index dfcbb62..af68a10 100644 --- a/fec/tests/exec/interns.fe +++ b/fec/tests/exec/interns.fe @@ -5,12 +5,14 @@ // OUTPUT:find 1 missing yes // OUTPUT:hash steady yes apart yes // OUTPUT:copied unit 4 +// OUTPUT:scope x 10 y 20 of 2 // OUTPUT:balanced unit interns; import std.io; import std.sys; import std.intern; +import std.map; // 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 @@ -46,6 +48,15 @@ fn run() -> !void { var buf: [8]u8 = undefined; let n: usize = t.copy_into(a, buf[..]); @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; }