10a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
20a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef flatten(tup):
30a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    elts = []
40a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    for elt in tup:
50a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if isinstance(elt, tuple):
60a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            elts = elts + flatten(elt)
70a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
80a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            elts.append(elt)
90a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return elts
100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
110a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass Set:
120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __init__(self):
130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.elts = {}
140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __len__(self):
150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return len(self.elts)
160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __contains__(self, elt):
170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return elt in self.elts
180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def add(self, elt):
190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.elts[elt] = elt
200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def elements(self):
210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return self.elts.keys()
220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def has_elt(self, elt):
230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return elt in self.elts
240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def remove(self, elt):
250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        del self.elts[elt]
260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def copy(self):
270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        c = Set()
280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        c.elts.update(self.elts)
290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return c
300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
310a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass Stack:
320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __init__(self):
330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.stack = []
340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.pop = self.stack.pop
350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __len__(self):
360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return len(self.stack)
370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def push(self, elt):
380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.stack.append(elt)
390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def top(self):
400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return self.stack[-1]
410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __getitem__(self, index): # needed by visitContinue()
420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return self.stack[index]
430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
440a8c90248264a8b26970b4473770bcc3df8515fJosh GaoMANGLE_LEN = 256 # magic constant from compile.c
450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
460a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef mangle(name, klass):
470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if not name.startswith('__'):
480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return name
490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if len(name) + 2 >= MANGLE_LEN:
500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return name
510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if name.endswith('__'):
520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return name
530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    try:
540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        i = 0
550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        while klass[i] == '_':
560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            i = i + 1
570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    except IndexError:
580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return name
590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    klass = klass[i:]
600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    tlen = len(klass) + len(name)
620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if tlen > MANGLE_LEN:
630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        klass = klass[:MANGLE_LEN-tlen]
640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return "_%s%s" % (klass, name)
660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
670a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef set_filename(filename, tree):
680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """Set the filename attribute to filename on every node in tree"""
690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    worklist = [tree]
700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    while worklist:
710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        node = worklist.pop(0)
720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        node.filename = filename
730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        worklist.extend(node.getChildNodes())
74