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(); 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] #[inline]
fn input(&self) -> &Input { fn input(&self) -> &Input {
&self.cfg.input &self.cfg.input

View file

@ -251,4 +251,8 @@ impl Compiler {
let desugared = HIRDesugarer::desugar(hir); let desugared = HIRDesugarer::desugar(hir);
Ok(CompleteArtifact::new(desugared, artifact.warns)) 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(); let mut res = warns.to_string();
// Tell the REPL server to execute the code // Tell the REPL server to execute the code
res += &match self.stream.as_mut().unwrap().write("load".as_bytes()) { res += &match self.stream.as_mut().unwrap().write("load".as_bytes()) {
Result::Ok(_) => { Result::Ok(_) => self.read()?,
// 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::Err(err) => { Result::Err(err) => {
self.finish(); self.finish();
eprintln!("Sending error: {err}"); eprintln!("Sending error: {err}");
@ -215,4 +197,27 @@ impl DummyVM {
pub fn eval(&mut self, src: String) -> Result<String, EvalErrors> { pub fn eval(&mut self, src: String) -> Result<String, EvalErrors> {
Runnable::eval(self, src) 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 sys as __sys
import importlib as __importlib import importlib as __importlib
import io as __io import io as __io
import traceback as __traceback
__server_socket = __socket.socket() __server_socket = __socket.socket()
# DummyVM will replace this __PORT__ with free port # DummyVM will replace this __PORT__ with free port
@ -12,7 +13,7 @@ __server_socket.listen(1)
(__client_socket, __client_address) = __server_socket.accept() (__client_socket, __client_address) = __server_socket.accept()
__already_loaded = False __already_loaded = False
__res = '' __ctx = {'__importlib': __importlib}
while True: while True:
try: try:
@ -24,20 +25,31 @@ while True:
break break
elif __order == 'load': elif __order == 'load':
__sys.stdout = __io.StringIO() __sys.stdout = __io.StringIO()
__res = ''
__exc = ''
try: try:
if __already_loaded: if __already_loaded:
# __MODULE__ will be replaced with module name # __MODULE__ will be replaced with module name
__res = str(exec('__importlib.reload(__MODULE__)')) __res = str(exec('__importlib.reload(__MODULE__)', __ctx))
else: else:
__res = str(exec('import __MODULE__')) __res = str(exec('import __MODULE__', __ctx))
__already_loaded = True
except SystemExit: except SystemExit:
__client_socket.send('[Exception] SystemExit'.encode()) __client_socket.send('[Exception] SystemExit'.encode())
continue continue
except e: except Exception as e:
__res = str(e) try:
__already_loaded = True 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] __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()) __client_socket.send(__res.encode())
else: else:
__client_socket.send('unknown operation'.encode()) __client_socket.send('unknown operation'.encode())