Save information about old values of values

This commit is contained in:
ZyX 2015-01-07 19:55:00 +03:00
parent c9d1b81954
commit ee78221af4
2 changed files with 53 additions and 8 deletions

View File

@ -42,15 +42,16 @@ def strtrans(s):
class Mark:
def __init__(self, name, line, column, buffer, pointer):
def __init__(self, name, line, column, buffer, pointer, old_mark=None):
self.name = name
self.line = line
self.column = column
self.buffer = buffer
self.pointer = pointer
self.old_mark = old_mark
def copy(self):
return Mark(self.name, self.line, self.column, self.buffer, self.pointer)
return Mark(self.name, self.line, self.column, self.buffer, self.pointer, self.old_mark)
def get_snippet(self, indent=4, max_length=75):
if self.buffer is None:
@ -85,17 +86,46 @@ class Mark:
ret.pointer += diff
return ret
def __str__(self):
snippet = self.get_snippet()
where = (' in "%s", line %d, column %d' % (
self.name, self.line + 1, self.column + 1))
if snippet is not None:
where += ':\n' + snippet
def set_old_mark(self, old_mark):
if self is old_mark:
return
checked_marks = set([id(self)])
older_mark = old_mark
while True:
if id(older_mark) in checked_marks:
raise ValueError('Trying to set recursive marks')
checked_marks.add(id(older_mark))
older_mark = older_mark.old_mark
if not older_mark:
break
self.old_mark = old_mark
def to_string(self, indent=0):
mark = self
where = ''
processed_marks = set()
while mark:
indentstr = ' ' * indent
snippet = mark.get_snippet(indent=(indent + 4))
where += (indentstr + ' in "%s", line %d, column %d' % (
mark.name, mark.line + 1, mark.column + 1))
if snippet:
where += ':\n' + snippet
processed_marks.add(id(mark))
if mark.old_mark:
where += '\n' + indentstr + ' which replaced value\n'
indent += 4
mark = mark.old_mark
if id(mark) in processed_marks:
raise ValueError('Trying to dump recursive mark')
if type(where) is str:
return where
else:
return where.encode('utf-8')
def __str__(self):
return self.to_string()
def echoerr(*args, **kwargs):
stream = kwargs.pop('stream', sys.stderr)

View File

@ -66,6 +66,21 @@ class MarkedDict(dict):
return r
def __setitem__(self, key, value):
try:
old_value = self[key]
except KeyError:
pass
else:
try:
key.mark.set_old_mark(self.keydict[key].mark)
except AttributeError:
pass
except KeyError:
pass
try:
value.mark.set_old_mark(old_value.mark)
except AttributeError:
pass
dict.__setitem__(self, key, value)
self.keydict[key] = key