mirror of
https://github.com/erg-lang/erg.git
synced 2025-10-02 21:44:34 +00:00
fix socket connection problems
This commit is contained in:
parent
fa5bb4f615
commit
b76d63f9a5
6 changed files with 52 additions and 30 deletions
|
@ -74,13 +74,15 @@ impl fmt::Display for ErgMode {
|
|||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct DummyStdin {
|
||||
pub name: String,
|
||||
current_line: usize,
|
||||
lines: Vec<String>,
|
||||
}
|
||||
|
||||
impl DummyStdin {
|
||||
pub fn new(lines: Vec<String>) -> Self {
|
||||
pub fn new(name: String, lines: Vec<String>) -> Self {
|
||||
Self {
|
||||
name,
|
||||
current_line: 0,
|
||||
lines,
|
||||
}
|
||||
|
@ -160,7 +162,8 @@ impl Input {
|
|||
pub fn filename(&self) -> &str {
|
||||
match self {
|
||||
Self::File(filename) => filename.file_name().and_then(|f| f.to_str()).unwrap_or("_"),
|
||||
Self::REPL | Self::DummyREPL(_) | Self::Pipe(_) => "stdin",
|
||||
Self::REPL | Self::Pipe(_) => "stdin",
|
||||
Self::DummyREPL(stdin) => &stdin.name,
|
||||
Self::Str(_) => "string",
|
||||
Self::Dummy => "dummy",
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
//! defines the compiler for Erg (ergc).
|
||||
#![allow(clippy::large_enum_variant)]
|
||||
#![allow(clippy::result_large_err)]
|
||||
extern crate erg_common;
|
||||
pub extern crate erg_parser;
|
||||
|
||||
|
|
20
src/dummy.rs
20
src/dummy.rs
|
@ -61,7 +61,8 @@ impl Runnable for DummyVM {
|
|||
}
|
||||
let port = find_available_port();
|
||||
let code = include_str!("scripts/repl_server.py")
|
||||
.replace("__PORT__", port.to_string().as_str());
|
||||
.replace("__PORT__", port.to_string().as_str())
|
||||
.replace("__MODULE__", &cfg.dump_filename());
|
||||
spawn_py(cfg.py_command, &code);
|
||||
let addr = SocketAddrV4::new(Ipv4Addr::LOCALHOST, port);
|
||||
if !cfg.quiet_repl {
|
||||
|
@ -112,7 +113,7 @@ impl Runnable for DummyVM {
|
|||
process::exit(1);
|
||||
}
|
||||
}
|
||||
remove_file("o.pyc").unwrap_or(());
|
||||
remove_file(self.cfg().dump_pyc_filename()).unwrap_or(());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,9 +143,10 @@ impl Runnable for DummyVM {
|
|||
}
|
||||
|
||||
fn eval(&mut self, src: String) -> Result<String, EvalErrors> {
|
||||
let path = self.cfg().dump_pyc_filename();
|
||||
let arti = self
|
||||
.compiler
|
||||
.eval_compile_and_dump_as_pyc("o.pyc", src, "eval")
|
||||
.eval_compile_and_dump_as_pyc(path, src, "eval")
|
||||
.map_err(|eart| eart.errors)?;
|
||||
let (last, warns) = (arti.object, arti.warns);
|
||||
let mut res = warns.to_string();
|
||||
|
@ -207,17 +209,23 @@ impl DummyVM {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn find_available_port() -> u16 {
|
||||
require_free_port()
|
||||
}
|
||||
#[cfg(not(test))]
|
||||
fn find_available_port() -> u16 {
|
||||
const DEFAULT_PORT: u16 = 8736;
|
||||
TcpListener::bind(SocketAddrV4::new(Ipv4Addr::LOCALHOST, DEFAULT_PORT))
|
||||
.is_ok()
|
||||
.then_some(DEFAULT_PORT)
|
||||
.unwrap_or_else(|| {
|
||||
// localhost:0 will bind to a free port
|
||||
.unwrap_or_else(require_free_port)
|
||||
}
|
||||
|
||||
fn require_free_port() -> u16 {
|
||||
let socket = SocketAddrV4::new(Ipv4Addr::LOCALHOST, 0);
|
||||
TcpListener::bind(socket)
|
||||
.and_then(|listener| listener.local_addr())
|
||||
.map(|sock_addr| sock_addr.port())
|
||||
.expect("No free port found.")
|
||||
})
|
||||
}
|
||||
|
|
|
@ -28,9 +28,10 @@ while True:
|
|||
__sys.stdout = __io.StringIO()
|
||||
try:
|
||||
if __already_loaded:
|
||||
__res = str(exec('__importlib.reload(o)'))
|
||||
# __MODULE__ will be replaced with module name
|
||||
__res = str(exec('__importlib.reload(__MODULE__)'))
|
||||
else:
|
||||
__res = str(exec('import o'))
|
||||
__res = str(exec('import __MODULE__'))
|
||||
except SystemExit:
|
||||
__client_socket.send('[Exception] SystemExit'.encode())
|
||||
continue
|
||||
|
|
|
@ -12,8 +12,8 @@ use erg_compiler::error::CompileErrors;
|
|||
|
||||
use erg::DummyVM;
|
||||
|
||||
pub(crate) fn expect_repl_success(lines: Vec<String>) -> Result<(), ()> {
|
||||
match exec_repl(lines) {
|
||||
pub(crate) fn expect_repl_success(name: &'static str, lines: Vec<String>) -> Result<(), ()> {
|
||||
match exec_repl(name, lines) {
|
||||
Ok(ExitStatus::OK) => Ok(()),
|
||||
Ok(stat) => {
|
||||
println!("err: should succeed, but got: {stat:?}");
|
||||
|
@ -114,10 +114,10 @@ fn _exec_file(file_path: &'static str) -> Result<i32, CompileErrors> {
|
|||
}
|
||||
|
||||
/// WARN: You must quit REPL manually (use `:exit`, `:quit` or call something shutdowns the interpreter)
|
||||
pub fn _exec_repl(lines: Vec<String>) -> Result<ExitStatus, CompileErrors> {
|
||||
pub fn _exec_repl(name: &'static str, lines: Vec<String>) -> Result<ExitStatus, CompileErrors> {
|
||||
println!("{GREEN}[test] exec dummy REPL: {lines:?}{RESET}");
|
||||
let cfg = ErgConfig {
|
||||
input: Input::DummyREPL(DummyStdin::new(lines)),
|
||||
input: Input::DummyREPL(DummyStdin::new(name.to_string(), lines)),
|
||||
quiet_repl: true,
|
||||
..Default::default()
|
||||
};
|
||||
|
@ -129,6 +129,9 @@ pub(crate) fn exec_file(file_path: &'static str) -> Result<i32, CompileErrors> {
|
|||
exec_new_thread(move || _exec_file(file_path))
|
||||
}
|
||||
|
||||
pub(crate) fn exec_repl(lines: Vec<String>) -> Result<ExitStatus, CompileErrors> {
|
||||
exec_new_thread(move || _exec_repl(lines))
|
||||
pub(crate) fn exec_repl(
|
||||
name: &'static str,
|
||||
lines: Vec<String>,
|
||||
) -> Result<ExitStatus, CompileErrors> {
|
||||
exec_new_thread(move || _exec_repl(name, lines))
|
||||
}
|
||||
|
|
|
@ -3,17 +3,23 @@ use common::expect_repl_success;
|
|||
|
||||
#[test]
|
||||
fn exec_repl_helloworld() -> Result<(), ()> {
|
||||
expect_repl_success(vec!["print! \"hello, world\"".into(), "exit()".into()])
|
||||
expect_repl_success(
|
||||
"repl_hello",
|
||||
vec!["print! \"hello, world\"".into(), "exit()".into()],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn exec_repl_def_func() -> Result<(), ()> {
|
||||
expect_repl_success(vec![
|
||||
expect_repl_success(
|
||||
"repl_def",
|
||||
vec![
|
||||
"f i =".into(),
|
||||
" i + 1".into(),
|
||||
"".into(),
|
||||
"x = f 2".into(),
|
||||
"assert x == 3".into(),
|
||||
"exit()".into(),
|
||||
])
|
||||
],
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue