@@ -105,7 +105,8 @@ type SymTable struct {
105105 // col_offset int // offset of first line of block
106106 // opt_lineno int // lineno of last exec or import *
107107 // opt_col_offset int // offset of last exec or import *
108- TmpName int // counter for listcomp temp vars
108+ TmpName int // counter for listcomp temp vars
109+ Private string // name of current class or ""
109110
110111 Symbols Symbols
111112 Global * SymTable // symbol table entry for module
@@ -154,15 +155,32 @@ func newSymTableBlock(Ast ast.Ast, Type BlockType, Name string, parent *SymTable
154155 return stNew
155156}
156157
158+ // Add arguments to the symbol table
159+ func (st * SymTable ) addArgumentsToSymbolTable (node * ast.Arguments ) {
160+ if node .Args == nil {
161+ return
162+ }
163+ // skip default arguments inside function block
164+ // XXX should ast be different?
165+ for _ , arg := range node .Args {
166+ st .AddDef (arg .Arg , defParam )
167+ }
168+ for _ , arg := range node .Kwonlyargs {
169+ st .AddDef (arg .Arg , defParam )
170+ }
171+ if node .Vararg != nil {
172+ st .AddDef (node .Vararg .Arg , defParam )
173+ st .Varargs = true
174+ }
175+ if node .Kwarg != nil {
176+ st .AddDef (node .Kwarg .Arg , defParam )
177+ st .Varkeywords = true
178+ }
179+ }
180+
157181// Parse the ast into the symbol table
158182func (st * SymTable ) Parse (Ast ast.Ast ) {
159183 ast .Walk (Ast , func (Ast ast.Ast ) bool {
160- // New symbol tables needed at these points
161- // FunctionDef
162- // ClassDef
163- // Lambda
164- // Comprehension (all types of comprehension in py3)
165-
166184 switch node := Ast .(type ) {
167185 case * ast.Nonlocal :
168186 for _ , name := range node .Names {
@@ -211,19 +229,22 @@ func (st *SymTable) Parse(Ast ast.Ast) {
211229 st .AddDef (node .Name , defLocal )
212230 name := string (node .Name )
213231
214- // Make a new symtable
215- stNew := newSymTableBlock ( Ast , FunctionBlock , name , st )
216-
217- // Walk the Decorators and Returns in this Symtable
232+ // Walk these things in original symbol table
233+ if node . Args != nil {
234+ st . Parse ( node . Args )
235+ }
218236 for _ , expr := range node .DecoratorList {
219237 st .Parse (expr )
220238 }
221239 st .Parse (node .Returns )
222240
223- // Walk the Args and Body in the new symtable
224- if node .Args != nil {
225- stNew .Parse (node .Args )
226- }
241+ // Make a new symtable
242+ stNew := newSymTableBlock (Ast , FunctionBlock , name , st )
243+
244+ // Add the arguments to the new symbol table
245+ stNew .addArgumentsToSymbolTable (node .Args )
246+
247+ // Walk the Body in the new symtable
227248 for _ , stmt := range node .Body {
228249 stNew .Parse (stmt )
229250 }
@@ -232,9 +253,49 @@ func (st *SymTable) Parse(Ast ast.Ast) {
232253 return false
233254 case * ast.ClassDef :
234255 st .AddDef (node .Name , defLocal )
256+ name := string (node .Name )
257+ // Parse in the original symtable
258+ for _ , expr := range node .Bases {
259+ st .Parse (expr )
260+ }
261+ for _ , keyword := range node .Keywords {
262+ st .Parse (keyword )
263+ }
264+ if node .Starargs != nil {
265+ st .Parse (node .Starargs )
266+ }
267+ if node .Kwargs != nil {
268+ st .Parse (node .Kwargs )
269+ }
270+ for _ , expr := range node .DecoratorList {
271+ st .Parse (expr )
272+ }
273+ // Make a new symtable
274+ stNew := newSymTableBlock (Ast , ClassBlock , name , st )
275+ stNew .Private = name // set name of class
276+ // Parse body in new symtable
277+ for _ , stmt := range node .Body {
278+ stNew .Parse (stmt )
279+ }
280+ // return false to stop the parse
281+ return false
235282 case * ast.Lambda :
283+ // Parse in the original symtable
284+ if node .Args != nil {
285+ st .Parse (node .Args )
286+ }
287+
288+ // Make a new symtable
289+ stNew := newSymTableBlock (Ast , FunctionBlock , "lambda" , st )
236290
237- // Comprehensions
291+ // Add the arguments to the new symbol table
292+ stNew .addArgumentsToSymbolTable (node .Args )
293+
294+ // Walk the Body in the new symtable
295+ stNew .Parse (node .Body )
296+
297+ // return false to stop the parse
298+ return false
238299 case * ast.ListComp :
239300 st .parseComprehension (Ast , "listcomp" , node .Generators , node .Elt , nil )
240301 return false
@@ -247,30 +308,10 @@ func (st *SymTable) Parse(Ast ast.Ast) {
247308 case * ast.GeneratorExp :
248309 st .parseComprehension (Ast , "genexpr" , node .Generators , node .Elt , nil )
249310 return false
250-
251- case * ast.Arguments :
252- // skip default arguments inside function block
253- // XXX should ast be different?
254- for _ , arg := range node .Args {
255- st .AddDef (arg .Arg , defParam )
256- }
257- for _ , arg := range node .Kwonlyargs {
258- st .AddDef (arg .Arg , defParam )
259- }
260- if node .Vararg != nil {
261- st .AddDef (node .Vararg .Arg , defParam )
262- st .Varargs = true
263- }
264- if node .Kwarg != nil {
265- st .AddDef (node .Kwarg .Arg , defParam )
266- st .Varkeywords = true
267- }
268-
269311 case * ast.ExceptHandler :
270312 if node .Name != "" {
271313 st .AddDef (node .Name , defLocal )
272314 }
273-
274315 case * ast.Alias :
275316 // Compute store_name, the name actually bound by the import
276317 // operation. It is different than node.name when node.name is a
@@ -282,7 +323,7 @@ func (st *SymTable) Parse(Ast ast.Ast) {
282323 dot := strings .LastIndex (string (name ), "." )
283324 store_name := name
284325 if dot >= 0 {
285- store_name = name [dot + 1 : ]
326+ store_name = name [: dot ]
286327 }
287328 if name != "*" {
288329 st .AddDef (store_name , defImport )
@@ -292,7 +333,6 @@ func (st *SymTable) Parse(Ast ast.Ast) {
292333 }
293334 st .Unoptimized |= optImportStar
294335 }
295-
296336 case * ast.Return :
297337 if node .Value != nil {
298338 st .ReturnsValue = true
@@ -342,18 +382,16 @@ func (st *SymTable) parseComprehension(Ast ast.Ast, scopeName string, generators
342382 stNew .Parse (elt )
343383}
344384
345- const duplicateArgument = "duplicate argument %q in function definition"
346-
347385// Add a symbol into the symble table
348386func (st * SymTable ) AddDef (name ast.Identifier , flags DefUse ) {
349- // FIXME mangled := _Py_Mangle(st.st_private , name)
387+ // FIXME mangled := _Py_Mangle(st.Private , name)
350388 mangled := string (name )
351389
352390 // Add or update the symbol in the Symbols
353391 if sym , ok := st .Symbols [mangled ]; ok {
354392 if (flags & defParam ) != 0 && (sym .Flags & defParam ) != 0 {
355393 // Is it better to use 'mangled' or 'name' here?
356- panic (py .ExceptionNewf (py .SyntaxError , duplicateArgument , name ))
394+ panic (py .ExceptionNewf (py .SyntaxError , "duplicate argument '%s' in function definition" , name ))
357395 // FIXME
358396 // PyErr_SyntaxLocationObject(st.st_filename,
359397 // st.st_cur.ste_lineno,
@@ -574,6 +612,14 @@ func (st *SymTable) CheckUnoptimized() {
574612 return
575613 }
576614
615+ // FIXME Acording to this
616+ // https://docs.python.org/3/whatsnew/3.0.html#removed-syntax
617+ //
618+ // The from module import * syntax is only allowed at the
619+ // module level, no longer inside functions.
620+ //
621+ // So I think this is dead code
622+
577623 trailer := "contains a nested function with free variables"
578624 if ! st .ChildFree {
579625 trailer = "is a nested function"
@@ -588,7 +634,7 @@ func (st *SymTable) CheckUnoptimized() {
588634 }
589635}
590636
591- /* Enter the final scope information into the ste_symbols dict.
637+ /* Enter the final scope information into the st.Symbols dict.
592638 *
593639 * All arguments are dicts. Modifies symbols, others are read-only.
594640 */
@@ -601,6 +647,9 @@ func (symbols Symbols) Update(scopes Scopes, bound, free StringSet, classflag bo
601647
602648 /* Record not yet resolved free variables from children (if any) */
603649 for name := range free {
650+ // FIXME haven't managed to find a test case for this code
651+ // suspect a problem!
652+
604653 /* Handle symbol that already exists in this scope */
605654 if symbol , ok := symbols [name ]; ok {
606655 /* Handle a free variable in a method of
@@ -643,12 +692,6 @@ func (symbols Symbols) Update(scopes Scopes, bound, free StringSet, classflag bo
643692 propagate back to a parent block.
644693*/
645694func (st * SymTable ) AnalyzeBlock (bound , free , global StringSet ) {
646- // PyObject *name, *v, *local = nil, *scopes = nil, *newbound = nil;
647- // PyObject *newglobal = nil, *newfree = nil, *allfree = nil;
648- // PyObject *temp;
649- // int i, success = 0;
650- // Py_ssize_t pos = 0;
651-
652695 local := make (StringSet ) // collect new names bound in block
653696 scopes := make (Scopes ) // collect scopes defined for each name
654697
0 commit comments