vxx2 / vlib / v3 / types / scope.v
57 lines · 52 sloc · 1.28 KB · 6c4d26f1f98c5464b012a375667ab345e462f7e0
Raw
1module types
2
3// Scope represents scope data used by types.
4@[heap]
5pub struct Scope {
6pub mut:
7 parent &Scope = unsafe { nil }
8 names []string
9 types []Type
10}
11
12// new_scope returns a reusable type-checker scope with an optional parent.
13pub fn new_scope(parent &Scope) &Scope {
14 unsafe {
15 return &Scope{
16 parent: parent
17 }
18 }
19}
20
21// reset retargets a pooled scope, clearing its bindings while keeping the
22// backing storage capacity so reuse does not reallocate. Without this clear
23// a pooled scope's arrays accumulate every binding ever inserted across all
24// generations, turning lookup/insert into an O(n) scan over dead entries.
25pub fn (mut s Scope) reset(parent &Scope) {
26 s.parent = parent
27 s.names.clear()
28 s.types.clear()
29}
30
31// lookup returns the nearest visible type binding for `name`.
32pub fn (s &Scope) lookup(name string) ?Type {
33 if name.len == 0 {
34 return none
35 }
36 for i := s.names.len - 1; i >= 0; i-- {
37 if s.names[i] == name {
38 return s.types[i]
39 }
40 }
41 if s.parent != unsafe { nil } {
42 return s.parent.lookup(name)
43 }
44 return none
45}
46
47// insert records or updates a type binding in this scope.
48pub fn (mut s Scope) insert(name string, typ Type) {
49 for i := s.names.len - 1; i >= 0; i-- {
50 if s.names[i] == name {
51 s.types[i] = typ
52 return
53 }
54 }
55 s.names << name
56 s.types << typ
57}
58