Skip to content

Commit 5d621d0

Browse files
committed
compiler: fill out symtable machinery
* Implement opt and scopes * Make functions and nested functions work * Stringer symbols for flags to aid debugging
1 parent 39eaaff commit 5d621d0

File tree

5 files changed

+904
-93
lines changed

5 files changed

+904
-93
lines changed

compile/make_symtable_test.py

Lines changed: 45 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,16 @@
1313

1414
inp = [
1515
('''1''', "eval"),
16-
#('''a*b*c''', "eval"),
17-
#('''def fn(): pass''', "exec"),
18-
#('''def fn(a,b):\n e=1\n return a*b*c*d*e''', "exec"),
19-
#('''def fn(a,b):\n def nested(c,d):\n return a*b*c*d*e''', "exec"),
20-
# ('''def fn(a,b,c): pass''', "exec"),
21-
# ('''def fn(a,b=1,c=2): pass''', "exec"),
22-
# ('''def fn(a,*arg,b=1,c=2): pass''', "exec"),
23-
# ('''def fn(a,*arg,b=1,c=2,**kwargs): pass''', "exec"),
24-
# ('''def fn(a:"a",*arg:"arg",b:"b"=1,c:"c"=2,**kwargs:"kw") -> "ret": pass''', "exec"),
25-
# ('''def fn(): a+b''', "exec"),
16+
('''a*b*c''', "eval"),
17+
('''def fn(): pass''', "exec"),
18+
('''def fn(a,b):\n e=1\n return a*b*c*d*e''', "exec"),
19+
('''def fn(a,b):\n def nested(c,d):\n return a*b*c*d*e''', "exec"),
20+
('''\
21+
def fn(a:"a",*arg:"arg",b:"b"=1,c:"c"=2,**kwargs:"kw") -> "ret":
22+
def fn(A,b):
23+
e=1
24+
return a*arg*b*c*kwargs*A*e*glob''', "exec"),
25+
# FIXME need with x as y
2626
]
2727

2828
def dump_bool(b):
@@ -52,29 +52,57 @@ def dump_strings(ss):
5252
("defImport", 2<<6), # assignment occurred via import
5353
)
5454

55+
#opt flags flags to names (from symtable.h)
56+
OPT_FLAGS = (
57+
("optImportStar", 1),
58+
("optTopLevel", 2),
59+
)
60+
5561
BLOCK_TYPES = {
5662
"function": "FunctionBlock",
5763
"class": "ClassBlock",
5864
"module": "ModuleBlock",
5965
}
6066

67+
def dump_flags(flag_bits, flags_dict):
68+
"""Dump the bits in flag_bits using the flags_dict"""
69+
flags = []
70+
for name, mask in flags_dict:
71+
if (flag_bits & mask) != 0:
72+
flags.append(name)
73+
if not flags:
74+
flags = ["0"]
75+
return "|".join(flags)
76+
6177
def dump_symtable(st):
6278
"""Dump the symtable"""
6379
out = "&SymTable{\n"
6480
out += 'Type:%s,\n' % BLOCK_TYPES[st.get_type()] # Return the type of the symbol table. Possible values are 'class', 'module', and 'function'.
6581
out += 'Name:"%s",\n' % st.get_name() # Return the table’s name. This is the name of the class if the table is for a class, the name of the function if the table is for a function, or 'top' if the table is global (get_type() returns 'module').
6682

