Skip to content

Instantly share code, notes, and snippets.

@tzaffi
Created December 23, 2021 03:39
Show Gist options
  • Save tzaffi/634d98dd92547566417137b509d92052 to your computer and use it in GitHub Desktop.
Save tzaffi/634d98dd92547566417137b509d92052 to your computer and use it in GitHub Desktop.
TEAL Program Diff
>>> progx = '#pragma version 5\ncallsub sub0\nint 1\nreturn\nsub0: // _impl\nint 0\nstore 0\nsub0_l1:\nload 0\nint 10\n<\nbz sub0_l3\nbyte "a"\nlog\nload 0\nint 1\n+\nstore 0\nb sub0_l1\nsub0_l3:\nretsub'
>>> progy = '#pragma version 5\ncallsub sub0\nint 1\nreturn\nsub0: // <lambda>\nint 0\nstore 0\nsub0_l1:\nload 0\nint 10\n<\nbz sub0_l3\nbyte "a"\nlog\nload 0\nint 1\n+\nstore 0\nb sub0_l1\nsub0_l3:\nretsub'
>>> td1 = TEALDiff(progx, progy)
>>> td1.assert_equals(msg=td1.first_diff())
# ... no problems ...
>>> td2 = TEALDiff(progx, progy, strip_comments=False)
>>> td2.assert_equals(td2.first_diff())
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
/var/folders/xf/ks83gjdd16dctb70r8p79w8h0000gp/T/ipykernel_50636/134533541.py in <module>
----> 1 td2.assert_equals(td2.first_diff())
/var/folders/xf/ks83gjdd16dctb70r8p79w8h0000gp/T/ipykernel_50636/3106005331.py in assert_equals(self, msg)
28
29 def assert_equals(self, msg: str = None) -> None:
---> 30 assert self.all_the_same(), msg
31
32 def first_diff(self) -> Union["LineDiff", None]:
AssertionError: <LINE 5>[sub0: // _impl] --> [sub0: // <lambda>]
import re
from typing import List, Union
class LineDiff:
def __init__(self, line_num: int, x: str, y: str):
self.line_num = line_num
self.x = x
self.y = y
self.same = (x == y)
def __repr__(self) -> str:
LN = f"<LINE {self.line_num}>"
return LN + ("(same)" if self.same else f"[{self.x}] --> [{self.y}]")
class TEALDiff:
def __init__(self, program_x: str, program_y: str, strip_comments: bool = True):
self.x = program_x
self.y = program_y
self.strip_comments = strip_comments
self.diffs: List["LineDiff"] = self.diff()
def all_the_same(self) -> bool:
return all(map(lambda d: d.same, self.diffs))
def assert_equals(self, msg: str = None) -> None:
assert self.all_the_same(), msg
def first_diff(self) -> Union["LineDiff", None]:
for diff in self.diffs:
if not diff.same:
return diff
return None
@classmethod
def decomment(cls, line: str) -> str:
m = re.search('(// [^"]+$)', line)
if not m:
return line
return line[:-len(m.groups()[-1])]
@classmethod
def lines(cls, src: str, strip_comments: bool = True) -> List[str]:
lines = map(lambda s: s.strip(), src.splitlines())
if strip_comments:
lines = map(lambda s: cls.decomment(s).strip(), lines)
return list(lines)
def diff(self) -> List["LineDiff"]:
xlines = self.lines(self.x, strip_comments=self.strip_comments)
ylines = self.lines(self.y, strip_comments=self.strip_comments)
len_diff = len(ylines) - len(xlines)
if len_diff < 0:
ylines += [""] * -len_diff
elif len_diff > 0:
xlines += [""] * len_diff
n = len(xlines)
line_diffs = list(map(lambda z: LineDiff(*z), zip(range(1, n+1), xlines, ylines)))
return line_diffs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment