Skip to content

Instantly share code, notes, and snippets.

@MinekPo1
Last active August 24, 2022 17:10
Show Gist options
  • Save MinekPo1/99ae6322787c73699645e952d35be826 to your computer and use it in GitHub Desktop.
Save MinekPo1/99ae6322787c73699645e952d35be826 to your computer and use it in GitHub Desktop.
jump analiser for SLVM machine code
"""
(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.***
"""
@MinekPo1
Copy link
Author

Now supports jt and jf

@MinekPo1
Copy link
Author

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