Skip to content

Commit e1abc20

Browse files
committed
250611.6
1 parent 3694090 commit e1abc20

9 files changed

+124
-51
lines changed
-36.1 KB
Binary file not shown.
36.2 KB
Binary file not shown.
Binary file not shown.

easycoder/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@
99
from .ec_timestamp import *
1010
from .ec_value import *
1111

12-
__version__ = "250609.2"
12+
__version__ = "250611.6"

easycoder/ec_compiler.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ def __init__(self, program):
1414
self.symbols = self.program.symbols
1515
self.code = self.program.code
1616
self.program.compiler = self
17-
self.addCommand = self.program.add
1817
self.compileConstant = self.value.compileConstant
1918
self.debugCompile = False
2019

@@ -77,6 +76,10 @@ def nextIs(self, value):
7776
def getCommandAt(self, pc):
7877
return self.program.code[pc]
7978

79+
# Add a command to the code list
80+
def add(self, command):
81+
self.code.append(command)
82+
8083
def isSymbol(self):
8184
token=self.getToken()
8285
try:
@@ -148,7 +151,7 @@ def compileSymbol(self, command, name, hasValue, extra=None):
148151
command['import'] = None
149152
command['locked'] = False
150153
command['extra'] = extra
151-
self.addCommand(command)
154+
self.add(command)
152155
return True
153156

154157
# Compile the current token

easycoder/ec_core.py

Lines changed: 110 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ def k_assert(self, command):
126126
command['with'] = self.nextValue()
127127
else:
128128
command['with'] = None
129-
self.addCommand(command)
129+
self.add(command)
130130
return True
131131

132132
def r_assert(self, command):
@@ -143,7 +143,7 @@ def k_begin(self, command):
143143
cmd['keyword'] = 'end'
144144
cmd['debug'] = True
145145
cmd['lino'] = command['lino']
146-
self.addCommand(cmd)
146+
self.add(cmd)
147147
return self.nextPC()
148148
else:
149149
return self.compileFromHere(['end'])
@@ -441,7 +441,7 @@ def k_get(self, command):
441441
timeout['type'] = 'int'
442442
timeout['content'] = 5
443443
command['timeout'] = timeout
444-
self.addCommand(command)
444+
self.add(command)
445445
if self.peek() == 'or':
446446
self.nextToken()
447447
self.nextToken()
@@ -453,7 +453,7 @@ def k_get(self, command):
453453
cmd['goto'] = 0
454454
cmd['debug'] = False
455455
skip = self.getPC()
456-
self.addCommand(cmd)
456+
self.add(cmd)
457457
# Process the 'or'
458458
self.getCommandAt(get)['or'] = self.getPC()
459459
self.compileOne()
@@ -535,7 +535,7 @@ def r_gosub(self, command):
535535
# if <condition> <action> [else <action>]
536536
def k_if(self, command):
537537
command['condition'] = self.nextCondition()
538-
self.addCommand(command)
538+
self.add(command)
539539
self.nextToken()
540540
pcElse = self.getPC()
541541
cmd = {}
@@ -544,7 +544,7 @@ def k_if(self, command):
544544
cmd['keyword'] = 'gotoPC'
545545
cmd['goto'] = 0
546546
cmd['debug'] = False
547-
self.addCommand(cmd)
547+
self.add(cmd)
548548
# Get the 'then' code
549549
self.compileOne()
550550
if self.peek() == 'else':
@@ -557,7 +557,7 @@ def k_if(self, command):
557557
cmd['keyword'] = 'gotoPC'
558558
cmd['goto'] = 0
559559
cmd['debug'] = False
560-
self.addCommand(cmd)
560+
self.add(cmd)
561561
# Fixup the link to the 'else' branch
562562
self.getCommandAt(pcElse)['goto'] = self.getPC()
563563
# Process the 'else' branch
@@ -603,7 +603,7 @@ def k_import(self, command):
603603
variable['keyword'] = keyword
604604
variable['import'] = None
605605
variable['used'] = False
606-
self.addCommand(variable)
606+
self.add(variable)
607607
if self.peek() != 'and':
608608
break
609609
self.nextToken()
@@ -732,17 +732,37 @@ def k_load(self, command):
732732
if record['keyword'] == 'ssh':
733733
command['ssh'] = record['name']
734734
command['path'] = self.nextValue()
735-
self.add(command)
736-
return True
737-
738-
command['file'] = self.getValue()
735+
else:
736+
command['file'] = self.getValue()
737+
else:
738+
command['file'] = self.getValue()
739+
command['or'] = None
740+
load = self.getPC()
739741
self.add(command)
742+
if self.peek() == 'or':
743+
self.nextToken()
744+
self.nextToken()
745+
# Add a 'goto' to skip the 'or'
746+
cmd = {}
747+
cmd['lino'] = command['lino']
748+
cmd['domain'] = 'core'
749+
cmd['keyword'] = 'gotoPC'
750+
cmd['goto'] = 0
751+
cmd['debug'] = False
752+
skip = self.getPC()
753+
self.add(cmd)
754+
# Process the 'or'
755+
self.getCommandAt(load)['or'] = self.getPC()
756+
self.compileOne()
757+
# Fixup the skip
758+
self.getCommandAt(skip)['goto'] = self.getPC()
740759
return True
741760
else:
742761
FatalError(self.compiler, f'I don\'t understand \'{self.getToken()}\'')
743762
return False
744763

