Projet-Systemes-Informatiques/graph_interpreter.py
2023-05-31 16:44:29 +02:00

134 lines
4.3 KiB
Python

import sys
from textual.color import Color
from textual import events
from textual.app import App, ComposeResult
from textual.containers import Container, VerticalScroll
from textual.widgets import Footer, Header, Static
def getLinesToShow(ip, lines):
if ip > 1 and ip + 2 < len(lines):
l= lines[ip - 2: ip + 3]
l[2] = "> " + l[2] + " <"
elif ip <= 1:
l= lines[0: 5]
l[ip] = "> " + l[ip] + " <"
else:
l= lines[-5:]
l[ip-len(lines)] = "> " + l[ip-len(lines)] + " <"
return l
def update_interpreter(self):
global ip
global ASMLines
global dataMem
if "NOP" not in ASMLines[ip]:
incr = 1
currLine = ASMLines[ip].split()
match currLine[0]:
case "ADD":
dataMem[currLine[1]] = dataMem[currLine[2]] + dataMem[currLine[3]]
case "MUL":
dataMem[currLine[1]] = dataMem[currLine[2]] * dataMem[currLine[3]]
case "SUB":
dataMem[currLine[1]] = dataMem[currLine[2]] - dataMem[currLine[3]]
case "DIV":
dataMem[currLine[1]] = dataMem[currLine[2]] / dataMem[currLine[3]]
case "COP":
dataMem[currLine[1]] = dataMem[currLine[2]]
case "AFC":
dataMem[currLine[1]] = int(currLine[2])
case "SUP":
dataMem[currLine[1]] = dataMem[currLine[2]] > dataMem[currLine[3]]
case "EQ":
dataMem[currLine[1]] = dataMem[currLine[2]] == dataMem[currLine[3]]
case "NOT":
dataMem[currLine[1]] = not dataMem[currLine[2]]
case "INF":
dataMem[currLine[1]] = dataMem[currLine[2]] < dataMem[currLine[3]]
case "AND":
dataMem[currLine[1]] = dataMem[currLine[2]] and dataMem[currLine[3]]
case "OR":
dataMem[currLine[1]] = dataMem[currLine[2]] and dataMem[currLine[3]]
case "JMP":
ip = int(currLine[1])
incr = 0
case "JMF":
if not dataMem[currLine[1]]:
incr = 0
ip = int(currLine[2])
print(ip)
case "CAL":
pass
case "RET":
pass
case "PRI":
pass
case default:
pass
print(ASMLines[ip], ", ".join([f"{i}:{dataMem.get(i)}" for i in dataMem]))
ip += incr
else:
cont = self.query_one("#cont", Container)
cont.styles.background = Color.parse("#151E3D")
code = self.query_one("#code", Static)
code.update(" ")
class codeLines(Static):
"""one line of assembly code"""
def update_code(self, line) -> None:
self.update(line)
class registers(Static):
"""one line of assembly code"""
def update_regs(self, line) -> None:
self.update(line)
class interpreter(App):
"""A Textual app to see your asm code run !."""
TITLE = "A Textual app to see your asm code run !."
CSS_PATH = "style.css"
BINDINGS = [
("q", "quit", "Quit"),
]
def compose(self) -> ComposeResult:
"""Compose our UI."""
path = "./" if len(sys.argv) < 2 else sys.argv[1]
yield Header()
with Container(id="cont"):
with VerticalScroll(id="code-view"):
yield codeLines("\n".join(getLinesToShow(ip, ASMLines)),id="code", expand=True)
yield registers(id="regs", expand=True)
yield Footer()
def on_key(self, event: events.Key) -> None:
code = self.query_one("#code", Static)
regs = self.query_one("#regs", Static)
update_interpreter(self)
global ip, ASMLines
code.update_code("\n".join(getLinesToShow(ip, ASMLines)))
l = []
for i in range(max([int(i)+1 for i in dataMem.keys()])):
if str(i) in dataMem.keys():
l.append([i, dataMem[str(i)]])
regs.update_regs("\n".join([f"@{k[0]} : {k[1]}" for k in l]))
if __name__ == "__main__":
fileInput = open("asm", "r")
global ASMLines
ASMLines = list(map(lambda e: e.rstrip("\n"), fileInput.readlines()))
fileInput.close()
ASMLines.append("NOP")
global dataMem
dataMem = {}
global ip
ip = 0
interpreter().run()