easycoder 250118.1__py2.py3-none-any.whl → 251103.4__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.
- easycoder/__init__.py +4 -1
- easycoder/close.png +0 -0
- easycoder/ec_border.py +63 -0
- easycoder/ec_classes.py +10 -6
- easycoder/ec_compiler.py +48 -19
- easycoder/ec_condition.py +2 -1
- easycoder/ec_core.py +632 -281
- easycoder/ec_handler.py +4 -2
- easycoder/ec_keyboard.py +439 -0
- easycoder/ec_program.py +43 -38
- easycoder/ec_pyside.py +1545 -0
- easycoder/ec_timestamp.py +1 -1
- easycoder/tick.png +0 -0
- {easycoder-250118.1.dist-info → easycoder-251103.4.dist-info}/METADATA +30 -30
- easycoder-251103.4.dist-info/RECORD +19 -0
- {easycoder-250118.1.dist-info → easycoder-251103.4.dist-info}/WHEEL +1 -1
- easycoder/README.md +0 -6
- easycoder/ec_graphics.py +0 -314
- easycoder/ec_gutils.py +0 -84
- easycoder-250118.1.dist-info/RECORD +0 -17
- {easycoder-250118.1.dist-info → easycoder-251103.4.dist-info}/entry_points.txt +0 -0
- {easycoder-250118.1.dist-info → easycoder-251103.4.dist-info/licenses}/LICENSE +0 -0
easycoder/__init__.py
CHANGED
|
@@ -5,8 +5,11 @@ from .ec_compiler import *
|
|
|
5
5
|
from .ec_condition import *
|
|
6
6
|
from .ec_core import *
|
|
7
7
|
from .ec_handler import *
|
|
8
|
+
from .ec_keyboard import *
|
|
9
|
+
from .ec_border import *
|
|
8
10
|
from .ec_program import *
|
|
11
|
+
from .ec_pyside import *
|
|
9
12
|
from .ec_timestamp import *
|
|
10
13
|
from .ec_value import *
|
|
11
14
|
|
|
12
|
-
__version__ = "
|
|
15
|
+
__version__ = "251103.4"
|
easycoder/close.png
ADDED
|
Binary file
|
easycoder/ec_border.py
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from PySide6.QtWidgets import QWidget
|
|
3
|
+
from PySide6.QtGui import QPixmap, QPainter
|
|
4
|
+
from PySide6.QtCore import Qt, Signal, QRect
|
|
5
|
+
|
|
6
|
+
class Border(QWidget):
|
|
7
|
+
tickClicked = Signal()
|
|
8
|
+
closeClicked = Signal()
|
|
9
|
+
|
|
10
|
+
def __init__(self):
|
|
11
|
+
super().__init__()
|
|
12
|
+
self.size = 40
|
|
13
|
+
self.setFixedHeight(self.size)
|
|
14
|
+
self._drag_active = False
|
|
15
|
+
self._drag_start_pos = None
|
|
16
|
+
|
|
17
|
+
def paintEvent(self, event):
|
|
18
|
+
painter = QPainter(self)
|
|
19
|
+
painter.setRenderHint(QPainter.Antialiasing)
|
|
20
|
+
# Draw the tick icon
|
|
21
|
+
self.tick = QPixmap(f'{os.path.dirname(os.path.abspath(__file__))}/tick.png').scaled(self.size, self.size, Qt.KeepAspectRatio, Qt.SmoothTransformation)
|
|
22
|
+
x = 0
|
|
23
|
+
y = 0
|
|
24
|
+
painter.drawPixmap(x, y, self.tick)
|
|
25
|
+
# Draw the close icon
|
|
26
|
+
self.close = QPixmap(f'{os.path.dirname(os.path.abspath(__file__))}/close.png').scaled(self.size, self.size, Qt.KeepAspectRatio, Qt.SmoothTransformation)
|
|
27
|
+
x = self.width() - self.close.width()
|
|
28
|
+
y = 0
|
|
29
|
+
painter.drawPixmap(x, y, self.close)
|
|
30
|
+
|
|
31
|
+
def mousePressEvent(self, event):
|
|
32
|
+
# Tick icon
|
|
33
|
+
x = 0
|
|
34
|
+
y = 0
|
|
35
|
+
tickRect = self.tick.rect().translated(x, y)
|
|
36
|
+
# Close icon
|
|
37
|
+
x = self.width() - self.close.width()
|
|
38
|
+
y = 0
|
|
39
|
+
closeRect = self.close.rect().translated(x, y)
|
|
40
|
+
if tickRect.contains(event.pos()):
|
|
41
|
+
self.tickClicked.emit()
|
|
42
|
+
if closeRect.contains(event.pos()):
|
|
43
|
+
self.closeClicked.emit()
|
|
44
|
+
elif QRect(0, 0, self.width(), self.height()).contains(event.pos()):
|
|
45
|
+
if hasattr(self.window().windowHandle(), 'startSystemMove'):
|
|
46
|
+
self.window().windowHandle().startSystemMove()
|
|
47
|
+
else:
|
|
48
|
+
self._drag_active = True
|
|
49
|
+
self._drag_start_pos = event.globalPosition().toPoint()
|
|
50
|
+
self._dialog_start_pos = self.window().pos()
|
|
51
|
+
else:
|
|
52
|
+
super().mousePressEvent(event)
|
|
53
|
+
|
|
54
|
+
def mouseMoveEvent(self, event):
|
|
55
|
+
if self._drag_active:
|
|
56
|
+
delta = event.globalPosition().toPoint() - self._drag_start_pos
|
|
57
|
+
self.window().move(self._dialog_start_pos + delta)
|
|
58
|
+
else:
|
|
59
|
+
super().mouseMoveEvent(event)
|
|
60
|
+
|
|
61
|
+
def mouseReleaseEvent(self, event):
|
|
62
|
+
self._drag_active = False
|
|
63
|
+
super().mouseReleaseEvent(event)
|
easycoder/ec_classes.py
CHANGED
|
@@ -5,14 +5,17 @@ class FatalError:
|
|
|
5
5
|
compiler.showWarnings()
|
|
6
6
|
lino = compiler.tokens[compiler.index].lino
|
|
7
7
|
script = compiler.script.lines[lino].strip()
|
|
8
|
-
print(f'Compile error in {compiler.program.name} at line {lino + 1} ({script})
|
|
8
|
+
print(f'Compile error in {compiler.program.name} at line {lino + 1} ({script}):\n-> {message}')
|
|
9
9
|
sys.exit()
|
|
10
10
|
|
|
11
|
+
class NoValueError(FatalError):
|
|
12
|
+
def __init__(self, compiler, record):
|
|
13
|
+
super().__init__(compiler, f'Variable {record["name"]} does not hold a value')
|
|
14
|
+
|
|
11
15
|
class AssertionError:
|
|
12
16
|
def __init__(self, program, msg=None):
|
|
13
17
|
code = program.code[program.pc]
|
|
14
18
|
lino = code['lino']
|
|
15
|
-
script = program.script.lines[lino].strip()
|
|
16
19
|
message = f'Assertion Error in {program.name} at line {lino + 1}'
|
|
17
20
|
if msg != None:
|
|
18
21
|
message += f': {msg}'
|
|
@@ -27,9 +30,13 @@ class RuntimeError:
|
|
|
27
30
|
code = program.code[program.pc]
|
|
28
31
|
lino = code['lino']
|
|
29
32
|
script = program.script.lines[lino].strip()
|
|
30
|
-
print(f'Runtime Error in {program.name} at line {lino + 1} ({script})
|
|
33
|
+
print(f'Runtime Error in {program.name} at line {lino + 1} ({script}):\n-> {message}')
|
|
31
34
|
sys.exit()
|
|
32
35
|
|
|
36
|
+
class NoValueRuntimeError(RuntimeError):
|
|
37
|
+
def __init__(self, program, record):
|
|
38
|
+
super().__init__(program, 'Variable {record["name"]} does not hold a value')
|
|
39
|
+
|
|
33
40
|
class RuntimeWarning:
|
|
34
41
|
def __init__(self, program, message):
|
|
35
42
|
if program == None:
|
|
@@ -50,8 +57,5 @@ class Token:
|
|
|
50
57
|
self.lino = lino
|
|
51
58
|
self.token = token
|
|
52
59
|
|
|
53
|
-
class Condition():
|
|
54
|
-
negate = False
|
|
55
|
-
|
|
56
60
|
class Object():
|
|
57
61
|
pass
|
easycoder/ec_compiler.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from .ec_classes import
|
|
1
|
+
from .ec_classes import FatalError
|
|
2
2
|
from .ec_value import Value
|
|
3
3
|
from .ec_condition import Condition
|
|
4
4
|
|
|
@@ -13,10 +13,10 @@ class Compiler:
|
|
|
13
13
|
self.tokens = self.script.tokens
|
|
14
14
|
self.symbols = self.program.symbols
|
|
15
15
|
self.code = self.program.code
|
|
16
|
-
self.warnings = []
|
|
17
16
|
self.program.compiler = self
|
|
18
|
-
self.addCommand = self.program.add
|
|
19
17
|
self.compileConstant = self.value.compileConstant
|
|
18
|
+
self.debugCompile = False
|
|
19
|
+
self.valueTypes = {}
|
|
20
20
|
|
|
21
21
|
def getPC(self):
|
|
22
22
|
return len(self.program.code)
|
|
@@ -77,8 +77,12 @@ class Compiler:
|
|
|
77
77
|
def getCommandAt(self, pc):
|
|
78
78
|
return self.program.code[pc]
|
|
79
79
|
|
|
80
|
+
# Add a command to the code list
|
|
81
|
+
def addCommand(self, command):
|
|
82
|
+
self.code.append(command)
|
|
83
|
+
|
|
80
84
|
def isSymbol(self):
|
|
81
|
-
token=self.getToken()
|
|
85
|
+
token = self.getToken()
|
|
82
86
|
try:
|
|
83
87
|
self.symbols[token]
|
|
84
88
|
except:
|
|
@@ -88,6 +92,15 @@ class Compiler:
|
|
|
88
92
|
def nextIsSymbol(self):
|
|
89
93
|
self.next()
|
|
90
94
|
return self.isSymbol()
|
|
95
|
+
|
|
96
|
+
def skip(self, token):
|
|
97
|
+
next = self.peek()
|
|
98
|
+
if type(token) == list:
|
|
99
|
+
for item in token:
|
|
100
|
+
if next == item:
|
|
101
|
+
self.nextToken()
|
|
102
|
+
return
|
|
103
|
+
elif next == token: self.nextToken()
|
|
91
104
|
|
|
92
105
|
def rewindTo(self, index):
|
|
93
106
|
self.index = index
|
|
@@ -106,20 +119,28 @@ class Compiler:
|
|
|
106
119
|
|
|
107
120
|
def getSymbolRecord(self):
|
|
108
121
|
token = self.getToken()
|
|
122
|
+
if not token in self.symbols:
|
|
123
|
+
FatalError(self, f'Undefined symbol name "{token}"')
|
|
124
|
+
return None
|
|
109
125
|
symbol = self.symbols[token]
|
|
110
|
-
if symbol
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
126
|
+
if symbol == None: return None
|
|
127
|
+
symbolRecord = self.code[symbol]
|
|
128
|
+
symbolRecord['used'] = True
|
|
129
|
+
return symbolRecord
|
|
130
|
+
|
|
131
|
+
def addValueType(self):
|
|
132
|
+
self.valueTypes[self.getToken()] = True
|
|
133
|
+
|
|
134
|
+
def hasValue(self, type):
|
|
135
|
+
return type in self.valueTypes
|
|
115
136
|
|
|
116
137
|
def compileLabel(self, command):
|
|
117
|
-
return self.compileSymbol(command, self.getToken()
|
|
138
|
+
return self.compileSymbol(command, self.getToken())
|
|
118
139
|
|
|
119
|
-
def compileVariable(self, command,
|
|
120
|
-
return self.compileSymbol(command, self.nextToken(),
|
|
140
|
+
def compileVariable(self, command, extra=None):
|
|
141
|
+
return self.compileSymbol(command, self.nextToken(), extra)
|
|
121
142
|
|
|
122
|
-
def compileSymbol(self, command, name,
|
|
143
|
+
def compileSymbol(self, command, name, extra=None):
|
|
123
144
|
try:
|
|
124
145
|
v = self.symbols[name]
|
|
125
146
|
except:
|
|
@@ -130,7 +151,6 @@ class Compiler:
|
|
|
130
151
|
self.symbols[name] = self.getPC()
|
|
131
152
|
command['program'] = self.program
|
|
132
153
|
command['type'] = 'symbol'
|
|
133
|
-
command['valueHolder'] = valueHolder
|
|
134
154
|
command['name'] = name
|
|
135
155
|
command['elements'] = 1
|
|
136
156
|
command['index'] = 0
|
|
@@ -139,15 +159,22 @@ class Compiler:
|
|
|
139
159
|
command['debug'] = False
|
|
140
160
|
command['import'] = None
|
|
141
161
|
command['locked'] = False
|
|
162
|
+
command['extra'] = extra
|
|
163
|
+
if 'keyword' in command: command['hasValue'] = self.hasValue(command['keyword'])
|
|
142
164
|
self.addCommand(command)
|
|
143
165
|
return True
|
|
144
166
|
|
|
145
167
|
# Compile the current token
|
|
146
168
|
def compileToken(self):
|
|
169
|
+
self.warnings = []
|
|
147
170
|
token = self.getToken()
|
|
148
171
|
# print(f'Compile {token}')
|
|
149
172
|
if not token:
|
|
150
173
|
return False
|
|
174
|
+
if len(self.code) == 0:
|
|
175
|
+
if self.program.parent == None and hasattr(self.program, 'usingGraphics'):
|
|
176
|
+
cmd = {'domain': 'graphics', 'keyword': 'init', 'debug': False}
|
|
177
|
+
self.code.append(cmd)
|
|
151
178
|
mark = self.getIndex()
|
|
152
179
|
for domain in self.program.getDomains():
|
|
153
180
|
handler = domain.keywordHandler(token)
|
|
@@ -165,14 +192,14 @@ class Compiler:
|
|
|
165
192
|
self.rewindTo(mark)
|
|
166
193
|
else:
|
|
167
194
|
self.rewindTo(mark)
|
|
168
|
-
FatalError(self, f'
|
|
195
|
+
FatalError(self, f'Unable to compile this "{token}" command')
|
|
169
196
|
|
|
170
197
|
# Compile a single command
|
|
171
198
|
def compileOne(self):
|
|
172
199
|
keyword = self.getToken()
|
|
173
200
|
if not keyword:
|
|
174
201
|
return False
|
|
175
|
-
|
|
202
|
+
print(f'Compile keyword "{keyword}"')
|
|
176
203
|
if keyword.endswith(':'):
|
|
177
204
|
command = {}
|
|
178
205
|
command['domain'] = None
|
|
@@ -186,9 +213,8 @@ class Compiler:
|
|
|
186
213
|
self.index = index
|
|
187
214
|
while True:
|
|
188
215
|
token = self.tokens[self.index]
|
|
189
|
-
keyword = token.token
|
|
190
|
-
|
|
191
|
-
# print(f'{keyword} - {line}')
|
|
216
|
+
# keyword = token.token
|
|
217
|
+
if self.debugCompile: print(self.script.lines[token.lino])
|
|
192
218
|
# if keyword != 'else':
|
|
193
219
|
if self.compileOne() == True:
|
|
194
220
|
if self.index == len(self.tokens) - 1:
|
|
@@ -201,3 +227,6 @@ class Compiler:
|
|
|
201
227
|
|
|
202
228
|
def compileFromHere(self, stopOn):
|
|
203
229
|
return self.compileFrom(self.getIndex(), stopOn)
|
|
230
|
+
|
|
231
|
+
def compileFromStart(self):
|
|
232
|
+
return self.compileFrom(0, [])
|
easycoder/ec_condition.py
CHANGED
|
@@ -9,6 +9,7 @@ class Condition:
|
|
|
9
9
|
self.tokenIs = compiler.tokenIs
|
|
10
10
|
self.rewindTo = compiler.rewindTo
|
|
11
11
|
self.program = compiler.program
|
|
12
|
+
self.negate = False
|
|
12
13
|
|
|
13
14
|
def compileCondition(self):
|
|
14
15
|
mark = self.getIndex()
|
|
@@ -18,7 +19,7 @@ class Condition:
|
|
|
18
19
|
condition.domain= domain.getName()
|
|
19
20
|
return condition
|
|
20
21
|
self.rewindTo(mark)
|
|
21
|
-
|
|
22
|
+
return None
|
|
22
23
|
|
|
23
24
|
def testCondition(self, condition):
|
|
24
25
|
handler = self.program.domainIndex[condition.domain]
|