diff --git a/Cargo.lock b/Cargo.lock index 8c9d5ea..71329ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -758,7 +758,7 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "minicode" -version = "1.3.6" +version = "1.3.7" dependencies = [ "clap", "pretty_assertions", diff --git a/Cargo.toml b/Cargo.toml index 00d2567..0cce53e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "minicode" -version = "1.3.6" +version = "1.3.7" authors = ["Kirill Leonov "] edition = "2021" repository = "https://github.com/leonovk/minicode" diff --git a/README.md b/README.md index 0a4a807..e42c513 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ FROM minicode:latest COPY . . -CMD ["minicode", "-p", "hello_world.mc"] +CMD ["minicode", "-p", "hello_world.mcode"] ``` ## Contributing diff --git a/docs/index.md b/docs/index.md index 86df520..51e76b0 100644 --- a/docs/index.md +++ b/docs/index.md @@ -199,7 +199,7 @@ p text The greater than or less than operators '>', '<' are also supported -You will find more examples in the folder -> test/examples +You will find more examples in the folder -> tests/examples ## Write data to file @@ -227,7 +227,15 @@ For example, this is how you can write the current version of your minicode into You can include another minicode file into your code. The code will connect and be executed immediately. ```mc --> test/examples/hello_world.mc +-> tests/examples/hello_world.mcode +``` + +Just like when running regular minicode code, you can pass arguments to the command line, which will be available as ARG_1, ARG_2 and so on in the list + +If you specify a long arrow as a command, as in the example below, then the following code will be executed asynchronously. + +```mc +--> tests/examples/hello_world.mcode ``` ## Some examples diff --git a/docs/ru.md b/docs/ru.md index dd80669..51c9c5f 100644 --- a/docs/ru.md +++ b/docs/ru.md @@ -217,7 +217,15 @@ p text Вы можете подключить другой файл с исходным кодом на миникоде, в ваш файл. Код из другого файла будет выполнен сразу. ```mc --> test/examples/hello_world.mc +-> tests/examples/hello_world.mcode +``` + +Точно также как и при запуске обычного миникод кода, вы можете передавать аргументы командой строки, который будут достпны как ARG_1, ARG_2 и так далее по списку + +Если указать длинную стрелочку в качестве команды, как на примере ниже, то сладеюущий код будет выполнятся асинхронно. + +```mc +--> tests/examples/hello_world.mcode ``` ## Некоторые примеры diff --git a/install.sh b/install.sh index 1ada12b..04c98e6 100644 --- a/install.sh +++ b/install.sh @@ -58,7 +58,7 @@ if command -v $exe_name --version >/dev/null; then printf "Run '\e[1;32m%s --help\e[0m' to get started\n" "$exe_name" else echo "Manually add the directory to your \$HOME/.bash_profile (or similar)" - echo " export PATH=${executable_folder}:\$PATH" + echo " echo 'export PATH=${executable_folder}:\$PATH' >> .bash_profile" printf "Run '\e[1;32m%s --help\e[0m' to get started\n" "$exe_name" fi diff --git a/src/files/mod.rs b/src/files/mod.rs index e5c154d..8a0b661 100644 --- a/src/files/mod.rs +++ b/src/files/mod.rs @@ -36,7 +36,7 @@ mod tests { #[test] fn test_get_lines() { - let path = "test/test_file.txt".to_string(); + let path = "tests/test_file.txt".to_string(); assert_eq!( get_lines(&path), vec!["first".to_string(), "second".to_string()] @@ -45,7 +45,7 @@ mod tests { #[test] fn test_get_content() { - let path = "test/test_file.txt".to_string(); + let path = "tests/test_file.txt".to_string(); assert_eq!(get_content(&path), "first\nsecond".to_string()); } } diff --git a/src/interpreter/include.rs b/src/interpreter/include.rs index 30dff72..65f0282 100644 --- a/src/interpreter/include.rs +++ b/src/interpreter/include.rs @@ -2,8 +2,14 @@ use crate::code_runner::run; use crate::opcode::ValueType; use crate::opcode::ValueType::*; use std::collections::HashMap; +use std::thread::{self, JoinHandle}; -pub fn include(file: &String, args: &Vec, storage: &HashMap<&String, ValueType>) { +pub fn include( + file: &String, + args: &Vec, + storage: &HashMap<&String, ValueType>, + stream: &bool, +) -> Option> { let mut result_args_value = Vec::new(); for arg in args { @@ -16,5 +22,15 @@ pub fn include(file: &String, args: &Vec, storage: &HashMap<&String, Val }; } - run(file.to_string(), result_args_value); + if *stream { + let file_clone = file.clone(); + let handle = thread::spawn(|| { + run(file_clone, result_args_value); + }); + + Some(handle) + } else { + run(file.to_string(), result_args_value); + None + } } diff --git a/src/interpreter/mod.rs b/src/interpreter/mod.rs index 7ea9bcd..962de11 100644 --- a/src/interpreter/mod.rs +++ b/src/interpreter/mod.rs @@ -3,6 +3,8 @@ use crate::opcode::OpCode::*; use crate::opcode::ValueType; use crate::opcode::ValueType::*; use std::collections::HashMap; +use std::thread; +use std::time::Duration; mod calculate; mod condition; mod create; @@ -26,6 +28,8 @@ pub fn exegete(operations: Vec, args: Vec) { let code_max_point = operations.len() - 1; let mut pointer: usize = 0; let mut addresses: HashMap<&String, ValueType> = HashMap::new(); + let mut parallel_computing = Vec::new(); + let c_args = parse_command_line_arguments(args); for (key, value) in &c_args { @@ -51,12 +55,24 @@ pub fn exegete(operations: Vec, args: Vec) { } PrintFile(key, path) => print_file(key, path, &addresses), Execute(k, c, arg) => execute(k, c, arg, &mut addresses), - Include(p, a) => include(p, a, &addresses), + Include(p, a, s) => { + let result = include(p, a, &addresses, s); + + match result { + Some(h) => parallel_computing.push(h), + None => {} + } + } + Sleep(i) => thread::sleep(Duration::from_secs(*i)), EmptyLine => {} } pointer += 1; } + + for compute in parallel_computing { + compute.join().expect("error"); + } } fn parse_command_line_arguments(args: Vec) -> HashMap { diff --git a/src/opcode/mod.rs b/src/opcode/mod.rs index 4fc3073..817ec77 100644 --- a/src/opcode/mod.rs +++ b/src/opcode/mod.rs @@ -29,6 +29,7 @@ pub enum OpCode { Condition(String, ValueType, ComparisonOperators, usize), ErrorCode(String), Execute(String, String, Vec), - Include(String, Vec), + Include(String, Vec, bool), + Sleep(u64), EmptyLine, } diff --git a/src/parser/include.rs b/src/parser/include.rs index ccdee88..c4a2716 100644 --- a/src/parser/include.rs +++ b/src/parser/include.rs @@ -1,7 +1,7 @@ pub use crate::opcode::OpCode; pub use crate::opcode::OpCode::*; -pub fn include(data: Vec<&str>) -> OpCode { +pub fn include(data: Vec<&str>, stream: bool) -> OpCode { if data.len() < 2 { return ErrorCode("the operation is not specified correctly".to_string()); } @@ -14,7 +14,7 @@ pub fn include(data: Vec<&str>) -> OpCode { args.push(arg.to_string()); } - Include(value_name, args) + Include(value_name, args, stream) } #[cfg(test)] @@ -26,24 +26,28 @@ mod tests { #[test] fn test_include_one() { let data = vec!["->", "a", "b", "c"]; - let result = include(data); + let result = include(data, false); assert_eq!( result, - Include("a".to_string(), vec!["b".to_string(), "c".to_string()]) + Include( + "a".to_string(), + vec!["b".to_string(), "c".to_string()], + false + ) ); } #[test] fn test_include_two() { let data = vec!["->", "a"]; - let result = include(data); - assert_eq!(result, Include("a".to_string(), vec![])); + let result = include(data, true); + assert_eq!(result, Include("a".to_string(), vec![], true)); } #[test] fn test_include_three() { let data = vec!["p"]; - let result = include(data); + let result = include(data, false); assert_eq!( result, ErrorCode("the operation is not specified correctly".to_string()) diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 2992218..62310fe 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -6,6 +6,7 @@ mod file; mod include; mod opcode_parser; mod print; +mod sleep; mod user_var; mod write; use crate::opcode::*; diff --git a/src/parser/opcode_parser.rs b/src/parser/opcode_parser.rs index 9ebff62..4f39749 100644 --- a/src/parser/opcode_parser.rs +++ b/src/parser/opcode_parser.rs @@ -8,6 +8,7 @@ use super::exec::exec; use super::file::file; use super::include::include; use super::print::print; +use super::sleep::sleep; use super::user_var::user_var; use super::write::file_write; @@ -24,7 +25,9 @@ pub fn get_opcode(line: &String) -> OpCode { "?" => condition(data), ">>" => file_write(data), "&" => exec(data), - "->" => include(data), + "->" => include(data, false), + "-->" => include(data, true), + "sleep" => sleep(data), _ => ErrorCode("Could not recognize the command".to_string()), } } @@ -52,7 +55,7 @@ mod tests { #[test] fn test_get_opcode_file() { - let ex1 = "f a test/test_file.txt".to_string(); + let ex1 = "f a tests/test_file.txt".to_string(); assert_eq!( get_opcode(&ex1), diff --git a/src/parser/sleep.rs b/src/parser/sleep.rs new file mode 100644 index 0000000..cd65100 --- /dev/null +++ b/src/parser/sleep.rs @@ -0,0 +1,15 @@ +use crate::opcode::OpCode; +use crate::opcode::OpCode::*; + +pub fn sleep(data: Vec<&str>) -> OpCode { + if data.len() != 2 { + return ErrorCode("the operation is not specified correctly".to_string()); + } + + let value = match data[1].to_string().parse::() { + Ok(parsed) => Sleep(parsed), + Err(_e) => ErrorCode("the operation is not specified correctly".to_string()), + }; + + value +} diff --git a/test/examples/file_write.mc b/test/examples/file_write.mc deleted file mode 100644 index fd9fba6..0000000 --- a/test/examples/file_write.mc +++ /dev/null @@ -1,2 +0,0 @@ -> a hello world ->> test/test.txt a diff --git a/test/examples/include.mc b/test/examples/include.mc deleted file mode 100644 index eb3c661..0000000 --- a/test/examples/include.mc +++ /dev/null @@ -1,9 +0,0 @@ -p text one --> test/examples/output_by_characters.mc -p done -p text two -> a 1 -> b 2 -> c 3 --> test/examples/cli.mc a b c -p done again diff --git a/test/examples/print_file.mc b/test/examples/print_file.mc deleted file mode 100644 index 91df168..0000000 --- a/test/examples/print_file.mc +++ /dev/null @@ -1,2 +0,0 @@ -f a test/test_file.txt -p a diff --git a/test/examples/arithmetic.mc b/tests/examples/arithmetic.mcode similarity index 100% rename from test/examples/arithmetic.mc rename to tests/examples/arithmetic.mcode diff --git a/test/examples/cli.mc b/tests/examples/cli.mcode similarity index 100% rename from test/examples/cli.mc rename to tests/examples/cli.mcode diff --git a/test/examples/condition.mc b/tests/examples/condition.mcode similarity index 100% rename from test/examples/condition.mc rename to tests/examples/condition.mcode diff --git a/test/examples/execute.mc b/tests/examples/execute.mcode similarity index 100% rename from test/examples/execute.mc rename to tests/examples/execute.mcode diff --git a/test/examples/extended_conditions.mc b/tests/examples/extended_conditions.mcode similarity index 100% rename from test/examples/extended_conditions.mc rename to tests/examples/extended_conditions.mcode diff --git a/test/examples/fib.mc b/tests/examples/fib.mcode similarity index 100% rename from test/examples/fib.mc rename to tests/examples/fib.mcode diff --git a/tests/examples/file_write.mcode b/tests/examples/file_write.mcode new file mode 100644 index 0000000..2593598 --- /dev/null +++ b/tests/examples/file_write.mcode @@ -0,0 +1,2 @@ +> a hello world +>> tests/test.txt a diff --git a/test/examples/float.mc b/tests/examples/float.mcode similarity index 100% rename from test/examples/float.mc rename to tests/examples/float.mcode diff --git a/test/examples/hello_world.mc b/tests/examples/hello_world.mcode similarity index 100% rename from test/examples/hello_world.mc rename to tests/examples/hello_world.mcode diff --git a/test/examples/inc_and_dec.mc b/tests/examples/inc_and_dec.mcode similarity index 100% rename from test/examples/inc_and_dec.mc rename to tests/examples/inc_and_dec.mcode diff --git a/tests/examples/include.mcode b/tests/examples/include.mcode new file mode 100644 index 0000000..eb049aa --- /dev/null +++ b/tests/examples/include.mcode @@ -0,0 +1,9 @@ +p text one +-> tests/examples/output_by_characters.mcode +p done +p text two +> a 1 +> b 2 +> c 3 +-> tests/examples/cli.mcode a b c +p done again diff --git a/tests/examples/include_p.mcode b/tests/examples/include_p.mcode new file mode 100644 index 0000000..ba2953b --- /dev/null +++ b/tests/examples/include_p.mcode @@ -0,0 +1,5 @@ +p start +--> tests/examples/sleep.mcode +--> tests/examples/sleep_2.mcode +--> tests/examples/sleep_3.mcode +p stop diff --git a/test/examples/more_or_less.mc b/tests/examples/more_or_less.mcode similarity index 100% rename from test/examples/more_or_less.mc rename to tests/examples/more_or_less.mcode diff --git a/test/examples/output_by_characters.mc b/tests/examples/output_by_characters.mcode similarity index 100% rename from test/examples/output_by_characters.mc rename to tests/examples/output_by_characters.mcode diff --git a/tests/examples/print_file.mcode b/tests/examples/print_file.mcode new file mode 100644 index 0000000..674e436 --- /dev/null +++ b/tests/examples/print_file.mcode @@ -0,0 +1,2 @@ +f a tests/test_file.txt +p a diff --git a/tests/examples/sleep.mcode b/tests/examples/sleep.mcode new file mode 100644 index 0000000..e52ab47 --- /dev/null +++ b/tests/examples/sleep.mcode @@ -0,0 +1,5 @@ +> text lol kek cheburek +p start sleep now +sleep 10 +p stop sleep now +p text diff --git a/tests/examples/sleep_2.mcode b/tests/examples/sleep_2.mcode new file mode 100644 index 0000000..20d4879 --- /dev/null +++ b/tests/examples/sleep_2.mcode @@ -0,0 +1,2 @@ +p sleep 2 +sleep 10 diff --git a/tests/examples/sleep_3.mcode b/tests/examples/sleep_3.mcode new file mode 100644 index 0000000..8a53c6f --- /dev/null +++ b/tests/examples/sleep_3.mcode @@ -0,0 +1,2 @@ +p sleep 3 +sleep 10 diff --git a/test/test_file.txt b/tests/test_file.txt similarity index 100% rename from test/test_file.txt rename to tests/test_file.txt