easycoder 241218.1__py2.py3-none-any.whl → 241227.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 CHANGED
@@ -1,5 +1,6 @@
1
1
  '''EasyCoder for Python'''
2
2
 
3
+ from .ec import Main
3
4
  from .ec_classes import *
4
5
  from .ec_compiler import *
5
6
  from .ec_condition import *
@@ -8,6 +9,5 @@ from .ec_handler import *
8
9
  from .ec_program import *
9
10
  from .ec_timestamp import *
10
11
  from .ec_value import *
11
- from .ec_graphics import *
12
12
 
13
- __version__ = "241218.1"
13
+ __version__ = "241227.1"
easycoder/ec.py ADDED
@@ -0,0 +1,10 @@
1
+ import sys
2
+ from .ec_program import Program
3
+
4
+ # This is the program launcher
5
+ def Main():
6
+ print(f'Args: {sys.argv}')
7
+ if (len(sys.argv) > 1):
8
+ Program(sys.argv[1:]).start()
9
+ else:
10
+ print('Syntax: easycoder <scriptname>')
easycoder/ec_classes.py CHANGED
@@ -52,3 +52,6 @@ class Token:
52
52
 
53
53
  class Condition():
54
54
  negate = False
55
+
56
+ class Object():
57
+ pass
easycoder/ec_compiler.py CHANGED
@@ -16,6 +16,7 @@ class Compiler:
16
16
  self.warnings = []
17
17
  self.program.compiler = self
18
18
  self.addCommand = self.program.add
19
+ self.compileConstant = self.value.compileConstant
19
20
 
20
21
  def getPC(self):
21
22
  return len(self.program.code)
@@ -44,6 +45,11 @@ class Compiler:
44
45
  except:
45
46
  return None
46
47
 
48
+ # Get a constant
49
+ def getConstant(self, token):
50
+ self.index += 1
51
+ return self.compileConstant(token)
52
+
47
53
  # Get a value
48
54
  def getValue(self):
49
55
  return self.value.compileValue()
@@ -53,11 +59,6 @@ class Compiler:
53
59
  self.index += 1
54
60
  return self.value.compileValue()
55
61
 
56
- # Get a constant
57
- def getConstant(self, token):
58
- self.index += 1
59
- return self.value.compileConstant(token)
60
-
61
62
  # Get a condition
62
63
  def getCondition(self):
63
64
  return self.condition.compileCondition()
@@ -101,7 +102,7 @@ class Compiler:
101
102
 
102
103
  def showWarnings(self):
103
104
  for warning in self.warnings:
104
- print(f'Warning: Line {self.getLino() + 1}: {warning}')
105
+ print(f'Warning at line {self.getLino() + 1} from {warning}')
105
106
 
106
107
  def getSymbolRecord(self):
107
108
  token = self.getToken()
easycoder/ec_core.py CHANGED
@@ -724,8 +724,10 @@ class Core(Handler):
724
724
  FatalError(self.program.compiler, 'Unknown file open mode {self.getToken()}')
725
725
  return False
726
726
  command['mode'] = mode
727
- self.add(command)
728
- return True
727
+ else:
728
+ command['mode'] = 'r'
729
+ self.add(command)
730
+ return True
729
731
  else:
730
732
  FatalError(self.compiler, f'Variable "{self.getToken()}" is not a file')
731
733
  else:
easycoder/ec_graphics.py CHANGED
@@ -1,6 +1,7 @@
1
- from .ec_classes import FatalError, RuntimeError
1
+ from .ec_classes import FatalError, RuntimeError, Object
2
2
  from .ec_handler import Handler
3
- from .ec_renderer import *
3
+ from .ec_screenspec import ScreenSpec
4
+ from .ec_renderer import Renderer
4
5
 
5
6
  class Graphics(Handler):
6
7
 
@@ -8,7 +9,7 @@ class Graphics(Handler):
8
9
  Handler.__init__(self, compiler)
9
10
 
10
11
  def getName(self):
11
- return 'graphics'
12
+ return 'kivy'
12
13
 
13
14
  #############################################################################
14
15
  # Keyword handlers
@@ -19,56 +20,183 @@ class Graphics(Handler):
19
20
  command['name'] = record['name']
