diff --git a/carp/src/bridge/bridge.py b/carp/src/bridge/bridge.py index 0843a27..959d1c0 100644 --- a/carp/src/bridge/bridge.py +++ b/carp/src/bridge/bridge.py @@ -1,7 +1,7 @@ import argparse import threading import sys -import hooks +from bridge import carp from bridge.hooks import * from bridge.object_registry import registry @@ -23,7 +23,7 @@ class EvalCommand: def execute_using_env(self, env): try: - self.execute() + return self.execute() except Exception as err: self.perform_proceed_action(notify_error(err,self)) @@ -44,7 +44,7 @@ class EvalCommand: return self.commandId def execute(self): - bridge.globals.proc.evaluate(self.statements) + return bridge.globals.proc.evaluate(self.statements) class Logger(): def log(self, msg): @@ -140,6 +140,7 @@ def run_bridge(): help="enable logging") args = vars(ap.parse_args()) + bridge.globals.proc = carp.start_carp_proc() bridge.globals.pharoPort = args["pharo"] if args["log"]: bridge.globals.logger = Logger() @@ -148,7 +149,6 @@ def run_bridge(): bridge.globals.pyPort = args["port"] bridge.globals.globalCommandList = CommandList() globalCommandList = bridge.globals.globalCommandList - bridge.globals.proc = carp.start_carp_proc() env = clean_locals_env() msg_service = None if args["port"] == None: @@ -165,14 +165,15 @@ def run_bridge(): raise Exception("Invalid communication strategy.") bridge.globals.msg_service = msg_service msg_service.start() - bridge.globals.logger.log("PYTHON: Start consuming commands") + bridge.globals.logger.log("CARP: Carp version " + bridge.globals.proc.version_info()) + bridge.globals.logger.log("CARP: Start consuming commands") while True: command = globalCommandList.consume_command() - bridge.globals.logger.log("PYTHON: Executing command " + command.command_id()) - bridge.globals.logger.log("PYTHON: bindings: " + str(command.bindings)) - bridge.globals.logger.log("PYTHON: " + command.statements) - command.execute_using_env(env) - bridge.globals.logger.log("PYTHON: Finished command execution") + bridge.globals.logger.log("CARP: Executing command " + command.command_id()) + bridge.globals.logger.log("CARP: bindings: " + str(command.bindings)) + bridge.globals.logger.log("CARP: " + command.statements) + notify(command.execute_using_env(env), command.command_id()) + bridge.globals.logger.log("CARP: Finished command execution") if __name__ == "__main__": run_bridge() diff --git a/carp/src/bridge/carp.py b/carp/src/bridge/carp.py index 3bff86e..b1fc223 100644 --- a/carp/src/bridge/carp.py +++ b/carp/src/bridge/carp.py @@ -1,13 +1,44 @@ -import subprocess +import re +import time +import diplomat class CarpProc: def __init__(self): - self.proc = subprocess.Popen(['carp']) + self.proc = diplomat.Diplomat('carp') + self._version_info = None + self.adornment_re = re.compile(".\[33m.*?\[0m") + + def wait_for_boot(self): + while not self.proc.output(): + time.sleep(0.5) + return self + + def version_info(self): + if not self._version_info: + self._version_info = list(self.proc.output_stream())[0].replace("Welcome to Carp ", "")[:-1] + return self._version_info + + def read_output(self, old_output): + while self.proc.output() == old_output: + time.sleep(0.5) + res = self.adornment_re.sub("", self.proc.output()[len(old_output):]).strip() + if res.startswith("=> "): + return {'result': 'success', 'value': res[3:]} + if not res: + return {'result': 'success', 'value': '()'} + return {'result': 'error', 'value': res} def evaluate(self, statements): - self.proc.stdin.send(statements) + assert self.proc.is_running(), "carp process has died" + if not self._version_info: + self.version_info() + + old_output = self.proc.output() + self.proc._process.stdin.write(statements.encode("utf-8") + b"\n") + self.proc._process.stdin.flush() + return self.read_output(old_output) def start_carp_proc(): - return CarpProc() + return CarpProc().wait_for_boot() diff --git a/carp/src/languagelink.py b/carp/src/languagelink.py index f80f199..497f83f 100644 --- a/carp/src/languagelink.py +++ b/carp/src/languagelink.py @@ -1,4 +1,4 @@ -from bridge import bridge -from bridge.bridge_hooks import * +from bridge import bridge as b +from bridge.hooks import * -bridge.run_bridge() +b.run_bridge()