6783
out += 'Lineno:%s,\n' % st.get_lineno() # Return the number of the first line in the block this table represents.
68-
out += 'Optimized:%s,\n' % dump_bool(st.is_optimized()) # Return True if the locals in this table can be optimized.
84+
out += 'Unoptimized:%s,\n' % dump_flags(st._table.optimized, OPT_FLAGS) # Return False if the locals in this table can be optimized.
6985
out += 'Nested:%s,\n' % dump_bool(st.is_nested()) # Return True if the block is a nested class or function.
70-
out += 'Exec:%s,\n' % dump_bool(st.has_exec()) # Return True if the block uses exec.
71-
out += 'ImportStar:%s,\n' % dump_bool(st.has_import_star()) # Return True if the block uses a starred from-import.
86+
#out += 'Exec:%s,\n' % dump_bool(st.has_exec()) # Return True if the block uses exec.
87+
#out += 'ImportStar:%s,\n' % dump_bool(st.has_import_star()) # Return True if the block uses a starred from-import.
88+
out += 'Varnames:%s,\n' % dump_strings(st._table.varnames)
7289
out += 'Symbols: Symbols{\n'
90+
children = dict()
7391
for name in st.get_identifiers():
74-
value = st.lookup(name)
75-
out += '"%s":%s,\n' % (name, dump_symbol(value))
92+
s = st.lookup(name)
93+
out += '"%s":%s,\n' % (name, dump_symbol(s))
94+
ns = s.get_namespaces()
95+
if len(ns) == 0:
96+
pass
97+
elif len(ns) == 1:
98+
children[name] = ns[0]
99+
else:
100+
raise AssertionError("More than one namespace")
101+
out += '},\n'
102+
out += 'Children:map[string]*SymTable{\n'
103+
for name, symtable in children.items():
104+
out += '"%s":%s,\n' % (name, dump_symtable(symtable))
76105
out += '},\n'
77-
# out += 'children:"%s",\n' % st.get_children() # Return a list of the nested symbol tables.
78106
out += "}"
79107
return out
80108

@@ -83,27 +111,9 @@ def dump_symbol(s):
83111
#class symtable.Symbol
84112
# An entry in a SymbolTable corresponding to an identifier in the source. The constructor is not public.
85113
out = "Symbol{\n"
86-
out += 'Name:"%s",\n' % s.get_name() # Return the symbol’s name.
87-
flags = []
88-
flag_bits = s._Symbol__flags
89-
for name, mask in DEF_FLAGS:
90-
if (flag_bits & mask) != 0:
91-
flags.append(name)
92-
if not flags:
93-
flags = ["0"]
94-
out += 'Flags:%s,\n' % "|".join(flags)
95-
114+
out += 'Flags:%s,\n' % dump_flags(s._Symbol__flags, DEF_FLAGS)
96115
scope = SCOPES.get(s._Symbol__scope, "scopeUnknown")
97116
out += 'Scope:%s,\n' % scope
98-
99-
# Return a namespace bound to this name.
100-
ns = s.get_namespaces()
101-
if len(ns) == 0:
102-
pass
103-
elif len(ns) == 1:
104-
out += 'Namespace:%s,\n' % dump_symtable(ns[0])
105-
else:
106-
raise AssertionError("More than one namespace")
107117
out += "}"
108118
return out
109119

compile/stringer.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// generated by stringer -type=Scope,BlockType -output stringer.go; DO NOT EDIT
2+
3+
package compile
4+
5+
import "fmt"
6+
7+
const _Scope_name = "scopeInvalidscopeLocalscopeGlobalExplicitscopeGlobalImplicitscopeFreescopeCell"
8+
9+
var _Scope_index = [...]uint8{0, 12, 22, 41, 60, 69, 78}
10+
11+
func (i Scope) String() string {
12+
if i+1 >= Scope(len(_Scope_index)) {
13+
return fmt.Sprintf("Scope(%d)", i)
14+
}
15+
return _Scope_name[_Scope_index[i]:_Scope_index[i+1]]
16+
}
17+
18+
const _BlockType_name = "FunctionBlockClassBlockModuleBlock"
19+
20+
var _BlockType_index = [...]uint8{0, 13, 23, 34}
21+
22+
func (i BlockType) String() string {
23+
if i+1 >= BlockType(len(_BlockType_index)) {
24+
return fmt.Sprintf("BlockType(%d)", i)
25+
}
26+
return _BlockType_name[_BlockType_index[i]:_BlockType_index[i+1]]
27+
}

0 commit comments

Comments
 (0)