easycoder 250424.3__py2.py3-none-any.whl → 250504.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.
- easycoder/__init__.py +1 -1
- easycoder/ec_compiler.py +14 -4
- easycoder/ec_core.py +61 -43
- easycoder/ec_handler.py +1 -0
- easycoder/ec_program.py +1 -1
- easycoder/{ec_pyside6.py → ec_pyside.py} +320 -119
- {easycoder-250424.3.dist-info → easycoder-250504.1.dist-info}/METADATA +12 -10
- easycoder-250504.1.dist-info/RECORD +18 -0
- {easycoder-250424.3.dist-info → easycoder-250504.1.dist-info}/WHEEL +1 -1
- easycoder-250424.3.dist-info/RECORD +0 -18
- {easycoder-250424.3.dist-info → easycoder-250504.1.dist-info}/entry_points.txt +0 -0
- {easycoder-250424.3.dist-info → easycoder-250504.1.dist-info/licenses}/LICENSE +0 -0
easycoder/__init__.py
CHANGED
easycoder/ec_compiler.py
CHANGED
|
@@ -87,6 +87,15 @@ class Compiler:
|
|
|
87
87
|
def nextIsSymbol(self):
|
|
88
88
|
self.next()
|
|
89
89
|
return self.isSymbol()
|
|
90
|
+
|
|
91
|
+
def skip(self, token):
|
|
92
|
+
next = self.peek()
|
|
93
|
+
if type(token) == list:
|
|
94
|
+
for item in token:
|
|
95
|
+
if next == item:
|
|
96
|
+
self.nextToken()
|
|
97
|
+
return
|
|
98
|
+
elif next == token: self.nextToken()
|
|
90
99
|
|
|
91
100
|
def rewindTo(self, index):
|
|
92
101
|
self.index = index
|
|
@@ -114,10 +123,10 @@ class Compiler:
|
|
|
114
123
|
def compileLabel(self, command):
|
|
115
124
|
return self.compileSymbol(command, self.getToken(), False)
|
|
116
125
|
|
|
117
|
-
def compileVariable(self, command, hasValue = False):
|
|
118
|
-
return self.compileSymbol(command, self.nextToken(), hasValue)
|
|
126
|
+
def compileVariable(self, command, hasValue = False, extra=None):
|
|
127
|
+
return self.compileSymbol(command, self.nextToken(), hasValue, extra)
|
|
119
128
|
|
|
120
|
-
def compileSymbol(self, command, name, hasValue):
|
|
129
|
+
def compileSymbol(self, command, name, hasValue, extra=None):
|
|
121
130
|
try:
|
|
122
131
|
v = self.symbols[name]
|
|
123
132
|
except:
|
|
@@ -137,6 +146,7 @@ class Compiler:
|
|
|
137
146
|
command['debug'] = False
|
|
138
147
|
command['import'] = None
|
|
139
148
|
command['locked'] = False
|
|
149
|
+
command['extra'] = extra
|
|
140
150
|
self.addCommand(command)
|
|
141
151
|
return True
|
|
142
152
|
|
|
@@ -164,7 +174,7 @@ class Compiler:
|
|
|
164
174
|
self.rewindTo(mark)
|
|
165
175
|
else:
|
|
166
176
|
self.rewindTo(mark)
|
|
167
|
-
FatalError(self, f'
|
|
177
|
+
FatalError(self, f'Unable to compile this "{token}" command. Perhaps a syntax error?')
|
|
168
178
|
|
|
169
179
|
# Compile a single command
|
|
170
180
|
def compileOne(self):
|
easycoder/ec_core.py
CHANGED
|
@@ -14,6 +14,9 @@ class Core(Handler):
|
|
|
14
14
|
|
|
15
15
|
def getName(self):
|
|
16
16
|
return 'core'
|
|
17
|
+
|
|
18
|
+
def noSymbolWarning(self):
|
|
19
|
+
self.warning(f'Symbol "{self.getToken()}" not found')
|
|
17
20
|
|
|
18
21
|
#############################################################################
|
|
19
22
|
# Keyword handlers
|
|
@@ -161,7 +164,6 @@ class Core(Handler):
|
|
|
161
164
|
val['type'] = 'boolean'
|
|
162
165
|
val['content'] = False
|
|
163
166
|
self.putSymbolValue(target, val)
|
|
164
|
-
# self.add(command)
|
|
165
167
|
return self.nextPC()
|
|
166
168
|
|
|
167
169
|
# Close a file
|
|
@@ -367,6 +369,8 @@ class Core(Handler):
|
|
|
367
369
|
return True
|
|
368
370
|
|
|
369
371
|
def r_exit(self, command):
|
|
372
|
+
if self.program.graphics != None:
|
|
373
|
+
self.program.graphics.force_exit()
|
|
370
374
|
return -1
|
|
371
375
|
|
|
372
376
|
# Declare a file variable
|
|
@@ -1052,21 +1056,22 @@ class Core(Handler):
|
|
|
1052
1056
|
self.putSymbolValue(stackRecord, stack)
|
|
1053
1057
|
return self.nextPC()
|
|
1054
1058
|
|
|
1055
|
-
# Put a value into a variable
|
|
1056
1059
|
# put {value} into {variable}
|
|
1057
1060
|
def k_put(self, command):
|
|
1058
|
-
|
|
1059
|
-
if
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1061
|
+
value = self.nextValue()
|
|
1062
|
+
if value != None:
|
|
1063
|
+
command['value'] = value
|
|
1064
|
+
if self.nextIs('into'):
|
|
1065
|
+
if self.nextIsSymbol():
|
|
1066
|
+
symbolRecord = self.getSymbolRecord()
|
|
1067
|
+
command['target'] = symbolRecord['name']
|
|
1068
|
+
if 'hasValue' in symbolRecord and symbolRecord['hasValue'] == False:
|
|
1069
|
+
FatalError(self.compiler, f'Symbol {symbolRecord["name"]} is not a value holder')
|
|
1070
|
+
else:
|
|
1071
|
+
self.add(command)
|
|
1072
|
+
return True
|
|
1065
1073
|
else:
|
|
1066
|
-
self.
|
|
1067
|
-
return True
|
|
1068
|
-
else:
|
|
1069
|
-
FatalError(self.compiler, f'Symbol {self.getToken()} is not a variable')
|
|
1074
|
+
FatalError(self.compiler, f'Symbol {self.getToken()} is not a variable')
|
|
1070
1075
|
return False
|
|
1071
1076
|
|
|
1072
1077
|
def r_put(self, command):
|
|
@@ -1295,7 +1300,10 @@ class Core(Handler):
|
|
|
1295
1300
|
if self.nextIsSymbol():
|
|
1296
1301
|
command['target'] = self.getSymbolRecord()['name']
|
|
1297
1302
|
if self.nextIs('to'):
|
|
1298
|
-
|
|
1303
|
+
value = self.nextValue()
|
|
1304
|
+
if value == None:
|
|
1305
|
+
FatalError(self.compiler, 'Unable to get a value')
|
|
1306
|
+
command['value'] = value
|
|
1299
1307
|
self.add(command)
|
|
1300
1308
|
return True
|
|
1301
1309
|
|
|
@@ -1379,6 +1387,33 @@ class Core(Handler):
|
|
|
1379
1387
|
self.putSymbolValue(targetVariable, val)
|
|
1380
1388
|
return self.nextPC()
|
|
1381
1389
|
|
|
1390
|
+
# Shuffle a list
|
|
1391
|
+
def k_shuffle(self, command):
|
|
1392
|
+
if self.nextIsSymbol():
|
|
1393
|
+
symbolRecord = self.getSymbolRecord()
|
|
1394
|
+
if symbolRecord['hasValue']:
|
|
1395
|
+
command['target'] = self.getToken()
|
|
1396
|
+
self.add(command)
|
|
1397
|
+
return True
|
|
1398
|
+
self.warning(f'Core.negate: Variable "{symbolRecord["name"]}" does not hold a value')
|
|
1399
|
+
return False
|
|
1400
|
+
|
|
1401
|
+
def r_shuffle(self, command):
|
|
1402
|
+
symbolRecord = self.getVariable(command['target'])
|
|
1403
|
+
if not symbolRecord['hasValue']:
|
|
1404
|
+
RuntimeError(self.program, f'{symbolRecord["name"]} does not hold a value')
|
|
1405
|
+
return None
|
|
1406
|
+
value = self.getSymbolValue(symbolRecord)
|
|
1407
|
+
if value == None:
|
|
1408
|
+
RuntimeError(self.program, f'{symbolRecord["name"]} has not been initialised')
|
|
1409
|
+
content = value['content']
|
|
1410
|
+
if isinstance(content, list):
|
|
1411
|
+
random.shuffle(content)
|
|
1412
|
+
value['content'] = content
|
|
1413
|
+
self.putSymbolValue(symbolRecord, value)
|
|
1414
|
+
return self.nextPC()
|
|
1415
|
+
RuntimeError(self.program, f'{symbolRecord["name"]} is not a list')
|
|
1416
|
+
|
|
1382
1417
|
# Split a string into a variable with several elements
|
|
1383
1418
|
# split {variable} on {value}
|
|
1384
1419
|
def k_split(self, command):
|
|
@@ -1400,6 +1435,7 @@ class Core(Handler):
|
|
|
1400
1435
|
command['on'] = self.nextValue()
|
|
1401
1436
|
self.add(command)
|
|
1402
1437
|
return True
|
|
1438
|
+
else: self.noSymbolWarning()
|
|
1403
1439
|
return False
|
|
1404
1440
|
|
|
1405
1441
|
def r_split(self, command):
|
|
@@ -1419,33 +1455,6 @@ class Core(Handler):
|
|
|
1419
1455
|
|
|
1420
1456
|
return self.nextPC()
|
|
1421
1457
|
|
|
1422
|
-
# Shuffle a list
|
|
1423
|
-
def k_shuffle(self, command):
|
|
1424
|
-
if self.nextIsSymbol():
|
|
1425
|
-
symbolRecord = self.getSymbolRecord()
|
|
1426
|
-
if symbolRecord['hasValue']:
|
|
1427
|
-
command['target'] = self.getToken()
|
|
1428
|
-
self.add(command)
|
|
1429
|
-
return True
|
|
1430
|
-
self.warning(f'Core.negate: Variable "{symbolRecord["name"]}" does not hold a value')
|
|
1431
|
-
return False
|
|
1432
|
-
|
|
1433
|
-
def r_shuffle(self, command):
|
|
1434
|
-
symbolRecord = self.getVariable(command['target'])
|
|
1435
|
-
if not symbolRecord['hasValue']:
|
|
1436
|
-
RuntimeError(self.program, f'{symbolRecord["name"]} does not hold a value')
|
|
1437
|
-
return None
|
|
1438
|
-
value = self.getSymbolValue(symbolRecord)
|
|
1439
|
-
if value == None:
|
|
1440
|
-
RuntimeError(self.program, f'{symbolRecord["name"]} has not been initialised')
|
|
1441
|
-
content = value['content']
|
|
1442
|
-
if isinstance(content, list):
|
|
1443
|
-
random.shuffle(content)
|
|
1444
|
-
value['content'] = content
|
|
1445
|
-
self.putSymbolValue(symbolRecord, value)
|
|
1446
|
-
return self.nextPC()
|
|
1447
|
-
RuntimeError(self.program, f'{symbolRecord["name"]} is not a list')
|
|
1448
|
-
|
|
1449
1458
|
# Declare a stack variable
|
|
1450
1459
|
def k_stack(self, command):
|
|
1451
1460
|
return self.compileVariable(command)
|
|
@@ -1599,7 +1608,9 @@ class Core(Handler):
|
|
|
1599
1608
|
|
|
1600
1609
|
def k_use(self, command):
|
|
1601
1610
|
if self.nextIs('graphics'):
|
|
1602
|
-
|
|
1611
|
+
print('Loading graphics module')
|
|
1612
|
+
from .ec_pyside import Graphics
|
|
1613
|
+
self.program.graphics = Graphics
|
|
1603
1614
|
self.program.classes.append(Graphics)
|
|
1604
1615
|
self.program.processClasses()
|
|
1605
1616
|
return True
|
|
@@ -1762,7 +1773,7 @@ class Core(Handler):
|
|
|
1762
1773
|
if token in ['now', 'today', 'newline', 'tab', 'empty']:
|
|
1763
1774
|
return value
|
|
1764
1775
|
|
|
1765
|
-
if token in ['stringify', 'json', 'lowercase', 'uppercase', 'hash', 'random', 'float', 'integer', 'encode', 'decode']:
|
|
1776
|
+
if token in ['stringify', 'prettify', 'json', 'lowercase', 'uppercase', 'hash', 'random', 'float', 'integer', 'encode', 'decode']:
|
|
1766
1777
|
value['content'] = self.nextValue()
|
|
1767
1778
|
return value
|
|
1768
1779
|
|
|
@@ -2272,6 +2283,13 @@ class Core(Handler):
|
|
|
2272
2283
|
value['content'] = haystack.rfind(needle) if last else haystack.find(needle)
|
|
2273
2284
|
return value
|
|
2274
2285
|
|
|
2286
|
+
def v_prettify(self, v):
|
|
2287
|
+
item = self.getRuntimeValue(v['content'])
|
|
2288
|
+
value = {}
|
|
2289
|
+
value['type'] = 'text'
|
|
2290
|
+
value['content'] = json.dumps(item, indent=4)
|
|
2291
|
+
return value
|
|
2292
|
+
|
|
2275
2293
|
def v_property(self, v):
|
|
2276
2294
|
propertyValue = self.getRuntimeValue(v['name'])
|
|
2277
2295
|
if 'target' in v:
|
easycoder/ec_handler.py
CHANGED
easycoder/ec_program.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import sys
|
|
2
2
|
from easycoder import Handler, FatalError, RuntimeError
|
|
3
3
|
from PySide6.QtCore import Qt, QTimer
|
|
4
|
+
from PySide6.QtGui import QPixmap
|
|
4
5
|
from PySide6.QtWidgets import (
|
|
5
6
|
QApplication,
|
|
6
7
|
QCheckBox,
|
|
@@ -85,28 +86,30 @@ class Graphics(Handler):
|
|
|
85
86
|
|
|
86
87
|
# Here it's either (1) or (2)
|
|
87
88
|
elif self.isSymbol():
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
self.nextToken()
|
|
93
|
-
return addToLayout()
|
|
94
|
-
else:
|
|
95
|
-
# (1)
|
|
96
|
-
command['value'] = self.getValue()
|
|
97
|
-
if self.nextIs('to'):
|
|
98
|
-
if self.nextIsSymbol():
|
|
89
|
+
record = self.getSymbolRecord()
|
|
90
|
+
if record['extra'] == 'gui':
|
|
91
|
+
if self.peek() == 'to':
|
|
92
|
+
# (2)
|
|
99
93
|
record = self.getSymbolRecord()
|
|
100
94
|
command['widget'] = record['name']
|
|
101
|
-
self.
|
|
102
|
-
return
|
|
95
|
+
self.nextToken()
|
|
96
|
+
return addToLayout()
|
|
97
|
+
return False
|
|
98
|
+
# (1)
|
|
99
|
+
command['value'] = self.getValue()
|
|
100
|
+
self.skip('to')
|
|
101
|
+
if self.nextIsSymbol():
|
|
102
|
+
record = self.getSymbolRecord()
|
|
103
|
+
command['widget'] = record['name']
|
|
104
|
+
self.add(command)
|
|
105
|
+
return True
|
|
103
106
|
return False
|
|
104
107
|
|
|
105
108
|
def r_add(self, command):
|
|
106
109
|
if 'value' in command:
|
|
107
110
|
value = self.getRuntimeValue(command['value'])
|
|
108
111
|
widget = self.getVariable(command['widget'])
|
|
109
|
-
if widget['keyword']
|
|
112
|
+
if widget['keyword'] in ['listbox', 'combobox']:
|
|
110
113
|
widget['widget'].addItem(value)
|
|
111
114
|
else:
|
|
112
115
|
layoutRecord = self.getVariable(command['layout'])
|
|
@@ -140,13 +143,13 @@ class Graphics(Handler):
|
|
|
140
143
|
record = self.getSymbolRecord()
|
|
141
144
|
if record['keyword'] == 'window':
|
|
142
145
|
command['window2'] = record['name']
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
146
|
+
self.skip('on')
|
|
147
|
+
if self.nextIsSymbol():
|
|
148
|
+
record = self.getSymbolRecord()
|
|
149
|
+
if record['keyword'] == 'window':
|
|
150
|
+
command['window1'] = record['name']
|
|
151
|
+
self.add(command)
|
|
152
|
+
return True
|
|
150
153
|
return False
|
|
151
154
|
|
|
152
155
|
def r_center(self, command):
|
|
@@ -160,12 +163,23 @@ class Graphics(Handler):
|
|
|
160
163
|
|
|
161
164
|
# Declare a checkbox variable
|
|
162
165
|
def k_checkbox(self, command):
|
|
163
|
-
return self.compileVariable(command, False)
|
|
166
|
+
return self.compileVariable(command, False, 'gui')
|
|
164
167
|
|
|
165
168
|
def r_checkbox(self, command):
|
|
166
169
|
return self.nextPC()
|
|
167
170
|
|
|
168
|
-
#
|
|
171
|
+
# clear {widget}
|
|
172
|
+
def k_clear(self, command):
|
|
173
|
+
if self.nextIsSymbol():
|
|
174
|
+
command['name'] = self.getSymbolRecord()['name']
|
|
175
|
+
self.add(command)
|
|
176
|
+
return True
|
|
177
|
+
return False
|
|
178
|
+
|
|
179
|
+
def r_clear(self, command):
|
|
180
|
+
self.getVariable(command['name'])['widget'].clear()
|
|
181
|
+
return self.nextPC()
|
|
182
|
+
|
|
169
183
|
# close {window}
|
|
170
184
|
def k_close(self, command):
|
|
171
185
|
if self.nextIsSymbol():
|
|
@@ -182,7 +196,7 @@ class Graphics(Handler):
|
|
|
182
196
|
|
|
183
197
|
# Declare a combobox variable
|
|
184
198
|
def k_combobox(self, command):
|
|
185
|
-
return self.compileVariable(command, False)
|
|
199
|
+
return self.compileVariable(command, False, 'gui')
|
|
186
200
|
|
|
187
201
|
def r_combobox(self, command):
|
|
188
202
|
return self.nextPC()
|
|
@@ -221,11 +235,10 @@ class Graphics(Handler):
|
|
|
221
235
|
|
|
222
236
|
# Create a widget
|
|
223
237
|
def k_createLayout(self, command):
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
return False
|
|
238
|
+
self.skip('type')
|
|
239
|
+
command['type'] = self.nextToken()
|
|
240
|
+
self.add(command)
|
|
241
|
+
return True
|
|
229
242
|
|
|
230
243
|
def k_createGroupBox(self, command):
|
|
231
244
|
if self.peek() == 'title':
|
|
@@ -237,7 +250,7 @@ class Graphics(Handler):
|
|
|
237
250
|
return True
|
|
238
251
|
|
|
239
252
|
def k_createLabel(self, command):
|
|
240
|
-
text = ''
|
|
253
|
+
text = self.compileConstant('')
|
|
241
254
|
while True:
|
|
242
255
|
token = self.peek()
|
|
243
256
|
if token == 'text':
|
|
@@ -246,6 +259,11 @@ class Graphics(Handler):
|
|
|
246
259
|
elif token == 'size':
|
|
247
260
|
self.nextToken()
|
|
248
261
|
command['size'] = self.nextValue()
|
|
262
|
+
elif token == 'align':
|
|
263
|
+
self.nextToken()
|
|
264
|
+
token = self.nextToken()
|
|
265
|
+
if token in ['left', 'right', 'center', 'centre', 'justify']:
|
|
266
|
+
command['align'] = token
|
|
249
267
|
else: break
|
|
250
268
|
command['text'] = text
|
|
251
269
|
self.add(command)
|
|
@@ -397,11 +415,19 @@ class Graphics(Handler):
|
|
|
397
415
|
c = label.contentsMargins()
|
|
398
416
|
w = fm.horizontalAdvance('m') * self.getRuntimeValue(command['size']) +c.left()+c.right()
|
|
399
417
|
label.setMaximumWidth(w)
|
|
418
|
+
if 'align' in command:
|
|
419
|
+
alignment = command['align']
|
|
420
|
+
if alignment == 'left': label.setAlignment(Qt.AlignLeft)
|
|
421
|
+
elif alignment == 'right': label.setAlignment(Qt.AlignRight)
|
|
422
|
+
elif alignment in ['center', 'centre']: label.setAlignment(Qt.AlignHCenter)
|
|
423
|
+
elif alignment == 'justify': label.setAlignment(Qt.AlignJustify)
|
|
400
424
|
record['widget'] = label
|
|
401
425
|
return self.nextPC()
|
|
402
426
|
|
|
403
427
|
def r_createPushbutton(self, command, record):
|
|
404
|
-
|
|
428
|
+
text = self.getRuntimeValue(command['text'])
|
|
429
|
+
pushbutton = QPushButton(text)
|
|
430
|
+
pushbutton.setAccessibleName(text)
|
|
405
431
|
if 'size' in command:
|
|
406
432
|
fm = pushbutton.fontMetrics()
|
|
407
433
|
c = pushbutton.contentsMargins()
|
|
@@ -504,7 +530,7 @@ class Graphics(Handler):
|
|
|
504
530
|
|
|
505
531
|
# Create a group box
|
|
506
532
|
def k_groupbox(self, command):
|
|
507
|
-
return self.compileVariable(command, False)
|
|
533
|
+
return self.compileVariable(command, False, 'gui')
|
|
508
534
|
|
|
509
535
|
def r_groupbox(self, command):
|
|
510
536
|
return self.nextPC()
|
|
@@ -526,28 +552,28 @@ class Graphics(Handler):
|
|
|
526
552
|
|
|
527
553
|
# Declare a label variable
|
|
528
554
|
def k_label(self, command):
|
|
529
|
-
return self.compileVariable(command, False)
|
|
555
|
+
return self.compileVariable(command, False, 'gui')
|
|
530
556
|
|
|
531
557
|
def r_label(self, command):
|
|
532
558
|
return self.nextPC()
|
|
533
559
|
|
|
534
560
|
# Declare a layout variable
|
|
535
561
|
def k_layout(self, command):
|
|
536
|
-
return self.compileVariable(command, False)
|
|
562
|
+
return self.compileVariable(command, False, 'gui')
|
|
537
563
|
|
|
538
564
|
def r_layout(self, command):
|
|
539
565
|
return self.nextPC()
|
|
540
566
|
|
|
541
567
|
# Declare a line input variable
|
|
542
568
|
def k_lineinput(self, command):
|
|
543
|
-
return self.compileVariable(command, False)
|
|
569
|
+
return self.compileVariable(command, False, 'gui')
|
|
544
570
|
|
|
545
571
|
def r_lineinput(self, command):
|
|
546
572
|
return self.nextPC()
|
|
547
573
|
|
|
548
574
|
# Declare a listbox input variable
|
|
549
575
|
def k_listbox(self, command):
|
|
550
|
-
return self.compileVariable(command, False)
|
|
576
|
+
return self.compileVariable(command, False, 'gui')
|
|
551
577
|
|
|
552
578
|
def r_listbox(self, command):
|
|
553
579
|
return self.nextPC()
|
|
@@ -559,100 +585,219 @@ class Graphics(Handler):
|
|
|
559
585
|
def r_messagebox(self, command):
|
|
560
586
|
return self.nextPC()
|
|
561
587
|
|
|
562
|
-
#
|
|
588
|
+
# on click {pushbutton}
|
|
589
|
+
# on select {combobox}/{listbox}
|
|
563
590
|
def k_on(self, command):
|
|
564
|
-
|
|
591
|
+
def setupOn():
|
|
592
|
+
command['name'] = record['name']
|
|
593
|
+
command['goto'] = self.getPC() + 2
|
|
594
|
+
self.add(command)
|
|
595
|
+
self.nextToken()
|
|
596
|
+
# Step over the click handler
|
|
597
|
+
pcNext = self.getPC()
|
|
598
|
+
cmd = {}
|
|
599
|
+
cmd['domain'] = 'core'
|
|
600
|
+
cmd['lino'] = command['lino']
|
|
601
|
+
cmd['keyword'] = 'gotoPC'
|
|
602
|
+
cmd['goto'] = 0
|
|
603
|
+
cmd['debug'] = False
|
|
604
|
+
self.addCommand(cmd)
|
|
605
|
+
# This is the click handler
|
|
606
|
+
self.compileOne()
|
|
607
|
+
cmd = {}
|
|
608
|
+
cmd['domain'] = 'core'
|
|
609
|
+
cmd['lino'] = command['lino']
|
|
610
|
+
cmd['keyword'] = 'stop'
|
|
611
|
+
cmd['debug'] = False
|
|
612
|
+
self.addCommand(cmd)
|
|
613
|
+
# Fixup the link
|
|
614
|
+
self.getCommandAt(pcNext)['goto'] = self.getPC()
|
|
615
|
+
|
|
616
|
+
token = self.nextToken()
|
|
617
|
+
if token == 'click':
|
|
565
618
|
if self.nextIsSymbol():
|
|
566
619
|
record = self.getSymbolRecord()
|
|
567
620
|
if record['keyword'] == 'pushbutton':
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
cmd['domain'] = 'core'
|
|
576
|
-
cmd['lino'] = command['lino']
|
|
577
|
-
cmd['keyword'] = 'gotoPC'
|
|
578
|
-
cmd['goto'] = 0
|
|
579
|
-
cmd['debug'] = False
|
|
580
|
-
self.addCommand(cmd)
|
|
581
|
-
# This is the click handler
|
|
582
|
-
self.compileOne()
|
|
583
|
-
cmd = {}
|
|
584
|
-
cmd['domain'] = 'core'
|
|
585
|
-
cmd['lino'] = command['lino']
|
|
586
|
-
cmd['keyword'] = 'stop'
|
|
587
|
-
cmd['debug'] = False
|
|
588
|
-
self.addCommand(cmd)
|
|
589
|
-
# Fixup the link
|
|
590
|
-
self.getCommandAt(pcNext)['goto'] = self.getPC()
|
|
621
|
+
setupOn()
|
|
622
|
+
return True
|
|
623
|
+
elif token == 'select':
|
|
624
|
+
if self.nextIsSymbol():
|
|
625
|
+
record = self.getSymbolRecord()
|
|
626
|
+
if record['keyword'] in ['combobox', 'listbox']:
|
|
627
|
+
setupOn()
|
|
591
628
|
return True
|
|
592
629
|
return False
|
|
593
630
|
|
|
594
631
|
def r_on(self, command):
|
|
595
|
-
|
|
596
|
-
|
|
632
|
+
record = self.getVariable(command['name'])
|
|
633
|
+
widget = record['widget']
|
|
634
|
+
keyword = record['keyword']
|
|
635
|
+
if keyword == 'pushbutton':
|
|
636
|
+
widget.clicked.connect(lambda: self.run(command['goto']))
|
|
637
|
+
elif keyword == 'combobox':
|
|
638
|
+
widget.currentIndexChanged.connect(lambda: self.run(command['goto']))
|
|
639
|
+
elif keyword == 'listbox':
|
|
640
|
+
widget.itemClicked.connect(lambda: self.run(command['goto']))
|
|
597
641
|
return self.nextPC()
|
|
598
642
|
|
|
599
643
|
# Declare a pushbutton variable
|
|
600
644
|
def k_pushbutton(self, command):
|
|
601
|
-
return self.compileVariable(command, False)
|
|
645
|
+
return self.compileVariable(command, False, 'gui')
|
|
602
646
|
|
|
603
647
|
def r_pushbutton(self, command):
|
|
604
648
|
return self.nextPC()
|
|
605
649
|
|
|
606
|
-
# remove current item from {combobox}
|
|
650
|
+
# remove [the] [current/selected] [item] [from/in] {combobox}/{listbox}
|
|
607
651
|
def k_remove(self, command):
|
|
608
652
|
command['variant'] = None
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
653
|
+
self.skip('the')
|
|
654
|
+
self.skip(['current', 'selected'])
|
|
655
|
+
self.skip('item')
|
|
656
|
+
self.skip(['from', 'in'])
|
|
657
|
+
if self.nextIsSymbol():
|
|
658
|
+
record = self.getSymbolRecord()
|
|
659
|
+
if record['keyword'] == 'combobox':
|
|
660
|
+
command['variant'] = 'current'
|
|
661
|
+
command['name'] = record['name']
|
|
662
|
+
self.addCommand(command)
|
|
663
|
+
return True
|
|
664
|
+
elif record['keyword'] == 'listbox':
|
|
665
|
+
command['variant'] = 'current'
|
|
666
|
+
command['name'] = record['name']
|
|
667
|
+
self.addCommand(command)
|
|
668
|
+
return True
|
|
619
669
|
return False
|
|
620
670
|
|
|
621
671
|
def r_remove(self, command):
|
|
622
672
|
variant = command['variant']
|
|
623
673
|
record = self.getVariable(command['name'])
|
|
624
|
-
if
|
|
625
|
-
|
|
626
|
-
|
|
674
|
+
if variant == 'current':
|
|
675
|
+
if record['keyword'] == 'combobox':
|
|
676
|
+
widget = record['widget']
|
|
677
|
+
widget.removeItem(widget.currentIndex())
|
|
678
|
+
if record['keyword'] == 'listbox':
|
|
679
|
+
widget = record['widget']
|
|
680
|
+
selectedItem = widget.currentItem()
|
|
681
|
+
if selectedItem:
|
|
682
|
+
row = widget.row(selectedItem)
|
|
683
|
+
widget.takeItem(row)
|
|
684
|
+
return self.nextPC()
|
|
685
|
+
|
|
686
|
+
# select index {n} [of] {combobox]}
|
|
687
|
+
# select {name} [in] {combobox}
|
|
688
|
+
def k_select(self, command):
|
|
689
|
+
if self.nextIs('index'):
|
|
690
|
+
command['index'] = self.nextValue()
|
|
691
|
+
self.skip('of')
|
|
692
|
+
else:
|
|
693
|
+
command['name'] = self.nextValue()
|
|
694
|
+
self.skip('in')
|
|
695
|
+
if self.nextIsSymbol():
|
|
696
|
+
record = self.getSymbolRecord()
|
|
697
|
+
if record['keyword'] == 'combobox':
|
|
698
|
+
command['widget'] = record['name']
|
|
699
|
+
self.add(command)
|
|
700
|
+
return True
|
|
701
|
+
return False
|
|
702
|
+
|
|
703
|
+
def r_select(self, command):
|
|
704
|
+
widget = self.getVariable(command['widget'])['widget']
|
|
705
|
+
if 'index' in command:
|
|
706
|
+
index = self.getRuntimeValue(command['index'])
|
|
707
|
+
else:
|
|
708
|
+
name = self.getRuntimeValue(command['name'])
|
|
709
|
+
index = widget.findText(name, Qt.MatchFixedString)
|
|
710
|
+
if index >= 0:
|
|
711
|
+
widget.setCurrentIndex(index)
|
|
627
712
|
return self.nextPC()
|
|
628
713
|
|
|
629
|
-
#
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
# Set something
|
|
714
|
+
# set [the] width/height [of] {widget} [to] {value}
|
|
715
|
+
# set [the] text [of] {label}/{button}/{lineinput} [to] {text}
|
|
716
|
+
# set [the] color [of] {label}/{button}/{lineinput} [to] {color}
|
|
717
|
+
# set {listbox} to {list}
|
|
634
718
|
def k_set(self, command):
|
|
719
|
+
self.skip('the')
|
|
635
720
|
token = self.nextToken()
|
|
636
|
-
|
|
637
|
-
if token
|
|
638
|
-
|
|
639
|
-
if self.
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
721
|
+
command['what'] = token
|
|
722
|
+
if token in ['width', 'height']:
|
|
723
|
+
self.skip('of')
|
|
724
|
+
if self.nextIsSymbol():
|
|
725
|
+
record = self.getSymbolRecord()
|
|
726
|
+
if record['extra'] == 'gui':
|
|
727
|
+
command['name'] = record['name']
|
|
728
|
+
self.skip('to')
|
|
729
|
+
command['value'] = self.nextValue()
|
|
730
|
+
self.add(command)
|
|
731
|
+
return True
|
|
732
|
+
elif token == 'text':
|
|
733
|
+
self.skip('of')
|
|
734
|
+
if self.nextIsSymbol():
|
|
735
|
+
record = self.getSymbolRecord()
|
|
736
|
+
if record['keyword'] in ['label', 'pushbutton', 'lineinput']:
|
|
737
|
+
command['name'] = record['name']
|
|
738
|
+
self.skip('to')
|
|
739
|
+
command['value'] = self.nextValue()
|
|
740
|
+
self.add(command)
|
|
741
|
+
return True
|
|
742
|
+
elif token == 'color':
|
|
743
|
+
self.skip('of')
|
|
744
|
+
if self.nextIsSymbol():
|
|
745
|
+
record = self.getSymbolRecord()
|
|
746
|
+
if record['keyword'] == 'label':
|
|
747
|
+
command['name'] = record['name']
|
|
748
|
+
self.skip('to')
|
|
749
|
+
command['value'] = self.nextValue()
|
|
750
|
+
self.add(command)
|
|
751
|
+
return True
|
|
752
|
+
elif token == 'background':
|
|
753
|
+
self.skip('color')
|
|
754
|
+
self.skip('of')
|
|
755
|
+
if self.nextIsSymbol():
|
|
756
|
+
record = self.getSymbolRecord()
|
|
757
|
+
if record['keyword'] in ['label', 'pushbutton', 'lineinput']:
|
|
758
|
+
command['name'] = record['name']
|
|
759
|
+
self.skip('to')
|
|
760
|
+
command['value'] = self.nextValue()
|
|
761
|
+
self.add(command)
|
|
762
|
+
return True
|
|
763
|
+
elif self.isSymbol():
|
|
764
|
+
record = self.getSymbolRecord()
|
|
765
|
+
if record['keyword'] == 'listbox':
|
|
766
|
+
command['what'] = 'listbox'
|
|
767
|
+
command['name'] = record['name']
|
|
768
|
+
self.skip('to')
|
|
769
|
+
command['value'] = self.nextValue()
|
|
770
|
+
self.add(command)
|
|
771
|
+
return True
|
|
649
772
|
return False
|
|
650
773
|
|
|
651
774
|
def r_set(self, command):
|
|
652
|
-
|
|
653
|
-
if
|
|
654
|
-
|
|
655
|
-
|
|
775
|
+
what = command['what']
|
|
776
|
+
if what == 'height':
|
|
777
|
+
widget = self.getVariable(command['name'])['widget']
|
|
778
|
+
widget.setFixedHeight(self.getRuntimeValue(command['value']))
|
|
779
|
+
elif what == 'width':
|
|
780
|
+
widget = self.getVariable(command['name'])['widget']
|
|
781
|
+
widget.setFixedWidth(self.getRuntimeValue(command['value']))
|
|
782
|
+
elif what == 'text':
|
|
783
|
+
record = self.getVariable(command['name'])
|
|
784
|
+
widget = self.getVariable(command['name'])['widget']
|
|
785
|
+
text = self.getRuntimeValue(command['value'])
|
|
786
|
+
widget.setText(text)
|
|
787
|
+
if record['keyword'] == 'pushbutton':
|
|
788
|
+
widget.setAccessibleName(text)
|
|
789
|
+
elif what == 'color':
|
|
790
|
+
widget = self.getVariable(command['name'])['widget']
|
|
791
|
+
color = self.getRuntimeValue(command['value'])
|
|
792
|
+
widget.setStyleSheet(f"color: {color};")
|
|
793
|
+
elif what == 'background-color':
|
|
794
|
+
widget = self.getVariable(command['name'])['widget']
|
|
795
|
+
bg_color = self.getRuntimeValue(command['value'])
|
|
796
|
+
widget.setStyleSheet(f"background-color: {bg_color};")
|
|
797
|
+
elif what == 'listbox':
|
|
798
|
+
widget = self.getVariable(command['name'])['widget']
|
|
799
|
+
value = self.getRuntimeValue(command['value'])
|
|
800
|
+
widget.addItems(value)
|
|
656
801
|
return self.nextPC()
|
|
657
802
|
|
|
658
803
|
# show {window}
|
|
@@ -672,11 +817,11 @@ class Graphics(Handler):
|
|
|
672
817
|
return True
|
|
673
818
|
elif keyword == 'messagebox':
|
|
674
819
|
command['messagebox'] = record['name']
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
820
|
+
self.skip('giving')
|
|
821
|
+
if self.nextIsSymbol():
|
|
822
|
+
command['result'] = self.getSymbolRecord()['name']
|
|
823
|
+
self.add(command)
|
|
824
|
+
return True
|
|
680
825
|
return False
|
|
681
826
|
|
|
682
827
|
def r_show(self, command):
|
|
@@ -717,12 +862,14 @@ class Graphics(Handler):
|
|
|
717
862
|
|
|
718
863
|
def r_start(self, command):
|
|
719
864
|
def on_last_window_closed():
|
|
720
|
-
print("
|
|
865
|
+
print("Kill the appication...")
|
|
721
866
|
self.program.kill()
|
|
722
867
|
def resume():
|
|
723
868
|
self.program.flush(self.nextPC())
|
|
869
|
+
def flush():
|
|
870
|
+
self.program.flushCB()
|
|
724
871
|
timer = QTimer()
|
|
725
|
-
timer.timeout.connect(
|
|
872
|
+
timer.timeout.connect(flush)
|
|
726
873
|
timer.start(10)
|
|
727
874
|
QTimer.singleShot(500, resume)
|
|
728
875
|
self.app.lastWindowClosed.connect(on_last_window_closed)
|
|
@@ -734,7 +881,7 @@ class Graphics(Handler):
|
|
|
734
881
|
|
|
735
882
|
def r_window(self, command):
|
|
736
883
|
return self.nextPC()
|
|
737
|
-
|
|
884
|
+
|
|
738
885
|
#############################################################################
|
|
739
886
|
# Compile a value in this domain
|
|
740
887
|
def compileValue(self):
|
|
@@ -751,15 +898,27 @@ class Graphics(Handler):
|
|
|
751
898
|
token = self.getToken()
|
|
752
899
|
|
|
753
900
|
if token == 'count':
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
901
|
+
self.skip('of')
|
|
902
|
+
if self.nextIsSymbol():
|
|
903
|
+
value['type'] = 'symbol'
|
|
904
|
+
record = self.getSymbolRecord()
|
|
905
|
+
keyword = record['keyword']
|
|
906
|
+
if keyword in ['combobox', 'listbox']:
|
|
907
|
+
value['type'] = 'count'
|
|
908
|
+
value['name'] = record['name']
|
|
909
|
+
return value
|
|
910
|
+
|
|
911
|
+
if token == 'current':
|
|
912
|
+
self.skip('item')
|
|
913
|
+
self.skip('in')
|
|
914
|
+
if self.nextIsSymbol():
|
|
915
|
+
value['type'] = 'symbol'
|
|
916
|
+
record = self.getSymbolRecord()
|
|
917
|
+
keyword = record['keyword']
|
|
918
|
+
if keyword == 'listbox':
|
|
919
|
+
value['type'] = 'current'
|
|
920
|
+
value['name'] = record['name']
|
|
921
|
+
return value
|
|
763
922
|
|
|
764
923
|
return None
|
|
765
924
|
|
|
@@ -775,7 +934,13 @@ class Graphics(Handler):
|
|
|
775
934
|
def v_symbol(self, symbolRecord):
|
|
776
935
|
symbolRecord = self.getVariable(symbolRecord['name'])
|
|
777
936
|
keyword = symbolRecord['keyword']
|
|
778
|
-
if keyword == '
|
|
937
|
+
if keyword == 'pushbutton':
|
|
938
|
+
pushbutton = symbolRecord['widget']
|
|
939
|
+
v = {}
|
|
940
|
+
v['type'] = 'text'
|
|
941
|
+
v['content'] = pushbutton.accessibleName()
|
|
942
|
+
return v
|
|
943
|
+
elif keyword == 'lineinput':
|
|
779
944
|
lineinput = symbolRecord['widget']
|
|
780
945
|
v = {}
|
|
781
946
|
v['type'] = 'text'
|
|
@@ -787,18 +952,35 @@ class Graphics(Handler):
|
|
|
787
952
|
v['type'] = 'text'
|
|
788
953
|
v['content'] = combobox.currentText()
|
|
789
954
|
return v
|
|
955
|
+
elif keyword == 'listbox':
|
|
956
|
+
listbox = symbolRecord['widget']
|
|
957
|
+
content = listbox.currentItem().text()
|
|
958
|
+
v = {}
|
|
959
|
+
v['type'] = 'text'
|
|
960
|
+
v['content'] = content
|
|
961
|
+
return v
|
|
790
962
|
return None
|
|
791
963
|
|
|
792
964
|
def v_count(self, v):
|
|
793
965
|
record = self.getVariable(v['name'])
|
|
794
966
|
keyword = record['keyword']
|
|
795
967
|
widget = record['widget']
|
|
796
|
-
if keyword
|
|
968
|
+
if keyword in ['combobox', 'listbox']: content = widget.count()
|
|
797
969
|
value = {}
|
|
798
970
|
value['type'] = 'int'
|
|
799
971
|
value['content'] = content
|
|
800
972
|
return value
|
|
801
973
|
|
|
974
|
+
def v_current(self, v):
|
|
975
|
+
record = self.getVariable(v['name'])
|
|
976
|
+
keyword = record['keyword']
|
|
977
|
+
widget = record['widget']
|
|
978
|
+
if keyword == 'listbox': content = widget.currentItem().text()
|
|
979
|
+
value = {}
|
|
980
|
+
value['type'] = 'text'
|
|
981
|
+
value['content'] = content
|
|
982
|
+
return value
|
|
983
|
+
|
|
802
984
|
#############################################################################
|
|
803
985
|
# Compile a condition
|
|
804
986
|
def compileCondition(self):
|
|
@@ -807,3 +989,22 @@ class Graphics(Handler):
|
|
|
807
989
|
|
|
808
990
|
#############################################################################
|
|
809
991
|
# Condition handlers
|
|
992
|
+
|
|
993
|
+
#############################################################################
|
|
994
|
+
# Force the application to exit
|
|
995
|
+
def force_exit(self):
|
|
996
|
+
QApplication.quit() # Gracefully close the application
|
|
997
|
+
sys.exit(0) # Force a complete system exit
|
|
998
|
+
|
|
999
|
+
|
|
1000
|
+
def addIconToLayout(layout, icon_path):
|
|
1001
|
+
"""
|
|
1002
|
+
Adds an icon to the specified layout.
|
|
1003
|
+
|
|
1004
|
+
:param layout: The layout to which the icon will be added.
|
|
1005
|
+
:param icon_path: The file path of the icon image.
|
|
1006
|
+
"""
|
|
1007
|
+
icon_label = QLabel()
|
|
1008
|
+
pixmap = QPixmap(icon_path)
|
|
1009
|
+
icon_label.setPixmap(pixmap)
|
|
1010
|
+
layout.addWidget(icon_label)
|
|
@@ -1,17 +1,22 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: easycoder
|
|
3
|
-
Version:
|
|
3
|
+
Version: 250504.1
|
|
4
4
|
Summary: Rapid scripting in English
|
|
5
5
|
Keywords: compiler,scripting,prototyping,programming,coding,python,low code,hypertalk,computer language,learn to code
|
|
6
6
|
Author-email: Graham Trott <gtanyware@gmail.com>
|
|
7
7
|
Description-Content-Type: text/markdown
|
|
8
8
|
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
License-File: LICENSE
|
|
9
10
|
Requires-Dist: pytz
|
|
10
11
|
Requires-Dist: pyside6
|
|
11
12
|
Project-URL: Home, https://github.com/easycoder/easycoder-py
|
|
12
13
|
|
|
13
14
|
# Introduction
|
|
14
|
-
**_EasyCoder_** is a high-level English-like scripting language suited for prototyping and rapid testing of ideas. It operates on the command line and a graphics module is under construction. The language is written in Python and it acts as a fairly thin wrapper around standard Python functions, giving fast compilation and good runtime performance for general applications.
|
|
15
|
+
**_EasyCoder_** is a high-level English-like domain-specific scripting language (DSL) suited for prototyping and rapid testing of ideas. It operates on the command line and a graphics module is under construction. The language is written in Python and it acts as a fairly thin wrapper around standard Python functions, giving fast compilation and good runtime performance for general applications.
|
|
16
|
+
|
|
17
|
+
**_EasyCoder_** is well suited to building command-line or graphical applications for expressing random logic such as operating procedures and rules, or controlling physical systems, primarily wifi devices. It is particularly easy to construct and issue REST commands to local or remote web servers.
|
|
18
|
+
|
|
19
|
+
For more advanced applications, **_EasyCoder_** is designed to be extensible, by enabling extra language syntax to be added via plugin-in modules. Once these are installed they act as seamless extensions to the basic syntax provided. **_EasyCoder_** derives its power from the use of rich and comprehensive language rather than a complex system of frameworks such as those commonly used in modern programming. This makes it very easy to learn as our brains are wired to operate that way. Having said that, the needs of most control systems are usually served by a fairly modest number of keywords and syntactic variants.
|
|
15
20
|
<hr>
|
|
16
21
|
|
|
17
22
|
There is also a JavaScript version of **_EasyCoder_**, which provides a full set of graphical features to run in a browser. For this, please visit
|
|
@@ -23,15 +28,12 @@ Website: [https://easycoder.github.io](https://easycoder.github.io)
|
|
|
23
28
|
## Quick Start
|
|
24
29
|
Install **_EasyCoder_** in your Python environment:
|
|
25
30
|
```
|
|
26
|
-
pip install requests
|
|
31
|
+
pip install requests easycoder
|
|
27
32
|
```
|
|
28
33
|
|
|
29
34
|
Test the install by typing the command `easycoder`.
|
|
30
35
|
<hr>
|
|
31
|
-
On Linux, this will probably fail as the installer places the executable file in the `$HOME/.local/bin` directory. So give the command
|
|
32
|
-
```
|
|
33
|
-
export PATH=$HOME/.local/bin:$PATH
|
|
34
|
-
```
|
|
36
|
+
On Linux, this will probably fail as the installer places the executable file in the `$HOME/.local/bin` directory. So give the command `export PATH=$HOME/.local/bin:$PATH`.
|
|
35
37
|
|
|
36
38
|
To make this change permanent, edit your `.profile` file, adding the following:
|
|
37
39
|
```
|
|
@@ -42,7 +44,7 @@ fi
|
|
|
42
44
|
```
|
|
43
45
|
<hr>
|
|
44
46
|
|
|
45
|
-
Now write a test script,
|
|
47
|
+
Now write a test script, `hello.ecs`, containing the following:
|
|
46
48
|
```
|
|
47
49
|
print `Hello, world!`
|
|
48
50
|
exit
|
|
@@ -84,7 +86,7 @@ Here in the repository is a folder called `scripts` containing some sample scrip
|
|
|
84
86
|
`benchmark.ecs` allows the performance of **_EasyCoder_** to be compared to other languages if a similar script is written for each one.
|
|
85
87
|
|
|
86
88
|
## Graphical programming
|
|
87
|
-
**_EasyCoder_** includes a graphical programming environment based on PySide6, that is in
|
|
89
|
+
**_EasyCoder_** includes a graphical programming environment based on PySide6, that is in under development. Some demo scripts will be included in the `scripts` directory as development proceeds. Anyone wishing to track progress can do so via this repository. At the time of writing we are transitioning from an early version based on PySimpleGUI to one based on PySide, the latter being an open product that matches the needs of a DSL better than does the former.
|
|
88
90
|
|
|
89
91
|
## Significant features
|
|
90
92
|
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
easycoder/README.md,sha256=BVXmYphcTJ6q6RN_9L6HtQukgCnOjSLVIsTM3lk-9aM,587
|
|
2
|
+
easycoder/__init__.py,sha256=EGnBVcP5HZKaL9fLqsey2v6VejGMeqhyENBsyHElMgw,262
|
|
3
|
+
easycoder/ec_classes.py,sha256=xnWBNak8oKydkFoxHLlq9wo3lIsB3aMnTDrqbtCfoWo,1512
|
|
4
|
+
easycoder/ec_compiler.py,sha256=vNOAKIK2pX_cW4mcxwCe0OR16iqeZqvZQ6JCgQ5MqtU,5062
|
|
5
|
+
easycoder/ec_condition.py,sha256=YXvSBQKEzKGCcgUGo3Qp8iHolXmm2BpEm0NimSDszIM,785
|
|
6
|
+
easycoder/ec_core.py,sha256=4mFDsTS0Cd_Z0li8Oad_EMT783weuSm3S1IlWSoXIMY,91286
|
|
7
|
+
easycoder/ec_graphics.py,sha256=WXxKMB4GJSmxvk-FVbOTyufiUx4TYIzyDoB1PCAO3JY,16067
|
|
8
|
+
easycoder/ec_gutils.py,sha256=yqu4RRQ6VdRkC5B2ADBYsXzgNu76dLnekd9aUjdEgPw,6399
|
|
9
|
+
easycoder/ec_handler.py,sha256=zPDZ_hqdgNnkCd8B5HmSLkqsGgf4aDmqcUBOPHgo47U,2305
|
|
10
|
+
easycoder/ec_program.py,sha256=CxGYl1slYXNOYFxiSMc-BuXL_QztYuBfCXltPCtw1U4,10011
|
|
11
|
+
easycoder/ec_pyside.py,sha256=6GIZpnmIj9LissJopfqcSvc1i1qbl4h56PQsJXOu9XU,36005
|
|
12
|
+
easycoder/ec_timestamp.py,sha256=_3QFJPzIWZ9Rzk3SQOQJ-gwmvB07pg78k23SPntoZtY,288
|
|
13
|
+
easycoder/ec_value.py,sha256=zgDJTJhIg3yOvmnnKIfccIizmIhGbtvL_ghLTL1T5fg,2516
|
|
14
|
+
easycoder-250504.1.dist-info/entry_points.txt,sha256=JXAZbenl0TnsIft2FcGJbJ-4qoztVu2FuT8PFmWFexM,44
|
|
15
|
+
easycoder-250504.1.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
16
|
+
easycoder-250504.1.dist-info/WHEEL,sha256=Dyt6SBfaasWElUrURkknVFAZDHSTwxg3PaTza7RSbkY,100
|
|
17
|
+
easycoder-250504.1.dist-info/METADATA,sha256=WFCQMbyGyIaudwFDHkiXLAfz4VtOkx2OBuPAV-NAelo,6825
|
|
18
|
+
easycoder-250504.1.dist-info/RECORD,,
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
easycoder/README.md,sha256=BVXmYphcTJ6q6RN_9L6HtQukgCnOjSLVIsTM3lk-9aM,587
|
|
2
|
-
easycoder/__init__.py,sha256=U91pzIS30xf6fU78HzxaL0kYq6R3saY-_c-EAacke8w,262
|
|
3
|
-
easycoder/ec_classes.py,sha256=xnWBNak8oKydkFoxHLlq9wo3lIsB3aMnTDrqbtCfoWo,1512
|
|
4
|
-
easycoder/ec_compiler.py,sha256=WN4DMTU66kzOAwOGJe3KDoXj2nPvq19ACegQ-RSMglo,4780
|
|
5
|
-
easycoder/ec_condition.py,sha256=YXvSBQKEzKGCcgUGo3Qp8iHolXmm2BpEm0NimSDszIM,785
|
|
6
|
-
easycoder/ec_core.py,sha256=RHFdEMgudlLPUOisbzj_sdvrWfokoPOYKv_T8oV19ag,90563
|
|
7
|
-
easycoder/ec_graphics.py,sha256=WXxKMB4GJSmxvk-FVbOTyufiUx4TYIzyDoB1PCAO3JY,16067
|
|
8
|
-
easycoder/ec_gutils.py,sha256=yqu4RRQ6VdRkC5B2ADBYsXzgNu76dLnekd9aUjdEgPw,6399
|
|
9
|
-
easycoder/ec_handler.py,sha256=K7nBuQTH8l0k8hX1o2b4KhTnhZHGdf2fkEuX4FJXJs8,2277
|
|
10
|
-
easycoder/ec_program.py,sha256=ZCcvI36iq9HG4o8rFwFxzVElzZ7PEeNOPMr8eqwz8ns,10010
|
|
11
|
-
easycoder/ec_pyside6.py,sha256=Ii3k3UV8nrmv_QqE6FrZuDSjnBXVTzhPy65k0KlvcGE,28339
|
|
12
|
-
easycoder/ec_timestamp.py,sha256=_3QFJPzIWZ9Rzk3SQOQJ-gwmvB07pg78k23SPntoZtY,288
|
|
13
|
-
easycoder/ec_value.py,sha256=zgDJTJhIg3yOvmnnKIfccIizmIhGbtvL_ghLTL1T5fg,2516
|
|
14
|
-
easycoder-250424.3.dist-info/entry_points.txt,sha256=JXAZbenl0TnsIft2FcGJbJ-4qoztVu2FuT8PFmWFexM,44
|
|
15
|
-
easycoder-250424.3.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
16
|
-
easycoder-250424.3.dist-info/WHEEL,sha256=ssQ84EZ5gH1pCOujd3iW7HClo_O_aDaClUbX4B8bjKY,100
|
|
17
|
-
easycoder-250424.3.dist-info/METADATA,sha256=spAxnp7GfGJlgr_oHMB3ekXEnOvLE7XOiMXAbT2byrY,5617
|
|
18
|
-
easycoder-250424.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|