From 40c9655424118439918bfc507abe978dfd6d6e86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Balzarotti?= Date: Wed, 22 Feb 2023 03:58:53 +0100 Subject: [PATCH] scm.py: support eval. Improve eval in home page --- app.py | 3 +-- phasectrl.py | 10 ++++++---- scm.py | 22 ++++++++++++++-------- templates/base.html | 3 +++ templates/index.html | 13 +++++++------ 5 files changed, 31 insertions(+), 20 deletions(-) diff --git a/app.py b/app.py index 7f1ae92..abc712d 100644 --- a/app.py +++ b/app.py @@ -90,8 +90,7 @@ def handle_new_client(): @socketio.on('eval scheme') def eval_scheme(code): - output = phasectrl.safe_eval(code, statemachine.env) - phasectrl.safe_eval(f'(notify "{output}")', statemachine.env) + output = phasectrl.safe_eval(code, statemachine.env, notify=False) socketio.emit('eval output', output) @socketio.on('get sensors history') diff --git a/phasectrl.py b/phasectrl.py index e06402a..e6cc6a3 100644 --- a/phasectrl.py +++ b/phasectrl.py @@ -14,13 +14,15 @@ MY_GLOBAL_ENV = ( _('format-time', 1, lambda x: stohms(x.car), GLOBAL_ENV))) -def safe_eval(data, env): +def safe_eval(data, env, notify=True): try: return eval(data, env) except Exception as e: err = ' '.join(('evaluating:', data, ':', str(e))) - chat.send_sync(err) - return True + if notify: + chat.send_sync(err) + return True + return err def load_phase(json): def fallback(v): @@ -244,7 +246,7 @@ class State(): actuators[actuator].enable() else: actuators[actuator].disable() - print('setting actuator ', actuator, 'to value', value, + print('setting actuator', actuator, 'to value', value, ', remember to change it manually if stopping?') def get_total_consumption(self): diff --git a/scm.py b/scm.py index a9296c2..398594e 100644 --- a/scm.py +++ b/scm.py @@ -82,6 +82,9 @@ class SchemeString: def __repr__(self): return '"' + self.string + '"' + def __eq__(self, other): + return self.string == other.string + class Environment (object): "Linked list of bindings mapping symbols to values" @@ -206,11 +209,13 @@ GLOBAL_ENV = ( # My custom helpers from datetime import datetime + GLOBAL_ENV = ( _('now', 0, lambda x: datetime.now(), _('concat', -1, lambda x: ''.join((stringify(x, False) for x in x)), _('exit', 0, lambda x: exit(), - GLOBAL_ENV)))) + _('eval', 1, lambda x: evaluate(x.car), + GLOBAL_ENV))))) # records = {} # def make_record_type(name, params): @@ -249,11 +254,12 @@ GLOBAL_ENV = Environment( _('cdr', 1, lambda x: x.car.cdr, _('cons', 2, lambda x: Cell(x.car, x.cdr.car), _('eq?', 2, lambda x: x.car is x.cdr.car, - _('pair?', 1, lambda x: isinstance(x.car, Cell), - _('null?', 1, lambda x: x.car is NIL, - _('not', 1, lambda x: x.car is False, - _('list', -1, lambda x: x, - GLOBAL_ENV))))))))) + _('equal?', 2, lambda x: x.car == x.cdr.car, + _('pair?', 1, lambda x: isinstance(x.car, Cell), + _('null?', 1, lambda x: x.car is NIL, + _('not', 1, lambda x: x.car is False, + _('list', -1, lambda x: x, + GLOBAL_ENV)))))))))) @@ -393,8 +399,8 @@ def apply_function(fun, arg, k, env): elif isinstance(fun, tuple): # as a continuation return arg.car, fun, env else: - raise TypeError('not a function: ' + stringify(fun) + ' with ' - + stringify(arg)) + raise TypeError('wrong type to apply: ' + stringify(fun) + ' with ' + + stringify(arg) + ' instance is ' + str(type(fun))) def _push_RESTORE_ENV(k, env): if k is NOCONT or k[0] is not RESTORE_ENV: # unless tail call... diff --git a/templates/base.html b/templates/base.html index 19498e1..9f9863b 100644 --- a/templates/base.html +++ b/templates/base.html @@ -21,6 +21,9 @@ socket.on("state", (data) => { applyState(data); }); + socket.on("eval output", (data) => { + document.getElementById('eval-output').value = data; + }); socket.on("sensors", (data) => { add_plot_data(data); render_sensors(data); diff --git a/templates/index.html b/templates/index.html index 9c29c99..48089d5 100644 --- a/templates/index.html +++ b/templates/index.html @@ -61,12 +61,13 @@
- + + + Eval + +