easycoder 241218.1__tar.gz → 241227.1__tar.gz
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-241218.1 → easycoder-241227.1}/PKG-INFO +1 -1
- {easycoder-241218.1 → easycoder-241227.1}/easycoder/__init__.py +2 -2
- easycoder-241227.1/easycoder/ec.py +10 -0
- {easycoder-241218.1 → easycoder-241227.1}/easycoder/ec_classes.py +3 -0
- {easycoder-241218.1 → easycoder-241227.1}/easycoder/ec_compiler.py +7 -6
- {easycoder-241218.1 → easycoder-241227.1}/easycoder/ec_core.py +4 -2
- easycoder-241227.1/easycoder/ec_graphics.py +371 -0
- {easycoder-241218.1 → easycoder-241227.1}/easycoder/ec_handler.py +1 -0
- {easycoder-241218.1 → easycoder-241227.1}/easycoder/ec_program.py +26 -28
- easycoder-241227.1/easycoder/ec_renderer.py +185 -0
- easycoder-241227.1/easycoder/ec_screenspec.py +78 -0
- {easycoder-241218.1 → easycoder-241227.1}/easycoder/ec_value.py +10 -10
- easycoder-241227.1/json/graphics-demo.json +75 -0
- easycoder-241227.1/scripts/graphics-demo.ecg +102 -0
- easycoder-241218.1/easycoder/ec_graphics.py +0 -376
- easycoder-241218.1/easycoder/ec_renderer.py +0 -335
- easycoder-241218.1/json/graphics-demo.json +0 -60
- easycoder-241218.1/scripts/graphics-demo.ecs +0 -71
- {easycoder-241218.1 → easycoder-241227.1}/LICENSE +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/README.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/README.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/add.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/append.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/assert.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/begin.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/clear.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/close.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/create.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/debug.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/decrement.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/delete.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/divide.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/exit.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/file.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/fork.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/get.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/go.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/gosub.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/if.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/import.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/increment.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/index.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/init.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/input.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/multiply.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/open.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/pop.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/post.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/print.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/push.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/put.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/read.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/replace.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/return.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/script.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/set.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/split.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/stack.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/stop.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/system.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/take.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/toggle.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/truncate.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/variable.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/wait.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/while.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/doc/core/write.md +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/easycoder/ec_condition.py +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/easycoder/ec_timestamp.py +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/images/Semoigo Dawn.jpg +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/plugins/ec_p100.py +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/plugins/example.py +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/pyproject.toml +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/scripts/benchmark.ecs +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/scripts/fizzbuzz.ecs +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/scripts/hello.ecs +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/scripts/points.ecs +0 -0
- {easycoder-241218.1 → easycoder-241227.1}/scripts/tests.ecs +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: easycoder
|
|
3
|
-
Version:
|
|
3
|
+
Version: 241227.1
|
|
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>
|
|
@@ -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__ = "
|
|
13
|
+
__version__ = "241227.1"
|
|
@@ -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
|
|
105
|
+
print(f'Warning at line {self.getLino() + 1} from {warning}')
|
|
105
106
|
|
|
106
107
|
def getSymbolRecord(self):
|
|
107
108
|
token = self.getToken()
|
|
@@ -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
|
-
|
|
728
|
-
|
|
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:
|
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
from .ec_classes import FatalError, RuntimeError, Object
|
|
2
|
+
from .ec_handler import Handler
|
|
3
|
+
from .ec_screenspec import ScreenSpec
|
|
4
|
+
from .ec_renderer import Renderer
|
|
5
|
+
|
|
6
|
+
class Graphics(Handler):
|
|
7
|
+
|
|
8
|
+
def __init__(self, compiler):
|
|
9
|
+
Handler.__init__(self, compiler)
|
|
10
|
+
|
|
11
|
+
def getName(self):
|
|
12
|
+
return 'kivy'
|
|
13
|
+
|
|
14
|
+
#############################################################################
|
|
15
|
+
# Keyword handlers
|
|
16
|
+
|
|
17
|
+
def k_attach(self, command):
|
|
18
|
+
if self.nextIsSymbol():
|
|
19
|
+
record = self.getSymbolRecord()
|
|
20
|
+
command['name'] = record['name']
|
|
21
|
+
if self.nextIs('to'):
|
|
22
|
+
value = self.nextValue()
|
|
23
|
+
record['id'] = value
|
|
24
|
+
command['id'] = value
|
|
25
|
+
self.add(command)
|
|
26
|
+
return True
|
|
27
|
+
|
|
28
|
+
def r_attach(self, command):
|
|
29
|
+
targetRecord = self.getVariable(command['name'])
|
|
30
|
+
keyword = targetRecord['keyword']
|
|
31
|
+
id = self.getRuntimeValue(command['id'])
|
|
32
|
+
element = self.ui.getElement(id)
|
|
33
|
+
if element == None:
|
|
34
|
+
FatalError(self.program.compiler, f'There is no screen element with id \'{id}\'')
|
|
35
|
+
return -1
|
|
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})
|
|
39
|
+
return self.nextPC()
|
|
40
|
+
|
|
41
|
+
# close window
|
|
42
|
+
def k_close(self, command):
|
|
43
|
+
if (self.nextIs('window')):
|
|
44
|
+
self.add(command)
|
|
45
|
+
return True
|
|
46
|
+
return False
|
|
47
|
+
|
|
48
|
+
def r_close(self, command):
|
|
49
|
+
self.renderer.stop()
|
|
50
|
+
return 0
|
|
51
|
+
|
|
52
|
+
# create window/ellipse/rectangle//text/image
|
|
53
|
+
def k_create(self, command):
|
|
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)
|
|
66
|
+
while True:
|
|
67
|
+
token = self.peek()
|
|
68
|
+
if token == 'title':
|
|
69
|
+
self.nextToken()
|
|
70
|
+
t = self.nextValue()
|
|
71
|
+
elif token == 'at':
|
|
72
|
+
self.nextToken()
|
|
73
|
+
left = self.nextValue()
|
|
74
|
+
top = self.nextValue()
|
|
75
|
+
elif token == 'size':
|
|
76
|
+
self.nextToken()
|
|
77
|
+
width = self.nextValue()
|
|
78
|
+
height = self.nextValue()
|
|
79
|
+
elif token == 'fill':
|
|
80
|
+
self.nextToken()
|
|
81
|
+
if self.nextIs('color'):
|
|
82
|
+
r = self.nextValue()
|
|
83
|
+
g = self.nextValue()
|
|
84
|
+
b = self.nextValue()
|
|
85
|
+
else:
|
|
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)
|
|
92
|
+
self.add(command)
|
|
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']
|
|
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
|
|
169
|
+
|
|
170
|
+
def r_create(self, 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)
|
|
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
|
|
200
|
+
|
|
201
|
+
def k_ellipse(self, command):
|
|
202
|
+
return self.compileVariable(command)
|
|
203
|
+
|
|
204
|
+
def r_ellipse(self, command):
|
|
205
|
+
return self.nextPC()
|
|
206
|
+
|
|
207
|
+
def k_image(self, command):
|
|
208
|
+
return self.compileVariable(command)
|
|
209
|
+
|
|
210
|
+
def r_image(self, command):
|
|
211
|
+
return self.nextPC()
|
|
212
|
+
|
|
213
|
+
def k_on(self, command):
|
|
214
|
+
token = self.nextToken()
|
|
215
|
+
if token in ['click', 'tap']:
|
|
216
|
+
command['type'] = 'tap'
|
|
217
|
+
if self.nextIsSymbol():
|
|
218
|
+
target = self.getSymbolRecord()
|
|
219
|
+
else:
|
|
220
|
+
FatalError(self.program.compiler, f'{self.getToken()} is not a screen element')
|
|
221
|
+
return False
|
|
222
|
+
command['target'] = target['name']
|
|
223
|
+
command['goto'] = self.getPC() + 2
|
|
224
|
+
self.add(command)
|
|
225
|
+
self.nextToken()
|
|
226
|
+
pcNext = self.getPC()
|
|
227
|
+
cmd = {}
|
|
228
|
+
cmd['domain'] = 'core'
|
|
229
|
+
cmd['lino'] = command['lino']
|
|
230
|
+
cmd['keyword'] = 'gotoPC'
|
|
231
|
+
cmd['goto'] = 0
|
|
232
|
+
cmd['debug'] = False
|
|
233
|
+
self.addCommand(cmd)
|
|
234
|
+
self.compileOne()
|
|
235
|
+
cmd = {}
|
|
236
|
+
cmd['domain'] = 'core'
|
|
237
|
+
cmd['lino'] = command['lino']
|
|
238
|
+
cmd['keyword'] = 'stop'
|
|
239
|
+
cmd['debug'] = False
|
|
240
|
+
self.addCommand(cmd)
|
|
241
|
+
# Fixup the link
|
|
242
|
+
self.getCommandAt(pcNext)['goto'] = self.getPC()
|
|
243
|
+
return True
|
|
244
|
+
return False
|
|
245
|
+
|
|
246
|
+
def r_on(self, command):
|
|
247
|
+
pc = command['goto']
|
|
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')
|
|
256
|
+
return self.nextPC()
|
|
257
|
+
|
|
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()
|
|
269
|
+
self.add(command)
|
|
270
|
+
return True
|
|
271
|
+
elif token == 'by':
|
|
272
|
+
command['keyword'] = 'moveBy'
|
|
273
|
+
command['dx'] = self.nextValue()
|
|
274
|
+
command['dy'] = self.nextValue()
|
|
275
|
+
self.add(command)
|
|
276
|
+
return True
|
|
277
|
+
return False
|
|
278
|
+
|
|
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)
|
|
282
|
+
return self.nextPC()
|
|
283
|
+
|
|
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)
|
|
287
|
+
return self.nextPC()
|
|
288
|
+
|
|
289
|
+
def k_rectangle(self, command):
|
|
290
|
+
return self.compileVariable(command)
|
|
291
|
+
|
|
292
|
+
def r_rectangle(self, command):
|
|
293
|
+
return self.nextPC()
|
|
294
|
+
|
|
295
|
+
def k_text(self, command):
|
|
296
|
+
return self.compileVariable(command)
|
|
297
|
+
|
|
298
|
+
def r_text(self, command):
|
|
299
|
+
return self.nextPC()
|
|
300
|
+
|
|
301
|
+
# render {spec}
|
|
302
|
+
def k_render(self, command):
|
|
303
|
+
command['spec'] = self.nextValue()
|
|
304
|
+
self.add(command)
|
|
305
|
+
return True
|
|
306
|
+
|
|
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()
|
|
325
|
+
|
|
326
|
+
#############################################################################
|
|
327
|
+
# Modify a value or leave it unchanged.
|
|
328
|
+
def modifyValue(self, value):
|
|
329
|
+
return value
|
|
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
|
+
|
|
348
|
+
#############################################################################
|
|
349
|
+
# Value handlers
|
|
350
|
+
|
|
351
|
+
def v_attribute(self, v):
|
|
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)
|
|
363
|
+
|
|
364
|
+
#############################################################################
|
|
365
|
+
# Compile a condition
|
|
366
|
+
def compileCondition(self):
|
|
367
|
+
condition = {}
|
|
368
|
+
return condition
|
|
369
|
+
|
|
370
|
+
#############################################################################
|
|
371
|
+
# Condition handlers
|
|
@@ -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
|
|
@@ -11,23 +11,18 @@ class Program:
|
|
|
11
11
|
|
|
12
12
|
def __init__(self, argv):
|
|
13
13
|
print(f'EasyCoder version {version("easycoder")}')
|
|
14
|
-
scriptName = None
|
|
15
14
|
if len(argv) == 0:
|
|
16
15
|
print('No script supplied')
|
|
17
16
|
exit()
|
|
18
17
|
self.classes=[Core]
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
self.classes.append(Graphics)
|
|
24
|
-
else:
|
|
25
|
-
scriptName = arg
|
|
18
|
+
scriptName = argv[0]
|
|
19
|
+
if scriptName.endswith('.ecg'):
|
|
20
|
+
from .ec_graphics import Graphics
|
|
21
|
+
self.classes.append(Graphics)
|
|
26
22
|
|
|
27
23
|
f = open(scriptName, 'r')
|
|
28
24
|
source = f.read()
|
|
29
25
|
f.close()
|
|
30
|
-
self.argv = argv
|
|
31
26
|
self.domains = []
|
|
32
27
|
self.domainIndex = {}
|
|
33
28
|
self.name = '<anon>'
|
|
@@ -43,6 +38,8 @@ class Program:
|
|
|
43
38
|
self.condition = self.compiler.condition
|
|
44
39
|
self.processClasses()
|
|
45
40
|
self.queue = deque()
|
|
41
|
+
self.externalControl = False
|
|
42
|
+
self.quit = False
|
|
46
43
|
|
|
47
44
|
def start(self):
|
|
48
45
|
startCompile = time.time()
|
|
@@ -242,18 +239,17 @@ class Program:
|
|
|
242
239
|
index += 1
|
|
243
240
|
lino += 1
|
|
244
241
|
return
|
|
242
|
+
|
|
243
|
+
def finish(self):
|
|
244
|
+
self.quit = True
|
|
245
245
|
|
|
246
|
-
#
|
|
247
|
-
def
|
|
248
|
-
# print(f'Run from {pc}')
|
|
249
|
-
length = len(self.queue)
|
|
250
|
-
self.queue.append(pc)
|
|
251
|
-
if length > 0:
|
|
252
|
-
return
|
|
253
|
-
|
|
246
|
+
# Flush the queue
|
|
247
|
+
def flush(self):
|
|
254
248
|
while len(self.queue):
|
|
255
249
|
self.pc = self.queue.popleft()
|
|
256
250
|
while True:
|
|
251
|
+
if self.quit:
|
|
252
|
+
return
|
|
257
253
|
command = self.code[self.pc]
|
|
258
254
|
domainName = command['domain']
|
|
259
255
|
if domainName == None:
|
|
@@ -272,11 +268,20 @@ class Program:
|
|
|
272
268
|
self.pc = handler(command)
|
|
273
269
|
try:
|
|
274
270
|
if self.pc == 0 or self.pc >= len(self.code):
|
|
275
|
-
|
|
271
|
+
break
|
|
276
272
|
except:
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
273
|
+
break
|
|
274
|
+
|
|
275
|
+
def setExternalControl(self):
|
|
276
|
+
self.externalControl = True
|
|
277
|
+
|
|
278
|
+
# Run the script
|
|
279
|
+
def run(self, pc):
|
|
280
|
+
length = len(self.queue)
|
|
281
|
+
self.queue.append(pc)
|
|
282
|
+
if not self.externalControl:
|
|
283
|
+
if length == 0:
|
|
284
|
+
return self.flush()
|
|
280
285
|
|
|
281
286
|
def nonNumericValueError(self):
|
|
282
287
|
FatalError(self.compiler, 'Non-numeric value')
|
|
@@ -322,10 +327,3 @@ class Program:
|
|
|
322
327
|
if v1 < v2:
|
|
323
328
|
return -1
|
|
324
329
|
return 0
|
|
325
|
-
|
|
326
|
-
# This is the program launcher
|
|
327
|
-
def Main():
|
|
328
|
-
if (len(sys.argv) > 1):
|
|
329
|
-
Program(sys.argv[1:]).start()
|
|
330
|
-
else:
|
|
331
|
-
print('Syntax: easycoder <scriptname> [plugins]')
|