easycoder 241211.3__py2.py3-none-any.whl → 250116.1__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of easycoder might be problematic. Click here for more details.

@@ -0,0 +1,326 @@
1
+ from .ec_classes import FatalError, RuntimeError, Object
2
+ from .ec_handler import Handler
3
+ from .ec_gutils import GUtils
4
+ import PySimpleGUI as psg
5
+ import json
6
+
7
+ class Graphics(Handler):
8
+
9
+ def __init__(self, compiler):
10
+ Handler.__init__(self, compiler)
11
+ self.utils = GUtils()
12
+
13
+ def getName(self):
14
+ return 'graphics'
15
+
16
+ #############################################################################
17
+ # Keyword handlers
18
+
19
+ def k_add(self, command):
20
+ elements = []
21
+ while True:
22
+ if self.nextIsSymbol():
23
+ symbolRecord = self.getSymbolRecord()
24
+ name = symbolRecord['name']
25
+ if 'iselement' in symbolRecord:
26
+ elements.append(name)
27
+ if self.peek() != 'and': break
28
+ else: FatalError(self.program.compiler, f'"{name}" is not a graphic element')
29
+ else: FatalError(self.program.compiler, f'Element expected; got "{self.getToken()}"')
30
+ self.nextToken()
31
+ command['elements'] = json.dumps(elements)
32
+ if self.nextIs('to'):
33
+ if self.nextIsSymbol():
34
+ symbolRecord = self.getSymbolRecord()
35
+ if symbolRecord['keyword'] == 'layout':
36
+ command['target'] = symbolRecord['name']
37
+ self.addCommand(command)
38
+ return True
39
+ return False
40
+
41
+ def r_add(self, command):
42
+ target = self.getVariable(command['target'])
43
+ elements = json.loads(command['elements'])
44
+ if not 'layout' in target:
45
+ target['layout'] = []
46
+ for element in elements:
47
+ v = self.getVariable(element)
48
+ target['layout'].append(v['layout'])
49
+ return self.nextPC()
50
+
51
+ def k_close(self, command):
52
+ if self.nextIsSymbol():
53
+ symbolRecord = self.getSymbolRecord()
54
+ if symbolRecord['keyword'] == 'window':
55
+ command['target'] = symbolRecord['name']
56
+ self.add(command)
57
+ return True
58
+ return False
59
+
60
+ def r_close(self, command):
61
+ target = self.getVariable(command['target'])
62
+ target['window'].close()
63
+ return self.nextPC()
64
+
65
+ # create {window} layout {layout}
66
+ # create {element} {args...}
67
+ def k_create(self, command):
68
+ if self.nextIsSymbol():
69
+ symbolRecord = self.getSymbolRecord()
70
+ type = symbolRecord['keyword']
71
+ command['type'] = type
72
+ command['name'] = symbolRecord['name']
73
+ if type == 'window':
74
+ command['title'] = self.nextValue()
75
+ if self.nextIs('layout'):
76
+ if self.nextIsSymbol():
77
+ symbolRecord = self.getSymbolRecord()
78
+ if symbolRecord['keyword'] == 'layout':
79
+ command['layout'] = symbolRecord['name']
80
+ self.addCommand(command)
81
+ return True
82
+ elif type[0:2] == 'g_':
83
+ command['args'] = self.compileConstant(self.utils.getArgs(self))
84
+ self.addCommand(command)
85
+ return True
86
+ return False
87
+
88
+ def r_create(self, command):
89
+ type = command['type']
90
+ record = self.getVariable(command['name'])
91
+ if type == 'window':
92
+ layout = self.getVariable(command['layout'])
93
+ title = self.getRuntimeValue(command['title'])
94
+ self.program.window = psg.Window(title, layout['layout'], finalize=True)
95
+ self.program.run(self.nextPC())
96
+ self.mainLoop()
97
+ self.program.kill()
98
+ return 0
99
+ elif 'iselement' in record:
100
+ layout = json.loads(self.getRuntimeValue(command['args']))
101
+ args = self.utils.getDefaultArgs(type)
102
+ content = json.loads(layout['content'])
103
+ for n in range(0, len(content)):
104
+ args = self.utils.decode(args, content[n])
105
+ element = self.utils.createElement(type, args)
106
+ record['layout'] = element
107
+ return self.nextPC()
108
+ else:
109
+ RuntimeError(self.program, 'Variable is not a window or an element')
110
+
111
+ def k_g_button(self, command):
112
+ command['iselement'] = True
113
+ return self.compileVariable(command)
114
+
115
+ def r_g_button(self, command):
116
+ return self.nextPC()
117
+
118
+ def k_g_input(self, command):
119
+ command['iselement'] = True
120
+ return self.compileVariable(command)
121
+
122
+ def r_g_input(self, command):
123
+ return self.nextPC()
124
+
125
+ def k_g_text(self, command):
126
+ command['iselement'] = True
127
+ return self.compileVariable(command)
128
+
129
+ def r_g_text(self, command):
130
+ return self.nextPC()
131
+
132
+ def k_init(self, command):
133
+ if self.nextIsSymbol():
134
+ record = self.getSymbolRecord()
135
+ if record['keyword'] == 'layout':
136
+ command['target'] = record['name']
137
+ if self.peek() == 'with':
138
+ self.nextToken()
139
+ if self.nextIsSymbol():
140
+ record = self.getSymbolRecord()
141
+ name = record['name']
142
+ if record['iselement']:
143
+ command['args'] = name
144
+ else: FatalError(self.program.compiler, f'\'{name}\' is not a graphic element')
145
+ else:
146
+ command['type'] = self.getToken()
147
+ command['args'] = self.utils.getArgs(self)
148
+ else: command['args'] = None
149
+ self.addCommand(command)
150
+ return True
151
+ return False
152
+
153
+ def r_init(self, command):
154
+ record = self.getVariable(command['target'])
155
+ record['layout'] = []
156
+ type = command['type']
157
+ args = command['args']
158
+ if args != None:
159
+ if args[0] == '{':
160
+ layout = json.loads(self.getRuntimeValue(json.loads(args)))
161
+ args = self.utils.getDefaultArgs(type)
162
+ for n in range(0, len(layout)):
163
+ args = self.utils.decode(args, layout[n])
164
+ record['layout'].append(self.utils.createElement(type, args))
165
+ else:
166
+ v = self.getVariable(args)
167
+ record['layout'].append(v['layout'])
168
+ return self.nextPC()
169
+
170
+ def k_layout(self, command):
171
+ command['iselement'] = True
172
+ return self.compileVariable(command)
173
+
174
+ def r_layout(self, command):
175
+ return self.nextPC()
176
+
177
+ def k_on(self, command):
178
+ token = self.nextToken()
179
+ command['type'] = token
180
+ if token == 'click':
181
+ command['event'] = token
182
+ if self.peek() == 'in':
183
+ self.nextToken()
184
+ if self.nextIs('screen'):
185
+ command['target'] = None
186
+ elif self.isSymbol():
187
+ target = self.getSymbolRecord()
188
+ command['target'] = target['name']
189
+ else:
190
+ FatalError(self.program.compiler, f'{self.getToken()} is not a screen element')
191
+ return False
192
+ command['goto'] = self.getPC() + 2
193
+ self.add(command)
194
+ self.nextToken()
195
+ pcNext = self.getPC()
196
+ cmd = {}
197
+ cmd['domain'] = 'core'
198
+ cmd['lino'] = command['lino']
199
+ cmd['keyword'] = 'gotoPC'
200
+ cmd['goto'] = 0
201
+ cmd['debug'] = False
202
+ self.addCommand(cmd)
203
+ self.compileOne()
204
+ cmd = {}
205
+ cmd['domain'] = 'core'
206
+ cmd['lino'] = command['lino']
207
+ cmd['keyword'] = 'stop'
208
+ cmd['debug'] = False
209
+ self.addCommand(cmd)
210
+ # Fixup the link
211
+ self.getCommandAt(pcNext)['goto'] = self.getPC()
212
+ return True
213
+ elif token == 'tick':
214
+ command['event'] = token
215
+ command['goto'] = self.getPC() + 2
216
+ self.add(command)
217
+ self.nextToken()
218
+ pcNext = self.getPC()
219
+ cmd = {}
220
+ cmd['domain'] = 'core'
221
+ cmd['lino'] = command['lino']
222
+ cmd['keyword'] = 'gotoPC'
223
+ cmd['goto'] = 0
224
+ cmd['debug'] = False
225
+ self.addCommand(cmd)
226
+ self.compileOne()
227
+ cmd = {}
228
+ cmd['domain'] = 'core'
229
+ cmd['lino'] = command['lino']
230
+ cmd['keyword'] = 'stop'
231
+ cmd['debug'] = False
232
+ self.addCommand(cmd)
233
+ # Fixup the link
234
+ self.getCommandAt(pcNext)['goto'] = self.getPC()
235
+ return True
236
+ return False
237
+
238
+ def r_on(self, command):
239
+ pc = command['goto']
240
+ if command['type'] == 'click':
241
+ event = command['event']
242
+ if event == 'click':
243
+ target = command['target']
244
+ if target == None:
245
+ value = 'screen'
246
+ else:
247
+ widget = self.getVariable(target)
248
+ value = widget['value'][widget['index']]
249
+ self.renderer.setOnClick(value['content'], lambda: self.run(pc))
250
+ return self.nextPC()
251
+
252
+ def k_popup(self, command):
253
+ command['message'] = self.nextValue()
254
+ self.addCommand(command)
255
+ return True
256
+
257
+ def r_popup(self, command):
258
+ psg.popup(self.getRuntimeValue(command['message']))
259
+ return self.nextPC()
260
+
261
+ def k_set(self, command):
262
+ return True
263
+
264
+ def r_set(self, command):
265
+ return self.nextPC()
266
+
267
+ def k_window(self, command):
268
+ return self.compileVariable(command)
269
+
270
+ def r_window(self, command):
271
+ return self.nextPC()
272
+
273
+ #############################################################################
274
+ # Compile a value in this domain
275
+ def compileValue(self):
276
+ value = {}
277
+ value['domain'] = 'graphics'
278
+ token = self.getToken()
279
+ if self.isSymbol():
280
+ return None
281
+
282
+ if self.tokenIs('the'):
283
+ self.nextToken()
284
+ token = self.getToken()
285
+
286
+ value['type'] = token
287
+
288
+ if token == 'test':
289
+ name = self.nextToken()
290
+ value = {}
291
+ value['type'] = 'text'
292
+ value['content'] = 'test'
293
+ return value
294
+
295
+ return None
296
+
297
+ #############################################################################
298
+ # Modify a value or leave it unchanged.
299
+ def modifyValue(self, value):
300
+ return value
301
+
302
+ #############################################################################
303
+ # Value handlers
304
+
305
+ def v_test(self, v):
306
+ return v
307
+
308
+ #############################################################################
309
+ # Compile a condition
310
+ def compileCondition(self):
311
+ condition = {}
312
+ return condition
313
+
314
+ #############################################################################
315
+ # Condition handlers
316
+
317
+ #############################################################################
318
+ # The main loop
319
+ def mainLoop(self):
320
+ while True:
321
+ event, values = self.program.window.Read(timeout=100)
322
+ if event == psg.WINDOW_CLOSED or event == "EXIT":
323
+ break
324
+ if event == '__TIMEOUT__': self.program.flushCB()
325
+ else:
326
+ print(event, values)
easycoder/ec_gutils.py ADDED
@@ -0,0 +1,52 @@
1
+ import PySimpleGUI as psg
2
+ import json
3
+
4
+ class GUtils:
5
+
6
+ # Parse a set of compile-time arguments
7
+ def getArgs(self, handler):
8
+ args = []
9
+ while True:
10
+ key = handler.nextToken()
11
+ value = json.dumps(handler.nextValue())
12
+ args.append(f'{key}={value}')
13
+ if handler.peek() == 'and':
14
+ handler.nextToken()
15
+ else: break
16
+ v = {}
17
+ v['type'] = 'text'
18
+ v['content'] = json.dumps(args)
19
+ return json.dumps(v)
20
+
21
+ # Get the default args for a graphic element
22
+ def getDefaultArgs(self, type):
23
+ args = {}
24
+ if type == 'g_text':
25
+ args['text'] = '(empty)'
26
+ args['expand_x'] = False
27
+ elif type == 'g_input':
28
+ args['key'] = None
29
+ args['size'] = (None, None)
30
+ elif type == 'g_button':
31
+ args['button_text'] = '(empty)'
32
+ return args
33
+
34
+ # Decode an argument at runtime
35
+ def decode(self, args, text):
36
+ p = text.find('=')
37
+ if p > 0:
38
+ key = text[0:p]
39
+ value = json.loads(text[p+1:])['content']
40
+ args[key] = value
41
+ return args
42
+ return None
43
+
44
+ # Create an element
45
+ def createElement(self, type, args):
46
+ if type == 'g_text': return psg.Text(text=args['text'], expand_x=args['expand_x'])
47
+ elif type == 'g_input':
48
+ size = args['size'].split()
49
+ size = (size[0], size[1])
50
+ return psg.Input(key=args['key'], size=size)
51
+ elif type == 'g_button': return psg.Button(button_text=args['button_text'])
52
+ else: return None
easycoder/ec_handler.py CHANGED
@@ -25,6 +25,7 @@ class Handler:
25
25
  self.getCommandAt = compiler.getCommandAt
26
26
  self.compileOne = compiler.compileOne
27
27
  self.compileFromHere = compiler.compileFromHere
28
+ self.compileConstant = compiler.compileConstant
28
29
 
29
30
  self.code = self.program.code
30
31
  self.add = self.program.add