Merge pull request #420 from Hanaasagi/fix-stderr

This commit is contained in:
Shunsuke Shibayama 2023-04-22 17:13:18 +09:00 committed by GitHub
commit db9a7fdfd4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 58 additions and 26 deletions

View file

@ -196,6 +196,17 @@ impl PyCodeGenerator {
self.units.clear();
}
pub fn initialize(&mut self) {
self.prelude_loaded = false;
self.mutate_op_loaded = false;
self.in_op_loaded = false;
self.record_type_loaded = false;
self.module_type_loaded = false;
self.control_loaded = false;
self.convertors_loaded = false;
self.abc_loaded = false;
}
#[inline]
fn input(&self) -> &Input {
&self.cfg.input

View file

@ -251,4 +251,8 @@ impl Compiler {
let desugared = HIRDesugarer::desugar(hir);
Ok(CompleteArtifact::new(desugared, artifact.warns))
}
pub fn initialize_generator(&mut self) {
self.code_generator.initialize();
}
}

View file

@ -160,25 +160,7 @@ impl Runnable for DummyVM {
let mut res = warns.to_string();
// Tell the REPL server to execute the code
res += &match self.stream.as_mut().unwrap().write("load".as_bytes()) {
Result::Ok(_) => {
// read the result from the REPL server
let mut buf = [0; 1024];
match self.stream.as_mut().unwrap().read(&mut buf) {
Result::Ok(n) => {
let s = std::str::from_utf8(&buf[..n])
.expect("failed to parse the response, maybe the output is too long");
if s == "[Exception] SystemExit" {
return Err(EvalErrors::from(EvalError::system_exit()));
}
s.to_string()
}
Result::Err(err) => {
self.finish();
eprintln!("Read error: {err}");
process::exit(1);
}
}
}
Result::Ok(_) => self.read()?,
Result::Err(err) => {
self.finish();
eprintln!("Sending error: {err}");
@ -215,4 +197,27 @@ impl DummyVM {
pub fn eval(&mut self, src: String) -> Result<String, EvalErrors> {
Runnable::eval(self, src)
}
fn read(&mut self) -> Result<String, EvalErrors> {
let mut buf = [0; 1024];
match self.stream.as_mut().unwrap().read(&mut buf) {
Result::Ok(n) => {
let s = std::str::from_utf8(&buf[..n])
.expect("failed to parse the response, maybe the output is too long");
match s {
"[Exception] SystemExit" => Err(EvalErrors::from(EvalError::system_exit())),
"[Initialize]" => {
self.compiler.initialize_generator();
self.read()
}
_ => Ok(s.to_string()),
}
}
Result::Err(err) => {
self.finish();
eprintln!("Read error: {err}");
process::exit(1);
}
}
}
}

View file

@ -4,6 +4,7 @@ import socket as __socket
import sys as __sys
import importlib as __importlib
import io as __io
import traceback as __traceback
__server_socket = __socket.socket()
# DummyVM will replace this __PORT__ with free port
@ -12,7 +13,7 @@ __server_socket.listen(1)
(__client_socket, __client_address) = __server_socket.accept()
__already_loaded = False
__res = ''
__ctx = {'__importlib': __importlib}
while True:
try:
@ -24,20 +25,31 @@ while True:
break
elif __order == 'load':
__sys.stdout = __io.StringIO()
__res = ''
__exc = ''
try:
if __already_loaded:
# __MODULE__ will be replaced with module name
__res = str(exec('__importlib.reload(__MODULE__)'))
__res = str(exec('__importlib.reload(__MODULE__)', __ctx))
else:
__res = str(exec('import __MODULE__'))
__res = str(exec('import __MODULE__', __ctx))
__already_loaded = True
except SystemExit:
__client_socket.send('[Exception] SystemExit'.encode())
continue
except e:
__res = str(e)
__already_loaded = True
except Exception as e:
try:
excs = __traceback.format_exception(e)
except:
excs = __traceback.format_exception_only(e.__class__, e)
__exc = ''.join(excs).rstrip()
__traceback.clear_frames(e.__traceback__)
__client_socket.send('[Initialize]'.encode())
__out = __sys.stdout.getvalue()[:-1]
__res = __out + '\n' + __res
# assert not(__exc and __res)
if __exc or __res:
__out += '\n'
__res = __out + __exc + __res
__client_socket.send(__res.encode())
else:
__client_socket.send('unknown operation'.encode())