Skip to content

Commit 329523c

Browse files
committed
symtable: add Find() method
1 parent f0cbe48 commit 329523c

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

symtable/symtable.go

+13
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ package symtable
1212
import (
1313
"fmt"
1414
"log"
15+
"sort"
1516
"strings"
1617

1718
"github.com/ncw/gpython/ast"
@@ -782,3 +783,15 @@ func (st *SymTable) Analyze() {
782783
global := make(StringSet)
783784
st.AnalyzeBlock(nil, free, global)
784785
}
786+
787+
// Return a sorted list of symbol names if the scope of a name matches
788+
// either scopeType or flag is set
789+
func (st *SymTable) Find(scopeType Scope, flag DefUseFlags) (out []string) {
790+
for name, v := range st.Symbols {
791+
if v.Scope == scopeType || (v.Flags&flag) != 0 {
792+
out = append(out, name)
793+
}
794+
}
795+
sort.Strings(out)
796+
return out
797+
}

symtable/symtable_test.go

+41
Original file line numberDiff line numberDiff line change
@@ -169,3 +169,44 @@ func TestStringer(t *testing.T) {
169169
EqString(t, "BlockType", "ClassBlock", ClassBlock.String())
170170
EqString(t, "BlockType", "BlockType(100)", BlockType(100).String())
171171
}
172+
173+
func TestSymTableFind(t *testing.T) {
174+
st := &SymTable{
175+
Symbols: Symbols{
176+
"x": Symbol{
177+
Flags: DefLocal | DefNonlocal,
178+
Scope: ScopeFree,
179+
},
180+
"a": Symbol{
181+
Flags: DefLocal | DefNonlocal,
182+
Scope: ScopeFree,
183+
},
184+
"b": Symbol{
185+
Flags: DefLocal | DefNonlocal,
186+
Scope: ScopeFree,
187+
},
188+
"c": Symbol{
189+
Flags: DefNonlocal,
190+
Scope: ScopeCell,
191+
},
192+
"d": Symbol{
193+
Flags: DefLocal,
194+
Scope: ScopeCell,
195+
},
196+
},
197+
}
198+
199+
for _, test := range []struct {
200+
scope Scope
201+
flag DefUseFlags
202+
want []string
203+
}{
204+
{scope: ScopeGlobalExplicit, flag: 0, want: []string{}},
205+
{scope: ScopeFree, flag: 0, want: []string{"a", "b", "x"}},
206+
{scope: ScopeFree, flag: DefLocal, want: []string{"a", "b", "d", "x"}},
207+
{scope: 0, flag: DefNonlocal, want: []string{"a", "b", "c", "x"}},
208+
} {
209+
got := st.Find(test.scope, test.flag)
210+
EqStrings(t, fmt.Sprintf("Scope %v, Flag %v", test.scope, test.flag), test.want, got)
211+
}
212+
}

0 commit comments

Comments
 (0)