20
21
  if self.nextIs('to'):
21
22
  value = self.nextValue()
23
+ record['id'] = value
22
24
  command['id'] = value
23
25
  self.add(command)
24
26
  return True
25
27
 
26
28
  def r_attach(self, command):
27
- target = self.getVariable(command['name'])
29
+ targetRecord = self.getVariable(command['name'])
30
+ keyword = targetRecord['keyword']
28
31
  id = self.getRuntimeValue(command['id'])
29
- element = getElement(id)
32
+ element = self.ui.getElement(id)
30
33
  if element == None:
31
34
  FatalError(self.program.compiler, f'There is no screen element with id \'{id}\'')
32
35
  return -1
33
- if element['type'] != target['keyword']:
34
- FatalError(self.program.compiler, f'Mismatched element type ({element['type']} and {target['keyword']})')
35
- self.putSymbolValue(target, {'type': 'text', 'content': id})
36
+ if element.getType() != keyword:
37
+ FatalError(self.program.compiler, f'Mismatched element type ({element['type']} and {keyword})')
38
+ self.putSymbolValue(targetRecord, {'type': 'text', 'content': id})
36
39
  return self.nextPC()
37
40
 
41
+ # close window
38
42
  def k_close(self, command):
39
- if self.nextIs('screen'):
43
+ if (self.nextIs('window')):
40
44
  self.add(command)
41
45
  return True
42
46
  return False
43
47
 
44
48
  def r_close(self, command):
45
- closeScreen()
46
- return self.nextPC()
49
+ self.renderer.stop()
50
+ return 0
47
51
 
52
+ # create window/ellipse/rectangle//text/image
48
53
  def k_create(self, command):
49
- if self.nextIs('screen'):
54
+ token = self.nextToken()
55
+ if (token == 'window'):
56
+ t = {}
57
+ t['type'] = 'text'
58
+ t['content'] = 'EasyCoder'
59
+ width = self.compileConstant(640)
60
+ height = self.compileConstant(480)
61
+ left = self.compileConstant(100)
62
+ top = self.compileConstant(100)
63
+ r = self.compileConstant(255)
64
+ g = self.compileConstant(255)
65
+ b = self.compileConstant(255)
50
66
  while True:
51
67
  token = self.peek()
52
- if token == 'at':
68
+ if token == 'title':
53
69
  self.nextToken()
54
- command['left'] = self.nextValue()
55
- command['top'] = self.nextValue()
70
+ t = self.nextValue()
71
+ elif token == 'at':
72
+ self.nextToken()
73
+ left = self.nextValue()
74
+ top = self.nextValue()
56
75
  elif token == 'size':
57
76
  self.nextToken()
58
- command['width'] = self.nextValue()
59
- command['height'] = self.nextValue()
77
+ width = self.nextValue()
78
+ height = self.nextValue()
60
79
  elif token == 'fill':
61
80
  self.nextToken()
62
- command['fill'] = self.nextValue()
81
+ if self.nextIs('color'):
82
+ r = self.nextValue()
83
+ g = self.nextValue()
84
+ b = self.nextValue()
63
85
  else:
64
86
  break
87
+ command['type'] = 'window'
88
+ command['title'] = t
89
+ command['pos'] = (left, top)
90
+ command['size'] = (width, height)
91
+ command['fill'] = (r, g, b)
65
92
  self.add(command)
66
93
  return True
94
+
95
+ elif self.isSymbol():
96
+ record = self.getSymbolRecord()
97
+ command['target'] = record['name']
98
+ type = record['keyword']
99
+ command['type'] = type
100
+ if type in ['ellipse', 'rectangle', 'image']:
101
+ self.getElementData(type, command)
102
+ for item in ['width', 'height', 'left', 'bottom', 'r', 'g', 'b']:
103
+ if command[item] == None:
104
+ FatalError(self.program.compiler, f'Missing property \'{item}\'')
105
+ return True
106
+ elif type == 'text':
107
+ self.getElementData(type, command)
108
+ for item in ['width', 'height', 'left', 'bottom', 'r', 'g', 'b', 'text']:
109
+ if command[item] == None:
110
+ FatalError(self.program.compiler, f'Missing property \'{item}\'')
111
+ self.add(command)
112
+ record['elementID'] = command['id']
67
113
  return False
