File: Synopsis/IR.py
 1#
 2# Copyright (C) 2007 Stefan Seefeld
 3# All rights reserved.
 4# Licensed to the public under the terms of the GNU LGPL (>= 2),
 5# see the file COPYING for details.
 6#
 7
 8import ASG
 9import SXR
10import cPickle
11
12class IR(object):
13    """Top-level Internal Representation. This is essentially a dictionary
14    of different representations such as Parse Tree, Abstract Semantic Graph, etc.
15    """
16
17    def __init__(self, files=None, asg=None, sxr=None):
18        """Constructor"""
19
20        self.files = files or {}
21        """A dictionary mapping filenames to `SourceFile.SourceFile` instances."""
22        self.asg = asg or ASG.ASG()
23        """The Abstract Semantic Graph."""
24        self.sxr = sxr or SXR.SXR()
25        """The Source Cross-Reference SymbolTable."""
26
27    def copy(self):
28        """Make a shallow copy of this IR."""
29
30        return type(self)(self.files.copy(),
31                          self.asg.copy(),
32                          self.sxr)
33
34    def save(self, filename):
35        """Saves an IR object to the given filename"""
36
37        file = open(filename, 'wb')
38        pickler = cPickle.Pickler(file, 1)
39        pickler.dump(self)
40        file.close()
41
42    def merge(self, other):
43        """Merges another IR. Files and declarations are appended to those in
44        this IR, and types are merged by overwriting existing types -
45        Unduplicator is responsible for sorting out the mess this may cause :)"""
46
47        #merge files
48        replacement = {}
49        for filename, file in other.files.iteritems():
50            if not self.files.has_key(filename):
51                self.files[filename] = file
52                continue
53            myfile = self.files[filename]
54            replacement[file] = myfile
55            # the 'main' flag dominates...
56            if not myfile.annotations['primary']:
57                myfile.annotations['primary'] = file.annotations['primary']
58            myfile.declarations.extend(file.declarations)
59            myfile.includes.extend(file.includes)
60        # fix dangling inclusions of 'old' files
61        for r in replacement:
62            for f in self.files.values():
63                for i in f.includes:
64                    if i.target == r:
65                        i.target = replacement[r]
66
67        # merge ASG
68        self.asg.merge(other.asg)
69
70        # merge SXR
71        self.sxr.merge(other.sxr)
72
73
74def load(filename):
75    """Loads an IR object from the given filename"""
76
77    file = open(filename, 'rb')
78    unpickler = cPickle.Unpickler(file)
79    ir = unpickler.load()
80    file.close()
81    return ir
82