easycoder 251105.1__py2.py3-none-any.whl → 260111.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.
Files changed (51) hide show
  1. easycoder/__init__.py +6 -3
  2. easycoder/debugger/__init__.py +5 -0
  3. easycoder/debugger/ec_dbg_value_display copy.py +195 -0
  4. easycoder/debugger/ec_dbg_value_display.py +24 -0
  5. easycoder/debugger/ec_dbg_watch_list copy.py +219 -0
  6. easycoder/debugger/ec_dbg_watchlist.py +293 -0
  7. easycoder/debugger/ec_debug.py +1025 -0
  8. easycoder/ec_classes.py +487 -11
  9. easycoder/ec_compiler.py +81 -44
  10. easycoder/ec_condition.py +1 -1
  11. easycoder/ec_core.py +1042 -1081
  12. easycoder/ec_gclasses.py +236 -0
  13. easycoder/ec_graphics.py +1683 -0
  14. easycoder/ec_handler.py +18 -14
  15. easycoder/ec_mqtt.py +248 -0
  16. easycoder/ec_program.py +297 -168
  17. easycoder/ec_psutil.py +48 -0
  18. easycoder/ec_value.py +65 -47
  19. easycoder/pre/README.md +3 -0
  20. easycoder/pre/__init__.py +17 -0
  21. easycoder/pre/debugger/__init__.py +5 -0
  22. easycoder/pre/debugger/ec_dbg_value_display copy.py +195 -0
  23. easycoder/pre/debugger/ec_dbg_value_display.py +24 -0
  24. easycoder/pre/debugger/ec_dbg_watch_list copy.py +219 -0
  25. easycoder/pre/debugger/ec_dbg_watchlist.py +293 -0
  26. easycoder/{ec_debug.py → pre/debugger/ec_debug.py} +418 -185
  27. easycoder/pre/ec_border.py +67 -0
  28. easycoder/pre/ec_classes.py +470 -0
  29. easycoder/pre/ec_compiler.py +291 -0
  30. easycoder/pre/ec_condition.py +27 -0
  31. easycoder/pre/ec_core.py +2772 -0
  32. easycoder/pre/ec_gclasses.py +230 -0
  33. easycoder/{ec_pyside.py → pre/ec_graphics.py} +583 -433
  34. easycoder/pre/ec_handler.py +79 -0
  35. easycoder/pre/ec_keyboard.py +439 -0
  36. easycoder/pre/ec_program.py +557 -0
  37. easycoder/pre/ec_psutil.py +48 -0
  38. easycoder/pre/ec_timestamp.py +11 -0
  39. easycoder/pre/ec_value.py +124 -0
  40. easycoder/pre/icons/close.png +0 -0
  41. easycoder/pre/icons/exit.png +0 -0
  42. easycoder/pre/icons/run.png +0 -0
  43. easycoder/pre/icons/step.png +0 -0
  44. easycoder/pre/icons/stop.png +0 -0
  45. easycoder/pre/icons/tick.png +0 -0
  46. {easycoder-251105.1.dist-info → easycoder-260111.1.dist-info}/METADATA +11 -1
  47. easycoder-260111.1.dist-info/RECORD +59 -0
  48. easycoder-251105.1.dist-info/RECORD +0 -24
  49. {easycoder-251105.1.dist-info → easycoder-260111.1.dist-info}/WHEEL +0 -0
  50. {easycoder-251105.1.dist-info → easycoder-260111.1.dist-info}/entry_points.txt +0 -0
  51. {easycoder-251105.1.dist-info → easycoder-260111.1.dist-info}/licenses/LICENSE +0 -0
easycoder/ec_program.py CHANGED
@@ -1,7 +1,17 @@
1
- import time, json, sys
1
+ import time, sys, json
2
2
  from copy import deepcopy
3
3
  from collections import deque
4
- from .ec_classes import Script, Token, FatalError, RuntimeError, Object
4
+
5
+ from .ec_classes import (
6
+ Script,
7
+ Token,
8
+ FatalError,
9
+ RuntimeError,
10
+ NoValueRuntimeError,
11
+ ECObject,
12
+ ECValue,
13
+ normalize_type
14
+ )
5
15
  from .ec_compiler import Compiler
