easycoder 250116.1__py2.py3-none-any.whl → 250116.3__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
@@ -9,4 +9,4 @@ from .ec_program import *
9
9
  from .ec_timestamp import *
10
10
  from .ec_value import *
11
11
 
12
- __version__ = "250116.1"
12
+ __version__ = "250116.3"
easycoder/ec_compiler.py CHANGED
@@ -98,11 +98,11 @@ class Compiler:
98
98
  return self.tokens[self.index].lino
99
99
 
100
100
  def warning(self, message):
101
- self.warnings.append(message)
101
+ self.warnings.append(f'Warning at line {self.getLino() + 1} of {self.program.name}: {message}')
102
102
 
103
103
  def showWarnings(self):
104
104
  for warning in self.warnings:
105
- print(f'Warning at line {self.getLino() + 1} of {self.program.name}: {warning}')
105
+ print(warning)
106
106
 
107
107
  def getSymbolRecord(self):
108
108
  token = self.getToken()
easycoder/ec_graphics.py CHANGED
@@ -9,6 +9,7 @@ class Graphics(Handler):
9
9
  def __init__(self, compiler):
10
10
  Handler.__init__(self, compiler)
11
11
  self.utils = GUtils()
12
+ self.eventHandlers = {}
12
13
 
13
14
  def getName(self):
14
15
  return 'graphics'
@@ -18,17 +19,18 @@ class Graphics(Handler):
18
19
 
19
20
  def k_add(self, command):
20
21
  elements = []
21
- while True:
22
- if self.nextIsSymbol():
23
- symbolRecord = self.getSymbolRecord()
24
- name = symbolRecord['name']
25
- if 'iselement' in symbolRecord:
26
- elements.append(name)
27
- if self.peek() != 'and': break
28
- else: FatalError(self.program.compiler, f'"{name}" is not a graphic element')
29
- else: FatalError(self.program.compiler, f'Element expected; got "{self.getToken()}"')
30
- self.nextToken()
31
- command['elements'] = json.dumps(elements)
22
+ token = self.nextToken()
23
+ if self.isSymbol():
24
+ symbolRecord = self.getSymbolRecord()
25
+ name = symbolRecord['name']
26
+ if symbolRecord['keyword'] == 'layout':
27
+ elements.append(name)
28
+ command['args'] = name
29
+ else: FatalError(self.compiler.program, f'\'{name}\' is not a layout')
30
+ elif token[0:2] == 'g_':
31
+ command['type'] = token
32
+ command['args'] = self.utils.getArgs(self)
33
+ else: return False
32
34
  if self.nextIs('to'):
33
35
  if self.nextIsSymbol():
34
36
  symbolRecord = self.getSymbolRecord()
@@ -40,14 +42,36 @@ class Graphics(Handler):
40
42
 
41
43
  def r_add(self, command):
42
44
  target = self.getVariable(command['target'])
43
- elements = json.loads(command['elements'])
45
+ type = command['type']
46
+ args = command['args']
44
47
  if not 'layout' in target:
45
48
  target['layout'] = []
46
- for element in elements:
47
- v = self.getVariable(element)
49
+ if args[0] == '{':
50
+ layout = json.loads(self.getRuntimeValue(json.loads(args)))
51
+ default = self.utils.getDefaultArgs(type)
52
+ for n in range(0, len(layout)):
53
+ args = self.utils.decode(default, layout[n])
54
+ target['layout'].append(self.utils.createElement(type, args))
55
+ else:
56
+ v = self.getVariable(args)
48
57
  target['layout'].append(v['layout'])
49
58
  return self.nextPC()
50
59
 
60
+ def k_capture(self, command):
61
+ if self.nextIs('event'):
62
+ if self.nextIs('as'):
63
+ if self.nextIsSymbol():
64
+ record = self.getSymbolRecord()
65
+ command['target'] = record['name']
66
+ self.addCommand(command)
67
+ return True
68
+ return False
69
+
70
+ def r_capture(self, command):
71
+ target = self.getVariable(command['target'])
72
+ self.putSymbolValue(target, self.getConstant(self.eventValues))
73
+ return self.nextPC()
74
+
51
75
  def k_close(self, command):
52
76
  if self.nextIsSymbol():
53
77
  symbolRecord = self.getSymbolRecord()
@@ -79,10 +103,6 @@ class Graphics(Handler):
79
103
  command['layout'] = symbolRecord['name']
