Projet-Systemes-Informatiques/graph_interpreter.py

140 lines
4.4 KiB
Python

import sys
try:
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
except:
print("please install textual and rich !")
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()