6
16
  from .ec_core import Core
7
17
  import importlib
@@ -16,26 +26,25 @@ def flush():
16
26
 
17
27
  class Program:
18
28
 
19
- def __init__(self, argv):
29
+ def __init__(self, arg):
20
30
  global queue
21
31
  print(f'EasyCoder version {version("easycoder")}')
22
- print(argv)
23
- if len(argv) == 0:
32
+ if len(arg) == 0:
24
33
  print('No script supplied')
25
34
  exit()
26
- if argv in ['-v', '--version']: return
27
- if argv[0:6] == 'debug ':
28
- scriptName = argv[6:]
35
+ if arg in ['-v', '--version']: return
36
+ if arg[0:6] == 'debug ':
37
+ print('Debug mode requested')
38
+ self.scriptName = arg[6:]
29
39
  self.debugging = True
30
40
  else:
31
- scriptName = argv
41
+ self.scriptName = arg
32
42
  self.debugging = False
33
43
 
34
- f = open(scriptName, 'r')
44
+ f = open(self.scriptName, 'r')
35
45
  source = f.read()
36
46
  f.close()
37
47
  queue = deque()
38
- self.argv = argv
39
48
  self.domains = []
40
49
  self.domainIndex = {}
41
50
  self.name = '<anon>'
@@ -44,18 +53,25 @@ class Program:
44
53
  self.symbols = {}
45
54
  self.onError = 0
46
55
  self.debugStep = False
56
+ self.debugSkip = False
47
57
  self.stack = []
48
58
  self.script = Script(source)
49
59
  self.compiler = Compiler(self)
60
+ self.object = ECObject()
50
61
  self.value = self.compiler.value
51
62
  self.condition = self.compiler.condition
52
63
  self.graphics = None
64
+ self.mqtt = None
65
+ self.psutil = None
53
66
  self.useClass(Core)
54
- self.externalControl = False
55
67
  self.ticker = 0
56
- self.usingGraphics = False
68
+ self.graphicsRunning = False
57
69
  self.debugger = None
58
- self.running = True
70
+ self.running = False
71
+ self.parent = None
72
+ self.message = None
73
+ self.onMessagePC = 0
74
+ self.breakpoint = False
59
75
 
60
76
  # This is called at 10msec intervals by the GUI code
61
77
  def flushCB(self):
@@ -79,7 +95,7 @@ class Program:
79
95
  f'{round((finishCompile - startCompile) * 1000)} ms')
80
96
  for name in self.symbols.keys():
81
97
  record = self.code[self.symbols[name]]
82
- if name[-1] != ':' and not record['used']:
98
+ if name[-1] != ':' and not 'used' in record:
83
99
  print(f'Variable "{name}" not used')
84
100
  else:
85
101
  print(f'Run {self.name}')
@@ -88,8 +104,8 @@ class Program:
88
104
  self.compiler.showWarnings()
89
105
 
90
106
  # If this is the main script and there's no graphics, run a main loop
91
- if parent == None and self.externalControl == False:
92
- while True:
107
+ if parent == None:
108
+ while not self.graphicsRunning:
93
109
  if self.running == True:
94
110
  flush()
95
111
  time.sleep(0.01)
@@ -98,14 +114,35 @@ class Program:
98
114
 
99
115
  # Use the graphics module
100
116
  def useGraphics(self):
101
- if not self.usingGraphics:
117
+ if self.graphics == None:
102
118
  print('Loading graphics module')
103
- from .ec_pyside import Graphics
119
+ from .ec_graphics import Graphics
104
120
  self.graphics = Graphics
105
121
  self.useClass(Graphics)
106
- self.usingGraphics = True
122
+ return True
123
+
124
+ # Use the MQTT module
125
+ def useMQTT(self):
126
+ if self.mqtt == None:
127
+ print('Loading MQTT module')
128
+ from .ec_mqtt import MQTT
129
+ self.mqtt = MQTT
130
+ self.useClass(MQTT)
131
+ return True
132
+
133
+ # Use the psutil module
134
+ def usePSUtil(self):
135
+ if self.psutil == None:
136
+ print('Loading psutil module')
137
+ from .ec_psutil import PSUtil
138
+ self.psutil = PSUtil
139
+ self.useClass(PSUtil)
107
140
  return True