745764
def r_load(self, command):
765+
errorReason = None
746766
target = self.getVariable(command['target'])
747767
if 'ssh' in command:
748768
ssh = self.getVariable(command['ssh'])
@@ -751,17 +771,24 @@ def r_load(self, command):
751771
try:
752772
with sftp.open(path, 'r') as remote_file: content = remote_file.read().decode()
753773
except:
754-
RuntimeError(self.program, 'Unable to read data')
774+
errorReason = f'Unable to read from {path}'
755775
else:
756776
filename = self.getRuntimeValue(command['file'])
757777
try:
758778
with open(filename) as f: content = f.read()
779+
try:
780+
if filename.endswith('.json'): content = json.loads(content)
781+
except:
782+
errorReason = 'Bad or null JSON string'
759783
except:
760-
content = ''
761-
try:
762-
if filename.endswith('.json'): content = json.loads(content)
763-
except:
764-
RuntimeError(self.program, 'Bad or null JSON string')
784+
errorReason = f'Unable to read from {filename}'
785+
786+
if errorReason:
787+
if command['or'] != None:
788+
print(f'Exception "{errorReason}": Running the "or" clause')
789+
return command['or']
790+
else:
791+
RuntimeError(self.program, f'Error: {errorReason}')
765792
value = {}
766793
value['type'] = 'text'
767794
value['content'] = content
@@ -888,15 +915,15 @@ def k_on(self, command):
888915
cmd['keyword'] = 'gotoPC'
889916
cmd['goto'] = 0
890917
cmd['debug'] = False
891-
self.addCommand(cmd)
918+
self.add(cmd)
892919
# Add the action and a 'stop'
893920
self.compileOne()
894921
cmd = {}
895922
cmd['domain'] = 'core'
896923
cmd['lino'] = command['lino']
897924
cmd['keyword'] = 'stop'
898925
cmd['debug'] = False
899-
self.addCommand(cmd)
926+
self.add(cmd)
900927
# Fixup the link
901928
command['goto'] = self.getPC()
902929
return True
@@ -990,7 +1017,7 @@ def k_post(self, command):
9901017
command['result'] = None
9911018
command['or'] = None
9921019
post = self.getPC()
993-
self.addCommand(command)
1020+
self.add(command)
9941021
if self.peek() == 'or':
9951022
self.nextToken()
9961023
self.nextToken()
@@ -1002,7 +1029,7 @@ def k_post(self, command):
10021029
cmd['goto'] = 0
10031030
cmd['debug'] = False
10041031
skip = self.getPC()
1005-
self.addCommand(cmd)
1032+
self.add(cmd)
10061033
# Process the 'or'
10071034
self.getCommandAt(post)['or'] = self.getPC()
10081035
self.compileOne()
@@ -1055,10 +1082,10 @@ def r_print(self, command):
10551082
program = command['program']
10561083
code = program.code[program.pc]
10571084
lino = str(code['lino'] + 1)
1058-
while len(lino) < 5: lino = f' {lino}'
1085+
# while len(lino) < 5: lino = f' {lino}'
10591086
if value == None: value = '<empty>'
10601087
if 'log' in command:
1061-
print(f'{datetime.now().time()}:{lino}-> {value}')
1088+
print(f'{datetime.now().time()}:{self.program.name}:{lino}->{value}')
10621089
else:
10631090
print(value)
10641091
return self.nextPC()
@@ -1262,17 +1289,65 @@ def k_script(self, command):
12621289
# Save a value to a file
12631290
def k_save(self, command):
12641291
command['content'] = self.nextValue()
1265-
if self.nextIs('to'):
1266-
command['file'] = self.nextValue()
1267-
self.add(command)
1268-
return True
1269-
return False
1292+
self.skip('to')
1293+
if self.nextIsSymbol():
1294+
record = self.getSymbolRecord()
1295+
if record['keyword'] == 'ssh':
1296+
command['ssh'] = record['name']
1297+
command['path'] = self.nextValue()
1298+
self.add(command)
1299+
else:
1300+
command['file'] = self.getValue()
1301+
else:
1302+
command['file'] = self.getValue()
1303+
command['or'] = None
1304+
save = self.getPC()
1305+
self.add(command)
1306+
if self.peek() == 'or':
1307+
self.nextToken()
1308+
self.nextToken()
1309+
# Add a 'goto' to skip the 'or'
1310+
cmd = {}
1311+
cmd['lino'] = command['lino']
1312+
cmd['domain'] = 'core'
1313+
cmd['keyword'] = 'gotoPC'
1314+
cmd['goto'] = 0
1315+
cmd['debug'] = False
1316+
skip = self.getPC()
1317+
self.add(cmd)
1318+
# Process the 'or'
1319+
self.getCommandAt(save)['or'] = self.getPC()
1320+
self.compileOne()
1321+
# Fixup the skip
1322+
self.getCommandAt(skip)['goto'] = self.getPC()
1323+
return True
12701324

