리졸버를 위한 자리: Node.bind 와 Map.clear
ast.Node 가 이름이 무엇으로 해석됐는지 들고, Map 이 저장소를 유지한 채 키만 잊는다. 스코프가 끝날 때 표를 다음 스코프에 넘기는 것이 리졸버가 원하는 모양이다 -- 함수마다가 아니라 중첩 단계마다 표 하나. bind 는 Name 노드의 남는 a 필드를 재활용할 수도 있었지만 명시적인 쪽을 골랐다. 노드가 32 에서 36 바이트가 되는 값으로 그 자리가 무엇인지 이름이 말한다. clear 는 아무도 부르지 않는 채로 들어와 있었다. maps.fe 가 이제 부른다: 키가 사라지고, 방은 64 로 남고, 그 위에 다시 채워도 버퍼를 새로 잡지 않는다. cleared 0 room 64 gone 0 / refilled 3 / balanced GOAL.md 를 더했다. 외부 감사와, 그 항목들을 실제로 빌드해서 확인한 결과를 합친 P0~P4 다. 228/228, 32/32.
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
// OUTPUT:fn 2 let 3 missing 0
|
||||
// OUTPUT:grown 64
|
||||
// OUTPUT:after 40
|
||||
// OUTPUT:cleared 0 room 64 gone 0
|
||||
// OUTPUT:refilled 3
|
||||
// OUTPUT:balanced
|
||||
unit maps;
|
||||
import std.io;
|
||||
@@ -37,6 +39,26 @@ fn run() -> !void {
|
||||
i = i + 1;
|
||||
}
|
||||
@print("after {}\n", found);
|
||||
|
||||
// `clear` forgets every key and keeps the storage, which is what a scope
|
||||
// that ends wants: hand the table to the next one without going back to
|
||||
// the allocator. The room has to survive and the keys have to not.
|
||||
let room: usize = seen.room();
|
||||
seen.clear();
|
||||
var gone: usize = 0;
|
||||
i = 0;
|
||||
while i < 40 {
|
||||
let n: usize = fmt.fmt_i32(buf[..], i as i32);
|
||||
if seen.has(buf[0..n]) { gone = gone + 1; }
|
||||
i = i + 1;
|
||||
}
|
||||
@print("cleared {} room {} gone {}\n", seen.count_of(), room, gone);
|
||||
|
||||
// And it is usable again afterwards, reusing the same buffers.
|
||||
try seen.put("a", 1);
|
||||
try seen.put("b", 2);
|
||||
try seen.put("c", 3);
|
||||
@print("refilled {}\n", seen.count_of());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user