108
141
 
142
+ # Indicate that graphics are running
143
+ def startGraphics(self):
144
+ self.graphicsRunning = True
145
+
109
146
  # Import a plugin
110
147
  def importPlugin(self, source):
111
148
  args=source.split(':')
@@ -129,122 +166,225 @@ class Program:
129
166
  self.domains.append(handler)
130
167
  self.domainIndex[handler.getName()] = handler
131
168
 
169
+ # This is the runtime callback for event handlers
170
+ def callback(self, item, record, goto):
171
+ object = self.getObject(record)
172
+ values = object.getValues() # type: ignore
173
+ for i, v in enumerate(values):
174
+ if isinstance(v, ECValue): v = v.getContent()
175
+ if v == item:
176
+ object.setIndex(i) # type: ignore
177
+ self.run(goto)
178
+ return
179
+
180
+ # Ensure the program is running
181
+ def ensureRunning(self):
182
+ if not self.running:
183
+ raise RuntimeError(self, 'Improper use of runtime function')
184
+
185
+ # Ensure the program is not running
186
+ def ensureNotRunning(self):
187
+ if self.running:
188
+ raise RuntimeError(self, 'Improper use of non-runtime function')
189
+
132
190
  # Get the domain list
133
191
  def getDomains(self):
134
192
  return self.domains
193
+
194
+ def isSymbol(self, name):
195
+ return name in self.symbols
135
196
 
136
- def getSymbolRecord(self, name):
197
+ # Get the symbol record for a given name
198
+ def getVariable(self, name):
199
+ self.ensureRunning()
200
+ if isinstance(name, dict): name = name['name']
137
201
  try:
138
202
  target = self.code[self.symbols[name]]
139
- if target['import'] != None:
203
+ if 'import' in target:
140
204
  target = target['import']
141
205
  return target
142
206
  except:
143
207
  RuntimeError(self, f'Unknown symbol \'{name}\'')
208
+
209
+ # Get the object represented by a symbol record
210
+ def getObject(self, record):
211
+ if isinstance(record, dict) and 'object' in record:
212
+ return record['object']
213
+ return record
214
+
215
+ # Check if an object is an instance of a given class
216
+ # This can either be variable record (a dict) or an instance of ECObject
217
+ def isObjectType(self, object, classes):
218
+ if isinstance(object, dict) and 'object' in object and isinstance(object['object'], ECObject):
219
+ object = object['object']
220
+ return isinstance(object, classes)
221
+
222
+ # Check if the object is an instance of one of a set of classes. Compile and runtime
223
+ def checkObjectType(self, object, classes):
224
+ if isinstance(object, dict): return
225
+ if not isinstance(object, classes):
226
+ if isinstance(classes, tuple):
227
+ class_names = ", ".join([c.__name__ for c in classes])
228
+ message = f"Variable {object.name} should be one of {class_names}"
229
+ else:
230
+ class_names = classes.__name__
231
+ message = f"Variable {object.name} should be {class_names}"
232
+ if self.running:
233
+ raise RuntimeError(self, message)
234
+ else:
235
+ raise FatalError(self.compiler, message)
236
+
237
+ # Get the inner (non-EC) object from a name, record or object
238
+ def getInnerObject(self, object):
239
+ if isinstance(object, dict): object = object['object']
240
+ elif isinstance(object, str):
241
+ record = self.getVariable(object) # type: ignore
242
+ object = self.getObject(record) # type: ignore
243
+ value = object.getValue() # type: ignore
244
+ if isinstance(value, ECValue) and value.getType() == 'object':
245
+ return value.getContent()
246
+ else: return value
144
247
 
145
- def doValue(self, value):
146
- if value == None:
147
- RuntimeError(self, f'Undefined value (variable not initialized?)')
148
-
248
+ def constant(self, content, numeric):
149
249
  result = {}
