From 062a2179953af25b9a44dc21ada0ec9f8cdd59d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9A=D0=B8=D1=80=D0=B8=D0=BB=D0=BB=20=D0=9B=D0=B5=D0=BE?= =?UTF-8?q?=D0=BD=D0=BE=D0=B2?= <71232234+leonovk@users.noreply.github.com> Date: Sun, 18 Feb 2024 23:07:20 +0300 Subject: [PATCH] =?UTF-8?q?=F0=9F=95=B8=20Implementation=20of=20work=20wit?= =?UTF-8?q?h=20the=20network=20(#31)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/interpreter/arrays.rs | 5 ++- src/interpreter/calculate.rs | 5 ++- src/interpreter/condition.rs | 5 ++- src/interpreter/create.rs | 5 ++- src/interpreter/error_printer.rs | 5 --- src/interpreter/execute.rs | 6 +-- src/interpreter/include.rs | 7 +-- src/interpreter/mod.rs | 18 ++++---- src/interpreter/network.rs | 50 +++++++++++++++++++++ src/interpreter/opcode_result_type.rs | 7 --- src/interpreter/{print_file.rs => print.rs} | 27 ++++++++++- src/interpreter/print_value.rs | 22 --------- src/main.rs | 1 + src/network/mod.rs | 12 +++++ src/opcode/mod.rs | 9 ++++ src/parser/mod.rs | 1 + src/parser/network.rs | 44 ++++++++++++++++++ src/parser/opcode_parser.rs | 2 + tests/examples/send_tcp.mcode | 4 ++ 21 files changed, 179 insertions(+), 60 deletions(-) delete mode 100644 src/interpreter/error_printer.rs create mode 100644 src/interpreter/network.rs delete mode 100644 src/interpreter/opcode_result_type.rs rename src/interpreter/{print_file.rs => print.rs} (53%) delete mode 100644 src/interpreter/print_value.rs create mode 100644 src/network/mod.rs create mode 100644 src/parser/network.rs create mode 100644 tests/examples/send_tcp.mcode diff --git a/Cargo.lock b/Cargo.lock index a318977..da7bff7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -758,7 +758,7 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "minicode" -version = "1.4.2" +version = "1.4.3" dependencies = [ "clap", "pretty_assertions", diff --git a/Cargo.toml b/Cargo.toml index c702f57..a09d166 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "minicode" -version = "1.4.2" +version = "1.4.3" authors = ["Kirill Leonov "] edition = "2021" repository = "https://github.com/leonovk/minicode" diff --git a/src/interpreter/arrays.rs b/src/interpreter/arrays.rs index 6c18015..f6a1c25 100644 --- a/src/interpreter/arrays.rs +++ b/src/interpreter/arrays.rs @@ -1,4 +1,5 @@ -use super::opcode_result_type::*; +use crate::opcode::OpCodeResultType; +use crate::opcode::OpCodeResultType::*; use crate::opcode::ValueType; use crate::opcode::ValueType::*; use std::collections::HashMap; @@ -26,7 +27,7 @@ pub fn push<'a>( first_value.push(second_value); - Ok(OpCodeResultType::Empty) + Ok(Empty) } #[cfg(test)] diff --git a/src/interpreter/calculate.rs b/src/interpreter/calculate.rs index 32b2670..e0ee052 100644 --- a/src/interpreter/calculate.rs +++ b/src/interpreter/calculate.rs @@ -1,4 +1,5 @@ -use super::opcode_result_type::*; +use crate::opcode::OpCodeResultType; +use crate::opcode::OpCodeResultType::*; use crate::opcode::OperationType; use crate::opcode::OperationType::*; use crate::opcode::ValueType; @@ -36,7 +37,7 @@ pub fn calculate<'a>( calculate_new_value(old_value, operational_meaning, o_type), ); - Ok(OpCodeResultType::Empty) + Ok(Empty) } fn calculate_new_value(old_value: &f64, oper_value: &f64, o_type: &OperationType) -> ValueType { diff --git a/src/interpreter/condition.rs b/src/interpreter/condition.rs index 697e057..f5bfa4f 100644 --- a/src/interpreter/condition.rs +++ b/src/interpreter/condition.rs @@ -1,6 +1,7 @@ -use super::opcode_result_type::*; use crate::opcode::ComparisonOperators; use crate::opcode::ComparisonOperators::*; +use crate::opcode::OpCodeResultType; +use crate::opcode::OpCodeResultType::*; use crate::opcode::ValueType; use crate::opcode::ValueType::*; use std::collections::HashMap; @@ -24,7 +25,7 @@ pub fn condition( }; match result { - Ok(b) => Ok(OpCodeResultType::Bool(b)), + Ok(b) => Ok(Bool(b)), Err(e) => Err(e), } } diff --git a/src/interpreter/create.rs b/src/interpreter/create.rs index 1e42da7..63be603 100644 --- a/src/interpreter/create.rs +++ b/src/interpreter/create.rs @@ -1,4 +1,5 @@ -use super::opcode_result_type::*; +use crate::opcode::OpCodeResultType; +use crate::opcode::OpCodeResultType::*; use crate::opcode::ValueType; use crate::opcode::ValueType::*; use std::collections::HashMap; @@ -20,7 +21,7 @@ pub fn create<'a>( Arr(_arr) => target.insert(key, Arr(Vec::new())), }; - Ok(OpCodeResultType::Empty) + Ok(Empty) } fn complex_assignments_value<'a>( diff --git a/src/interpreter/error_printer.rs b/src/interpreter/error_printer.rs deleted file mode 100644 index 67b086c..0000000 --- a/src/interpreter/error_printer.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub fn print_error(file: &String, line: usize, error: &String) { - println!("File -> {}", file); - println!("Line # {}", line); - println!("Error: {}", error); -} diff --git a/src/interpreter/execute.rs b/src/interpreter/execute.rs index 79ab0f4..3d4590d 100644 --- a/src/interpreter/execute.rs +++ b/src/interpreter/execute.rs @@ -1,10 +1,10 @@ +use crate::opcode::OpCodeResultType; +use crate::opcode::OpCodeResultType::*; use crate::opcode::ValueType; use crate::opcode::ValueType::*; use std::collections::HashMap; use std::process::Command; -use super::OpCodeResultType; - pub fn execute<'a>( key: &'a String, command: &String, @@ -22,5 +22,5 @@ pub fn execute<'a>( target.insert(key, Line(result)); - Ok(OpCodeResultType::Empty) + Ok(Empty) } diff --git a/src/interpreter/include.rs b/src/interpreter/include.rs index 1a06233..e7a4640 100644 --- a/src/interpreter/include.rs +++ b/src/interpreter/include.rs @@ -1,5 +1,6 @@ -use super::opcode_result_type::*; use crate::code_runner::run; +use crate::opcode::OpCodeResultType; +use crate::opcode::OpCodeResultType::*; use crate::opcode::ValueType; use crate::opcode::ValueType::*; use std::collections::HashMap; @@ -30,9 +31,9 @@ pub fn include( run(file_clone, result_args_value); }); - Ok(OpCodeResultType::Thread(Some(handle))) + Ok(Thread(Some(handle))) } else { run(file.to_string(), result_args_value); - Ok(OpCodeResultType::Thread(None)) + Ok(Thread(None)) } } diff --git a/src/interpreter/mod.rs b/src/interpreter/mod.rs index 53e96d2..350d094 100644 --- a/src/interpreter/mod.rs +++ b/src/interpreter/mod.rs @@ -1,5 +1,7 @@ use crate::opcode::OpCode; use crate::opcode::OpCode::*; +use crate::opcode::OpCodeResultType; +use crate::opcode::OpCodeResultType::*; use crate::opcode::ValueType; use crate::opcode::ValueType::*; use std::collections::HashMap; @@ -9,21 +11,18 @@ mod arrays; mod calculate; mod condition; mod create; -mod error_printer; mod execute; mod include; -mod opcode_result_type; -mod print_file; -mod print_value; +mod network; +mod print; use arrays::push; use calculate::calculate; use condition::condition; use create::create; use execute::execute; use include::include; -use opcode_result_type::*; -use print_file::print_file; -use print_value::print_value; +use network::*; +use print::*; pub fn exegete(operations: Vec, args: Vec, file: &String) { if operations.is_empty() { @@ -58,14 +57,15 @@ pub fn exegete(operations: Vec, args: Vec, file: &String) { Include(p, a, s) => { push_new_thread(&mut parallel_computing, include(p, a, &addresses, s)) } + SendTcp(addr, mes) => send_tcp(addr, mes, &addresses), Sleep(i) => go_sleep(i), - EmptyLine => Ok(OpCodeResultType::Empty), + EmptyLine => Ok(Empty), }; match result { Ok(_) => {} Err(e) => { - error_printer::print_error(file, pointer + 1, &e); + print_error(file, pointer + 1, &e); return; } } diff --git a/src/interpreter/network.rs b/src/interpreter/network.rs new file mode 100644 index 0000000..476671e --- /dev/null +++ b/src/interpreter/network.rs @@ -0,0 +1,50 @@ +use crate::network::send_tcp_message; +use crate::opcode::OpCodeResultType; +use crate::opcode::OpCodeResultType::*; +use crate::opcode::ValueType; +use crate::opcode::ValueType::*; +use std::collections::HashMap; + +pub fn send_tcp( + addr: &String, + mes: &String, + storage: &HashMap<&String, ValueType>, +) -> Result { + let binding_addr = Line(addr.to_string()); + let binding_mes = Line(addr.to_string()); + let address = storage.get(addr).unwrap_or(&binding_addr); + let message = storage.get(mes).unwrap_or(&binding_mes); + + if !all_lines(address, message) { + return Err("Only strings can be either an address or a message".to_string()); + } + + let data = unpack_strings(address, message); + let result = send_tcp_message(data.0, data.1); + + // +_+ + match result { + Ok(_ok) => Ok(Empty), + Err(er) => Err(er.to_string()), + } +} + +fn all_lines(adr: &ValueType, mes: &ValueType) -> bool { + match (adr, mes) { + (ValueType::Line(_), ValueType::Line(_)) => true, + _ => false, + } +} + +fn unpack_strings<'a>(adr: &'a ValueType, mes: &'a ValueType) -> (&'a String, &'a String) { + let adr_string = match adr { + Line(line) => line, + _ => panic!("address parsing error"), + }; + let mes_string = match mes { + Line(line) => line, + _ => panic!("message parsing error"), + }; + + (adr_string, mes_string) +} diff --git a/src/interpreter/opcode_result_type.rs b/src/interpreter/opcode_result_type.rs deleted file mode 100644 index 8f07f3f..0000000 --- a/src/interpreter/opcode_result_type.rs +++ /dev/null @@ -1,7 +0,0 @@ -use std::thread::JoinHandle; - -pub enum OpCodeResultType { - Bool(bool), - Thread(Option>), - Empty, -} diff --git a/src/interpreter/print_file.rs b/src/interpreter/print.rs similarity index 53% rename from src/interpreter/print_file.rs rename to src/interpreter/print.rs index f223634..10e1c27 100644 --- a/src/interpreter/print_file.rs +++ b/src/interpreter/print.rs @@ -1,9 +1,28 @@ -use super::opcode_result_type::*; use crate::files::write_content_to_file; +use crate::opcode::OpCodeResultType; +use crate::opcode::OpCodeResultType::*; use crate::opcode::ValueType; use crate::opcode::ValueType::*; use std::collections::HashMap; +pub fn print_value( + key: &String, + storage: &HashMap<&String, ValueType>, +) -> Result { + let value = storage.get(key); + + match value { + Some(s) => match s { + Int(i) => println!("{}", i), + Line(s) => println!("{}", s), + Arr(_a) => return Err("you can't print an array".to_string()), + }, + None => println!("{}", key), + }; + + Ok(Empty) +} + pub fn print_file( key: &String, path: &String, @@ -25,3 +44,9 @@ pub fn print_file( Ok(OpCodeResultType::Empty) } + +pub fn print_error(file: &String, line: usize, error: &String) { + println!("File -> {}", file); + println!("Line # {}", line); + println!("Error: {}", error); +} diff --git a/src/interpreter/print_value.rs b/src/interpreter/print_value.rs deleted file mode 100644 index 8e46f61..0000000 --- a/src/interpreter/print_value.rs +++ /dev/null @@ -1,22 +0,0 @@ -use super::opcode_result_type::*; -use crate::opcode::ValueType; -use crate::opcode::ValueType::*; -use std::collections::HashMap; - -pub fn print_value( - key: &String, - storage: &HashMap<&String, ValueType>, -) -> Result { - let value = storage.get(key); - - match value { - Some(s) => match s { - Int(i) => println!("{}", i), - Line(s) => println!("{}", s), - Arr(_a) => return Err("you can't print an array".to_string()), - }, - None => println!("{}", key), - }; - - Ok(OpCodeResultType::Empty) -} diff --git a/src/main.rs b/src/main.rs index e4669d4..2ad5747 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,7 @@ use clap::Parser; mod code_runner; mod files; mod interpreter; +mod network; mod opcode; mod parser; mod self_update; diff --git a/src/network/mod.rs b/src/network/mod.rs new file mode 100644 index 0000000..d00a31d --- /dev/null +++ b/src/network/mod.rs @@ -0,0 +1,12 @@ +use std::io::Write; +use std::net::TcpStream; + +pub fn send_tcp_message(addr: &String, message: &String) -> std::io::Result<()> { + // Подключаемся к серверу по указанному IP и порту + let mut stream = TcpStream::connect(addr)?; + + // Отправляем сообщение + stream.write_all(message.as_bytes())?; + + Ok(()) +} diff --git a/src/opcode/mod.rs b/src/opcode/mod.rs index b7e71b4..7876f11 100644 --- a/src/opcode/mod.rs +++ b/src/opcode/mod.rs @@ -1,3 +1,5 @@ +use std::thread::JoinHandle; + #[derive(PartialEq, Debug, Clone, PartialOrd)] pub enum ValueType { Int(f64), @@ -32,6 +34,13 @@ pub enum OpCode { ErrorCode(String), Execute(String, String, Vec), Include(String, Vec, bool), + SendTcp(String, String), Sleep(u64), EmptyLine, } + +pub enum OpCodeResultType { + Bool(bool), + Thread(Option>), + Empty, +} diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 99f22a1..34577ac 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -5,6 +5,7 @@ mod condition; mod exec; mod file; mod include; +mod network; mod opcode_parser; mod print; mod sleep; diff --git a/src/parser/network.rs b/src/parser/network.rs new file mode 100644 index 0000000..17d8ea3 --- /dev/null +++ b/src/parser/network.rs @@ -0,0 +1,44 @@ +pub use crate::opcode::OpCode; +pub use crate::opcode::OpCode::*; + +pub fn send_tcp(data: Vec<&str>) -> OpCode { + if data.len() < 3 { + return ErrorCode("the operation is not specified correctly".to_string()); + } + + let addr = data[1].to_string(); + let message = data[2].to_string(); + + SendTcp(addr, message) +} + +#[cfg(test)] +mod tests { + use super::send_tcp; + use crate::opcode::OpCode::*; + use pretty_assertions::assert_eq; + + #[test] + fn test_send_tcp_one() { + let data = vec!["@", "a", "m"]; + let result = send_tcp(data); + assert_eq!(result, SendTcp("a".to_string(), "m".to_string())); + } + + #[test] + fn test_send_tcp_two() { + let data = vec!["@", "a", "m", "asdas", "asdsad"]; + let result = send_tcp(data); + assert_eq!(result, SendTcp("a".to_string(), "m".to_string())); + } + + #[test] + fn test_send_tcp_three() { + let data = vec!["@", "a"]; + let result = send_tcp(data); + assert_eq!( + result, + ErrorCode("the operation is not specified correctly".to_string()) + ); + } +} diff --git a/src/parser/opcode_parser.rs b/src/parser/opcode_parser.rs index 8bee13b..3a30ce4 100644 --- a/src/parser/opcode_parser.rs +++ b/src/parser/opcode_parser.rs @@ -8,6 +8,7 @@ use super::condition::condition; use super::exec::exec; use super::file::file; use super::include::include; +use super::network::send_tcp; use super::print::print; use super::sleep::sleep; use super::user_var::user_var; @@ -31,6 +32,7 @@ pub fn get_opcode(line: &String) -> OpCode { "->" => include(data, false), "-->" => include(data, true), "-_-" => sleep(data), + "@" => send_tcp(data), "#" => EmptyLine, _ => ErrorCode("Could not recognize the command".to_string()), } diff --git a/tests/examples/send_tcp.mcode b/tests/examples/send_tcp.mcode new file mode 100644 index 0000000..989e360 --- /dev/null +++ b/tests/examples/send_tcp.mcode @@ -0,0 +1,4 @@ +> address 127.0.0.1:1509 +> message hello from minicode +@ address message +p done