114
+
115
+ def getElementData(self, type, command):
116
+ width = None
117
+ height = None
118
+ left = None
119
+ bottom = None
120
+ r = None
121
+ g = None
122
+ b = None
123
+ text = None
124
+ source = None
125
+ id = self.nextValue()
126
+ while True:
127
+ token = self.peek()
128
+ if token == 'size':
129
+ self.nextToken()
130
+ width = self.nextValue()
131
+ height = self.nextValue()
132
+ elif token == 'at':
133
+ self.nextToken()
134
+ left = self.nextValue()
135
+ bottom = self.nextValue()
136
+ elif token == 'fill':
137
+ self.nextToken()
138
+ r = self.nextValue()
139
+ g = self.nextValue()
140
+ b = self.nextValue()
141
+ elif token == 'text':
142
+ self.nextToken()
143
+ text = self.nextValue()
144
+ elif token == 'source':
145
+ self.nextToken()
146
+ source = self.nextValue()
147
+ else:
148
+ break
149
+ command['id'] = id
150
+ command['type'] = type
151
+ if width != None:
152
+ command['width'] = width
153
+ if height != None:
154
+ command['height'] = height
155
+ if left!= None:
156
+ command['left'] = left
157
+ if bottom != None:
158
+ command['bottom'] = bottom
159
+ if r != None:
160
+ command['r'] = r
161
+ if g != None:
162
+ command['g'] = g
163
+ if b != None:
164
+ command['b'] = b
165
+ if text != None:
166
+ command['text'] = text
167
+ if source != None:
168
+ command['source'] = source
68
169
 
69
170
  def r_create(self, command):
70
- createScreen(command)
171
+ try:
172
+ type = command['type']
173
+ if type == 'window':
174
+ self.windowSpec = Object()
175
+ self.windowSpec.title = command['title']['content']
176
+ self.windowSpec.flush = self.program.flush
177
+ self.windowSpec.finish = self.program.finish
178
+ self.windowSpec.pos = (self.getRuntimeValue(command['pos'][0]), self.getRuntimeValue(command['pos'][1]))
179
+ self.windowSpec.size = (self.getRuntimeValue(command['size'][0]), self.getRuntimeValue(command['size'][1]))
180
+ self.windowSpec.fill = (self.getRuntimeValue(command['fill'][0])/255, self.getRuntimeValue(command['fill'][1])/255, self.getRuntimeValue(command['fill'][2])/255)
181
+ else:
182
+ element = self.ui.createWidget(self.getWidgetSpec(command))
183
+ print(element)
184
+ except Exception as e:
185
+ RuntimeError(self.program, e)
71
186
  return self.nextPC()
187
+
188
+ def getWidgetSpec(self, command):
189
+ spec = Object()
190
+ spec.id = self.getRuntimeValue(command['id'])
191
+ spec.type = command['type']
192
+ spec.w = self.getRuntimeValue(command['width'])
193
+ spec.h = self.getRuntimeValue(command['height'])
194
+ spec.x = self.getRuntimeValue(command['left'])
195
+ spec.y = self.getRuntimeValue(command['bottom'])
196
+ spec.r = self.getRuntimeValue(command['r'])/255
197
+ spec.g = self.getRuntimeValue(command['g'])/255
198
+ spec.b = self.getRuntimeValue(command['b'])/255
199
+ return spec
72
200
 
73
201
  def k_ellipse(self, command):
74
202
  return self.compileVariable(command)
@@ -82,69 +210,16 @@ class Graphics(Handler):
82
210
  def r_image(self, command):
83
211
  return self.nextPC()
84
212
 
85
- def k_move(self, command):
86
- if self.nextIsSymbol():
87
- record = self.getSymbolRecord()
88
- if record['keyword'] in ['rectangle', 'ellipse', 'text', 'image']:
89
- command['name'] = record['name']
90
- if self.nextToken() in ['by', 'to']:
91
- command['type'] = self.getToken()
92
- command['x'] = self.nextValue()
93
- command['y'] = self.nextValue()
94
- self.add(command)
95
- return True
96
- return False
97
-
98
- def r_move(self, command):
99
- target = self.getVariable(command['name'])
100
- id = self.getSymbolValue(target)['content']
101
- type = command['type']
102
- x = self.getRuntimeValue(command['x'])
103
- y = self.getRuntimeValue(command['y'])
104
- if type == 'by':
105
- moveElement(id, x, y)
106
- elif type == 'to':
107
- moveElementTo(id, x, y)
108
- return self.nextPC()
109
-
110
213
  def k_on(self, command):