150
- valType = value['type']
151
- if valType in ['boolean', 'int', 'text', 'object']:
152
- result = value
250
+ result['type'] = int if numeric else str
251
+ result['content'] = content
252
+ return result
253
+
254
+ # Test if an item is a string or a number
255
+ def getItemType(self, value):
256
+ return int if isinstance(value, int) else str
257
+
258
+ # Get the value of an item that may be an ECValue or a raw value. Return as an ECValue
259
+ def getValueOf(self, item):
260
+ value = ECValue()
261
+ if isinstance(item, ECValue):
262
+ if item.getType() == 'object':
263
+ return item.getContent()
264
+ else: value = item
265
+ else:
266
+ varType = type(item).__name__
267
+ if varType == 'int': value.setValue(type=int, content=item)
268
+ elif varType == 'str': value.setValue(type=str, content=item)
269
+ elif varType == 'bool': value.setValue(type=bool, content=item)
270
+ elif varType == 'float': value.setValue(type=str, content=str(item))
271
+ elif varType == 'list': value.setValue(type=list, content=item)
272
+ elif varType == 'dict': value.setValue(type=dict, content=item)
273
+ else: value.setValue(type=None, content=None)
274
+ return value
275
+
276
+ # Runtime function to evaluate an ECObject or ECValue. Returns another ECValue
277
+ # This function may be called recursively by value handlers.
278
+ def evaluate(self, item):
279
+ self.ensureRunning()
280
+ if isinstance(item, ECObject):
281
+ value = item.getValue()
282
+ if value == None:
283
+ raise RuntimeError(self, f'Symbol {item.getName()} not initialized')
284
+ else: value = item
285
+ try:
286
+ valType = normalize_type(value.getType()) # type: ignore
287
+ except:
288
+ RuntimeError(self, 'Value does not hold a valid ECValue')
289
+ result = ECValue(type=valType)
290
+
291
+ if valType in ('str', 'int', 'bool', 'list', 'dict', None):
292
+ # Simple value - just return the content
293
+ result.setContent(value.getContent()) # type: ignore
294
+
295
+ elif valType == 'object':
296
+ # Object other than ECVariable
297
+ record = self.getVariable(value.getName())
298
+ object = self.getObject(record) # type: ignore
299
+ result = object.getContent() # type: ignore
300
+
301
+ elif valType == 'symbol': # type: ignore
302
+ # If it's a symbol, get its value
303
+ record = self.getVariable(value.getContent()) # type: ignore
304
+ if not 'object' in record: return None # type: ignore
305
+ variable = self.getObject(record) # type: ignore
306
+ result = variable.getValue() # type: ignore
307
+ if isinstance(result, ECValue): return self.evaluate(result)
308
+ if isinstance(result, ECObject): return result.getValue()
309
+ if isinstance(result, dict) or isinstance(result, list):
310
+ return result
311
+ # See if one of the domains can handle this value
312
+ value = result
313
+ result = None
314
+ for domain in self.domains:
315
+ result = domain.getUnknownValue(value)
316
+ if result != None: break
317
+
153
318
  elif valType == 'cat':
319
+ # Handle concatenation
154
320
  content = ''
155
- for part in value['value']:
156
- val = self.doValue(part)
157
- if val == None:
158
- val = ''
159
- if val != '':
160
- val = str(val['content'])
161
- if val == None:
162
- val = ''
163
- content += val
164
- result['type'] = 'text'
165
- result['content'] = content
166
- elif valType == 'symbol':
167
- name = value['name']
168
- symbolRecord = self.getSymbolRecord(name)
169
- # if symbolRecord['hasValue']:
170
- if symbolRecord:
171
- handler = self.domainIndex[symbolRecord['domain']].valueHandler('symbol')
172
- result = handler(symbolRecord)
173
- # else:
174
- # # Call the given domain to handle a value
175
- # # domain = self.domainIndex[value['domain']]
176
- # handler = domain.valueHandler(value['type'])
177
- # if handler: result = handler(value)
321
+ for part in value.getContent(): # pyright: ignore[reportOptionalMemberAccess]
322
+ val = self.evaluate(part) # pyright: ignore[reportAttributeAccessIssue]
323
+ if val != None:
324
+ if isinstance(val, ECValue): val = str(val.getContent())
325
+ if val == None: val = ''
326
+ else: content += str(val)
327
+ result.setValue(type=str, content=content)
328
+
178
329
  else:
179
330
  # Call the given domain to handle a value
180
- domain = self.domainIndex[value['domain']]
181
- handler = domain.valueHandler(value['type'])
331
+ domainName = value.getDomain() # type: ignore
332
+ if domainName == None: domainName = 'core'
333
+ domain = self.domainIndex[domainName]
334
+ handler = domain.valueHandler(value.getType()) # type: ignore
182
335
  if handler: result = handler(value)
183
336
 
184
337
  return result
185
338
 
186
- def constant(self, content, numeric):
187
- result = {}
188
- result['type'] = 'int' if numeric else 'text'
189
- result['content'] = content
190
- return result
191
-
192
- def evaluate(self, value):
193
- if value == None:
194
- result = {}
195
- result['type'] = 'text'
196
- result['content'] = ''
197
- return result
198
-
199
- result = self.doValue(value)
200
- if result:
201
- return result
202
- return None
203
-
204
- def getValue(self, value):
205
- result = self.evaluate(value)
206
- if result:
207
- return result.get('content') # type: ignore[union-attr]
208
- return None
209
-
210
- def getRuntimeValue(self, value):
339
+ # Get the runtime value of a value object (as a string or integer)
340
+ def textify(self, value):
341
+ self.ensureRunning()
211
342
  if value is None:
212
343
  return None
213
- v = self.evaluate(value)
214
- if v != None:
215
- content = v['content']
216
- if v['type'] == 'boolean':
217
- return True if content else False
218
- if v['type'] in ['int', 'float', 'text', 'object']:
219
- return content
220
- return ''
221
- return None
222
-
223
- def getSymbolContent(self, symbolRecord):
224
- if len(symbolRecord['value']) == 0:
225
- return None
226
- try: return symbolRecord['value'][symbolRecord['index']]
227
- except: RuntimeError(self, f'Cannot get content of symbol "{symbolRecord["name"]}"')
228
-
229
- def getSymbolValue(self, symbolRecord):
230
- if len(symbolRecord['value']) == 0:
344
+
345
+ if isinstance(value, dict):
346
+ value = value['object']
347
+ if isinstance(value, ECObject):
348
+ value = value.getValue()
349
+ if isinstance(value, ECValue): # type: ignore
350
+ v = self.evaluate(value) # type: ignore
351
+ else:
352
+ v = value
353
+ if v is None: return None
354
+ if isinstance(v, ECValue):
355
+ if v.getType() == 'object':
356
+ return value.getContent() # type: ignore
357
+ return v.getContent()
358
+ if isinstance(v, (dict, list)):
359
+ return json.dumps(v)
360
+ return v
361
+
362
+ # Get the content of a symbol
363
+ def getSymbolContent(self, record):
364
+ if len(record['value']) == 0:
231
365
  return None
232
- try: value = symbolRecord['value'][symbolRecord['index']]
233
- except: RuntimeError(self, f'Cannot get value of symbol "{symbolRecord["name"]}"')
234
- copy = deepcopy(value)
366
+ try: return record['value'][record['index']]
367
+ except: raise RuntimeError(self, f'Cannot get content of symbol "{record["name"]}"')
368
+
369
+ # Get the value of a symbol as an ECValue
370
+ def getSymbolValue(self, record):
371
+ self.ensureRunning()
372
+ object = self.getObject(record)
373
+ self.checkObjectType(object, ECObject)
374
+ value = object.getValue() # type: ignore
375
+ if value is None:
376
+ raise NoValueRuntimeError(self, f'Symbol "{record["name"]}" has no value')
377
+ # copy = deepcopy(value)
378
+ copy = ECValue(domain=value.getDomain(),type=value.getType(),content=deepcopy(value.getContent()))
235
379
  return copy
236
380
 
