easycoder 251104.1__py2.py3-none-any.whl → 251215.2__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 -2
- easycoder/debugger/__init__.py +5 -0
- easycoder/debugger/ec_dbg_value_display copy.py +195 -0
- easycoder/debugger/ec_dbg_value_display.py +23 -0
- easycoder/debugger/ec_dbg_watch_list copy.py +219 -0
- easycoder/debugger/ec_dbg_watchlist.py +159 -0
- easycoder/debugger/ec_debug.py +948 -0
- easycoder/ec_border.py +15 -11
- easycoder/ec_classes.py +285 -7
- easycoder/ec_compiler.py +56 -39
- easycoder/ec_condition.py +1 -1
- easycoder/ec_core.py +848 -1016
- easycoder/ec_gclasses.py +225 -0
- easycoder/{ec_pyside.py → ec_graphics.py} +614 -492
- easycoder/ec_handler.py +16 -12
- easycoder/ec_keyboard.py +50 -50
- easycoder/ec_program.py +279 -151
- easycoder/ec_psutil.py +48 -0
- easycoder/ec_timestamp.py +2 -1
- easycoder/ec_value.py +29 -32
- easycoder/icons/exit.png +0 -0
- easycoder/icons/run.png +0 -0
- easycoder/icons/step.png +0 -0
- easycoder/icons/stop.png +0 -0
- {easycoder-251104.1.dist-info → easycoder-251215.2.dist-info}/METADATA +11 -1
- easycoder-251215.2.dist-info/RECORD +31 -0
- easycoder-251104.1.dist-info/RECORD +0 -19
- /easycoder/{close.png → icons/close.png} +0 -0
- /easycoder/{tick.png → icons/tick.png} +0 -0
- {easycoder-251104.1.dist-info → easycoder-251215.2.dist-info}/WHEEL +0 -0
- {easycoder-251104.1.dist-info → easycoder-251215.2.dist-info}/entry_points.txt +0 -0
- {easycoder-251104.1.dist-info → easycoder-251215.2.dist-info}/licenses/LICENSE +0 -0
easycoder/ec_border.py
CHANGED
|
@@ -9,34 +9,38 @@ class Border(QWidget):
|
|
|
9
9
|
|
|
10
10
|
def __init__(self):
|
|
11
11
|
super().__init__()
|
|
12
|
-
self.
|
|
13
|
-
self.setFixedHeight(self.
|
|
12
|
+
self._size = 40
|
|
13
|
+
self.setFixedHeight(self._size)
|
|
14
14
|
self._drag_active = False
|
|
15
15
|
self._drag_start_pos = None
|
|
16
|
+
self._tick: QPixmap = QPixmap()
|
|
17
|
+
self._close_icon: QPixmap = QPixmap()
|
|
16
18
|
|
|
17
19
|
def paintEvent(self, event):
|
|
18
20
|
painter = QPainter(self)
|
|
19
|
-
painter.setRenderHint(QPainter.Antialiasing)
|
|
21
|
+
painter.setRenderHint(QPainter.RenderHint.Antialiasing)
|
|
20
22
|
# Draw the tick icon
|
|
21
|
-
self.
|
|
23
|
+
self._tick = QPixmap(f'{os.path.dirname(os.path.abspath(__file__))}/icons/tick.png').scaled(
|
|
24
|
+
self._size, self._size, Qt.AspectRatioMode.KeepAspectRatio, Qt.TransformationMode.SmoothTransformation)
|
|
22
25
|
x = 0
|
|
23
26
|
y = 0
|
|
24
|
-
painter.drawPixmap(x, y, self.
|
|
27
|
+
painter.drawPixmap(x, y, self._tick)
|
|
25
28
|
# Draw the close icon
|
|
26
|
-
self.
|
|
27
|
-
|
|
29
|
+
self._close_icon = QPixmap(f'{os.path.dirname(os.path.abspath(__file__))}/icons/close.png').scaled(
|
|
30
|
+
self._size, self._size, Qt.AspectRatioMode.KeepAspectRatio, Qt.TransformationMode.SmoothTransformation)
|
|
31
|
+
x = self.width() - self._close_icon.width()
|
|
28
32
|
y = 0
|
|
29
|
-
painter.drawPixmap(x, y, self.
|
|
33
|
+
painter.drawPixmap(x, y, self._close_icon)
|
|
30
34
|
|
|
31
35
|
def mousePressEvent(self, event):
|
|
32
36
|
# Tick icon
|
|
33
37
|
x = 0
|
|
34
38
|
y = 0
|
|
35
|
-
tickRect = self.
|
|
39
|
+
tickRect = self._tick.rect().translated(x, y)
|
|
36
40
|
# Close icon
|
|
37
|
-
x = self.width() - self.
|
|
41
|
+
x = self.width() - self._close_icon.width()
|
|
38
42
|
y = 0
|
|
39
|
-
closeRect = self.
|
|
43
|
+
closeRect = self._close_icon.rect().translated(x, y)
|
|
40
44
|
if tickRect.contains(event.pos()):
|
|
41
45
|
self.tickClicked.emit()
|
|
42
46
|
if closeRect.contains(event.pos()):
|
easycoder/ec_classes.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import sys
|
|
1
|
+
import sys, paramiko
|
|
2
|
+
from typing import Optional, Any
|
|
2
3
|
|
|
3
|
-
class FatalError:
|
|
4
|
+
class FatalError(BaseException):
|
|
4
5
|
def __init__(self, compiler, message):
|
|
5
6
|
compiler.showWarnings()
|
|
6
7
|
lino = compiler.tokens[compiler.index].lino
|
|
@@ -12,7 +13,7 @@ class NoValueError(FatalError):
|
|
|
12
13
|
def __init__(self, compiler, record):
|
|
13
14
|
super().__init__(compiler, f'Variable {record["name"]} does not hold a value')
|
|
14
15
|
|
|
15
|
-
class
|
|
16
|
+
class RuntimeAssertionError:
|
|
16
17
|
def __init__(self, program, msg=None):
|
|
17
18
|
code = program.code[program.pc]
|
|
18
19
|
lino = code['lino']
|
|
@@ -22,7 +23,7 @@ class AssertionError:
|
|
|
22
23
|
print(message)
|
|
23
24
|
sys.exit()
|
|
24
25
|
|
|
25
|
-
class RuntimeError:
|
|
26
|
+
class RuntimeError(BaseException):
|
|
26
27
|
def __init__(self, program, message):
|
|
27
28
|
if program == None:
|
|
28
29
|
sys.exit(f'Runtime Error: {message}')
|
|
@@ -56,6 +57,283 @@ class Token:
|
|
|
56
57
|
def __init__(self, lino, token):
|
|
57
58
|
self.lino = lino
|
|
58
59
|
self.token = token
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
|
|
61
|
+
###############################################################################
|
|
62
|
+
# This is the set of generic EasyCoder objects (values and variables)
|
|
63
|
+
|
|
64
|
+
###############################################################################
|
|
65
|
+
# A multipurpose value object. Holds a single value, with domain and type information
|
|
66
|
+
class ECValue():
|
|
67
|
+
def __init__(self, domain: Optional[str] = None, type: Optional[str] = None,
|
|
68
|
+
content: Any = None, name: Optional[str] = None):
|
|
69
|
+
object.__setattr__(self, 'domain', domain)
|
|
70
|
+
object.__setattr__(self, 'type', type)
|
|
71
|
+
object.__setattr__(self, 'content', content)
|
|
72
|
+
object.__setattr__(self, 'name', name)
|
|
73
|
+
object.__setattr__(self, 'properties', {})
|
|
74
|
+
object.__setattr__(self, 'locked', False)
|
|
75
|
+
object.__setattr__(self, '_attrs', {}) # Store dynamic attributes
|
|
76
|
+
|
|
77
|
+
def __setattr__(self, name: str, value: Any) -> None:
|
|
78
|
+
"""Allow setting any attribute dynamically."""
|
|
79
|
+
if name in ('domain', 'type', 'content', 'name', 'properties', 'locked', '_attrs'):
|
|
80
|
+
object.__setattr__(self, name, value)
|
|
81
|
+
else:
|
|
82
|
+
# Store dynamic attributes in _attrs dict
|
|
83
|
+
self._attrs[name] = value
|
|
84
|
+
|
|
85
|
+
def __getattr__(self, name: str) -> Any:
|
|
86
|
+
"""Retrieve dynamic attributes or return None if not found."""
|
|
87
|
+
if name == '_attrs':
|
|
88
|
+
return object.__getattribute__(self, '_attrs')
|
|
89
|
+
return self._attrs.get(name)
|
|
90
|
+
|
|
91
|
+
def setDomain(self, domain):
|
|
92
|
+
self.domain = domain
|
|
93
|
+
|
|
94
|
+
def getDomain(self):
|
|
95
|
+
return self.domain
|
|
96
|
+
|
|
97
|
+
def setType(self, type):
|
|
98
|
+
self.type = type
|
|
99
|
+
|
|
100
|
+
def getType(self):
|
|
101
|
+
return self.type
|
|
102
|
+
|
|
103
|
+
def setContent(self, content):
|
|
104
|
+
self.content = content
|
|
105
|
+
|
|
106
|
+
def getContent(self):
|
|
107
|
+
return self.content
|
|
108
|
+
|
|
109
|
+
def setValue(self, type=None, content=None):
|
|
110
|
+
self.type = type
|
|
111
|
+
self.content = content
|
|
112
|
+
|
|
113
|
+
def setProperty(self, key, value):
|
|
114
|
+
self.properties[key] = value
|
|
115
|
+
|
|
116
|
+
def getProperty(self, key):
|
|
117
|
+
return self.properties.get(key, None)
|
|
118
|
+
|
|
119
|
+
def setName(self, name):
|
|
120
|
+
self.name = name
|
|
121
|
+
|
|
122
|
+
def getName(self):
|
|
123
|
+
return self.name
|
|
124
|
+
|
|
125
|
+
def lock(self):
|
|
126
|
+
self.locked = True
|
|
127
|
+
|
|
128
|
+
def isLocked(self):
|
|
129
|
+
return self.locked
|
|
130
|
+
|
|
131
|
+
###############################################################################
|
|
132
|
+
# The base class for all EasyCoder variable types
|
|
133
|
+
class ECObject():
|
|
134
|
+
def __init__(self):
|
|
135
|
+
self.locked: bool = False
|
|
136
|
+
self.elements: int = 0
|
|
137
|
+
self.index: Optional[int] = None
|
|
138
|
+
self.values: Optional[list] = None
|
|
139
|
+
self.name: Optional[str] = None
|
|
140
|
+
|
|
141
|
+
# Set the index for the variable
|
|
142
|
+
def setIndex(self, index: int) -> None:
|
|
143
|
+
self.index = index
|
|
144
|
+
|
|
145
|
+
# Get the index for the variable
|
|
146
|
+
def getIndex(self):
|
|
147
|
+
return self.index
|
|
148
|
+
|
|
149
|
+
# Lock the variable
|
|
150
|
+
def setLocked(self):
|
|
151
|
+
self.locked = True
|
|
152
|
+
|
|
153
|
+
# Check if the variable is locked
|
|
154
|
+
def isLocked(self):
|
|
155
|
+
return self.locked
|
|
156
|
+
|
|
157
|
+
# Set the value at the current index
|
|
158
|
+
def setValue(self, value):
|
|
159
|
+
if self.values is None:
|
|
160
|
+
self.index = 0
|
|
161
|
+
self.elements = 1
|
|
162
|
+
self.values = [None]
|
|
163
|
+
if isinstance(value, ECValue): value.setName(self.name)
|
|
164
|
+
self.values[self.index] = value # type: ignore
|
|
165
|
+
|
|
166
|
+
# Get the value at the current index
|
|
167
|
+
def getValue(self):
|
|
168
|
+
if self.values is None: return None
|
|
169
|
+
return self.values[self.index] # type: ignore
|
|
170
|
+
|
|
171
|
+
# Get all the values
|
|
172
|
+
def getValues(self):
|
|
173
|
+
return self.values
|
|
174
|
+
|
|
175
|
+
# Set the number of elements in the variable
|
|
176
|
+
def setElements(self, elements):
|
|
177
|
+
if self.elements == 0:
|
|
178
|
+
self.values = [None] * elements
|
|
179
|
+
self.elements = elements
|
|
180
|
+
self.index = 0
|
|
181
|
+
if elements == self.elements:
|
|
182
|
+
pass
|
|
183
|
+
elif elements > self.elements:
|
|
184
|
+
self.values.extend([None] * (elements - self.elements)) # pyright: ignore[reportOptionalMemberAccess]
|
|
185
|
+
else:
|
|
186
|
+
del self.values[elements:] # pyright: ignore[reportOptionalSubscript]
|
|
187
|
+
self.index = 0
|
|
188
|
+
self.elements = elements
|
|
189
|
+
|
|
190
|
+
# Get the number of elements in the variable
|
|
191
|
+
def getElements(self):
|
|
192
|
+
return self.elements
|
|
193
|
+
|
|
194
|
+
# Check if the object has a runtime value. Default is False
|
|
195
|
+
def hasRuntimeValue(self):
|
|
196
|
+
return False
|
|
197
|
+
|
|
198
|
+
# Check if the object is mutable. Default is False
|
|
199
|
+
def isMutable(self):
|
|
200
|
+
return False
|
|
201
|
+
|
|
202
|
+
# Check if the object is clearable
|
|
203
|
+
def isClearable(self):
|
|
204
|
+
return False
|
|
205
|
+
|
|
206
|
+
# Get the content of the value at the current index
|
|
207
|
+
def getContent(self):
|
|
208
|
+
if not self.hasRuntimeValue(): return None
|
|
209
|
+
v = self.getValue()
|
|
210
|
+
if v is None: return None
|
|
211
|
+
return v.getContent()
|
|
212
|
+
|
|
213
|
+
# Get the type of the value at the current index
|
|
214
|
+
def getType(self):
|
|
215
|
+
if not self.hasRuntimeValue(): return None
|
|
216
|
+
v = self.getValue()
|
|
217
|
+
if v is None: return None
|
|
218
|
+
return v.getType()
|
|
219
|
+
|
|
220
|
+
# Check if the object is empty. Default is True
|
|
221
|
+
def isEmpty(self):
|
|
222
|
+
return True
|
|
223
|
+
|
|
224
|
+
# Set the name of the object
|
|
225
|
+
def setName(self, name):
|
|
226
|
+
self.name = name
|
|
227
|
+
|
|
228
|
+
# Get the name of the object
|
|
229
|
+
def getName(self):
|
|
230
|
+
return self.name
|
|
231
|
+
|
|
232
|
+
# Check if the object can have properties
|
|
233
|
+
def hasProperties(self):
|
|
234
|
+
return False
|
|
235
|
+
|
|
236
|
+
###############################################################################
|
|
237
|
+
# A generic variable object that can hold a mutable value
|
|
238
|
+
class ECVariable(ECObject):
|
|
239
|
+
def __init__(self):
|
|
240
|
+
super().__init__()
|
|
241
|
+
self.properties = {}
|
|
242
|
+
|
|
243
|
+
# Set the content of the value at the current index
|
|
244
|
+
def setContent(self, content):
|
|
245
|
+
if self.values is None:
|
|
246
|
+
self.index = 0
|
|
247
|
+
self.elements = 1
|
|
248
|
+
self.values = [None]
|
|
249
|
+
self.values[self.index] = content # type: ignore
|
|
250
|
+
|
|
251
|
+
# Set the value to a given ECValue
|
|
252
|
+
def setValue(self, value):
|
|
253
|
+
if self.values is None:
|
|
254
|
+
self.index = 0
|
|
255
|
+
self.elements = 1
|
|
256
|
+
self.values = [None]
|
|
257
|
+
if self.index >= self.elements: raise RuntimeError(None, 'Index out of range') # type: ignore
|
|
258
|
+
self.values[self.index] = value # type: ignore
|
|
259
|
+
|
|
260
|
+
# Report if the object is clearable
|
|
261
|
+
def isClearable(self):
|
|
262
|
+
return True
|
|
263
|
+
|
|
264
|
+
# This object has a runtime value
|
|
265
|
+
def hasRuntimeValue(self):
|
|
266
|
+
return True
|
|
267
|
+
|
|
268
|
+
# This object is mutable.
|
|
269
|
+
def isMutable(self):
|
|
270
|
+
return True
|
|
271
|
+
|
|
272
|
+
# Reset the object to empty state
|
|
273
|
+
def reset(self):
|
|
274
|
+
self.setValue(ECValue())
|
|
275
|
+
|
|
276
|
+
# Check if the object can have properties
|
|
277
|
+
def hasProperties(self):
|
|
278
|
+
return True
|
|
279
|
+
|
|
280
|
+
# Set a specific property on the object
|
|
281
|
+
def setProperty(self, name, value):
|
|
282
|
+
self.properties[name] = value
|
|
283
|
+
|
|
284
|
+
# Check if the object has a specific property
|
|
285
|
+
def hasProperty(self, name):
|
|
286
|
+
return name in self.properties
|
|
287
|
+
|
|
288
|
+
# Get a specific property
|
|
289
|
+
def getProperty(self, name):
|
|
290
|
+
return self.properties[name]
|
|
291
|
+
|
|
292
|
+
###############################################################################
|
|
293
|
+
# A file variable
|
|
294
|
+
class ECFile(ECObject):
|
|
295
|
+
def __init__(self):
|
|
296
|
+
super().__init__()
|
|
297
|
+
|
|
298
|
+
###############################################################################
|
|
299
|
+
# An SSH variable
|
|
300
|
+
class ECSSH(ECObject):
|
|
301
|
+
def __init__(self):
|
|
302
|
+
super().__init__()
|
|
303
|
+
|
|
304
|
+
# Set up the SSH connection
|
|
305
|
+
def setup(self, host=None, user=None, password=None):
|
|
306
|
+
ssh = paramiko.SSHClient()
|
|
307
|
+
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
|
308
|
+
try:
|
|
309
|
+
ssh.connect(host, username=user, password=password, timeout=10) # type: ignore
|
|
310
|
+
self.setValue(ssh)
|
|
311
|
+
self.sftp = ssh.open_sftp()
|
|
312
|
+
return True
|
|
313
|
+
except:
|
|
314
|
+
return False
|
|
315
|
+
|
|
316
|
+
# Get the SFTP client
|
|
317
|
+
def getSFTP(self):
|
|
318
|
+
return self.sftp
|
|
319
|
+
|
|
320
|
+
###############################################################################
|
|
321
|
+
# A stack variable
|
|
322
|
+
class ECStack(ECObject):
|
|
323
|
+
|
|
324
|
+
def __init__(self):
|
|
325
|
+
super().__init__()
|
|
326
|
+
self.values: Optional[list[list[Any]]] = None # List of stacks, each holding any type
|
|
327
|
+
|
|
328
|
+
def push(self, item: Any) -> None:
|
|
329
|
+
if self.values is None:
|
|
330
|
+
self.index = 0
|
|
331
|
+
self.elements = 1
|
|
332
|
+
self.values = [[]]
|
|
333
|
+
assert self.index is not None # Type narrowing: index is always set when values exists
|
|
334
|
+
self.values[self.index].append(item)
|
|
335
|
+
|
|
336
|
+
def pop(self) -> Any:
|
|
337
|
+
if self.values is None or self.index is None or self.values[self.index] is None or len(self.values[self.index]) == 0:
|
|
338
|
+
return None
|
|
339
|
+
return self.values[self.index].pop()
|
easycoder/ec_compiler.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import sys
|
|
1
2
|
from .ec_classes import FatalError
|
|
2
3
|
from .ec_value import Value
|
|
3
4
|
from .ec_condition import Condition
|
|
@@ -84,7 +85,9 @@ class Compiler:
|
|
|
84
85
|
return self.program.code[pc]
|
|
85
86
|
|
|
86
87
|
# Add a command to the code list
|
|
87
|
-
def addCommand(self, command):
|
|
88
|
+
def addCommand(self, command, debug=True):
|
|
89
|
+
command['debug'] = debug
|
|
90
|
+
command['bp'] = False
|
|
88
91
|
self.code.append(command)
|
|
89
92
|
|
|
90
93
|
# Test if the current token is a symbol
|
|
@@ -131,16 +134,16 @@ class Compiler:
|
|
|
131
134
|
print(warning)
|
|
132
135
|
|
|
133
136
|
# Get the symbol record for the current token (assumes it is a symbol name)
|
|
134
|
-
def getSymbolRecord(self):
|
|
135
|
-
|
|
136
|
-
if not
|
|
137
|
-
FatalError(self, f'Undefined symbol name "{
|
|
137
|
+
def getSymbolRecord(self, name=None):
|
|
138
|
+
if name == None: name = self.getToken()
|
|
139
|
+
if not name in self.symbols:
|
|
140
|
+
FatalError(self, f'Undefined symbol name "{name}"')
|
|
138
141
|
return None
|
|
139
|
-
symbol = self.symbols[
|
|
142
|
+
symbol = self.symbols[name]
|
|
140
143
|
if symbol == None: return None
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
return
|
|
144
|
+
record = self.code[symbol]
|
|
145
|
+
record['used'] = True
|
|
146
|
+
return record
|
|
144
147
|
|
|
145
148
|
# Add a value type
|
|
146
149
|
def addValueType(self):
|
|
@@ -149,40 +152,56 @@ class Compiler:
|
|
|
149
152
|
# Test if a given value is in the value types list
|
|
150
153
|
def hasValue(self, type):
|
|
151
154
|
return type in self.valueTypes
|
|
152
|
-
|
|
153
|
-
#
|
|
154
|
-
def
|
|
155
|
-
|
|
155
|
+
|
|
156
|
+
# Instantiate an object of the given class name
|
|
157
|
+
def instantiate(self, classname):
|
|
158
|
+
# Search through all loaded modules for the class
|
|
159
|
+
items = sys.modules.items()
|
|
160
|
+
for module_name, module in items:
|
|
161
|
+
if module is None:
|
|
162
|
+
continue
|
|
163
|
+
try:
|
|
164
|
+
if hasattr(module, classname):
|
|
165
|
+
cls = getattr(module, classname)
|
|
166
|
+
# Verify it's actually a class
|
|
167
|
+
if isinstance(cls, type):
|
|
168
|
+
# Attempt to instantiate
|
|
169
|
+
try:
|
|
170
|
+
return cls()
|
|
171
|
+
except TypeError as ex:
|
|
172
|
+
raise FatalError(self, f"Object instantiation error: {ex}")
|
|
173
|
+
except Exception:
|
|
174
|
+
continue
|
|
175
|
+
return None
|
|
156
176
|
|
|
157
177
|
# Compile a variable
|
|
158
|
-
def compileVariable(self, command,
|
|
159
|
-
return self.compileSymbol(command, self.nextToken(),
|
|
178
|
+
def compileVariable(self, command, classname):
|
|
179
|
+
return self.compileSymbol(command, self.nextToken(), classname)
|
|
160
180
|
|
|
161
181
|
# Compile a symbol
|
|
162
|
-
def compileSymbol(self, command, name,
|
|
182
|
+
def compileSymbol(self, command, name, classname):
|
|
163
183
|
try:
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
if v:
|
|
168
|
-
FatalError(self, f'Duplicate symbol name "{name}"')
|
|
169
|
-
return False
|
|
170
|
-
self.symbols[name] = self.getCodeSize()
|
|
171
|
-
command['program'] = self.program
|
|
172
|
-
command['type'] = 'symbol'
|
|
184
|
+
self.symbols[name]
|
|
185
|
+
raise FatalError(self, f'Duplicate symbol name "{name}"')
|
|
186
|
+
except: pass
|
|
173
187
|
command['name'] = name
|
|
174
|
-
command['
|
|
175
|
-
command['
|
|
176
|
-
command['value'] = [None]
|
|
188
|
+
command['classname'] = classname
|
|
189
|
+
command['program'] = self.program
|
|
177
190
|
command['used'] = False
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
191
|
+
self.symbols[name] = self.getCodeSize()
|
|
192
|
+
if classname != ':':
|
|
193
|
+
object = self.instantiate(classname)
|
|
194
|
+
command['object'] = object
|
|
195
|
+
if object != None:
|
|
196
|
+
command['type'] = 'symbol'
|
|
197
|
+
object.setName(name) # type: ignore
|
|
198
|
+
self.addCommand(command, False)
|
|
184
199
|
return True
|
|
185
200
|
|
|
201
|
+
# Compile a program label (a symbol ending with ':')
|
|
202
|
+
def compileLabel(self, command):
|
|
203
|
+
return self.compileSymbol(command, self.getToken(), ':')
|
|
204
|
+
|
|
186
205
|
# Compile the current token
|
|
187
206
|
def compileToken(self):
|
|
188
207
|
self.warnings = []
|
|
@@ -191,8 +210,8 @@ class Compiler:
|
|
|
191
210
|
if not token:
|
|
192
211
|
return False
|
|
193
212
|
if len(self.code) == 0:
|
|
194
|
-
if self.program.parent == None and
|
|
195
|
-
cmd = {'domain': 'graphics', 'keyword': 'init'
|
|
213
|
+
if self.program.parent == None and self.program.graphics:
|
|
214
|
+
cmd = {'domain': 'graphics', 'keyword': 'init'}
|
|
196
215
|
self.code.append(cmd)
|
|
197
216
|
mark = self.getIndex()
|
|
198
217
|
for domain in self.program.getDomains():
|
|
@@ -202,8 +221,6 @@ class Compiler:
|
|
|
202
221
|
command['domain'] = domain.getName()
|
|
203
222
|
command['lino'] = self.tokens[self.index].lino
|
|
204
223
|
command['keyword'] = token
|
|
205
|
-
command['type'] = None
|
|
206
|
-
command['debug'] = True
|
|
207
224
|
result = handler(command)
|
|
208
225
|
if result:
|
|
209
226
|
return result
|
|
@@ -233,7 +250,7 @@ class Compiler:
|
|
|
233
250
|
while True:
|
|
234
251
|
token = self.tokens[self.index]
|
|
235
252
|
# keyword = token.token
|
|
236
|
-
if self.debugCompile: print(self.script.lines[token.lino])
|
|
253
|
+
if self.debugCompile: print(f'{token.lino + 1}: {self.script.lines[token.lino]}')
|
|
237
254
|
# if keyword != 'else':
|
|
238
255
|
if self.compileOne() == True:
|
|
239
256
|
if self.index == len(self.tokens) - 1:
|
easycoder/ec_condition.py
CHANGED
|
@@ -16,7 +16,7 @@ class Condition:
|
|
|
16
16
|
for domain in self.compiler.program.getDomains():
|
|
17
17
|
condition = domain.compileCondition()
|
|
18
18
|
if condition != None:
|
|
19
|
-
condition.domain= domain.getName()
|
|
19
|
+
condition.domain = domain.getName()
|
|
20
20
|
return condition
|
|
21
21
|
self.rewindTo(mark)
|
|
22
22
|
return None
|