80
104
  self.addCommand(command)
81
105
  return True
82
- elif type[0:2] == 'g_':
83
- command['args'] = self.compileConstant(self.utils.getArgs(self))
84
- self.addCommand(command)
85
- return True
86
106
  return False
87
107
 
88
108
  def r_create(self, command):
@@ -96,79 +116,10 @@ class Graphics(Handler):
96
116
  self.mainLoop()
97
117
  self.program.kill()
98
118
  return 0
99
- elif 'iselement' in record:
100
- layout = json.loads(self.getRuntimeValue(command['args']))
101
- args = self.utils.getDefaultArgs(type)
102
- content = json.loads(layout['content'])
103
- for n in range(0, len(content)):
104
- args = self.utils.decode(args, content[n])
105
- element = self.utils.createElement(type, args)
106
- record['layout'] = element
107
- return self.nextPC()
108
119
  else:
109
120
  RuntimeError(self.program, 'Variable is not a window or an element')
110
121
 
111
- def k_g_button(self, command):
112
- command['iselement'] = True
113
- return self.compileVariable(command)
114
-
115
- def r_g_button(self, command):
116
- return self.nextPC()
117
-
118
- def k_g_input(self, command):
119
- command['iselement'] = True
120
- return self.compileVariable(command)
121
-
122
- def r_g_input(self, command):
123
- return self.nextPC()
124
-
125
- def k_g_text(self, command):
126
- command['iselement'] = True
127
- return self.compileVariable(command)
128
-
129
- def r_g_text(self, command):
130
- return self.nextPC()
131
-
132
- def k_init(self, command):
133
- if self.nextIsSymbol():
134
- record = self.getSymbolRecord()
135
- if record['keyword'] == 'layout':
136
- command['target'] = record['name']
137
- if self.peek() == 'with':
138
- self.nextToken()
139
- if self.nextIsSymbol():
140
- record = self.getSymbolRecord()
141
- name = record['name']
142
- if record['iselement']:
143
- command['args'] = name
144
- else: FatalError(self.program.compiler, f'\'{name}\' is not a graphic element')
145
- else:
146
- command['type'] = self.getToken()
147
- command['args'] = self.utils.getArgs(self)
148
- else: command['args'] = None
149
- self.addCommand(command)
150
- return True
151
- return False
152
-
153
- def r_init(self, command):
154
- record = self.getVariable(command['target'])
155
- record['layout'] = []
156
- type = command['type']
157
- args = command['args']
158
- if args != None:
159
- if args[0] == '{':
160
- layout = json.loads(self.getRuntimeValue(json.loads(args)))
161
- args = self.utils.getDefaultArgs(type)
162
- for n in range(0, len(layout)):
163
- args = self.utils.decode(args, layout[n])
164
- record['layout'].append(self.utils.createElement(type, args))
165
- else:
166
- v = self.getVariable(args)
167
- record['layout'].append(v['layout'])
168
- return self.nextPC()
169
-
170
122
  def k_layout(self, command):
171
- command['iselement'] = True
172
123
  return self.compileVariable(command)
173
124
 
174
125
  def r_layout(self, command):
@@ -176,42 +127,8 @@ class Graphics(Handler):
176
127
 
177
128
  def k_on(self, command):
178
129
  token = self.nextToken()
179
- command['type'] = token
180
- if token == 'click':
181
- command['event'] = token
182
- if self.peek() == 'in':
183
- self.nextToken()
184
- if self.nextIs('screen'):
185
- command['target'] = None
186
- elif self.isSymbol():
187
- target = self.getSymbolRecord()
188
- command['target'] = target['name']
189
- else:
190
- FatalError(self.program.compiler, f'{self.getToken()} is not a screen element')
191
- return False
192
- command['goto'] = self.getPC() + 2
193
- self.add(command)
194
- self.nextToken()
195
- pcNext = self.getPC()
196
- cmd = {}
197
- cmd['domain'] = 'core'
198
- cmd['lino'] = command['lino']
199
- cmd['keyword'] = 'gotoPC'
200
- cmd['goto'] = 0
201
- cmd['debug'] = False
202
- self.addCommand(cmd)
203
- self.compileOne()
204
- cmd = {}
205
- cmd['domain'] = 'core'
206
- cmd['lino'] = command['lino']
207
- cmd['keyword'] = 'stop'
208
- cmd['debug'] = False
209
- self.addCommand(cmd)
210
- # Fixup the link
211
- self.getCommandAt(pcNext)['goto'] = self.getPC()
212
- return True
213
- elif token == 'tick':
214
- command['event'] = token
130
+ if token == 'event':
131
+ command['key'] = self.nextValue()
215
132
  command['goto'] = self.getPC() + 2