237
- def putSymbolValue(self, symbolRecord, value):
238
- if symbolRecord['locked']:
239
- name = symbolRecord['name']
240
- RuntimeError(self, f'Symbol "{name}" is locked')
241
- if symbolRecord['value'] == None or symbolRecord['value'] == []:
242
- symbolRecord['value'] = [value]
243
- else:
244
- index = symbolRecord['index']
245
- if index == None:
246
- index = 0
247
- symbolRecord['value'][index] = value
381
+ # Set the value of a symbol to either an ECValue or a raw value
382
+ def putSymbolValue(self, record, value):
383
+ variable = self.getObject(record)
384
+ if variable.isLocked(): # type: ignore
385
+ name = record['name']
386
+ raise RuntimeError(self, f'Symbol "{name}" is locked')
387
+ variable.setValue(self.getValueOf(value)) # type: ignore
248
388
 
249
389
  def encode(self, value):
250
390
  return value
@@ -321,12 +461,21 @@ class Program:
321
461
  self.pc = pc
322
462
  while self.running:
323
463
  command = self.code[self.pc]
464
+
465
+ # Check if debugger wants to halt before executing this command
466
+ if self.debugger != None:
467
+ # pc==1 is the first real command (pc==0 is the debug loader)
468
+ is_first = (self.pc == 1)
469
+ if self.debugger.checkIfHalt(is_first):
470
+ # Debugger says halt - break out and wait for user
471
+ break
472
+
324
473
  domainName = command['domain']
325
474
  if domainName == None:
326
475
  self.pc += 1
327
476
  else:
328
477
  keyword = command['keyword']
329
- if self.debugStep and command['debug']:
478
+ if self.debugStep and not self.debugSkip and 'debug' in command:
330
479
  lino = command['lino'] + 1
331
480
  line = self.script.lines[command['lino']].strip()
332
481
  print(f'{self.name}: Line {lino}: {domainName}:{keyword}: {line}')
@@ -335,7 +484,12 @@ class Program:
335
484
  if handler:
336
485
  command = self.code[self.pc]
337
486
  command['program'] = self
338
- self.pc = handler(command)
487
+ try:
488
+ if self.breakpoint:
489
+ pass # Place a breakpoint here for a debugger to catch
490
+ self.pc = handler(command)
491
+ except Exception as e:
492
+ raise RuntimeError(self, f'Error during execution of {domainName}:{keyword}: {str(e)}')
339
493
  # Deal with 'exit'
340
494
  if self.pc == -1:
341
495
  queue = deque()
@@ -345,69 +499,52 @@ class Program:
345
499
  break
346
500
  elif self.pc == None or self.pc == 0 or self.pc >= len(self.code):
347
501
  break
348
- elif self.debugger != None and not self.debugger.continueExecution():
349
- break
350
502
 
351
503
  # Run the script at a given PC value
352
504
  def run(self, pc):
353
505
  global queue
354
- item = Object()
355
- item.program = self
356
- item.pc = pc
506
+ item = ECValue()
507
+ item.program = self # type: ignore
508
+ item.pc = pc # type: ignore
357
509
  queue.append(item)
510
+ self.running = True
358
511
 
359
512
  def kill(self):
360
513
  self.running = False
361
514
  if self.parent != None: self.parent.program.kill()
362
515
 
363
- def setExternalControl(self):
364
- self.externalControl = True
365
-
366
516
  def nonNumericValueError(self):
367
517
  FatalError(self.compiler, 'Non-numeric value')
368
518
 
369
- def variableDoesNotHoldAValueError(self, name):
370
- raise FatalError(self.compiler, f'Variable "{name}" does not hold a value')
371
-
372
- def noneValueError(self, name):
373
- raise FatalError(self.compiler, f'Value is None')
374
-
375
519
  def compare(self, value1, value2):
376
- val1 = self.evaluate(value1)
377
- val2 = self.evaluate(value2)
378
- if val1 == None or val2 == None:
520
+ if value1 == None or value2 == None:
521
+ RuntimeError(self, 'Cannot compare a value with None')
522
+ v1 = self.textify(value1)
523
+ v2 = self.textify(value2)
524
+ if v1 == None or v2 == None:
525
+ raise RuntimeError(self, 'Both items must have a value for comparison')
526
+ if type(v1) == str and type(v2) == str:
527
+ # String comparison
528
+ if v1 < v2: return -1
529
+ if v1 > v2: return 1
379
530
  return 0
