Last active
August 24, 2022 17:10
-
-
Save MinekPo1/99ae6322787c73699645e952d35be826 to your computer and use it in GitHub Desktop.
jump analiser for SLVM machine code
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
""" | |
(c) MinekPo1 | |
This code is under the FAFOL licence, which is attached at the end | |
""" | |
############ | |
# Settings # | |
############ | |
SPREAD = 2 | |
TWO_LINE_SEP = True | |
NO_H_LINES = True | |
########################################## | |
# Actual code, don't touch or read # | |
# Seriously you will suffer brain damage # | |
########################################## | |
lines: list[str] = [] | |
while True: | |
try: | |
lines.append(input()) | |
except (KeyboardInterrupt, EOFError): | |
break | |
lines = [line.strip() for line in lines] | |
jts = [] | |
ret = [] | |
con = {} | |
jumps: dict[int,int] = {} | |
do_jump = False | |
for i, line in enumerate(lines): | |
if line == "jmp": | |
do_jump = True | |
continue | |
elif line == "jts": | |
print(i + 1) | |
jts.append(i + 1) | |
do_jump = True | |
continue | |
elif line == "ret": | |
ret.append(i + 1) | |
continue | |
elif line == "jf": | |
do_jump = True | |
con[i + 1] = False | |
continue | |
elif line == "jt": | |
do_jump = True | |
con[i + 1] = True | |
continue | |
if do_jump: | |
jumps[i] = int(line) + 1 | |
do_jump = False | |
continue | |
# figure out what jumps are backwards | |
backwards: dict[int,int] = {v: k for k, v in jumps.items() if k > v} | |
for v in backwards.values(): | |
del jumps[v] | |
jump_stack: list[tuple[int,bool]] = [] | |
jump_targets: list[int] = [] | |
num_size = len(str(len(lines))) | |
def s(sep, ch): | |
return sep * SPREAD + ch | |
def print_separator(): | |
taken_columns = {j[0]:j[1] for j in jump_stack} | |
second_line = "" | |
header = " " * num_size + " |" | |
print(header, "", end="") | |
for i in range(max(taken_columns.keys()) + 1): | |
if TWO_LINE_SEP: | |
if i in taken_columns: | |
if taken_columns[i]: | |
print(s(" ","^"), end="") | |
second_line += s(" ","|") | |
else: | |
print(s(" ","|"), end="") | |
second_line += s(" ","v") | |
else: | |
print(s(" "," "), end="") | |
second_line += s(" "," ") | |
elif i in taken_columns: | |
if taken_columns[i]: | |
print(s(" ","^"), end="") | |
else: | |
print(s(" ","v"), end="") | |
else: | |
print(s(" "," "), end="") | |
print() | |
if TWO_LINE_SEP: | |
print(header,second_line) | |
for i in range(len(lines)+1): | |
new = [] | |
if i in jumps: | |
new.append((jumps[i],False)) | |
if i in backwards: | |
new.append((backwards[i],True)) | |
if new: | |
pluses = [j[0] for j in jump_stack] | |
m = max(pluses + [0]) | |
me= False | |
for (le,_),j2 in zip(jump_stack,jump_targets): | |
if le != m: | |
continue | |
if j2 == i: | |
me = True | |
break | |
affected = {} | |
# find the first free column | |
last = 0 | |
for n,b in new: | |
while last in pluses: | |
last += 1 | |
jump_stack.append((last, b)) | |
affected[last] = b | |
jump_targets.append(n) | |
pluses.append(last) | |
ext = last | |
while i in jump_targets: | |
p = jump_targets.index(i) | |
if jump_stack[p][0] > ext: | |
ext = jump_stack[p][0] | |
jump_targets.pop(p) | |
jump_stack.pop(p) | |
# e = " >)"[min(2,(i in jumps) + (i in jumps.values()) + (i in backwards))] | |
if i in jumps: | |
if i in jumps.values() or i in backwards: | |
e = ")" | |
else: | |
e = ">" | |
else: | |
e = " " | |
print(f"{i:>{num_size}} |" + e, end="") | |
if i in jts: | |
print("\bS", end="") | |
elif i in ret: | |
print("\br", end="") | |
elif i in con: | |
if con[i]: | |
print("\bt", end="") | |
else: | |
print("\bf", end="") | |
for j2 in range(max(pluses) + 1): | |
sep = " " if j2 >= ext + 1 or NO_H_LINES else "-" | |
if j2 in pluses: | |
if j2 == max(pluses): | |
if NO_H_LINES and j2 in affected: | |
print(s(sep,"v-"[affected[j2]])) | |
elif j2 == last: | |
print(s(sep,"\\")) | |
elif me: | |
print(s(sep,"/")) | |
else: | |
print(s(sep,"|")) | |
elif j2 == ext and not NO_H_LINES: | |
if j2 == last: | |
print(s(sep,"\\"),end="") | |
else: | |
print(s(sep,"/"),end="") | |
elif j2 >= ext + 1: | |
print(s(sep,"|"), end="") | |
elif not NO_H_LINES: | |
print(s(sep,"+"), end="") | |
elif j2 in affected: | |
print(s(sep,"v-"[affected[j2]]), end="") | |
else: | |
print(s(sep,"|",),end="") | |
else: | |
print(s(sep,sep), end="") | |
print_separator() | |
continue | |
if i in jump_targets: | |
pluses = [j[0] for j in jump_stack] | |
m = max(pluses + [0]) | |
me= False | |
for (le,_),j2 in zip(jump_stack,jump_targets): | |
if le != m: | |
continue | |
if j2 == i: | |
me = True | |
break | |
print(f"{i:>{num_size}} |" + (" >"[i in backwards.values()]), end="") | |
if i in jts: | |
print("\bS", end="") | |
if i in ret: | |
print("\br", end="") | |
ext = 0 | |
affect = {} | |
while i in jump_targets: | |
p = jump_targets.index(i) | |
if jump_stack[p][0] > ext: | |
ext = jump_stack[p][0] | |
jump_targets.pop(p) | |
affect[jump_stack[p][0]] = jump_stack[p][1] | |
jump_stack.pop(p) | |
for j2 in range(max(pluses) + 1): | |
sep = " " if j2 >= ext + 1 or NO_H_LINES else "-" | |
if j2 in pluses: | |
if j2 == max(pluses): | |
if me and not NO_H_LINES: | |
print(s(sep,"/")) | |
else: | |
print(s(sep,"|")) | |
elif j2 == ext and not NO_H_LINES: | |
print(s(sep,"/"),end="") | |
elif j2 >= ext + 1: | |
print(s(sep,"|"), end="") | |
elif not NO_H_LINES: | |
print(s(sep,"+"), end="") | |
elif j2 in affect: | |
print(s(sep,"-^"[affect[j2]]), end="") | |
else: | |
print(s(sep,"|"), end="") | |
else: | |
print(s(sep,sep), end="") | |
if jump_targets: | |
print_separator() | |
continue | |
if i in ret: | |
columns = [j[0] for j in jump_stack] | |
print(f"{i:>{num_size}} |r", end="") | |
for j in range(max(columns) + 1): | |
if j in columns: | |
print(s(" ","|"), end="") | |
else: | |
print(s(" "," "), end="") | |
print() | |
print_separator() | |
""" | |
License: | |
# The Fuck Around and Find Out License, version 0.2 | |
## Purpose | |
This license gives everyone as much permission to work with | |
this software as possible, while protecting contributors | |
from liability, and ensuring this software is used | |
ethically. | |
## Acceptance | |
In order to receive this license, you must agree to its | |
rules. The rules of this license are both obligations | |
under that agreement and conditions to your license. | |
You must not do anything with this software that triggers | |
a rule that you cannot or will not follow. | |
## Copyright | |
Each contributor licenses you to do everything with this | |
software that would otherwise infringe that contributor's | |
copyright in it. | |
## Ethics | |
This software must be used for Good, not Evil, as | |
determined by the primary contributors to the software. | |
## Excuse | |
If anyone notifies you in writing that you have not | |
complied with [Ethics](#ethics), you can keep your | |
license by taking all practical steps to comply within 30 | |
days after the notice. If you do not do so, your license | |
ends immediately. | |
## Patent | |
Each contributor licenses you to do everything with this | |
software that would otherwise infringe any patent claims | |
they can license or become able to license. | |
## Reliability | |
No contributor can revoke this license. | |
## No Liability | |
***As far as the law allows, this software comes as is, | |
without any warranty or condition, and no contributor | |
will be liable to anyone for any damages related to this | |
software or this license, under any kind of legal claim.*** | |
""" |
changed rendering a bit, old style can be brought back with NO_H_LINES = False
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Now supports
jt
andjf