-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdbgcodeeditor.py
134 lines (106 loc) · 4.28 KB
/
dbgcodeeditor.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import tkinter
from tkinter import font as tkfont
import logging
import codeeditor
import assembler
import runner
READ_COLOR = "#EE0"
WRITTEN_COLOR = "#E00"
EXECUTED_COLOR = "#0A0"
NEXT_EXEC_COLOR = "#CCC"
COLOR_MAP = dict(zip(runner.ValueState, ["#FFF", READ_COLOR, WRITTEN_COLOR,
EXECUTED_COLOR, NEXT_EXEC_COLOR]))
logger = logging.getLogger(__name__)
def darken(s):
return s.translate(str.maketrans("23456789ABCDEF", "0123456789ABCE"))
class DbgTooltipContentInterface(codeeditor.TooltipContentInterface):
def action(self, state):
self.put(state.value.title(), "state_" + state.value)
class DbgTooltip(codeeditor.Tooltip):
def __init__(self, master, memval, position, content_interface=DbgTooltipContentInterface):
super().__init__(master, [memval], position, content_interface=content_interface)
def setup_text(self, text_widget):
super().setup_text(text_widget)
normal_font = text_widget.cget("font")
bold_font = tkfont.Font(text_widget, normal_font)
bold_font["weight"] = "bold"
for state, color in zip(runner.ValueState, ["#000", READ_COLOR, WRITTEN_COLOR,
EXECUTED_COLOR, NEXT_EXEC_COLOR]):
text_widget.tag_configure("state_" + state.value, font=bold_font, foreground=darken(color))
class DebugCodeEditor(codeeditor.CodeEditor):
def __init__(self, master):
super().__init__(master)
self.runner = None
for state, color in COLOR_MAP.items():
self.text.tag_configure("state_" + state.value, background=color)
self.text.tag_raise("sel")
self.text.tag_lower("state_" + runner.ValueState.normal.value)
self.text["state"] = "disabled"
def update_runner(self, runner):
self.runner = runner
self.assembler = self.runner.assembler
self.text["state"] = "normal"
self.text.delete("1.0", tkinter.END)
self.text.insert(tkinter.END, self.assembler.raw_code[:-1])
self.text.edit_reset()
self.text.edit_modified(False)
self.text["state"] = "disabled"
self.set_name()
self.update_syntax()
def update_syntax(self):
self.text["state"] = "normal"
super().update_syntax()
for state in runner.ValueState:
self.text.tag_remove("state_" + state.value, "1.0", tkinter.END)
if self.runner:
for val in self.runner.memory:
if val.token is None:
continue
lineno = val.token.position.lineno + 1
self.text.tag_add("state_" + val.state.value,
str(lineno) + ".0",
str(lineno + 1) + ".0")
self.text["state"] = "disabled"
def make_tooltip(self, token):
if self.tooltip:
self.nuke_tooltip()
if token and isinstance(token, assembler.Mnemonic):
logger.info("Making tooltip")
x, y = self.text.winfo_pointerx(), self.text.winfo_pointery()
pos = x + 20, y - 35
self.tooltip = DbgTooltip(self, self.runner.memory[token.address], pos)
else:
logger.info("Did not make tooltip as nothing to show")
def create_problem_tag(self, token):
# Disable problem underlining
pass
def set_name(self):
pass
def breakpoints_changed(self):
master = self.master
while hasattr(master, "master"):
if hasattr(master, "breakpoints_changed"):
return master.breakpoints_changed(self.breakpoints)
master = master.master
if __name__ == "__main__":
import sys
import tkinter.ttk as ttk
assem = assembler.Assembler()
assem.update_code(open(sys.argv[1]).read())
print(assem.assemble())
runner_ = runner.Runner(lambda x: print(">>>", x))
runner_.load_code(assem)
root = tkinter.Tk(className='ToolTip-demo')
t = ttk.Notebook(root)
t.grid(sticky=tkinter.NE + tkinter.SW)
ce = DebugCodeEditor(t)
t.add(ce, text="Hi")
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)
ce.update_runner(runner_)
def c():
runner_.next_step()
ce.update_syntax()
b = tkinter.Button(root, text="Step", command=c)
b.grid()
root.mainloop()