380
- v1 = val1['content']
381
- v2 = val2['content']
382
- # if v1 == None and v2 != None or v1 != None and v2 == None:
383
- # return 0
384
- if v1 == None and v2 != None: return -1
385
- elif v2 == None and v1 != None: return 1
386
- if v1 != None and val1['type'] == 'int':
387
- if not val2['type'] == 'int':
388
- if type(v2) is str:
389
- try:
390
- v2 = int(v2)
391
- except:
392
- lino = self.code[self.pc]['lino'] + 1
393
- RuntimeError(None, f'Line {lino}: \'{v2}\' is not an integer')
394
- else:
395
- if v2 != None and val2['type'] == 'int':
396
- v2 = str(v2)
397
- if v1 == None:
398
- v1 = ''
399
- if v2 == None:
400
- v2 = ''
401
- if type(v1) == int:
402
- if type(v2) != int:
403
- v1 = f'{v1}'
404
- if type(v2) == int:
405
- if type(v1) != int:
406
- v2 = f'{v2}'
407
- if v1 > v2: # type: ignore[operator]
408
- return 1
531
+
532
+ if type(v1) is str:
533
+ try:
534
+ v1 = int(v1)
535
+ except:
536
+ print(f'{v1} is not an integer')
537
+ return None
538
+ if type(v2) is str:
539
+ try:
540
+ v2 = int(v2)
541
+ except:
542
+ print(f'{v2} is not an integer')
543
+ return None
409
544
  if v1 < v2: # type: ignore[operator]
410
545
  return -1
546
+ if v1 > v2: # type: ignore[operator]
547
+ return 1
411
548
  return 0
412
549
 
413
550
  # Set up a message handler
@@ -421,16 +558,8 @@ class Program:
421
558
 
422
559
  # This is the program launcher
423
560
  def Main():
424
- print(sys.argv)
425
561
  if (len(sys.argv) > 1):
426
- # Check if 'debug' is the first argument
427
- if sys.argv[1] == 'debug' and len(sys.argv) > 2:
428
- # Create program with debug flag
429
- program = Program(sys.argv[2])
430
- program.debugging = True
431
- program.start()
432
- else:
433
- Program(sys.argv[1]).start()
562
+ Program(' '.join(sys.argv[1:])).start()
434
563
  else:
435
564
  Program('-v')
436
565
 
easycoder/ec_psutil.py ADDED
@@ -0,0 +1,48 @@
1
+ from easycoder import Handler, ECValue
2
+ import os
3
+ from psutil import Process
4
+
5
+ class PSUtil(Handler):
6
+
7
+ def __init__(self, compiler):
8
+ Handler.__init__(self, compiler)
9
+
10
+ def getName(self):
11
+ return 'psutil'
12
+
13
+ #############################################################################
14
+ # Keyword handlers
15
+
16
+ #############################################################################
17
+ # Compile a value in this domain
18
+ def compileValue(self):
19
+ value = ECValue(domain=self.getName())
20
+ if self.tokenIs('the'):
21
+ self.nextToken()
22
+ token = self.getToken()
23
+ if token in ['mem', 'memory']:
24
+ value.setType('memory')
25
+ return value
26
+ return None
27
+
28
+ #############################################################################
29
+ # Modify a value or leave it unchanged.
30
+ def modifyValue(self, value):
31
+ return value
32
+
33
+ #############################################################################
34
+ # Value handlers
35
+
36
+ def v_memory(self, v):
37
+ process: Process = Process(os.getpid())
38
+ megabytes: float = process.memory_info().rss / (1024 * 1024)
39
+ return ECValue(domain=self.getName(), type=float, content=megabytes)
40
+
41
+ #############################################################################
42
+ # Compile a condition
43
+ def compileCondition(self):
44
+ condition = {}
45
+ return condition
46
+
47
+ #############################################################################
48
+ # Condition handlers