111
214
  token = self.nextToken()
112
- command['type'] = token
113
- if token == 'click':
114
- command['event'] = token
115
- if self.peek() == 'in':
116
- self.nextToken()
117
- if self.nextIs('screen'):
118
- command['target'] = None
119
- elif self.isSymbol():
215
+ if token in ['click', 'tap']:
216
+ command['type'] = 'tap'
217
+ if self.nextIsSymbol():
120
218
  target = self.getSymbolRecord()
121
- command['target'] = target['name']
122
219
  else:
123
220
  FatalError(self.program.compiler, f'{self.getToken()} is not a screen element')
124
221
  return False
125
- command['goto'] = self.getPC() + 2
126
- self.add(command)
127
- self.nextToken()
128
- pcNext = self.getPC()
129
- cmd = {}
130
- cmd['domain'] = 'core'
131
- cmd['lino'] = command['lino']
132
- cmd['keyword'] = 'gotoPC'
133
- cmd['goto'] = 0
134
- cmd['debug'] = False
135
- self.addCommand(cmd)
136
- self.compileOne()
137
- cmd = {}
138
- cmd['domain'] = 'core'
139
- cmd['lino'] = command['lino']
140
- cmd['keyword'] = 'stop'
141
- cmd['debug'] = False
142
- self.addCommand(cmd)
143
- # Fixup the link
144
- self.getCommandAt(pcNext)['goto'] = self.getPC()
145
- return True
146
- elif token == 'tick':
147
- command['event'] = token
222
+ command['target'] = target['name']
148
223
  command['goto'] = self.getPC() + 2
149
224
  self.add(command)
150
225
  self.nextToken()
@@ -170,122 +245,51 @@ class Graphics(Handler):
170
245
 
171
246
  def r_on(self, command):
172
247
  pc = command['goto']
173
- if command['type'] == 'click':
174
- event = command['event']
175
- if event == 'click':
176
- target = command['target']
177
- if target == None:
178
- value = 'screen'
179
- else:
180
- widget = self.getVariable(target)
181
- value = widget['value'][widget['index']]
182
- setOnClick(value['content'], lambda: self.run(pc))
183
- elif command['type'] == 'tick':
184
- setOnTick(lambda: self.run(pc))
185
- return self.nextPC()
186
-
187
- def k_rectangle(self, command):
188
- return self.compileVariable(command)
189
-
190
- def r_rectangle(self, command):
248
+ if command['type'] == 'tap':
249
+ record = self.getVariable(command['target'])
250
+ keyword = record['keyword']
251
+ if keyword in ['ellipse', 'rectangle', 'text', 'image']:
252
+ id = record['value'][record['index']]['content']
253
+ self.ui.setOnClick(id, lambda: self.run(pc))
254
+ else:
255
+ RuntimeError(self.program, f'{record['name']} is not a clickable object')
191
256
  return self.nextPC()
192
257
 
193
- def k_render(self, command):
194
- command['value'] = self.nextValue()
195
- command['parent'] = 'screen'
196
- if self.peek() == 'in':
197
- self.nextToken()
198
- if self.nextIsSymbol():
199
- record = self.getSymbolRecord()
200
- type = record['type']
201
- name = record['name']
202
- if type in ['rectangle', 'ellipse']:
203
- command['parent'] = record['name']
258
+ # move an element
259
+ def k_move(self, command):
260
+ if self.nextIsSymbol():
261
+ record = self.getSymbolRecord()
262
+ type = record['keyword']
263
+ if type in ['ellipse', 'rectangle']:
264
+ command['target'] = record['id']
265
+ token = self.nextToken()
266
+ if token == 'to':
267
+ command['x'] = self.nextValue()
268
+ command['y'] = self.nextValue()
204
269
  self.add(command)
205
270
  return True
