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 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__ = "250118.1"
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}): {message}')
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}): {message}')
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 Token, FatalError
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 != None:
111
- symbolRecord = self.code[symbol]
112
- symbolRecord['used'] = True
113
- return symbolRecord
114
- return None
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(), False)
138
+ return self.compileSymbol(command, self.getToken())
118
139
 
119
- def compileVariable(self, command, valueHolder = False):
120
- return self.compileSymbol(command, self.nextToken(), valueHolder)
140
+ def compileVariable(self, command, extra=None):
141
+ return self.compileSymbol(command, self.nextToken(), extra)
121
142
 
122
- def compileSymbol(self, command, name, valueHolder):
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'No handler found for "{token}"')
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
- # print(f'Compile keyword "{keyword}"')
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
- # line = self.script.lines[token.lino]
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
- return None
22
+ return None
22
23
 
23
24
  def testCondition(self, condition):
24
25
  handler = self.program.domainIndex[condition.domain]