216
133
  self.add(command)
217
134
  self.nextToken()
@@ -236,17 +153,9 @@ class Graphics(Handler):
236
153
  return False
237
154
 
238
155
  def r_on(self, command):
156
+ key = self.getRuntimeValue(command['key'])
239
157
  pc = command['goto']
240
- if command['type'] == 'click':
241
- event = command['event']
242
- if event == 'click':
243
- target = command['target']
244
- if target == None:
245
- value = 'screen'
246
- else:
247
- widget = self.getVariable(target)
248
- value = widget['value'][widget['index']]
249
- self.renderer.setOnClick(value['content'], lambda: self.run(pc))
158
+ self.eventHandlers[key] = lambda: self.run(pc)
250
159
  return self.nextPC()
251
160
 
252
161
  def k_popup(self, command):
@@ -259,9 +168,37 @@ class Graphics(Handler):
259
168
  return self.nextPC()
260
169
 
261
170
  def k_set(self, command):
262
- return True
171
+ if self.nextIsSymbol():
172
+ record = self.getSymbolRecord()
173
+ keyword = record['keyword']
174
+ if keyword == 'layout':
175
+ command['target'] = record['name']
176
+ if self.peek() == 'to':
177
+ self.nextToken()
178
+ command['type'] = self.nextToken()
179
+ command['args'] = self.utils.getArgs(self)
180
+ else: command['args'] = None
181
+ self.addCommand(command)
182
+ return True
183
+ elif keyword == 'event':
184
+ pass
185
+ return False
263
186
 
264
187
  def r_set(self, command):
188
+ target = self.getVariable(command['target'])
189
+ target['layout'] = []
190
+ type = command['type']
191
+ args = command['args']
192
+ if args != None:
193
+ if args[0] == '{':
194
+ layout = json.loads(self.getRuntimeValue(json.loads(args)))
195
+ default = self.utils.getDefaultArgs(type)
196
+ for n in range(0, len(layout)):
197
+ args = self.utils.decode(default, layout[n])
198
+ target['layout'].append(self.utils.createElement(type, args))
199
+ else:
200
+ v = self.getVariable(args)
201
+ target['layout'].append(v['layout'])
265
202
  return self.nextPC()
266
203
 
267
204
  def k_window(self, command):
@@ -274,19 +211,20 @@ class Graphics(Handler):
274
211
  # Compile a value in this domain
275
212
  def compileValue(self):
276
213
  value = {}
277
- value['domain'] = 'graphics'
214
+ value['domain'] = self.getName()
278
215
  token = self.getToken()
279
216
  if self.isSymbol():
217
+ value['name'] = token
218
+ symbolRecord = self.getSymbolRecord()
219
+ keyword = symbolRecord['keyword']
220
+ if keyword == 'event':
221
+ value['type'] = 'symbol'
222
+ return value
280
223
  return None
281
224
 
282
- if self.tokenIs('the'):
283
- self.nextToken()
284
- token = self.getToken()
285
-
286
225
  value['type'] = token
287
226
 
288
227
  if token == 'test':
289
- name = self.nextToken()
290
228
  value = {}
291
229
  value['type'] = 'text'
292
230
  value['content'] = 'test'
@@ -302,6 +240,13 @@ class Graphics(Handler):
302
240
  #############################################################################
303
241
  # Value handlers
304
242
 
243
+ # This is used by the expression evaluator to get the value of a symbol
244
+ def v_symbol(self, symbolRecord):
245
+ if symbolRecord['keyword'] == 'event':
246
+ return self.getSymbolValue(symbolRecord)
247
+ else:
248
+ return None
249
+
305
250
  def v_test(self, v):
306
251
  return v
307
252
 
@@ -323,4 +268,7 @@ class Graphics(Handler):
323
268
  break
324
269
  if event == '__TIMEOUT__': self.program.flushCB()
325
270
  else:
326
- print(event, values)
271
+ if event in self.eventHandlers:
272
+ self.eventValues = values
273
+ self.eventHandlers[event]()
274
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: easycoder
3
- Version: 250116.1
3
+ Version: 250116.3
4
4
  Summary: Rapid scripting in English
5
5
  Keywords: compiler,scripting,prototyping,programming,coding,python,low code,hypertalk,computer language,learn to code
6
6
  Author-email: Graham Trott <gtanyware@gmail.com>
@@ -22,15 +22,30 @@ Website: [https://easycoder.github.io](https://easycoder.github.io)
22
22
  ## Quick Start
23
23
  Install **_EasyCoder_** in your Python environment:
24
24
  ```
25
- pip install easycoder
25
+ pip install requests pytz easycoder
26
26
  ```
27
- You may also need to install `pytz`, as some commands need it.
28
27
 
29
- Write a test script, 'hello.ecs', containing the following:
28
+ Test the install by typing the command `easycoder`.
29
+ <hr>
30
+ On Linux, this will probably fail as the installer places the executable file in the `$HOME/.local/bin` directory. So give the command
31
+ ```
32
+ export PATH=$HOME/.local/bin:$PATH
33
+ ```
34
+
35
+ To make this change permanent, edit your `.profile` file, adding the following:
36
+ ```
37
+ # set PATH so it includes user's private .local/bin if it exists
38
+ if [ -d "$HOME/.local/bin" ] ; then
39
+ PATH="$HOME/.local/bin:$PATH"
40
+ fi
41
+ ```
42
+ <hr>
43
+
44
+ Now write a test script, 'hello.ecs', containing the following:
30
45
  ```
31
46
  print `Hello, world!`
32
47
  ```
33
- This is traditionally the first program to be written in virtually any language. To run it, use `easycoder hello.ecs`.
48
+ (Note the backticks.) This is traditionally the first program to be written in virtually any language. To run it, use `easycoder hello.ecs`.
34
49
 
35
50
  The output will look like this (the version number will differ):
36
51
  ```
@@ -63,19 +78,18 @@ Here in the repository is a folder called `scripts` containing some sample scrip
63
78
  `benchmark.ecs` allows the performance of **_EasyCoder_** to be compared to other languages if a similar script is written for each one.
64
79
 
65
80
  ## Graphical programmming
66
- **_EasyCoder_** includes a graphical programming environment that is in the early stages of development. A couple of demo scripts are included in the `scripts` directory. To run them, first install the Python `kivy` graphics library if it's not already present on your system. This is done with `pip install kivy`. Then run your **_EasyCoder_** script using `easycoder {scriptname}.ecg`.
67
-
68
- Graphical scripts look much like any other script but their file names must use the extension `.ecg` to signal to **_EasyCoder_** that it needs to load the graphics module. Non-graphical applications can use any extension but `.ecs` is recommended. This allows the **_EasyCoder_** application to be used wherever Python is installed, in either a command-line or a graphical environment, but graphics will of course not be available in the former.
69
-
70
- Some demo graphical scripts are included in the `scripts` directory:
81
+ **_EasyCoder_** includes a graphical programming environment that is in the early stages of development. Some demo scripts will be included in the `scripts` directory; these can be recognised by the extension`.ecg`. To run them, first install `tkinter`. On Linux this is done with
82
+ ```
83
+ sudo apt install python3-tk
84
+ ```
71
85
 
72
- `graphics-demo.ecg` shows some of the elements that can be created, and demonstrates a variety of the graphical features of the language such as detecting when elements are clicked.
86
+ Next, install the Python `pySimpleGUI` graphics library; this is done with `pip install pysimplegui`. Then run your **_EasyCoder_** script using `easycoder {scriptname}.ecg`.
73
87
 
74
- `wave.ecg` is a "Mexican Wave" simulation.
88
+ Graphical scripts look much like any other script but their file names must use the extension `.ecg` to signal to **_EasyCoder_** that it needs to load the graphics module. Non-graphical applications can use any extension but `.ecs` is recommended. This allows the **_EasyCoder_** application to be used wherever Python is installed, in either a command-line or a graphical environment, but graphics will of course not be available in the former.
75
89
 
76
- `keyboard.ecg` creates an on-screen keyboard (currently a 4-function calculator keypad) that responds to clicks on its keys. It uses a plugin module (see below) to add extra vocabulary and syntax to the language. This is currently under development so its features are likely to change. The intention is to support a wide range of keyboard styles with the minimum mount of coding. The plugin (`ec_keyword.py`) can be downloaded from the repository.
90
+ Some demo graphical scripts will included in the `scripts` directory as development proceeds.
77
91
 
78
- **_EasyCoder_** graphics are handled by a library module, `ec_renderer` that can be used outside of the **_EasyCoder_** environment, in other Python programs. The renderer works with JSON-formatted specifications of the itens to be displayed.
92
+ `gtest.ecg` contains sample code to demonstrate and test basic features.
79
93
 
80
94
  ## Significant features
81
95
 
@@ -1,17 +1,17 @@
1
1
  easycoder/README.md,sha256=PYqOc_SkIGiFbyCNs90y7JqoqWe4aO1xYIW-6bOnFKU,573
2
- easycoder/__init__.py,sha256=6tfI5jOPMiZDuD7BsvqLihJFFijWgyIr-EKAapPxT-s,262
2
+ easycoder/__init__.py,sha256=cxPTgZu3SQ4VrP87zrYqBbSfyYN9eFpLgxLd57elEQA,262
3
3
  easycoder/ec_classes.py,sha256=xnWBNak8oKydkFoxHLlq9wo3lIsB3aMnTDrqbtCfoWo,1512
4
- easycoder/ec_compiler.py,sha256=f3zZRtbNsegBuRHTvTLK8BOdnuRq5p_p-1vtJYb-LiY,4800
4
+ easycoder/ec_compiler.py,sha256=dFJEA_uOhD-HeSiAdBzmmA6q3LHThUVoJpSETanmSHs,4800
5
5
  easycoder/ec_condition.py,sha256=WSbONo4zs2sX1icOVpscZDFSCAEFmTsquoc2RGcLx_k,763
6
6
  easycoder/ec_core.py,sha256=yO7d5OyEFHBDGKSaC1Fhf1uGjzsttAl6VCvR1W5X5YE,86279
7
- easycoder/ec_graphics.py,sha256=R1LVI-heohCM_uNwHas8VuTIOdxtT6-RMjhca_B5l4Q,11335
7
+ easycoder/ec_graphics.py,sha256=zM0MDL0ES6WkcU0XizI6VTWp7NcJODMy1fIn7Rj2U4M,9469
8
8
  easycoder/ec_gutils.py,sha256=fqh0VKfm2ry5yjHoOE1ufF7uu741lOU7EEwTUEabJ4k,1624
9
9
  easycoder/ec_handler.py,sha256=IJvxcrJJSR53d6DS_8H5qPHKhp9y5-GV4WXAjhZxu_o,2250
10
10
  easycoder/ec_program.py,sha256=wU-vWRWAYK2Ie4EFnp8HeSPUL0bxz-j9HLQSNplObcc,9919
11
11
  easycoder/ec_timestamp.py,sha256=_3QFJPzIWZ9Rzk3SQOQJ-gwmvB07pg78k23SPntoZtY,288
12
12
  easycoder/ec_value.py,sha256=zgDJTJhIg3yOvmnnKIfccIizmIhGbtvL_ghLTL1T5fg,2516
13
- easycoder-250116.1.dist-info/entry_points.txt,sha256=JXAZbenl0TnsIft2FcGJbJ-4qoztVu2FuT8PFmWFexM,44
14
- easycoder-250116.1.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
15
- easycoder-250116.1.dist-info/WHEEL,sha256=Sgu64hAMa6g5FdzHxXv9Xdse9yxpGGMeagVtPMWpJQY,99
16
- easycoder-250116.1.dist-info/METADATA,sha256=L9ZijU5ykpK7eHLHghThRQcJ_xqxM3BKQfsLn1kcDAo,6426
17
- easycoder-250116.1.dist-info/RECORD,,
13
+ easycoder-250116.3.dist-info/entry_points.txt,sha256=JXAZbenl0TnsIft2FcGJbJ-4qoztVu2FuT8PFmWFexM,44
14
+ easycoder-250116.3.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
15
+ easycoder-250116.3.dist-info/WHEEL,sha256=Sgu64hAMa6g5FdzHxXv9Xdse9yxpGGMeagVtPMWpJQY,99
16
+ easycoder-250116.3.dist-info/METADATA,sha256=f2ymQEg79v-tk57RqjgFFiMeWABBcGRLKv2OTR6iXPE,6162
17
+ easycoder-250116.3.dist-info/RECORD,,