Skip to content

Commit d351933

Browse files
committed
Merge branch 'main' of https://github.com/Timoite/GF2
2 parents 32e8183 + 5d2a449 commit d351933

4 files changed

Lines changed: 242 additions & 37 deletions

File tree

__pycache__/gui.cpython-313.pyc

2.46 KB
Binary file not shown.

gui.py

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from monitors import Monitors
1212
from scanner import Scanner
1313
from parse import Parser
14+
import sys
1415

1516

1617
class MyGLCanvas(wxcanvas.GLCanvas):
@@ -191,7 +192,6 @@ def on_resize(self, event):
191192
x, y = self.GetViewStart()
192193
self.canvas.SetPosition((-x, -y))
193194

194-
195195
class Gui(wx.Frame):
196196
"""Configure the main window and all the widgets.
197197
@@ -235,7 +235,10 @@ def __init__(self, title):
235235
# File io widgets
236236
open_image = wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN, wx.ART_TOOLBAR)
237237
open_button = wx.BitmapButton(self, wx.ID_ANY, open_image)
238-
fileio_sizer.Add(open_button, 0)
238+
fileio_sizer.Add(open_button, 1, wx.RIGHT, 5)
239+
quit_image = wx.ArtProvider.GetBitmap(wx.ART_QUIT, wx.ART_TOOLBAR)
240+
quit_button = wx.BitmapButton(self, wx.ID_ANY, quit_image)
241+
fileio_sizer.Add(quit_button, 1, wx.LEFT, 5)
239242

240243
# Cycles widgets
241244
text = wx.StaticText(self, wx.ID_ANY, "Cycles:")
@@ -263,6 +266,14 @@ def __init__(self, title):
263266
# Monitor widgets
264267
text = wx.StaticText(self, wx.ID_ANY, "Monitors")
265268
self.lower_sizer.Add(text, 0, wx.ALL | wx.CENTER, 10)
269+
270+
self.monitors_sizer = wx.BoxSizer(wx.VERTICAL)
271+
self.scrolled_panel = wx.ScrolledWindow(self, style=wx.VSCROLL)
272+
self.scrolled_panel.SetScrollRate(10, 10)
273+
self.scrolled_panel.SetSizer(self.monitors_sizer)
274+
self.lower_sizer.Add(self.scrolled_panel, 100, wx.EXPAND)
275+
self.monitors_sizer.Fit(self.scrolled_panel)
276+
266277
self.add_sizer = wx.BoxSizer(wx.HORIZONTAL)
267278
self.lower_sizer.Add(self.add_sizer, wx.CENTER)
268279
add_image = wx.ArtProvider.GetBitmap(wx.ART_PLUS)
@@ -273,13 +284,14 @@ def __init__(self, title):
273284

274285
# Bind events to widgets
275286
open_button.Bind(wx.EVT_BUTTON, self.OpenFile)
287+
quit_button.Bind(wx.EVT_BUTTON, self.Quit)
276288
run_button.Bind(wx.EVT_BUTTON, self.Run)
277289
cont_button.Bind(wx.EVT_BUTTON, self.Continue)
278290
add_button.Bind(wx.EVT_BUTTON, self.CreateMonitor)
279291

280292
# Set screen size
281-
self.SetSizeHints(500, 440)
282-
self.SetSize(570, 1070)
293+
self.SetSizeHints(500, 500)
294+
self.SetSize(600, 600)
283295
self.SetSizer(self.main_sizer)
284296
self.SetPosition((0, 39))
285297

@@ -336,19 +348,20 @@ def CreateMonitor(self, event):
336348
def AddMonitor(self, signal_name):
337349
"""Add a monitor that already exists to GUI."""
338350
monitor_sizer = wx.BoxSizer(wx.HORIZONTAL)
339-
pos = len(self.lower_sizer.GetChildren()) - 1
351+
pos = len(self.monitors_sizer.GetChildren())
340352

341-
self.lower_sizer.Insert(pos, monitor_sizer, 0, wx.EXPAND, 0)
353+
self.monitors_sizer.Add(monitor_sizer, 0, wx.EXPAND, 0)
342354
minus_image = wx.ArtProvider.GetBitmap(wx.ART_MINUS)
343-
zap_button = wx.BitmapButton(self, wx.ID_ANY, minus_image)
344-
text = wx.StaticText(self, wx.ID_ANY, signal_name)
355+
zap_button = wx.BitmapButton(self.scrolled_panel, wx.ID_ANY, minus_image)
356+
text = wx.StaticText(self.scrolled_panel, wx.ID_ANY, signal_name)
345357
text.SetMinSize((60, -1))
346358
monitor_sizer.Add(zap_button, 0, wx.CENTER | wx.ALL, 20)
347359
monitor_sizer.Add(text, 0, wx.CENTER | wx.RIGHT, 10)
348360
self.scroll_gl = ScrollableGLPanel(
349-
self, signal_name, self.cycles_completed)
361+
self.scrolled_panel, signal_name, self.cycles_completed)
350362
monitor_sizer.Add(self.scroll_gl, 1, wx.EXPAND | wx.CENTER | wx.ALL, 5)
351363

364+
self.scrolled_panel.FitInside()
352365
self.Layout()
353366

354367
zap_button.Bind(wx.EVT_BUTTON,
@@ -362,6 +375,7 @@ def ZapMonitor(self, event, pos, signal_name):
362375
if self.monitors.remove_monitor(device, port):
363376
# Remove from GUI
364377
self.lower_sizer.GetChildren()[pos].DeleteWindows()
378+
self.scrolled_panel.FitInside()
365379
self.Layout()
366380
else:
367381
self.Error("Could not zap monitor.")
@@ -458,3 +472,6 @@ def Continue(self, event):
458472
def Error(self, error_msg):
459473
"""Create error box."""
460474
wx.MessageBox(error_msg, 'Error', wx.OK | wx.ICON_ERROR)
475+
476+
def Quit(self, event):
477+
sys.exit()

parse.py

Lines changed: 190 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,198 @@ class Parser:
3636
def __init__(self, names, devices, network, monitors, scanner):
3737
"""Initialise constants."""
3838

39+
def _error(self, error_type, stopping_symbol):
40+
self.error_count += 1
41+
if error_type == self.MISSING_DASH_OR_EQUALS:
42+
print("Error: expected a dsah or equals symbol.")
43+
elif error_type == self.MISSING_ARROW_OR_EQUALS:
44+
print("Error: expected a right arrow or equals symbol.")
45+
elif error_type == self.MISSING_DASH_OR_COMMA:
46+
print("Error: expected a comma or dash.")
47+
elif error_type == self.MISSING_STRING:
48+
print("Error: expected a string.")
49+
elif error_type == self.MISSING_INTEGER:
50+
print("Error: expected an integer.")
51+
elif error_type == self.MISSING_ARROW:
52+
print("Error: expected a right arrow.")
53+
elif error_type == self.MISSING_EQUALS:
54+
print("Error: expected an equals symbol.")
55+
elif error_type == self.NOT_DEVICE_NAME:
56+
print("Error: Device name is not in recognised set.")
57+
elif error_type == self.MISSING_COMMA:
58+
print("Error: expected an integer")
59+
elif error_type == self.MISSING_DEVICES_HEADER:
60+
print("Error: Missing the section header keyword for devices")
61+
elif error_type == self.MISSING_CONNECTIONS_HEADER:
62+
print("Error: Missing the section header keyword for connections")
63+
elif error_type == self.MISSING_MONITORS_HEADER:
64+
print("Error: Missing the section header keyword for monitors")
65+
elif error_type == self.MISSING_END_HEADER:
66+
print("Error: Missing the end-of-file keyword")
67+
if stopping_symbol == "standard":
68+
while not (self.symbol.type == self.scanner.COMMA or self.symbol.type == self.scanner.KEYWORD):
69+
self.symbol = self.scanner.get_symbol()
70+
elif stopping_symbol == "end":
71+
while not self.symbol.ID == self.scanner.END_ID:
72+
self.symbol = self.scanner.get_symbol()
73+
74+
def _name(self):
75+
name = ""
76+
while (self.symbol.type == self.scanner.STRING or self.symbol.type == self.scanner.INTEGER
77+
or self.symbol.type == self.scanner.UNDERSCORE):
78+
name = name + self.symbol.id
79+
self.symbol = self.scanner.get_symbol()
80+
if not (self.symbol.type == self.scanner.EQUALS or self.symbol.type == self.scanner.DASH):
81+
self._error(self.MISSING_DASH_OR_EQUALS, "standard")
82+
else:
83+
return name
84+
85+
def _portID(self):
86+
portID = ""
87+
if self.symbol.type == self.STRING:
88+
portID = portID + self.symbol.id
89+
self.symbol = self.scanner.get_symbol()
90+
if self.symbol.type == self.INTEGER:
91+
portID = portID + str(self.symbol.ID)
92+
self.symbol = self.scanner.get_symbol()
93+
if not (self.symbol.type == self.scanner.ARROW or self.symbol.type == self.scanner.EQUALS):
94+
self._error(self.MISSING_ARROW_OR_EQUALS, "standard")
95+
else:
96+
return portID
97+
else:
98+
self._error(self.MISSING_STRING, "standard")
99+
100+
def _signalID(self):
101+
deviceID = self._name()
102+
if self.symbol.type == self.scanner.DASH:
103+
self.symbol = self.scanner.get_symbol()
104+
portID = self._portID()
105+
return [deviceID, portID]
106+
else:
107+
if not self.symbol.type == self.scanner.COMMA or self.symbol.type == self.scanner.ARROW:
108+
self._error(self.MISSING_DASH_OR_COMMA, "standard")
109+
else:
110+
return [deviceID, ""] #Not quite sure what this needs to be yet?
111+
112+
def _devicetype(self):
113+
if self.symbol.type == self.scanner.DEVICE_TYPE:
114+
devicetype = self.symbol.id
115+
self.symbol = self.scanner.get_symbol()
116+
return devicetype
117+
else:
118+
self._error(self.NOT_DEVICE_TYPE, "standard")
119+
120+
def _device(self):
121+
deviceID = self._name()
122+
if self.symbol.type == self.scanner.EQUALS:
123+
self.symbol = self.scanner.get_symbol()
124+
device = self._devicetype()
125+
if self.symbol.type == self.scanner.SLASH:
126+
self.symbol = self.scanner.get_symbol()
127+
if self.symbol.type == self.scanner.INTEGER:
128+
qualifier = self.symbol.ID()
129+
self.symbol = self.scanner.get_symbol()
130+
else:
131+
self._error(self.MISSING_INTEGER, "standard")
132+
elif self.symbol.type == self.scanner.COMMA:
133+
self.symbol = self.scanner.get_symbol()
134+
qualifier = None
135+
else:
136+
self._error(self.MISSING_EQUALS, "standard")
137+
else:
138+
self._error()
139+
if self.error_count == 0:
140+
error_type = self._make_device(device, deviceID, qualifier)
141+
if error_type != self.devices.NO_ERROR:
142+
self._error(error_type)
143+
144+
def _make_device(self, device, deviceID, qualifier):
145+
if device in ["AND", "OR", "NAND", "NOR", "XOR"]:
146+
error = self.devices.make_gate(deviceID, device, qualifier)
147+
elif device == "CLOCK":
148+
error = self.devices.make_clock(deviceID, qualifier)
149+
elif device == "SWITCH":
150+
error = self.devices.make_clock(deviceID, qualifier)
151+
elif device == "DTYPE":
152+
error = self.devices.make_d_type(deviceID)
153+
else:
154+
error = self.devices.NO_ERROR
155+
return error
156+
157+
158+
def _connection(self):
159+
connectionID = self._name()
160+
if self.symbol.type == self.scanner.EQUALS:
161+
self.symbol = self.scanner.get_symbol()
162+
signal1 = self._signalID()
163+
if self.symbol.type == self.scanner.ARROW:
164+
self.symbol = self.scanner.get_symbol()
165+
signal2 = self._signalID()
166+
else:
167+
self._error(self.MISSING_ARROW, "standard")
168+
else:
169+
self._error(self.MISSING_EQUALS, "standard")
170+
if self.error_count == 0:
171+
error_type = self.network.make_connection(signal1[0], signal1[1], signal2[0], signal2[1])
172+
if error_type != self.network.NO_ERROR:
173+
self._error(error_type)
174+
175+
def _monitor(self):
176+
monitorID = self._name()
177+
if self.symbol.type == self.scanner.EQUALS:
178+
self.symbol = self.scanner.get_symbol()
179+
port = self._signalID()
180+
else:
181+
self._error(self.MISSING_EQUALS, "standard")
182+
if self.error_count == 0:
183+
error_type = self.monitors.make_monitor(port[0], port[1])
184+
if error_type != self.monitors.NO_ERROR:
185+
self._error(error_type, "standard")
186+
187+
def _devices_list(self):
188+
if (self.symbol.type == self.scanner.KEYWORD and self.symbol.id == self.scanner.DEVICES_ID):
189+
self.symbol = self.scanner.get_symbol()
190+
self._device()
191+
while self.symbol.type == self.scanner.COMMA:
192+
self.symbol = self.scanner.get_symbol()
193+
self._device()
194+
else:
195+
self._error(self.MISSING_DEVICES_HEADER, "End")
196+
197+
def _connections_list(self):
198+
if (self.symbol.type == self.scanner.KEYWORD and self.symbol.id == self.scanner.CONNECTIONS_ID):
199+
self.symbol = self.scanner.get_symbol()
200+
self._connection()
201+
while self.symbol.type == self.scanner.COMMA:
202+
self.symbol = self.scanner.get_symbol()
203+
self._connection()
204+
else:
205+
self._error(self.MISSING_CONNECTIONS_HEADER, "End")
206+
207+
def _monitors_list(self):
208+
if (self.symbol.type == self.scanner.KEYWORD and self.symbol.id == self.scanner.MONITORS_ID):
209+
self.symbol = self.scanner.get_symbol()
210+
self._monitor()
211+
while self.symbol.type == self.scanner.COMMA:
212+
self.symbol = self.scanner.get_symbol()
213+
self._monitor()
214+
if not (self.symbol.type == self.scanner.KEYWORD and self.symbol.id == self.scanner.END_ID):
215+
self._error(self.MISSING_END_HEADER, "Stop")
216+
else:
217+
self._error(self.MISSING_MONITORS_HEADER, "End")
218+
39219
def parse_network(self):
40220
"""Parse the circuit definition file."""
221+
self.error_count = 0
222+
self._devices_list()
223+
self._connections_list()
224+
self._monitors_list()
225+
if self.error_count == 0:
226+
return True
227+
else:
228+
return False
41229
# For now just return True, so that userint and gui can run in the
42230
# skeleton code. When complete, should return False when there are
43231
# errors in the circuit definition file.
44-
return True
232+
233+

0 commit comments

Comments
 (0)