12711325
def r_save(self, command):
1326+
errorReason = None
12721327
content = self.getRuntimeValue(command['content'])
1273-
filename = self.getRuntimeValue(command['file'])
1274-
if filename.endswith('.json'): content = json.dumps(content)
1275-
with open(filename, 'w') as f: f.write(content)
1328+
if 'ssh' in command:
1329+
ssh = self.getVariable(command['ssh'])
1330+
path = self.getRuntimeValue(command['path'])
1331+
sftp = ssh['sftp']
1332+
if path.endswith('.json'): content = json.dumps(content)
1333+
try:
1334+
with sftp.open(path, 'w') as remote_file: remote_file.write(content)
1335+
except:
1336+
errorReason = 'Unable to write to {path}'
1337+
else:
1338+
filename = self.getRuntimeValue(command['file'])
1339+
if filename.endswith('.json'): content = json.dumps(content)
1340+
try:
1341+
with open(filename, 'w') as f: f.write(content)
1342+
except:
1343+
errorReason = f'Unable to write to {filename}'
1344+
1345+
if errorReason:
1346+
if command['or'] != None:
1347+
print(f'Exception "{errorReason}": Running the "or" clause')
1348+
return command['or']
1349+
else:
1350+
RuntimeError(self.program, f'Error: {errorReason}')
12761351
return self.nextPC()
12771352

12781353
# Send a message to a module
@@ -1746,7 +1821,7 @@ def k_while(self, command):
17461821
# token = self.getToken()
17471822
command['condition'] = code
17481823
test = self.getPC()
1749-
self.addCommand(command)
1824+
self.add(command)
17501825
# Set up a goto for when the test fails
17511826
fail = self.getPC()
17521827
cmd = {}
@@ -1755,7 +1830,7 @@ def k_while(self, command):
17551830
cmd['keyword'] = 'gotoPC'
17561831
cmd['goto'] = 0
17571832
cmd['debug'] = False
1758-
self.addCommand(cmd)
1833+
self.add(cmd)
17591834
# Do the body of the while
17601835
self.nextToken()
17611836
if self.compileOne() == False:
@@ -1767,7 +1842,7 @@ def k_while(self, command):
17671842
cmd['keyword'] = 'gotoPC'
17681843
cmd['goto'] = test
17691844
cmd['debug'] = False
1770-
self.addCommand(cmd)
1845+
self.add(cmd)
17711846
# Fixup the 'goto' on completion
17721847
self.getCommandAt(fail)['goto'] = self.getPC()
17731848
return True

easycoder/ec_handler.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,13 @@ def __init__(self, compiler):
2323
self.rewindTo = compiler.rewindTo
2424
self.warning = compiler.warning
2525
self.getPC = compiler.getPC
26-
self.addCommand = compiler.addCommand
26+
self.add = compiler.add
2727
self.getCommandAt = compiler.getCommandAt
2828
self.compileOne = compiler.compileOne
2929
self.compileFromHere = compiler.compileFromHere
3030
self.compileConstant = compiler.compileConstant
3131

3232
self.code = self.program.code
33-
self.add = self.program.add
3433
self.evaluate = self.program.evaluate
3534
self.getVariable = self.program.getSymbolRecord
3635
self.getRuntimeValue = self.program.getRuntimeValue

easycoder/ec_program.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,6 @@ def processClasses(self):
116116
def getDomains(self):
117117
return self.domains
118118

119-
# Add a command to the code list
120-
def add(self, command):
121-
self.code.append(command)
122-
123119
def getSymbolRecord(self, name):
124120
try:
125121
target = self.code[self.symbols[name]]

0 commit comments

Comments
 (0)