Created
December 23, 2021 03:39
-
-
Save tzaffi/634d98dd92547566417137b509d92052 to your computer and use it in GitHub Desktop.
TEAL Program Diff
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
>>> 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>] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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