Skip to content

Instantly share code, notes, and snippets.

@shutebt01
Last active March 15, 2022 07:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save shutebt01/f840186c62e0c8ce2ff9 to your computer and use it in GitHub Desktop.
Save shutebt01/f840186c62e0c8ce2ff9 to your computer and use it in GitHub Desktop.
Python LMC (Little Man Computer) Emulator
'''
Created on 22 Oct 2014
Little Man Computer Emulator
@author: shutebt01
'''
import tkinter
import sys
import threading, time
from tkinter.constants import *
tk = tkinter.Tk();
current = 0
acumulator = 0
last = 0
def callback(sv, pos, type):
print(sv.get() + ":" + str(pos) + ":" + type)
if (type == "Assembly"):
AssemblyParser(sv, pos)
#if (type == "Machine"):
# MachineParser(sv, pos)
#null method for invalid string
def null(string, pos):
print("Invalid Thing")
# Assembly Parser Start
def hlt(string, pos):
try:
MachineCellsSV[pos].set("000")
except:
pass
def add(string, pos):
value = 100
try:
value = value + int(string[1])
except:
pass
if value in range(100, 200, 1):
try:
MachineCellsSV[pos].set(str(value))
except:
pass
def sub(string, pos):
value = 200
try:
value = value + int(string[1])
except:
pass
if value in range(200, 300, 1):
try:
MachineCellsSV[pos].set(str(value))
except:
pass
def sta(string, pos):
value = 300
try:
value = value + int(string[1])
except:
pass
if value in range(300, 400, 1):
try:
MachineCellsSV[pos].set(str(value))
except:
pass
def lda(string, pos):
value = 500
try:
value = value + int(string[1])
except:
pass
if value in range(500, 600, 1):
try:
MachineCellsSV[pos].set(str(value))
except:
pass
def bra(string, pos):
value = 600
try:
value = value + int(string[1])
except:
pass
if value in range(600, 700, 1):
try:
MachineCellsSV[pos].set(str(value))
except:
pass
def brz(string, pos):
value = 700
try:
value = value + int(string[1])
except:
pass
if value in range(700, 800, 1):
try:
MachineCellsSV[pos].set(str(value))
except:
pass
def brp(string, pos):
value = 800
try:
value = value + int(string[1])
except:
pass
if value in range(800, 900, 1):
try:
MachineCellsSV[pos].set(str(value))
except:
pass
def inp(string, pos):
try:
MachineCellsSV[pos].set("901")
except:
pass
def out(string, pos):
try:
MachineCellsSV[pos].set("902")
except:
pass
def dat(string, pos):
value = 0
try:
value = value + int(string[1])
except:
pass
if value in range(0, 1000, 1):
try:
MachineCellsSV[pos].set(str(value))
except:
pass
AssemblyConversion = {"HLT":hlt, "ADD":add, "SUB":sub,
"STA":sta, "LDA":lda, "BRA":bra,
"BRZ":brz, "BRP":brp, "INP":inp,
"OUT":out, "DAT":dat}
def AssemblyParser(sv, pos):
fullString = sv.get()
splitString = fullString.split()
if len(splitString) != 0:
AssemblyConversion.get(splitString[0], null)(splitString, pos)
#Assembly Parser End
#Machine executor Begin
class ExecThread(threading.Thread):
current = 0
acumulator = 0
last = 0
def __init__(self):
threading.Thread.__init__(self, name="Execution Thread")
self._target = self.execute
def ex0xx(self, addr):
print("Executing Halt")
self.current = 100
def ex1xx(self, addr):
print("Executing Add")
global MachineCellsSV
remote = int(MachineCellsSV[addr].get())
self.acumulator += remote
def ex2xx(self, addr):
print("Executing Sub")
global MachineCellsSV
remote = int(MachineCellsSV[addr].get())
self.acumulator -= remote
def ex3xx(self, addr):
print("Executing Sta")
global MachineCellsSV
MachineCellsSV[addr].set(self.acumulator)
def ex5xx(self, addr):
print("Executing Lda")
global MachineCellsSV
remote = int(MachineCellsSV[addr].get())
self.acumulator = remote
def ex6xx(self, addr):
print("Executing Bra")
self.current = addr
def ex7xx(self, addr):
print("Executing Brz")
if self.acumulator == 0:
self.current = addr
def ex8xx(self, addr):
print("Executing Brp")
if self.acumulator >= 0:
self.current = addr
def setAcumulator(self, ac, iv):
ac = iv.get()
def unlock(self, lock):
lock=False
def ex9xx(self, addr):
print("Executing I/O")
if addr == 1:
top = tkinter.Toplevel(tk)
iv = tkinter.IntVar(top)
text = tkinter.Entry(top, textvariable=iv)
text.pack()
iv.trace("w", lambda name, index, mode, ac=self.acumulator, iv=iv: setAcumulator(ac, iv))
close = tkinter.Button(top, text="Close", command=top.destroy())
close.pack()
lock=True
top.wm_protocol("WM_DELETE_WINDOW", lambda lock=lock: unlock(lock))
top.mainloop()
while lock:
pass
if addr == 2:
tkinter.messagebox.showinfo("Output", "Output Is: " + str(self.acumulator))
def execute(self):
global MachineCellsSV
print("Starting Execution")
self.current = 0
MacineExecParser = {"0":self.ex0xx, "1":self.ex1xx,
"2":self.ex2xx, "3":self.ex3xx,
"5":self.ex5xx, "6":self.ex6xx,
"7":self.ex7xx, "8":self.ex8xx,
"9":self.ex9xx}
try:
while self.current <=99:
value = MachineCellsSV[self.current].get()
self.current += 1
MacineExecParser.get(value[0], self.ex0xx)(int(value[1:3]))
print("Finished Execution")
print(self.acumulator)
except Exception as e:
print(str(e))
def halt(self):
self.current = 100
ExecThread = ExecThread()
#Assembly executor END
class Cell(tkinter.StringVar):
def __init__(self, pos, type):
self.pos = pos
self.type = type
tkinter.StringVar.__init__(self)
# TODO: determine what lambda does
tkinter.StringVar.trace(self, "w", lambda name, index, mode, self=self: callback(self, self.pos, type))
AssemblyCells = [None]*100
AssemblyCellsSV = [None]*100
for i in range(0, 100, 1):
AssemblyCellsSV[i] = Cell(i, "Assembly")
ittrvar = AssemblyCellsSV[i]
ittrvar.set("HLT")
AssemblyLbls = [None]*100
MachineCells = [None]*100
MachineCellsSV = [None]*100
for i in range(0, 100, 1):
MachineCellsSV[i] = Cell(i, "Machine")
ittrvar = MachineCellsSV[i]
ittrvar.set("000")
MachineLbls = [None]*100
tk.title("Little Man Computer")
frame = tkinter.Frame(tk, relief=RIDGE, borderwidth=2)
frame.pack(fill=BOTH,expand=1)
#Assembly Code GUI Section
AssemblyLabel = tkinter.Label(frame, text = "Assembly")
AssemblyLabel.grid(row=0, column=0)
AssemblyFrame = tkinter.Frame(frame, relief=RIDGE, borderwidth=2, width=200, height=500)
AssemblyFrame.grid(row=1, column=0, rowspan=6)
AssemblyCanvas = tkinter.Canvas(AssemblyFrame, width=100, height=250)
AssemblyCanvas.pack(side=LEFT, fill=BOTH)
AssemblyScroll = tkinter.Scrollbar(AssemblyFrame, command=AssemblyCanvas.yview)
AssemblyCanvas.config(yscrollcommand=AssemblyScroll.set, scrollregion=(-200,0,50,2110))
AssemblyScroll.pack(side=RIGHT, fill=Y)
AssemblyCanvasFrame = tkinter.Frame(AssemblyCanvas)
AssemblyCanvasFrameFiller = tkinter.Label(AssemblyCanvasFrame, text="Hidden", height=3)
AssemblyCanvasFrameFiller.grid(row=0, column=0)
for i in range(0, 100, 1):
AssemblyLbls[i] = tkinter.Label(AssemblyCanvasFrame, text = str(i))
AssemblyLbls[i].grid(row=i+1, column=0)
AssemblyCells[i] = tkinter.Entry(AssemblyCanvasFrame, width=10, textvariable=AssemblyCellsSV[i])
AssemblyCells[i].grid(row=i+1, column=1)
AssemblyCanvas.create_window(0, 1030, window=AssemblyCanvasFrame)
# Machine Code GUI Section
MachineLabel = tkinter.Label(frame, text = "Machine Code")
MachineLabel.grid(row=0, column=2)
MachineFrame = tkinter.Frame(frame, relief=RIDGE, borderwidth=2, width=200, height=500)
MachineFrame.grid(row=1, column=2, rowspan=6)
MachineCanvas = tkinter.Canvas(MachineFrame, width=100, height=250)
MachineCanvas.pack(side=LEFT, fill=BOTH)
MachineScroll = tkinter.Scrollbar(MachineFrame, command=MachineCanvas.yview)
MachineCanvas.config(yscrollcommand=MachineScroll.set, scrollregion=(-200,0,50,2110))
MachineScroll.pack(side=RIGHT, fill=Y)
MachineCanvasFrame = tkinter.Frame(MachineCanvas)
MachineCanvasFrameFiller = tkinter.Label(MachineCanvasFrame, text="Hidden", height=3)
MachineCanvasFrameFiller.grid(row=0, column=0)
for i in range(0, 100, 1):
MachineLbls[i] = tkinter.Label(MachineCanvasFrame, text = str(i))
MachineLbls[i].grid(row=i+1, column=0)
MachineCells[i] = tkinter.Entry(MachineCanvasFrame, width=10, textvariable=MachineCellsSV[i])
MachineCells[i].grid(row=i+1, column=1)
MachineCanvas.create_window(0, 1030, window=MachineCanvasFrame)
#Other GUI Stuff
InfoLBL1 = tkinter.Label(frame, text="This program will")
InfoLBL2 = tkinter.Label(frame, text="only parse from")
InfoLBL3 = tkinter.Label(frame, text="assembly to machine")
InfoLBL1.grid(row = 1, column=1)
InfoLBL2.grid(row = 2, column=1)
InfoLBL3.grid(row = 3, column=1)
ControlExec = tkinter.Button(frame, text="Start", command=ExecThread.execute)
ControlStop = tkinter.Button(frame, text="Stop", command=ExecThread.halt)
ControlExec.grid(row=1, column=3)
ControlStop.grid(row=2, column=3)
ExecThread.start()
tk.mainloop();
try:
tk.destroy();
except:
pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment