easycoder 5__py2.py3-none-any.whl → 241211.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 +1 -1
- easycoder/ec_compiler.py +2 -4
- easycoder/ec_condition.py +2 -2
- easycoder/ec_core.py +68 -26
- easycoder/ec_program.py +30 -18
- easycoder/ec_value.py +2 -3
- easycoder-241211.1.dist-info/METADATA +71 -0
- easycoder-241211.1.dist-info/RECORD +14 -0
- easycoder-5.dist-info/METADATA +0 -79
- easycoder-5.dist-info/RECORD +0 -14
- {easycoder-5.dist-info → easycoder-241211.1.dist-info}/LICENSE +0 -0
- {easycoder-5.dist-info → easycoder-241211.1.dist-info}/WHEEL +0 -0
- {easycoder-5.dist-info → easycoder-241211.1.dist-info}/entry_points.txt +0 -0
easycoder/__init__.py
CHANGED
easycoder/ec_compiler.py
CHANGED
|
@@ -6,7 +6,6 @@ class Compiler:
|
|
|
6
6
|
|
|
7
7
|
def __init__(self, program):
|
|
8
8
|
self.program = program
|
|
9
|
-
self.domains = self.program.domains
|
|
10
9
|
self.value = Value(self)
|
|
11
10
|
self.condition = Condition(self)
|
|
12
11
|
self.marker = 0
|
|
@@ -142,11 +141,11 @@ class Compiler:
|
|
|
142
141
|
# Compile the current token
|
|
143
142
|
def compileToken(self):
|
|
144
143
|
token = self.getToken()
|
|
145
|
-
|
|
144
|
+
# print(f'Compile {token}')
|
|
146
145
|
if not token:
|
|
147
146
|
return False
|
|
148
147
|
mark = self.getIndex()
|
|
149
|
-
for domain in self.
|
|
148
|
+
for domain in self.program.getDomains():
|
|
150
149
|
handler = domain.keywordHandler(token)
|
|
151
150
|
if handler:
|
|
152
151
|
command = {}
|
|
@@ -163,7 +162,6 @@ class Compiler:
|
|
|
163
162
|
else:
|
|
164
163
|
self.rewindTo(mark)
|
|
165
164
|
FatalError(self, f'No handler found for "{token}"')
|
|
166
|
-
return False
|
|
167
165
|
|
|
168
166
|
# Compile a single command
|
|
169
167
|
def compileOne(self):
|
easycoder/ec_condition.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
class Condition:
|
|
2
2
|
|
|
3
3
|
def __init__(self, compiler):
|
|
4
|
-
self.
|
|
4
|
+
self.compiler = compiler
|
|
5
5
|
self.getToken = compiler.getToken
|
|
6
6
|
self.nextToken = compiler.nextToken
|
|
7
7
|
self.peek = compiler.peek
|
|
@@ -12,7 +12,7 @@ class Condition:
|
|
|
12
12
|
|
|
13
13
|
def compileCondition(self):
|
|
14
14
|
mark = self.getIndex()
|
|
15
|
-
for domain in self.
|
|
15
|
+
for domain in self.compiler.program.getDomains():
|
|
16
16
|
condition = domain.compileCondition()
|
|
17
17
|
if condition != None:
|
|
18
18
|
condition.domain= domain.getName()
|
easycoder/ec_core.py
CHANGED
|
@@ -18,6 +18,7 @@ class Core(Handler):
|
|
|
18
18
|
# Keyword handlers
|
|
19
19
|
|
|
20
20
|
# Arithmetic add
|
|
21
|
+
# add {value} to {variable}[ giving {variable}]}
|
|
21
22
|
def k_add(self, command):
|
|
22
23
|
# Get the (first) value
|
|
23
24
|
command['value1'] = self.nextValue()
|
|
@@ -79,6 +80,7 @@ class Core(Handler):
|
|
|
79
80
|
return self.nextPC()
|
|
80
81
|
|
|
81
82
|
# Append a value to an array
|
|
83
|
+
# append {value} to {array}
|
|
82
84
|
def k_append(self, command):
|
|
83
85
|
command['value'] = self.nextValue()
|
|
84
86
|
if self.nextIs('to'):
|
|
@@ -111,8 +113,14 @@ class Core(Handler):
|
|
|
111
113
|
return self.nextPC()
|
|
112
114
|
|
|
113
115
|
# Assertion
|
|
116
|
+
#assert {condition} [with {message}]
|
|
114
117
|
def k_assert(self, command):
|
|
115
118
|
command['test'] = self.nextCondition()
|
|
119
|
+
if self.peek() == 'with':
|
|
120
|
+
self.nextToken()
|
|
121
|
+
command['with'] = self.nextValue()
|
|
122
|
+
else:
|
|
123
|
+
command['with'] = None
|
|
116
124
|
self.addCommand(command)
|
|
117
125
|
return True
|
|
118
126
|
|
|
@@ -120,7 +128,7 @@ class Core(Handler):
|
|
|
120
128
|
test = self.program.condition.testCondition(command['test'])
|
|
121
129
|
if test:
|
|
122
130
|
return self.nextPC()
|
|
123
|
-
AssertionError(self.program)
|
|
131
|
+
AssertionError(self.program, self.getRuntimeValue(command['with']))
|
|
124
132
|
|
|
125
133
|
# Begin a block
|
|
126
134
|
def k_begin(self, command):
|
|
@@ -136,6 +144,7 @@ class Core(Handler):
|
|
|
136
144
|
return self.compileFromHere(['end'])
|
|
137
145
|
|
|
138
146
|
# Clear (set False)
|
|
147
|
+
# clear {variable}
|
|
139
148
|
def k_clear(self, command):
|
|
140
149
|
if self.nextIsSymbol():
|
|
141
150
|
target = self.getSymbolRecord()
|
|
@@ -155,6 +164,7 @@ class Core(Handler):
|
|
|
155
164
|
return self.nextPC()
|
|
156
165
|
|
|
157
166
|
# Close a file
|
|
167
|
+
# close {file}
|
|
158
168
|
def k_close(self, command):
|
|
159
169
|
if self.nextIsSymbol():
|
|
160
170
|
fileRecord = self.getSymbolRecord()
|
|
@@ -170,6 +180,7 @@ class Core(Handler):
|
|
|
170
180
|
return self.nextPC()
|
|
171
181
|
|
|
172
182
|
#Create directory
|
|
183
|
+
# create directory {name}
|
|
173
184
|
def k_create(self, command):
|
|
174
185
|
if self.nextIs('directory'):
|
|
175
186
|
command['item'] = 'directory'
|
|
@@ -229,6 +240,7 @@ class Core(Handler):
|
|
|
229
240
|
return self.nextPC()
|
|
230
241
|
|
|
231
242
|
# Decrement a variable
|
|
243
|
+
# decrement {variable}
|
|
232
244
|
def k_decrement(self, command):
|
|
233
245
|
if self.nextIsSymbol():
|
|
234
246
|
symbolRecord = self.getSymbolRecord()
|
|
@@ -243,6 +255,8 @@ class Core(Handler):
|
|
|
243
255
|
return self.incdec(command, '-')
|
|
244
256
|
|
|
245
257
|
# Delete a file or a property
|
|
258
|
+
# delete {filename}
|
|
259
|
+
# delete property {value} of {variable}
|
|
246
260
|
def k_delete(self, command):
|
|
247
261
|
token = self.nextToken( )
|
|
248
262
|
if token == 'file':
|
|
@@ -281,6 +295,7 @@ class Core(Handler):
|
|
|
281
295
|
return self.nextPC()
|
|
282
296
|
|
|
283
297
|
# Arithmetic division
|
|
298
|
+
# divide {variable} by {value}[ giving {variable}]}
|
|
284
299
|
def k_divide(self, command):
|
|
285
300
|
# Get the (first) value
|
|
286
301
|
command['value1'] = self.nextValue()
|
|
@@ -381,6 +396,7 @@ class Core(Handler):
|
|
|
381
396
|
return next
|
|
382
397
|
|
|
383
398
|
# Issue a REST GET request
|
|
399
|
+
# get {variable) from {url} [or {command}]
|
|
384
400
|
def k_get(self, command):
|
|
385
401
|
if self.nextIsSymbol():
|
|
386
402
|
symbolRecord = self.getSymbolRecord()
|
|
@@ -490,7 +506,7 @@ class Core(Handler):
|
|
|
490
506
|
def r_gotoPC(self, command):
|
|
491
507
|
return command['goto']
|
|
492
508
|
|
|
493
|
-
#
|
|
509
|
+
# if <condition> <action> [else <action>]
|
|
494
510
|
def k_if(self, command):
|
|
495
511
|
command['condition'] = self.nextCondition()
|
|
496
512
|
self.addCommand(command)
|
|
@@ -536,6 +552,16 @@ class Core(Handler):
|
|
|
536
552
|
self.program.pc += 1
|
|
537
553
|
return self.program.pc
|
|
538
554
|
|
|
555
|
+
# Import a plugin. This is done at compile time.
|
|
556
|
+
# import {class} from {source}
|
|
557
|
+
def k_import(self, command):
|
|
558
|
+
clazz = self.nextToken()
|
|
559
|
+
if self.nextIs('from'):
|
|
560
|
+
source = self.nextToken()
|
|
561
|
+
self.program.importPlugin(f'{source}:{clazz}')
|
|
562
|
+
return True
|
|
563
|
+
return False
|
|
564
|
+
|
|
539
565
|
# Increment a variable
|
|
540
566
|
def k_increment(self, command):
|
|
541
567
|
if self.nextIsSymbol():
|
|
@@ -551,6 +577,7 @@ class Core(Handler):
|
|
|
551
577
|
return self.incdec(command, '+')
|
|
552
578
|
|
|
553
579
|
# Index to a specified element in a variable
|
|
580
|
+
# index {variable} to {value}
|
|
554
581
|
def k_index(self, command):
|
|
555
582
|
# get the variable
|
|
556
583
|
if self.nextIsSymbol():
|
|
@@ -567,7 +594,31 @@ class Core(Handler):
|
|
|
567
594
|
symbolRecord['index'] = self.getRuntimeValue(command['value'])
|
|
568
595
|
return self.nextPC()
|
|
569
596
|
|
|
597
|
+
# Initialise a stack, array or object
|
|
598
|
+
def k_init(self, command):
|
|
599
|
+
# get the variable
|
|
600
|
+
if self.nextIsSymbol():
|
|
601
|
+
symbolRecord = self.getSymbolRecord()
|
|
602
|
+
keyword = symbolRecord['keyword']
|
|
603
|
+
if keyword in ['stack','array', 'object']:
|
|
604
|
+
command['keyword'] = keyword
|
|
605
|
+
command['target'] = symbolRecord['name']
|
|
606
|
+
return True
|
|
607
|
+
return False
|
|
608
|
+
|
|
609
|
+
def r_init(self, command):
|
|
610
|
+
symbolRecord = self.getVariable(command['target'])
|
|
611
|
+
keyword = command['keyword']
|
|
612
|
+
if keyword in ['stack', 'array']:
|
|
613
|
+
self.putSymbolValue(symbolRecord, json.loads('[]'))
|
|
614
|
+
elif keyword == 'object':
|
|
615
|
+
self.putSymbolValue(symbolRecord, json.loads('{}'))
|
|
616
|
+
else:
|
|
617
|
+
RuntimeError(self.program, f"Inappropriate variable type '{keyword}'")
|
|
618
|
+
return self.nextPC()
|
|
619
|
+
|
|
570
620
|
# Inout a value from the terminal
|
|
621
|
+
# input {variable} [with {prompt}]
|
|
571
622
|
def k_input(self, command):
|
|
572
623
|
# get the variable
|
|
573
624
|
if self.nextIsSymbol():
|
|
@@ -594,30 +645,8 @@ class Core(Handler):
|
|
|
594
645
|
self.putSymbolValue(symbolRecord, value)
|
|
595
646
|
return self.nextPC()
|
|
596
647
|
|
|
597
|
-
# Initialise a stack, array or object
|
|
598
|
-
def k_init(self, command):
|
|
599
|
-
# get the variable
|
|
600
|
-
if self.nextIsSymbol():
|
|
601
|
-
symbolRecord = self.getSymbolRecord()
|
|
602
|
-
keyword = symbolRecord['keyword']
|
|
603
|
-
if keyword in ['stack','array', 'object']:
|
|
604
|
-
command['keyword'] = keyword
|
|
605
|
-
command['target'] = symbolRecord['name']
|
|
606
|
-
return True
|
|
607
|
-
return False
|
|
608
|
-
|
|
609
|
-
def r_init(self, command):
|
|
610
|
-
symbolRecord = self.getVariable(command['target'])
|
|
611
|
-
keyword = command['keyword']
|
|
612
|
-
if keyword in ['stack', 'array']:
|
|
613
|
-
self.putSymbolValue(symbolRecord, json.loads('[]'))
|
|
614
|
-
elif keyword == 'object':
|
|
615
|
-
self.putSymbolValue(symbolRecord, json.loads('{}'))
|
|
616
|
-
else:
|
|
617
|
-
RuntimeError(self.program, f"Inappropriate variable type '{keyword}'")
|
|
618
|
-
return self.nextPC()
|
|
619
|
-
|
|
620
648
|
# Arithmetic multiply
|
|
649
|
+
# multiply {variable} by {value}[ giving {variable}]}
|
|
621
650
|
def k_multiply(self, command):
|
|
622
651
|
# Get the (first) value
|
|
623
652
|
command['value1'] = self.nextValue()
|
|
@@ -675,6 +704,7 @@ class Core(Handler):
|
|
|
675
704
|
return self.nextPC()
|
|
676
705
|
|
|
677
706
|
# Open a file
|
|
707
|
+
# open {file} for reading/writing/appending
|
|
678
708
|
def k_open(self, command):
|
|
679
709
|
if self.nextIsSymbol():
|
|
680
710
|
symbolRecord = self.getSymbolRecord()
|
|
@@ -711,6 +741,7 @@ class Core(Handler):
|
|
|
711
741
|
RuntimeError(self.program, f"File {path} does not exist")
|
|
712
742
|
|
|
713
743
|
# Pop a value from a stack
|
|
744
|
+
# pop {variable} from {stack}
|
|
714
745
|
def k_pop(self, command):
|
|
715
746
|
if (self.nextIsSymbol()):
|
|
716
747
|
symbolRecord = self.getSymbolRecord()
|
|
@@ -738,6 +769,7 @@ class Core(Handler):
|
|
|
738
769
|
return self.nextPC()
|
|
739
770
|
|
|
740
771
|
# Perform an HTTP POST
|
|
772
|
+
# post {value} to {url} [giving {variable}] [or {command}]
|
|
741
773
|
def k_post(self, command):
|
|
742
774
|
if self.nextIs('to'):
|
|
743
775
|
command['value'] = self.getConstant('')
|
|
@@ -825,6 +857,7 @@ class Core(Handler):
|
|
|
825
857
|
return self.nextPC()
|
|
826
858
|
|
|
827
859
|
# Push a value onto a stack
|
|
860
|
+
# push {value} to/onto {stack}
|
|
828
861
|
def k_push(self, command):
|
|
829
862
|
value = self.nextValue()
|
|
830
863
|
command['value'] = value
|
|
@@ -853,6 +886,7 @@ class Core(Handler):
|
|
|
853
886
|
return self.nextPC()
|
|
854
887
|
|
|
855
888
|
# Put a value into a variable
|
|
889
|
+
# put {value} into {variable}
|
|
856
890
|
def k_put(self, command):
|
|
857
891
|
command['value'] = self.nextValue()
|
|
858
892
|
if self.nextIs('into'):
|
|
@@ -880,6 +914,7 @@ class Core(Handler):
|
|
|
880
914
|
return self.nextPC()
|
|
881
915
|
|
|
882
916
|
# Read from a file
|
|
917
|
+
# read {variable} from {file}
|
|
883
918
|
def k_read(self, command):
|
|
884
919
|
if self.peek() == 'line':
|
|
885
920
|
self.nextToken()
|
|
@@ -918,6 +953,7 @@ class Core(Handler):
|
|
|
918
953
|
return self.nextPC()
|
|
919
954
|
|
|
920
955
|
# Replace a substring
|
|
956
|
+
#replace {value} with {value} in {variable}
|
|
921
957
|
def k_replace(self, command):
|
|
922
958
|
original = self.nextValue()
|
|
923
959
|
if self.peek() == 'with':
|
|
@@ -960,6 +996,9 @@ class Core(Handler):
|
|
|
960
996
|
return True
|
|
961
997
|
|
|
962
998
|
# Set a value
|
|
999
|
+
# set {variable}
|
|
1000
|
+
# set the elements of {variable} to {value}
|
|
1001
|
+
# set element/property of {variable} to {value}
|
|
963
1002
|
def k_set(self, command):
|
|
964
1003
|
if self.nextIsSymbol():
|
|
965
1004
|
target = self.getSymbolRecord()
|
|
@@ -1074,6 +1113,7 @@ class Core(Handler):
|
|
|
1074
1113
|
return self.nextPC()
|
|
1075
1114
|
|
|
1076
1115
|
# Split a string into a variable with several elements
|
|
1116
|
+
# split {variable} on {value}
|
|
1077
1117
|
def k_split(self, command):
|
|
1078
1118
|
if self.nextIsSymbol():
|
|
1079
1119
|
symbolRecord = self.getSymbolRecord()
|
|
@@ -1128,6 +1168,7 @@ class Core(Handler):
|
|
|
1128
1168
|
return 0
|
|
1129
1169
|
|
|
1130
1170
|
# Issue a system call
|
|
1171
|
+
# system {command}
|
|
1131
1172
|
def k_system(self, command):
|
|
1132
1173
|
background = False
|
|
1133
1174
|
token = self.nextToken()
|
|
@@ -1154,6 +1195,7 @@ class Core(Handler):
|
|
|
1154
1195
|
return self.nextPC()
|
|
1155
1196
|
|
|
1156
1197
|
# Arithmetic subtraction
|
|
1198
|
+
# take {value} from {variable}[ giving {variable}]}
|
|
1157
1199
|
def k_take(self, command):
|
|
1158
1200
|
# Get the (first) value
|
|
1159
1201
|
command['value1'] = self.nextValue()
|
|
@@ -1281,7 +1323,7 @@ class Core(Handler):
|
|
|
1281
1323
|
threading.Timer(value/1000.0, lambda: (self.run(next))).start()
|
|
1282
1324
|
return 0
|
|
1283
1325
|
|
|
1284
|
-
#
|
|
1326
|
+
# while <condition> <action>
|
|
1285
1327
|
def k_while(self, command):
|
|
1286
1328
|
code = self.nextCondition()
|
|
1287
1329
|
if code == None:
|
easycoder/ec_program.py
CHANGED
|
@@ -12,21 +12,8 @@ class Program:
|
|
|
12
12
|
def __init__(self, argv):
|
|
13
13
|
print(f'EasyCoder version {version("easycoder")}')
|
|
14
14
|
scriptName = None
|
|
15
|
-
domains=[Core]
|
|
16
15
|
if len(argv)>0:
|
|
17
16
|
scriptName = argv[0]
|
|
18
|
-
# Process any extra modules needed
|
|
19
|
-
for n in range(1, len(argv)):
|
|
20
|
-
args=argv[n].split(':')
|
|
21
|
-
idx=args[0].rfind('/')
|
|
22
|
-
if idx<0:
|
|
23
|
-
modue=args[0]
|
|
24
|
-
else:
|
|
25
|
-
sys.path.append(args[0][0:idx])
|
|
26
|
-
module=args[0][idx+1:]
|
|
27
|
-
module = importlib.import_module(module.replace('/','.').replace('.py',''))
|
|
28
|
-
myClass = getattr(module, args[1])
|
|
29
|
-
domains.append(myClass)
|
|
30
17
|
else:
|
|
31
18
|
print('No script supplied')
|
|
32
19
|
exit();
|
|
@@ -36,6 +23,7 @@ class Program:
|
|
|
36
23
|
source = f.read()
|
|
37
24
|
f.close()
|
|
38
25
|
self.argv = argv
|
|
26
|
+
self.classes=[Core]
|
|
39
27
|
self.domains = []
|
|
40
28
|
self.domainIndex = {}
|
|
41
29
|
self.name = '<anon>'
|
|
@@ -44,15 +32,12 @@ class Program:
|
|
|
44
32
|
self.onError = 0
|
|
45
33
|
self.pc = 0
|
|
46
34
|
self.debugStep = False
|
|
47
|
-
self.script = Script(source)
|
|
48
35
|
self.stack = []
|
|
36
|
+
self.script = Script(source)
|
|
49
37
|
self.compiler = Compiler(self)
|
|
50
38
|
self.value = self.compiler.value
|
|
51
39
|
self.condition = self.compiler.condition
|
|
52
|
-
|
|
53
|
-
handler = domain(self.compiler)
|
|
54
|
-
self.domains.append(handler)
|
|
55
|
-
self.domainIndex[handler.getName()] = handler
|
|
40
|
+
self.processClasses()
|
|
56
41
|
self.queue = deque()
|
|
57
42
|
|
|
58
43
|
startCompile = time.time()
|
|
@@ -74,6 +59,33 @@ class Program:
|
|
|
74
59
|
self.compiler.showWarnings()
|
|
75
60
|
return
|
|
76
61
|
|
|
62
|
+
# Import a plugin
|
|
63
|
+
def importPlugin(self, source):
|
|
64
|
+
args=source.split(':')
|
|
65
|
+
idx=args[0].rfind('/')
|
|
66
|
+
if idx<0:
|
|
67
|
+
module=args[0]
|
|
68
|
+
else:
|
|
69
|
+
sys.path.append(args[0][1:idx])
|
|
70
|
+
module=args[0][idx+1:len(args[0])-1]
|
|
71
|
+
module = module.replace('/','.').replace('.py','')
|
|
72
|
+
module = importlib.import_module(module)
|
|
73
|
+
plugin = getattr(module, args[1][1:len(args[1])-1])
|
|
74
|
+
self.classes.append(plugin)
|
|
75
|
+
self.processClasses()
|
|
76
|
+
|
|
77
|
+
# Process the class list to get the domains
|
|
78
|
+
def processClasses(self):
|
|
79
|
+
self.domains=[]
|
|
80
|
+
for clazz in self.classes:
|
|
81
|
+
handler = clazz(self.compiler)
|
|
82
|
+
self.domains.append(handler)
|
|
83
|
+
self.domainIndex[handler.getName()] = handler
|
|
84
|
+
|
|
85
|
+
# Get the domain list
|
|
86
|
+
def getDomains(self):
|
|
87
|
+
return self.domains
|
|
88
|
+
|
|
77
89
|
# Add a command to the code list
|
|
78
90
|
def add(self, command):
|
|
79
91
|
self.code.append(command)
|
easycoder/ec_value.py
CHANGED
|
@@ -4,7 +4,6 @@ class Value:
|
|
|
4
4
|
|
|
5
5
|
def __init__(self, compiler):
|
|
6
6
|
self.compiler = compiler
|
|
7
|
-
self.domains = compiler.domains
|
|
8
7
|
self.getToken = compiler.getToken
|
|
9
8
|
self.nextToken = compiler.nextToken
|
|
10
9
|
self.peek = compiler.peek
|
|
@@ -47,7 +46,7 @@ class Value:
|
|
|
47
46
|
|
|
48
47
|
# See if any of the domains can handle it
|
|
49
48
|
mark = self.compiler.getIndex()
|
|
50
|
-
for domain in self.
|
|
49
|
+
for domain in self.compiler.program.getDomains():
|
|
51
50
|
item = domain.compileValue()
|
|
52
51
|
if item != None:
|
|
53
52
|
return item
|
|
@@ -77,7 +76,7 @@ class Value:
|
|
|
77
76
|
value = item
|
|
78
77
|
|
|
79
78
|
# See if any domain has something to add to the value
|
|
80
|
-
for domain in self.
|
|
79
|
+
for domain in self.compiler.program.getDomains():
|
|
81
80
|
value = domain.modifyValue(value)
|
|
82
81
|
|
|
83
82
|
return value
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: easycoder
|
|
3
|
+
Version: 241211.1
|
|
4
|
+
Summary: EasyCoder for Python
|
|
5
|
+
Author-email: Graham Trott <gtanyware@gmail.com>
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
8
|
+
Requires-Dist: pytz
|
|
9
|
+
Project-URL: Home, https://github.com/easycoder
|
|
10
|
+
|
|
11
|
+
# Introduction
|
|
12
|
+
This is the Python version of **_EasyCoder_**, a high-level English-like scripting language suited for prototyping and rapid testing of ideas. It operates on the command line.
|
|
13
|
+
|
|
14
|
+
The JavaScript version of **_EasyCoder_**, which provides a full set of graphical features to run in a browser, is at
|
|
15
|
+
|
|
16
|
+
Repository: [https://github.com/easycoder/easycoder.github.io](https://github.com/easycoder/easycoder.github.io)
|
|
17
|
+
Website: [https://easycoder.github.io](https://easycoder.github.io)
|
|
18
|
+
|
|
19
|
+
## Quick Start
|
|
20
|
+
Install **_EasyCoder_** in your Python environment:
|
|
21
|
+
```
|
|
22
|
+
pip install easycoder
|
|
23
|
+
```
|
|
24
|
+
Write a test script, 'hello.ecs', containing the following:
|
|
25
|
+
```
|
|
26
|
+
print `Hello, world!`
|
|
27
|
+
```
|
|
28
|
+
This is traditionally the first program to be written in virtually any language. To run it, use `easycoder hello.ecs`.
|
|
29
|
+
|
|
30
|
+
The output will look like this:
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
EasyCoder version 5
|
|
34
|
+
Compiled <anon>: 1 lines (2 tokens) in 0 ms
|
|
35
|
+
Run <anon>
|
|
36
|
+
1-> Hello, world!
|
|
37
|
+
```
|
|
38
|
+
It's conventional to add a program title to a script:
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
! Test script
|
|
42
|
+
script Test
|
|
43
|
+
print `Hello, world!`
|
|
44
|
+
```
|
|
45
|
+
The first line here is just a comment and has no effect on the running of the script. The second line gives the script a name, which is useful in debugging as it says which script was running. When run, the output is now
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
EasyCoder version 5
|
|
49
|
+
Compiled Test: 5 lines (4 tokens) in 0 ms
|
|
50
|
+
Run Test
|
|
51
|
+
5-> Hello, world!
|
|
52
|
+
```
|
|
53
|
+
As you can guess from the above, the print command gives the line in the script it was called from. This is very useful in tracking down debugging print commands in large scripts.
|
|
54
|
+
|
|
55
|
+
Here in the repository is a folder called `scripts` containing some sample scripts:
|
|
56
|
+
|
|
57
|
+
`benchmark.ecs` allows the performance of EasyCoder to be compared to other languages if a similar program is written for each one
|
|
58
|
+
`tests.ecs` is a test program containing many of the EasyCoder features
|
|
59
|
+
`fizzbuzz.ecs` is a simple programming challenge often given at job interviews
|
|
60
|
+
|
|
61
|
+
## The EasyCoder programming language
|
|
62
|
+
There are three primary components to the language:
|
|
63
|
+
|
|
64
|
+
- Keywords
|
|
65
|
+
- Values
|
|
66
|
+
- Conditions
|
|
67
|
+
|
|
68
|
+
The language comprises a general-purpose core package, which can be enhanced by plugins to provide special features on demand.
|
|
69
|
+
|
|
70
|
+
[The core package](doc/core.md)
|
|
71
|
+
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
easycoder/__init__.py,sha256=eOqNGCU4g6MwlxDersMEb_FgzxfIYAg7EK3zmX6ZTjs,262
|
|
2
|
+
easycoder/ec_classes.py,sha256=onBKF6Lj8BZKNuJKacx4HyhOrVLXsoHdzl6RnMf77uM,1413
|
|
3
|
+
easycoder/ec_compiler.py,sha256=1z5U92uzUdCOO5-k0VXLnU581iAhwzQga04kfdTlpMY,4629
|
|
4
|
+
easycoder/ec_condition.py,sha256=WSbONo4zs2sX1icOVpscZDFSCAEFmTsquoc2RGcLx_k,763
|
|
5
|
+
easycoder/ec_core.py,sha256=AnPrSJ4oUIOFGV0iF6KxE3AmEb9NG77ae0KwoyvafYs,76175
|
|
6
|
+
easycoder/ec_handler.py,sha256=WDDIz0awD3vSQZ149rgbUWsClt6zXqED8ByXQJ5p1Ds,2200
|
|
7
|
+
easycoder/ec_program.py,sha256=_tfAS_p9JBk6aH9ZOzsrf_xuSNyTdy7yqxJ5ER-AJfw,7890
|
|
8
|
+
easycoder/ec_timestamp.py,sha256=_3QFJPzIWZ9Rzk3SQOQJ-gwmvB07pg78k23SPntoZtY,288
|
|
9
|
+
easycoder/ec_value.py,sha256=aOvSF6bM1iKpcLLm0zyGerxHixBkyjE3iYl1Bx6jmzU,2381
|
|
10
|
+
easycoder-241211.1.dist-info/entry_points.txt,sha256=JXAZbenl0TnsIft2FcGJbJ-4qoztVu2FuT8PFmWFexM,44
|
|
11
|
+
easycoder-241211.1.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
12
|
+
easycoder-241211.1.dist-info/WHEEL,sha256=ssQ84EZ5gH1pCOujd3iW7HClo_O_aDaClUbX4B8bjKY,100
|
|
13
|
+
easycoder-241211.1.dist-info/METADATA,sha256=uJRPPgtc65Ou6ShnNRJ-DwvQ9WLWqy4Vqb7GnU7chjs,2511
|
|
14
|
+
easycoder-241211.1.dist-info/RECORD,,
|
easycoder-5.dist-info/METADATA
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.3
|
|
2
|
-
Name: easycoder
|
|
3
|
-
Version: 5
|
|
4
|
-
Summary: EasyCoder for Python
|
|
5
|
-
Author-email: Graham Trott <gtanyware@gmail.com>
|
|
6
|
-
Description-Content-Type: text/markdown
|
|
7
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
8
|
-
Requires-Dist: pytz
|
|
9
|
-
Project-URL: Home, https://github.com/easycoder
|
|
10
|
-
|
|
11
|
-
# Introduction
|
|
12
|
-
This is the Python version of EasyCoder, a high-level English-like scripting language suited for prototyping and rapid testing of ideas. It operates on the command line.
|
|
13
|
-
|
|
14
|
-
The JavaScript version of EasyCoder, which provides a full set of graphical features to run in a browser, is at [https://easycoder.github.io](https://easycoder.github.io)
|
|
15
|
-
|
|
16
|
-
## Quick Start
|
|
17
|
-
1: Install EasyCoder in your Python environment:
|
|
18
|
-
```
|
|
19
|
-
pip install easycoder
|
|
20
|
-
```
|
|
21
|
-
2: Write a test script, 'hello.ecs':
|
|
22
|
-
```
|
|
23
|
-
print `Hello, world!`
|
|
24
|
-
```
|
|
25
|
-
This is traditionally the first program to be written in virtually any language. To run it under REPL, launch Python and type the following commands:
|
|
26
|
-
```
|
|
27
|
-
from easycoder import Program
|
|
28
|
-
Program(['hello.ecs'])
|
|
29
|
-
```
|
|
30
|
-
The script is passed in as a list because it could be just one of a number of command-line arguments.
|
|
31
|
-
|
|
32
|
-
The output will look like this:
|
|
33
|
-
```
|
|
34
|
-
Compiled <anon>: 1 lines (2 tokens) in 0 ms
|
|
35
|
-
Run <anon>
|
|
36
|
-
1-> Hello, world!
|
|
37
|
-
```
|
|
38
|
-
To avoid having to use REPL you can set up a simple executable command such as this Python script. On Linux the first line will ensure it runs as a command if given execute permission. You can name it 'easycoder' - there's no need for a '.py' extension.
|
|
39
|
-
```
|
|
40
|
-
#!/bin/python3
|
|
41
|
-
|
|
42
|
-
from sys import argv
|
|
43
|
-
from easycoder import Program
|
|
44
|
-
|
|
45
|
-
if (len(argv) > 1):
|
|
46
|
-
Program(argv[1:])
|
|
47
|
-
else:
|
|
48
|
-
print('Syntax: easycoder <scriptname> [plugins]')
|
|
49
|
-
```
|
|
50
|
-
With this you can run your script with the command `easycoder hello.ecs`. You can place `easycoder` anywhere on your system execution path, such as in a local `bin` directory.
|
|
51
|
-
|
|
52
|
-
It's conventional to add a program title to a script:
|
|
53
|
-
```
|
|
54
|
-
! Test script
|
|
55
|
-
|
|
56
|
-
script Test
|
|
57
|
-
|
|
58
|
-
print `Hello, world!`
|
|
59
|
-
```
|
|
60
|
-
The first line here is just a comment and has no effect on the running of the script. The second line gives the script a name, which is useful in debugging as it says which script was running. When run, the output is now
|
|
61
|
-
```
|
|
62
|
-
Compiled Test: 5 lines (4 tokens) in 0 ms
|
|
63
|
-
Run Test
|
|
64
|
-
5-> Hello, world!
|
|
65
|
-
```
|
|
66
|
-
As you can guess from the above, the print command gives the line in the script it was called from. This is very useful in tracking down debugging print commands in large scripts.
|
|
67
|
-
|
|
68
|
-
In the repository is a folder called `tests` containing a couple of sample scripts. `benchmark.ecs` allows the performance of EasyCoder to be compared to other languages if a similar program is written for each one. `tests.ecs` is a test program containing many of the EasyCoder features.
|
|
69
|
-
|
|
70
|
-
## The EasyCoder programming language
|
|
71
|
-
There are three primary components to the language:
|
|
72
|
-
1 Keywords
|
|
73
|
-
2 Values
|
|
74
|
-
3 Conditions
|
|
75
|
-
|
|
76
|
-
All program lines start with a keyword - a command to EasyCoder to do something
|
|
77
|
-
|
|
78
|
-
(Under construction)
|
|
79
|
-
|
easycoder-5.dist-info/RECORD
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
easycoder/__init__.py,sha256=ZoQYUvtfcu53_Oowbjb15eQL3q7CW1ea7zkQ-qEShtE,255
|
|
2
|
-
easycoder/ec_classes.py,sha256=onBKF6Lj8BZKNuJKacx4HyhOrVLXsoHdzl6RnMf77uM,1413
|
|
3
|
-
easycoder/ec_compiler.py,sha256=ByWwWA4GTzDX1kljgNbBwzfvvUuR34FRQSEpRVtRo5s,4670
|
|
4
|
-
easycoder/ec_condition.py,sha256=s7xKM3ZeOOiSgZv16RnWznAikHZaJRp1UHwrliebpUE,748
|
|
5
|
-
easycoder/ec_core.py,sha256=_PnwCJcxa7vD5MouuM9COTAC9RnGvzSZ9022Tlqzh5M,74591
|
|
6
|
-
easycoder/ec_handler.py,sha256=WDDIz0awD3vSQZ149rgbUWsClt6zXqED8ByXQJ5p1Ds,2200
|
|
7
|
-
easycoder/ec_program.py,sha256=u9DQcbWqefDU69UKL2ZJyoxfT2e5MoEUHvvv82aDUu0,7658
|
|
8
|
-
easycoder/ec_timestamp.py,sha256=_3QFJPzIWZ9Rzk3SQOQJ-gwmvB07pg78k23SPntoZtY,288
|
|
9
|
-
easycoder/ec_value.py,sha256=GnHkWSfcB2InGeLj4T8x_H8U9bvbkj9lF4klEUylt38,2371
|
|
10
|
-
easycoder-5.dist-info/entry_points.txt,sha256=JXAZbenl0TnsIft2FcGJbJ-4qoztVu2FuT8PFmWFexM,44
|
|
11
|
-
easycoder-5.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
12
|
-
easycoder-5.dist-info/WHEEL,sha256=ssQ84EZ5gH1pCOujd3iW7HClo_O_aDaClUbX4B8bjKY,100
|
|
13
|
-
easycoder-5.dist-info/METADATA,sha256=na9ADFzJRttO8YwHA3uW5yd8y4kYGSyWDCjHCJtyjS8,2964
|
|
14
|
-
easycoder-5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|