206
- else:
207
- self.warning(f'Graphics.render: {name} cannot be a parent of another element')
208
- return False
209
- self.add(command)
210
- return True
211
- FatalError(self.program.compiler, 'Nothing specified to render')
212
- return False
213
-
214
- def r_render(self, command):
215
- parent = command['parent']
216
- value = self.getRuntimeValue(command['value'])
217
- render(value, parent)
218
- return self.nextPC()
219
-
220
- def k_set(self, command):
221
- if self.peek() == 'the':
222
- self.nextToken()
223
- token = self.peek()
224
- if token == 'text':
225
- self.nextToken()
226
- command['variant'] = 'setText'
227
- if self.peek() == 'of':
228
- self.nextToken()
229
- if self.nextIsSymbol():
230
- record = self.getSymbolRecord()
231
- command['name'] = record['name']
232
- if record['keyword'] != 'text':
233
- RuntimeError(command['program'], f'Symbol type is not \'text\'')
234
- if self.peek() == 'to':
235
- self.nextToken()
236
- command['value'] = self.nextValue()
271
+ elif token == 'by':
272
+ command['keyword'] = 'moveBy'
273
+ command['dx'] = self.nextValue()
274
+ command['dy'] = self.nextValue()
237
275
  self.add(command)
238
276
  return True
239
- return False
240
- elif token == 'background':
241
- self.nextToken()
242
- command['variant'] = 'setBackground'
243
- if self.peek() == 'color':
244
- self.nextToken()
245
- if self.peek() == 'of':
246
- self.nextToken()
247
- if self.nextIsSymbol():
248
- record = self.getSymbolRecord()
249
- command['name'] = record['name']
250
- if not record['keyword'] in ['rectangle', 'ellipse']:
251
- RuntimeError(command['program'], f'Symbol type is not \'rectangle\' or \'ellipse\'')
252
- if self.peek() == 'to':
253
- self.nextToken()
254
- command['value'] = self.nextValue()
255
- self.add(command)
256
- return True
257
- return False
258
277
  return False
259
278
 
260
- def r_set(self, command):
261
- variant = command['variant']
262
- if variant == 'setText':
263
- variable = self.getVariable(command['name'])
264
- element = self.getSymbolValue(variable)
265
- value = self.getRuntimeValue(command['value'])
266
- setText(element['content'], value)
267
- elif variant == 'setBackground':
268
- variable = self.getVariable(command['name'])
269
- element = self.getSymbolValue(variable)
270
- value = self.getRuntimeValue(command['value'])
271
- setBackground(element['content'], value)
279
+ def r_move(self, command):
280
+ pos = (self.getRuntimeValue(command['x']), self.getRuntimeValue(command['y']))
281
+ self.ui.moveElementTo(self.getRuntimeValue(command['target']), pos)
272
282
  return self.nextPC()
273
283
 
274
- def k_show(self, command):
275
- if self.nextIs('screen'):
276
- command['name'] = None
277
- self.add(command)
278
- return True
279
- return False
280
-
281
- def r_show(self, command):
282
- showScreen()
284
+ def r_moveBy(self, command):
285
+ dist = (self.getRuntimeValue(command['dx']), self.getRuntimeValue(command['dy']))
286
+ self.ui.moveElementBy(self.getRuntimeValue(command['target']), dist)
283
287
  return self.nextPC()
284
288
 
285
- def k_spec(self, command):
286
- return self.compileVariable(command, True)
289
+ def k_rectangle(self, command):
290
+ return self.compileVariable(command)
287
291
 
288
- def r_spec(self, command):
292
+ def r_rectangle(self, command):
289
293
  return self.nextPC()
290
294
 
291
295
  def k_text(self, command):
@@ -293,78 +297,69 @@ class Graphics(Handler):
293
297
 
294
298
  def r_text(self, command):
295
299
  return self.nextPC()
