Skip to content

enhancements scope transformimpl

DagSverreSeljebotn edited this page May 17, 2008 · 8 revisions

This is to answer the question: How to solve the scoping problem using a simple transform? (This might not be the proper solution, just investigating. I know too little about why the current variable scoping is broken.)

(Btw there's some rationale for doing this: It would closely emulate how the Python parser works when interpreting the module scope -- almost simulate running the module-level code (though with an eye only for the namespace handling). This kind of stuff (emulating the simple Python parser) is imnsho much easier to do with a visitor than in a recursive process.)

What one does: Transform every variable assignment, and reference, but the last one, to a temporary. I.e:

#!python
import math

f = 3
f = 34 + math.sin(f)

class f:
    x = f
    x = 2*f

x = f()

def f(y):
   return x(y)

def x(z):
    return 4

By a single pass (keeping track of names assigned to in AssignmentNodes and references to them in NameNode in dicts and lists) one can without much pain (= ~50 lines of "interesting but not really challenging code") transform this to (where each tmpx variable is a TempNode that doesn't name-clash with variables named tmpx, of course. Also the tmpx variables does not enter the module dict):

#!python

tmp1 = 3
tmp2 = 34 + math.sin(tmp1)

class tmp3:
    tmp4 = tmp2
    x = tmp4

tmp5 = tmp3()

def f(y):
    return x(y) # Python semantics is to keep x here now, and not tmp4 which is x at definition time? Transform can work either way.

def tmp6(z):
    return 4

This will in turn cause static linking in the correct way everywhere.

In addition, some fudging of the function names stored etc. is needed (add an "should_appear_as" attribute to TempNode and use it in code generation of a function), but that appears to be it?

The same transform could easily raise an error when a global name is used before it is defined too.

Clone this wiki locally