|
@@ -0,0 +1,41 @@
|
|
|
+"""Defines source maps: dictionaries that map lines in generated source to debug information."""
|
|
|
+
|
|
|
+class SourceMap(object):
|
|
|
+ """A source map, which converts generated source lines to debug information."""
|
|
|
+ def __init__(self):
|
|
|
+ self.lines = {}
|
|
|
+
|
|
|
+ def map_line(self, line_number, debug_info):
|
|
|
+ """Assigns the given debug information to the given line."""
|
|
|
+ self.lines[line_number] = debug_info
|
|
|
+
|
|
|
+ def get_debug_info(self, line_number):
|
|
|
+ """Gets the debug information for the given line number, or None if no debug info was
|
|
|
+ found."""
|
|
|
+ return self.lines[line_number]
|
|
|
+
|
|
|
+class SourceMapBuilder(object):
|
|
|
+ """A type of object that makes it easy to build source maps for hierarchical instructions."""
|
|
|
+ def __init__(self, initial_line_number=0):
|
|
|
+ self.source_map = SourceMap()
|
|
|
+ self.debug_info_stack = []
|
|
|
+ self.line_number = initial_line_number - 1
|
|
|
+
|
|
|
+ def push_debug_info(self, debug_info):
|
|
|
+ """Informs the source map that subsequent lines of code will have the given debug
|
|
|
+ information associated with them."""
|
|
|
+ self.debug_info_stack.append(debug_info)
|
|
|
+
|
|
|
+ def pop_debug_info(self):
|
|
|
+ """Informs the source map that the debug information that was pushed last should
|
|
|
+ be discarded in favor of the debug information that was pushed onto the stack
|
|
|
+ just prior to it."""
|
|
|
+ return self.debug_info_stack.pop()
|
|
|
+
|
|
|
+ def append_line(self):
|
|
|
+ """Has the source map builder increment its line number counter, and assigns the debug
|
|
|
+ information that is at the top of the debug information stack to that line."""
|
|
|
+ self.line_number += 1
|
|
|
+ if len(self.debug_info_stack) > 0:
|
|
|
+ self.source_map.map_line(self.line_number, self.debug_info_stack[-1])
|
|
|
+
|