296
-
297
- #############################################################################
298
- # Compile a value in this domain
299
- def compileValue(self):
300
- value = {}
301
- value['domain'] = 'graphics'
302
- token = self.getToken()
303
- if self.isSymbol():
304
- value['name'] = token
305
- symbolRecord = self.getSymbolRecord()
306
- keyword = symbolRecord['keyword']
307
- if keyword == 'module':
308
- value['type'] = 'module'
309
- return value
310
-
311
- if symbolRecord['valueHolder'] == True or keyword == 'dictionary':
312
- value['type'] = 'symbol'
313
- return value
314
- return None
315
-
316
- if self.tokenIs('the'):
317
- self.nextToken()
318
- token = self.getToken()
319
300
 
320
- value['type'] = token
301
+ # render {spec}
302
+ def k_render(self, command):
303
+ command['spec'] = self.nextValue()
304
+ self.add(command)
305
+ return True
321
306
 
322
- if token == 'color':
323
- name = self.nextToken()
324
- value = {}
325
- value['type'] = 'string'
326
- value['content'] = name
327
- return value
328
-
329
- elif token == 'attribute':
330
- value['attribute'] = self.nextValue()
331
- if (self.nextIs('of')):
332
- if (self.nextIsSymbol()):
333
- value['name'] = self.getToken()
334
- return value
335
- return None
307
+ def r_render(self, command):
308
+ self.ui = self.renderer.getUI()
309
+ ScreenSpec().render(self.getRuntimeValue(command['spec']), self.ui)
310
+ return self.nextPC()
311
+
312
+ # run graphics
313
+ def k_run(self, command):
314
+ if self.nextIs('graphics'):
315
+ self.add(command)
316
+ return True
317
+ return False
318
+
319
+ def r_run(self, command):
320
+ self.renderer = Renderer()
321
+ self.renderer.init(self.windowSpec)
322
+ self.program.setExternalControl()
323
+ self.program.run(self.nextPC())
324
+ self.renderer.run()
336
325
 
337
326
  #############################################################################
338
327
  # Modify a value or leave it unchanged.
339
328
  def modifyValue(self, value):
340
329
  return value
341
330
 
331
+ #############################################################################
332
+ # Compile a value in this domain
333
+ def compileValue(self):
334
+ value = {}
335
+ value['domain'] = self.getName()
336
+ if self.tokenIs('attribute'):
337
+ attribute = self.nextValue()
338
+ if self.nextIs('of'):
339
+ if self.nextIsSymbol():
340
+ record = self.getSymbolRecord()
341
+ if record['keyword'] in ['ellipse', 'rectangle']:
342
+ value['type'] = 'attribute'
343
+ value['attribute'] = attribute
344
+ value['target'] = record['name']
345
+ return value
346
+ return None
347
+
342
348
  #############################################################################
343
349
  # Value handlers
344
350
 
345
- def v_symbol(self, symbolRecord):
346
- result = {}
347
- if symbolRecord['valueHolder']:
348
- symbolValue = self.getSymbolValue(symbolRecord)
349
- if symbolValue == None:
350
- return None
351
- result['type'] = symbolValue['type']
352
- content = symbolValue['content']
353
- if content == None:
354
- return ''
355
- result['content'] = content
356
- return result
357
- else:
358
- return ''
359
-
360
351
  def v_attribute(self, v):
361
- target = self.getVariable(v['name'])
362
- attribute = self.getRuntimeValue(v['attribute'])
363
- name = target['value'][target['index']]['content']
364
- value = {}
365
- value['type'] = 'int'
366
- value['content'] = getAttribute(name, attribute)
367
- return value
352
+ try:
353
+ attribute = self.getRuntimeValue(v['attribute'])
354
+ target = self.getVariable(v['target'])
355
+ val = self.getSymbolValue(target)
356
+ v = self.ui.getAttribute(val['content'], attribute)
357
+ value = {}
358
+ value['type'] = 'int'
359
+ value['content'] = int(round(v))
360
+ return value
361
+ except Exception as e:
362
+ RuntimeError(self.program, e)
368
363
 
369
364
  #############################################################################
370
365
  # Compile a condition
easycoder/ec_handler.py CHANGED
@@ -25,6 +25,7 @@ class Handler:
25
25
  self.getCommandAt = compiler.getCommandAt
26
26
  self.compileOne = compiler.compileOne
27
27
  self.compileFromHere = compiler.compileFromHere
28
+ self.compileConstant = compiler.compileConstant
28
29
 
29
30
  self.code = self.program.code
30
31
  self.add = self.program.add