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:
@@ -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,
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user