From fcd31b81f40a827ca5c014a0c512896fcb57bbd2 Mon Sep 17 00:00:00 2001 From: Kay Date: Mon, 18 Mar 2024 01:25:21 +0000 Subject: [PATCH] style: using cargo fmt for formatting --- .github/workflows/rust.yml | 2 + src/arg_paresr.rs | 13 +- src/common/chunk.rs | 5 +- src/common/data_type.rs | 36 +- src/common/errors.rs | 79 ++-- src/common/executable.rs | 26 +- src/common/help.rs | 5 +- src/common/line_of_code.rs | 12 +- src/common/mod.rs | 9 +- src/common/param.rs | 3 +- src/common/splitter.rs | 28 +- src/common/version.rs | 6 +- src/eval/mod.rs | 46 +-- src/file_executor/mod.rs | 57 ++- src/lib.rs | 5 +- src/main.rs | 24 +- src/parser/chunk_detector.rs | 206 +++++----- src/parser/get_single_var.rs | 58 ++- src/parser/mod.rs | 367 +++++++++++------- src/preprocessor/mod.rs | 184 +++++---- src/repl/mod.rs | 40 +- src/runtime/builtin_function/assign.rs | 43 +- src/runtime/builtin_function/bools/and.rs | 25 +- src/runtime/builtin_function/bools/equal.rs | 12 +- .../builtin_function/bools/greater_than.rs | 25 +- .../builtin_function/bools/less_than.rs | 26 +- src/runtime/builtin_function/bools/mod.rs | 9 +- src/runtime/builtin_function/bools/not.rs | 23 +- .../builtin_function/bools/not_equal.rs | 12 +- src/runtime/builtin_function/bools/or.rs | 26 +- .../builtin_function/control_flow/jump.rs | 46 ++- .../builtin_function/control_flow/jump_if.rs | 25 +- .../control_flow/jump_if_equal.rs | 15 +- .../control_flow/jump_if_not.rs | 25 +- .../control_flow/jump_if_not_equal.rs | 15 +- .../builtin_function/control_flow/mod.rs | 9 +- .../builtin_function/control_flow/new_tag.rs | 42 +- src/runtime/builtin_function/date_time/mod.rs | 2 - src/runtime/builtin_function/date_time/now.rs | 7 +- src/runtime/builtin_function/debugger/dump.rs | 22 +- src/runtime/builtin_function/debugger/mod.rs | 60 ++- src/runtime/builtin_function/delay/mod.rs | 6 +- .../builtin_function/delay/wait_hour.rs | 21 +- .../builtin_function/delay/wait_millis.rs | 21 +- .../builtin_function/delay/wait_minute.rs | 22 +- .../builtin_function/delay/wait_second.rs | 22 +- .../builtin_function/error_handling/mod.rs | 3 +- src/runtime/builtin_function/list/get.rs | 47 ++- src/runtime/builtin_function/list/has.rs | 25 +- src/runtime/builtin_function/list/index_of.rs | 28 +- src/runtime/builtin_function/list/insert.rs | 32 +- src/runtime/builtin_function/list/last.rs | 36 +- src/runtime/builtin_function/list/mod.rs | 19 +- src/runtime/builtin_function/list/pop.rs | 36 +- src/runtime/builtin_function/list/remove.rs | 33 +- .../builtin_function/list/remove_at.rs | 52 ++- src/runtime/builtin_function/math/add.rs | 31 +- src/runtime/builtin_function/math/add_many.rs | 13 +- src/runtime/builtin_function/math/decrease.rs | 34 +- src/runtime/builtin_function/math/divide.rs | 33 +- src/runtime/builtin_function/math/increase.rs | 37 +- src/runtime/builtin_function/math/minus.rs | 31 +- src/runtime/builtin_function/math/mod.rs | 14 +- src/runtime/builtin_function/math/modulus.rs | 29 +- src/runtime/builtin_function/math/multiply.rs | 23 +- src/runtime/builtin_function/math/power.rs | 23 +- src/runtime/builtin_function/math/sqrt.rs | 21 +- src/runtime/builtin_function/mod.rs | 103 +++-- src/runtime/builtin_function/random/mod.rs | 7 +- .../builtin_function/random/random_bool.rs | 9 +- .../builtin_function/random/random_choice.rs | 24 +- .../builtin_function/random/random_number.rs | 34 +- .../builtin_function/random/random_string.rs | 44 +-- src/runtime/builtin_function/std/exit.rs | 9 +- src/runtime/builtin_function/std/input.rs | 34 +- src/runtime/builtin_function/std/mod.rs | 4 +- src/runtime/builtin_function/std/println.rs | 86 ++-- .../builtin_function/strings/contact.rs | 10 +- .../builtin_function/strings/contains.rs | 10 +- .../builtin_function/strings/length.rs | 26 +- src/runtime/builtin_function/strings/mod.rs | 8 +- .../builtin_function/strings/repeat.rs | 22 +- src/runtime/builtin_function/strings/slice.rs | 23 +- .../builtin_function/type_conversion/mod.rs | 6 +- .../type_conversion/to_float.rs | 34 +- .../type_conversion/to_int.rs | 39 +- .../type_conversion/to_string.rs | 8 +- src/runtime/builtin_function/type_of.rs | 8 +- src/runtime/builtin_function/utils.rs | 89 +++-- src/runtime/mod.rs | 85 ++-- 90 files changed, 1661 insertions(+), 1433 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index b780e66..e87b048 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -20,3 +20,5 @@ jobs: run: cargo build --verbose - name: Run tests run: cargo test --verbose + - name: Run Cargo Fmt + run: cargo fmt --check diff --git a/src/arg_paresr.rs b/src/arg_paresr.rs index 5dd73be..bd329f9 100644 --- a/src/arg_paresr.rs +++ b/src/arg_paresr.rs @@ -1,24 +1,21 @@ - use std::env; -pub fn arg_parser() -> InputType{ +pub fn arg_parser() -> InputType { let args: Vec = env::args().collect(); match args.get(1) { None => InputType::Repl, Some(param) => match param.as_str() { "--help" | "-h" => InputType::Help, - "--version" | "-v"=> InputType::Version, - file_name => { - InputType::ExecuteFile(file_name.to_string()) - } + "--version" | "-v" => InputType::Version, + file_name => InputType::ExecuteFile(file_name.to_string()), }, } } -pub enum InputType{ +pub enum InputType { ExecuteFile(String), Help, Repl, - Version + Version, } diff --git a/src/common/chunk.rs b/src/common/chunk.rs index 20cb132..cfdefe1 100644 --- a/src/common/chunk.rs +++ b/src/common/chunk.rs @@ -1,8 +1,7 @@ - use super::param::Param; #[derive(Debug, PartialEq, Clone)] -pub enum Chunk{ +pub enum Chunk { Params(Vec), Function(String), -} \ No newline at end of file +} diff --git a/src/common/data_type.rs b/src/common/data_type.rs index e358c8f..3e63347 100644 --- a/src/common/data_type.rs +++ b/src/common/data_type.rs @@ -1,12 +1,10 @@ - - #[derive(PartialEq, Debug, Clone)] pub enum DataType { String(String), Int(i32), Float(f64), Bool(bool), - List(Vec) + List(Vec), } impl ToString for DataType { @@ -17,18 +15,17 @@ impl ToString for DataType { Self::Float(f) => f.to_string(), Self::Bool(b) => b.to_string(), Self::List(b) => { - let a = b.iter().map(|x|x.to_string()); + let a = b.iter().map(|x| x.to_string()); let a: Vec = a.collect(); let i = a.join(" "); - format!("[{}]",i) - }, + format!("[{}]", i) + } } } } impl DataType { - - pub fn type_name(&self) -> String{ + pub fn type_name(&self) -> String { match self { DataType::String(_) => "string".to_string(), DataType::Int(_) => "int".to_string(), @@ -39,26 +36,25 @@ impl DataType { } } - #[cfg(test)] -mod tests{ +mod tests { use super::*; #[test] - fn data_type_equal_test(){ - assert!( - DataType::String("abcd".to_string()) == DataType::String("abcd".to_string()) - ); - assert!( - DataType::String("abce".to_string()) != DataType::String("abcd".to_string()) - ); + fn data_type_equal_test() { + assert!(DataType::String("abcd".to_string()) == DataType::String("abcd".to_string())); + assert!(DataType::String("abce".to_string()) != DataType::String("abcd".to_string())); } #[test] - fn list_to_string(){ + fn list_to_string() { assert_eq!( - DataType::List(vec![DataType::Int(1), DataType::String("hello".to_string())]).to_string(), + DataType::List(vec![ + DataType::Int(1), + DataType::String("hello".to_string()) + ]) + .to_string(), "[1 hello]" ); } -} \ No newline at end of file +} diff --git a/src/common/errors.rs b/src/common/errors.rs index 2352efe..b7ed733 100644 --- a/src/common/errors.rs +++ b/src/common/errors.rs @@ -10,7 +10,7 @@ pub enum ErrorType { } impl ErrorType { - pub fn to_string(&self) -> &str{ + pub fn to_string(&self) -> &str { match *self { ErrorType::Syntax => "syntax", ErrorType::StaticAnalyzer => "static analyzer", @@ -22,60 +22,93 @@ impl ErrorType { } #[derive(PartialEq, Debug, Clone)] -pub struct ChapError{ +pub struct ChapError { line_number: u32, msg: Option, - pub err_type: ErrorType + pub err_type: ErrorType, } pub type Result = core::result::Result; - impl ChapError { - pub fn syntax_with_msg(line_number: u32, msg: String) -> Self { - Self { line_number, msg: Some(msg), err_type: ErrorType::Syntax } + Self { + line_number, + msg: Some(msg), + err_type: ErrorType::Syntax, + } } pub fn static_analyzer_with_msg(line_number: u32, msg: String) -> Self { - Self { line_number, msg: Some(msg), err_type: ErrorType::StaticAnalyzer } + Self { + line_number, + msg: Some(msg), + err_type: ErrorType::StaticAnalyzer, + } } pub fn runtime_with_msg(line_number: u32, msg: String) -> Self { - Self { line_number, msg: Some(msg), err_type: ErrorType::Runtime } + Self { + line_number, + msg: Some(msg), + err_type: ErrorType::Runtime, + } } pub fn syntax(line_number: u32) -> Self { - Self { line_number, msg: None, err_type: ErrorType::Syntax } + Self { + line_number, + msg: None, + err_type: ErrorType::Syntax, + } } pub fn static_analyzer(line_number: u32) -> Self { - Self { line_number, msg: None, err_type: ErrorType::StaticAnalyzer } + Self { + line_number, + msg: None, + err_type: ErrorType::StaticAnalyzer, + } } pub fn runtime(line_number: u32) -> Self { - Self { line_number, msg: None, err_type: ErrorType::Runtime } + Self { + line_number, + msg: None, + err_type: ErrorType::Runtime, + } } - pub fn no_more_line() -> Self{ - Self { line_number: 0, msg: None, err_type: ErrorType::NothingToExecute } + pub fn no_more_line() -> Self { + Self { + line_number: 0, + msg: None, + err_type: ErrorType::NothingToExecute, + } } - pub fn stop() -> Self{ - Self { line_number: 0, msg: None, err_type: ErrorType::Stop } + pub fn stop() -> Self { + Self { + line_number: 0, + msg: None, + err_type: ErrorType::Stop, + } } - pub fn exit_with_error(&self){ + pub fn exit_with_error(&self) { println!("{}", self.error_message()); panic!(); } - // on the REPL mode we should not shut the whole interperter down - pub fn show_warning(&self){ + // on the REPL mode we should not shut the whole interperter down + pub fn show_warning(&self) { println!("{}", self.error_message()); } - pub fn error_message(&self) -> String{ + pub fn error_message(&self) -> String { let mut result = String::new(); - result.push_str(&format!("\t{} Error on line: {}", self.err_type.to_string(), self.line_number)); - if let Some(msg) = &self.msg{ - result.push_str(&format!("\terror message: {} ",msg)); + result.push_str(&format!( + "\t{} Error on line: {}", + self.err_type.to_string(), + self.line_number + )); + if let Some(msg) = &self.msg { + result.push_str(&format!("\terror message: {} ", msg)); } result } - } diff --git a/src/common/executable.rs b/src/common/executable.rs index be2918a..3199900 100644 --- a/src/common/executable.rs +++ b/src/common/executable.rs @@ -1,13 +1,12 @@ - -use crate::runtime::Runtime; -use crate::runtime::builtin_function::closure_gen; -use crate::common::errors::Result; use super::param::Param; +use crate::common::errors::Result; +use crate::runtime::builtin_function::closure_gen; +use crate::runtime::Runtime; pub type BuiltinFunction = fn(&mut Runtime, &ExecutableLine) -> Result<()>; #[derive(PartialEq, Debug, Clone)] -pub struct ExecutableLine{ +pub struct ExecutableLine { pub line_number: u32, // for error throw information pub function_name: String, pub params: Vec, @@ -16,24 +15,23 @@ pub struct ExecutableLine{ } impl ExecutableLine { - pub fn new( line_number: u32, function_name: String, params: Vec, - output_var: Option - ) -> Self{ - Self { + output_var: Option, + ) -> Self { + Self { line_number, function_name, params, - output_var, - closure: |_,_|{Ok(())}, + output_var, + closure: |_, _| Ok(()), } } - pub fn bind_closure(&mut self) -> Result<()>{ - self.closure = closure_gen(self)?; + pub fn bind_closure(&mut self) -> Result<()> { + self.closure = closure_gen(self)?; Ok(()) } -} \ No newline at end of file +} diff --git a/src/common/help.rs b/src/common/help.rs index 0f1d549..1f26b4d 100644 --- a/src/common/help.rs +++ b/src/common/help.rs @@ -1,5 +1,4 @@ - -pub fn show_help(){ +pub fn show_help() { println!("┌───────────────────────────────────────────────┐"); println!("│ Chap Language │"); println!("│ │"); @@ -16,4 +15,4 @@ pub fn show_help(){ println!("│ -v, --version │"); println!("│ │"); println!("└───────────────────────────────────────────────┘"); - } \ No newline at end of file +} diff --git a/src/common/line_of_code.rs b/src/common/line_of_code.rs index 8dad767..309930e 100644 --- a/src/common/line_of_code.rs +++ b/src/common/line_of_code.rs @@ -1,13 +1,11 @@ - - #[derive(Debug)] -pub struct LineOfCode{ +pub struct LineOfCode { pub line_number: u32, - pub code: String + pub code: String, } impl LineOfCode { - pub fn new(line_number: u32, code: String) -> Self{ - Self{line_number, code} + pub fn new(line_number: u32, code: String) -> Self { + Self { line_number, code } } -} \ No newline at end of file +} diff --git a/src/common/mod.rs b/src/common/mod.rs index 6c01cbc..c4f797a 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -1,10 +1,9 @@ - -pub mod line_of_code; pub mod chunk; -pub mod param; pub mod data_type; -pub mod executable; pub mod errors; +pub mod executable; pub mod help; +pub mod line_of_code; +pub mod param; +pub mod splitter; pub mod version; -pub mod splitter; \ No newline at end of file diff --git a/src/common/param.rs b/src/common/param.rs index 62eb5eb..aa1e09f 100644 --- a/src/common/param.rs +++ b/src/common/param.rs @@ -1,4 +1,3 @@ - use super::data_type::DataType; #[derive(PartialEq, Debug, Clone)] @@ -6,4 +5,4 @@ pub enum Param { Tag(String), Variable(String), Value(DataType), -} \ No newline at end of file +} diff --git a/src/common/splitter.rs b/src/common/splitter.rs index f6a4224..b6050db 100644 --- a/src/common/splitter.rs +++ b/src/common/splitter.rs @@ -1,15 +1,14 @@ - -pub fn string_safe_split(inp: &str, pattern: String) -> Vec<&str>{ +pub fn string_safe_split(inp: &str, pattern: String) -> Vec<&str> { let mut result: Vec<&str> = vec![]; - let mut quotations_on_left=0; + let mut quotations_on_left = 0; let mut last_seen = 0; - for (i,ch) in inp.chars().enumerate(){ - if ch == '\"'{ - quotations_on_left+=1; + for (i, ch) in inp.chars().enumerate() { + if ch == '\"' { + quotations_on_left += 1; } let token = &inp[i..]; - if token.starts_with(&pattern) && quotations_on_left%2==0{ + if token.starts_with(&pattern) && quotations_on_left % 2 == 0 { result.push(&inp[last_seen..i]); last_seen = i + pattern.len(); } @@ -19,28 +18,27 @@ pub fn string_safe_split(inp: &str, pattern: String) -> Vec<&str>{ result } - #[cfg(test)] -mod tests{ +mod tests { use crate::common::splitter::string_safe_split; #[test] - fn comma_spliter_test(){ + fn comma_spliter_test() { assert_eq!( string_safe_split("ali,hasan,majid", ",".to_string()), - vec!["ali","hasan","majid"] + vec!["ali", "hasan", "majid"] ); assert_eq!( string_safe_split("\"ali,hasan\",majid", ",".to_string()), - vec!["\"ali,hasan\"","majid"] + vec!["\"ali,hasan\"", "majid"] ); } #[test] - fn split_longer_pattern(){ + fn split_longer_pattern() { assert_eq!( string_safe_split("1 -> print -> $a ", "->".to_string()), - vec!["1 "," print ", " $a "] + vec!["1 ", " print ", " $a "] ); } -} \ No newline at end of file +} diff --git a/src/common/version.rs b/src/common/version.rs index 9bd7004..7f05af9 100644 --- a/src/common/version.rs +++ b/src/common/version.rs @@ -1,7 +1,5 @@ - pub const VERSION: &str = env!("CARGO_PKG_VERSION"); - -pub fn show_version(){ +pub fn show_version() { println!("{}", VERSION); -} \ No newline at end of file +} diff --git a/src/eval/mod.rs b/src/eval/mod.rs index 0fba7ef..eae63fe 100644 --- a/src/eval/mod.rs +++ b/src/eval/mod.rs @@ -1,69 +1,71 @@ -use crate::common::errors::{ErrorType, ChapError}; -use crate::preprocessor::Preprocessor; +use crate::common::errors::{ChapError, ErrorType}; use crate::parser::Parser; +use crate::preprocessor::Preprocessor; use crate::runtime::Runtime; -pub fn eval(code: String, std_out: fn(&str), std_in: fn() -> String, on_exit: fn(), on_error: fn(ChapError)) { - +pub fn eval( + code: String, + std_out: fn(&str), + std_in: fn() -> String, + on_exit: fn(), + on_error: fn(ChapError), +) { // initialize let mut preprocessor = Preprocessor::default(); - let mut parser= Parser::default(); + let mut parser = Parser::default(); let mut runtime = Runtime::new(std_out, std_in); for line in code.split('\n') { let ls = preprocessor.on_new_line(line.to_string()); match ls { Ok(ls) => { - for line in ls{ + for line in ls { let e = parser.on_new_line(line); match e { Ok(els) => { - for el in els{ - if let Err(e) = runtime.on_new_line(el){ + for el in els { + if let Err(e) = runtime.on_new_line(el) { on_error(e); return; } } - }, + } Err(e) => { on_error(e); return; - }, + } } } - }, + } Err(e) => { on_error(e); return; - }, + } } } loop { - if let Err(e) = runtime.execution_cycle(){ + if let Err(e) = runtime.execution_cycle() { match e.err_type { ErrorType::NothingToExecute | ErrorType::Stop => { on_exit(); return; - }, - _=> { + } + _ => { on_error(e); return; } } } } - } - #[cfg(test)] -mod tests{ +mod tests { use super::eval; #[test] - fn test_eval(){ - eval( - "3".to_string(), |_|{}, ||{"".to_string()}, ||{}, |_|{}); + fn test_eval() { + eval("3".to_string(), |_| {}, || "".to_string(), || {}, |_| {}); } -} \ No newline at end of file +} diff --git a/src/file_executor/mod.rs b/src/file_executor/mod.rs index ff67b9e..2d5ae32 100644 --- a/src/file_executor/mod.rs +++ b/src/file_executor/mod.rs @@ -1,64 +1,63 @@ - -use std::io; use std::fs::read_to_string; +use std::io; use std::process::exit; -use crate::common::errors::{Result, ErrorType}; -use crate::preprocessor::Preprocessor; +use crate::common::errors::{ErrorType, Result}; use crate::parser::Parser; +use crate::preprocessor::Preprocessor; use crate::runtime::Runtime; -pub fn file_executor(file_name: &str) -> Result<()>{ - +pub fn file_executor(file_name: &str) -> Result<()> { // initialize let mut preprocessor = Preprocessor::default(); - let mut parser= Parser::default(); - - let mut runtime = Runtime::new(|msg|{ - println!("{}", msg); - },||{ - let mut buffer = String::new(); - let stdin = io::stdin(); // We get `Stdin` here. - stdin.read_line(&mut buffer).unwrap(); - buffer = buffer.replace('\n', "").trim().to_string(); - buffer - }); - + let mut parser = Parser::default(); + + let mut runtime = Runtime::new( + |msg| { + println!("{}", msg); + }, + || { + let mut buffer = String::new(); + let stdin = io::stdin(); // We get `Stdin` here. + stdin.read_line(&mut buffer).unwrap(); + buffer = buffer.replace('\n', "").trim().to_string(); + buffer + }, + ); for line in read_to_string(file_name).unwrap().lines() { let ls = preprocessor.on_new_line(line.to_string()); - match ls{ + match ls { Ok(ls) => { - for line in ls{ + for line in ls { let e = parser.on_new_line(line); match e { Ok(els) => { - for el in els{ - if let Err(e)=runtime.on_new_line(el){ + for el in els { + if let Err(e) = runtime.on_new_line(el) { e.exit_with_error(); } } - }, + } Err(err) => { err.exit_with_error(); - }, + } } } - }, + } Err(e) => e.exit_with_error(), } } loop { - if let Err(err) = runtime.execution_cycle(){ + if let Err(err) = runtime.execution_cycle() { match err.err_type { ErrorType::NothingToExecute | ErrorType::Stop => exit(0), - _=> { + _ => { err.exit_with_error(); } } } } - -} \ No newline at end of file +} diff --git a/src/lib.rs b/src/lib.rs index ca24dcd..9933477 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,10 +1,9 @@ - pub mod common; // language common defenitions //phases +pub mod parser; // phase 2 pub mod preprocessor; // phase 1 -pub mod parser; // phase 2 -pub mod runtime; // phase 3 +pub mod runtime; // phase 3 pub mod eval; diff --git a/src/main.rs b/src/main.rs index 299fb53..473cdc7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,31 +1,25 @@ - mod common; // language common defenitions //phases -mod preprocessor;// phase 1 -mod parser; // phase 2 -mod runtime; // phase 3 +mod parser; // phase 2 +mod preprocessor; // phase 1 +mod runtime; // phase 3 -// cli -mod repl; -mod file_executor; +// cli mod arg_paresr; +mod file_executor; +mod repl; -use crate::common::{ - help::show_help, - version::show_version, - errors::Result -}; +use crate::arg_paresr::{arg_parser, InputType}; +use crate::common::{errors::Result, help::show_help, version::show_version}; use crate::file_executor::file_executor; use crate::repl::start_rpel; -use crate::arg_paresr::{arg_parser,InputType}; fn main() -> Result<()> { - match arg_parser() { InputType::ExecuteFile(file_name) => { file_executor(&file_name)?; - }, + } InputType::Help => show_help(), InputType::Version => show_version(), InputType::Repl => start_rpel(), diff --git a/src/parser/chunk_detector.rs b/src/parser/chunk_detector.rs index 9a19862..4371ab3 100644 --- a/src/parser/chunk_detector.rs +++ b/src/parser/chunk_detector.rs @@ -1,22 +1,20 @@ - -use crate::common::{chunk::Chunk, param::Param, data_type::DataType}; -use crate::common::errors::{Result, ChapError}; +use crate::common::errors::{ChapError, Result}; use crate::common::splitter::string_safe_split; +use crate::common::{chunk::Chunk, data_type::DataType, param::Param}; -pub fn chunk_detector(chunk_str: String, line_number: u32) -> Result{ - +pub fn chunk_detector(chunk_str: String, line_number: u32) -> Result { let chunk_str = chunk_str.trim(); - if chunk_str.starts_with("true") || chunk_str.starts_with("false"){ + if chunk_str.starts_with("true") || chunk_str.starts_with("false") { return Ok(Chunk::Params(params_parser(chunk_str, line_number)?)); } - let r= match chunk_str.chars().next().unwrap_or(' ') { + let r = match chunk_str.chars().next().unwrap_or(' ') { '$' | '@' | '"' | '-' | '+' | '[' => Chunk::Params(params_parser(chunk_str, line_number)?), c => { - if c.is_ascii_digit(){ + if c.is_ascii_digit() { Chunk::Params(params_parser(chunk_str, line_number)?) - }else{ + } else { Chunk::Function(chunk_str.to_string()) } } @@ -24,116 +22,139 @@ pub fn chunk_detector(chunk_str: String, line_number: u32) -> Result{ Ok(r) } -fn params_parser(chunk_str: &str,line_number: u32) -> Result>{ +fn params_parser(chunk_str: &str, line_number: u32) -> Result> { let temp = string_safe_split(chunk_str, ",".to_string()); - let params_str: Vec<&str> = temp.iter().map(|x|{x.trim()}).collect(); + let params_str: Vec<&str> = temp.iter().map(|x| x.trim()).collect(); - let mut result:Vec = Vec::new(); + let mut result: Vec = Vec::new(); for param_str in params_str { - result.push(param_parser(param_str,line_number)?) + result.push(param_parser(param_str, line_number)?) } Ok(result) } -fn param_parser(param: &str, line_number: u32) -> Result{ - - if param == "true" { return Ok(Param::Value(DataType::Bool(true))); } - if param == "false" { return Ok(Param::Value(DataType::Bool(false))); } - - let parsed_param = match param.chars().next().unwrap_or(' ') { - '$' => Param::Variable((param[1..]).to_string()), - '@' => Param::Tag((param[1..]).to_string()), - '"' => { - let len = param.len(); - if !(¶m.ends_with('\"')){ - return Err(ChapError::syntax_with_msg(line_number, "string should ends with \"".to_string())); - } - Param::Value( DataType::String((param[1..len-1]).to_string())) - }, - '[' => { - let mut list: Vec = vec![]; - if !(¶m.ends_with(']')){ - return Err(ChapError::syntax_with_msg(line_number, "list should ends with ]".to_string())); - } - let param = ¶m[1..param.len()-1]; - if !param.trim().is_empty(){ - let items = param.split(' ').map(|token| param_parser(token, line_number)); - for item in items{ - match item? { - Param::Tag(_) => return Err(ChapError::syntax_with_msg(line_number,"tags cant be in list".to_string())), - Param::Variable(_) => return Err(ChapError::syntax_with_msg(line_number,"variables cant be in list".to_string())), - Param::Value(v) => list.push(v), - } +fn param_parser(param: &str, line_number: u32) -> Result { + if param == "true" { + return Ok(Param::Value(DataType::Bool(true))); + } + if param == "false" { + return Ok(Param::Value(DataType::Bool(false))); + } + + let parsed_param = match param.chars().next().unwrap_or(' ') { + '$' => Param::Variable((param[1..]).to_string()), + '@' => Param::Tag((param[1..]).to_string()), + '"' => { + let len = param.len(); + if !(¶m.ends_with('\"')) { + return Err(ChapError::syntax_with_msg( + line_number, + "string should ends with \"".to_string(), + )); + } + Param::Value(DataType::String((param[1..len - 1]).to_string())) + } + '[' => { + let mut list: Vec = vec![]; + if !(¶m.ends_with(']')) { + return Err(ChapError::syntax_with_msg( + line_number, + "list should ends with ]".to_string(), + )); + } + let param = ¶m[1..param.len() - 1]; + if !param.trim().is_empty() { + let items = param + .split(' ') + .map(|token| param_parser(token, line_number)); + for item in items { + match item? { + Param::Tag(_) => { + return Err(ChapError::syntax_with_msg( + line_number, + "tags cant be in list".to_string(), + )) + } + Param::Variable(_) => { + return Err(ChapError::syntax_with_msg( + line_number, + "variables cant be in list".to_string(), + )) } + Param::Value(v) => list.push(v), } - Param::Value(DataType::List(list)) + } } - _=> { - if param.contains('.'){ - if let Ok(float_value) = param.parse() { - Param::Value(DataType::Float(float_value)) - } else { - Err(ChapError::syntax_with_msg(line_number, "parsing float".to_string()))? - } - } else if let Ok(float_value) = param.parse() { - Param::Value(DataType::Int(float_value)) + Param::Value(DataType::List(list)) + } + _ => { + if param.contains('.') { + if let Ok(float_value) = param.parse() { + Param::Value(DataType::Float(float_value)) } else { - Err(ChapError::syntax_with_msg(line_number, "parsing int".to_string()))? + Err(ChapError::syntax_with_msg( + line_number, + "parsing float".to_string(), + ))? } + } else if let Ok(float_value) = param.parse() { + Param::Value(DataType::Int(float_value)) + } else { + Err(ChapError::syntax_with_msg( + line_number, + "parsing int".to_string(), + ))? } - }; - Ok(parsed_param) + } + }; + Ok(parsed_param) } - #[cfg(test)] mod tests { use crate::parser::chunk_detector::*; #[test] fn param_parser_empty() { - let _ = param_parser("",0); + let _ = param_parser("", 0); } #[test] fn param_parser_variable() { assert_eq!( - param_parser("$name",0), + param_parser("$name", 0), Ok(Param::Variable("name".to_string())) ); } #[test] fn param_parser_tag() { - assert_eq!( - param_parser("@name",0), - Ok(Param::Tag("name".to_string())) - ); + assert_eq!(param_parser("@name", 0), Ok(Param::Tag("name".to_string()))); } #[test] fn param_parser_string() { assert_eq!( - param_parser("\"name\"",1), + param_parser("\"name\"", 1), Ok(Param::Value(DataType::String("name".to_string()))) ); assert_eq!( - param_parser("\"name",1), - Err(ChapError::syntax_with_msg(1, "string should ends with \"".to_string())) + param_parser("\"name", 1), + Err(ChapError::syntax_with_msg( + 1, + "string should ends with \"".to_string() + )) ); } #[test] fn param_parser_integer() { - assert_eq!( - param_parser("2",1), - Ok(Param::Value(DataType::Int(2))) - ); + assert_eq!(param_parser("2", 1), Ok(Param::Value(DataType::Int(2)))); assert_eq!( - param_parser("2h",1), + param_parser("2h", 1), Err(ChapError::syntax_with_msg(1, "parsing int".to_string())) ); } @@ -141,12 +162,12 @@ mod tests { #[test] fn param_parser_float() { assert_eq!( - param_parser("1.5",1), + param_parser("1.5", 1), Ok(Param::Value(DataType::Float(1.5))) ); assert_eq!( - param_parser(".1.5",1), + param_parser(".1.5", 1), Err(ChapError::syntax_with_msg(1, "parsing float".to_string())) ); } @@ -154,20 +175,20 @@ mod tests { #[test] fn chunk_parser_negetive_number() { assert_eq!( - chunk_detector("-1.5".to_string(),1), + chunk_detector("-1.5".to_string(), 1), Ok(Chunk::Params(vec![Param::Value(DataType::Float(-1.5))])) ); assert_eq!( - chunk_detector("-3".to_string(),1), + chunk_detector("-3".to_string(), 1), Ok(Chunk::Params(vec![Param::Value(DataType::Int(-3))])) ); } #[test] - fn params_test(){ + fn params_test() { assert_eq!( - params_parser(" $n1,\"s1\" ,2,1.5 ",0), - Ok(vec![ + params_parser(" $n1,\"s1\" ,2,1.5 ", 0), + Ok(vec![ Param::Variable("n1".to_string()), Param::Value(DataType::String("s1".to_string())), Param::Value(DataType::Int(2)), @@ -177,40 +198,45 @@ mod tests { } #[test] - fn chunk_detector_test(){ + fn chunk_detector_test() { assert_eq!( - chunk_detector("print".to_string(),0), + chunk_detector("print".to_string(), 0), Ok(Chunk::Function("print".to_string())) ); } #[test] - fn comma_in_quotation_error(){ + fn comma_in_quotation_error() { assert_eq!( chunk_detector("\"ali, majid\"".to_string(), 0), - Ok(Chunk::Params(vec![Param::Value(DataType::String("ali, majid".to_string()))])) - )//this is single string param - } - + Ok(Chunk::Params(vec![Param::Value(DataType::String( + "ali, majid".to_string() + ))])) + ) //this is single string param + } #[test] - fn bool_parser(){ + fn bool_parser() { assert_eq!( chunk_detector("true".to_string(), 1), - Ok(Chunk::Params(vec![Param::Value(DataType::Bool(true))]) ) + Ok(Chunk::Params(vec![Param::Value(DataType::Bool(true))])) ); assert_eq!( chunk_detector("false".to_string(), 1), - Ok(Chunk::Params(vec![Param::Value(DataType::Bool(false))]) ) + Ok(Chunk::Params(vec![Param::Value(DataType::Bool(false))])) ); } #[test] - fn list_parser(){ + fn list_parser() { assert_eq!( params_parser("[1 2 3], 3", 1), Ok(vec![ - Param::Value(DataType::List(vec![DataType::Int(1), DataType::Int(2),DataType::Int(3)])), + Param::Value(DataType::List(vec![ + DataType::Int(1), + DataType::Int(2), + DataType::Int(3) + ])), Param::Value(DataType::Int(3)), ]) ); @@ -224,4 +250,4 @@ mod tests { ]) ); } -} \ No newline at end of file +} diff --git a/src/parser/get_single_var.rs b/src/parser/get_single_var.rs index 988185e..f0e0e8b 100644 --- a/src/parser/get_single_var.rs +++ b/src/parser/get_single_var.rs @@ -1,46 +1,66 @@ - -use crate::common::{param::Param, errors::ChapError}; use crate::common::errors::Result; +use crate::common::{errors::ChapError, param::Param}; - -pub fn get_single_var(params:Vec, line_number: u32) -> Result{ - - if params.len() != 1{ - return Err(ChapError::syntax_with_msg(line_number, "result of function cant be multiple params".to_string())); +pub fn get_single_var(params: Vec, line_number: u32) -> Result { + if params.len() != 1 { + return Err(ChapError::syntax_with_msg( + line_number, + "result of function cant be multiple params".to_string(), + )); } - match params.get(0).unwrap(){ - Param::Tag(_) => Err(ChapError::syntax_with_msg(line_number, "you can't set function result to a tag".to_string())), - Param::Value(_) => Err(ChapError::syntax_with_msg(line_number, "you can't set function result to a value".to_string())), + match params.get(0).unwrap() { + Param::Tag(_) => Err(ChapError::syntax_with_msg( + line_number, + "you can't set function result to a tag".to_string(), + )), + Param::Value(_) => Err(ChapError::syntax_with_msg( + line_number, + "you can't set function result to a value".to_string(), + )), Param::Variable(name) => Ok(name.clone()), } } - #[cfg(test)] -mod tests{ +mod tests { use crate::common::data_type::DataType; use super::*; #[test] - fn get_single_var_test(){ + fn get_single_var_test() { assert_eq!( - get_single_var(vec![Param::Tag("".to_string()),Param::Tag("".to_string())], 1), - Err(ChapError::syntax_with_msg(1, "result of function cant be multiple params".to_string())) + get_single_var( + vec![Param::Tag("".to_string()), Param::Tag("".to_string())], + 1 + ), + Err(ChapError::syntax_with_msg( + 1, + "result of function cant be multiple params".to_string() + )) ); assert_eq!( get_single_var(vec![], 1), - Err(ChapError::syntax_with_msg(1, "result of function cant be multiple params".to_string())) + Err(ChapError::syntax_with_msg( + 1, + "result of function cant be multiple params".to_string() + )) ); assert_eq!( get_single_var(vec![Param::Value(DataType::String("hich".to_string()))], 1), - Err(ChapError::syntax_with_msg(1, "you can't set function result to a value".to_string())) + Err(ChapError::syntax_with_msg( + 1, + "you can't set function result to a value".to_string() + )) ); assert_eq!( get_single_var(vec![Param::Tag("mytag".to_string())], 1), - Err(ChapError::syntax_with_msg(1, "you can't set function result to a tag".to_string())) + Err(ChapError::syntax_with_msg( + 1, + "you can't set function result to a tag".to_string() + )) ); } -} \ No newline at end of file +} diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 4d5f47a..914bbda 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -1,257 +1,352 @@ - mod chunk_detector; mod get_single_var; -use crate::common::param::Param; -use crate::parser::get_single_var::get_single_var; -use crate::parser::chunk_detector::chunk_detector; use crate::common::chunk::Chunk; -use crate::common::{line_of_code::LineOfCode, executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; +use crate::common::errors::{ChapError, Result}; +use crate::common::param::Param; use crate::common::splitter::string_safe_split; +use crate::common::{executable::ExecutableLine, line_of_code::LineOfCode}; +use crate::parser::chunk_detector::chunk_detector; +use crate::parser::get_single_var::get_single_var; #[derive(Default)] -pub struct Parser{ - tmp_var_counter: usize +pub struct Parser { + tmp_var_counter: usize, } - -impl Parser { - - pub fn on_new_line(&mut self, new_line: LineOfCode) -> Result>{ +impl Parser { + pub fn on_new_line(&mut self, new_line: LineOfCode) -> Result> { let ln = new_line.line_number; let chunks = string_safe_split(&new_line.code, "->".to_string()); - let chunks: Vec>= chunks.iter().map(|x|{chunk_detector(x.to_string(), ln)}).collect(); + let chunks: Vec> = chunks + .iter() + .map(|x| chunk_detector(x.to_string(), ln)) + .collect(); let mut result = Vec::::new(); let mut pointer = 0usize; - loop{ - - let pc= if pointer==0 { None } else{ chunks.get(pointer - 1) }; - let cc= chunks.get(pointer).unwrap().clone()?; - let nc= chunks.get(pointer + 1); - pointer+=1; - - if pointer==1{ // first - match cc{ + loop { + let pc = if pointer == 0 { + None + } else { + chunks.get(pointer - 1) + }; + let cc = chunks.get(pointer).unwrap().clone()?; + let nc = chunks.get(pointer + 1); + pointer += 1; + + if pointer == 1 { + // first + match cc { Chunk::Params(cc) => { match nc { - None => { // nothing -> param -> nothing + None => { + // nothing -> param -> nothing match cc.get(0) { - None => return Err(ChapError::syntax_with_msg(ln,"nothing to execute".to_string())), - Some(cc1) => { - match cc1 { - Param::Tag(_) => { - if cc.len() > 1{ - return Err(ChapError::syntax_with_msg(ln, ",... does not mean anything".to_string())); - } - result.push(ExecutableLine::new(ln, "new_tag".to_string(), cc, None)) - }, - _ => { - result.push(ExecutableLine::new(ln, "print".to_string(), cc, None)) - }, + None => { + return Err(ChapError::syntax_with_msg( + ln, + "nothing to execute".to_string(), + )) + } + Some(cc1) => match cc1 { + Param::Tag(_) => { + if cc.len() > 1 { + return Err(ChapError::syntax_with_msg( + ln, + ",... does not mean anything" + .to_string(), + )); + } + result.push(ExecutableLine::new( + ln, + "new_tag".to_string(), + cc, + None, + )) } + _ => result.push(ExecutableLine::new( + ln, + "print".to_string(), + cc, + None, + )), }, } break; - }, - Some(nc) => { + } + Some(nc) => { let nc = nc.clone()?; match nc { - Chunk::Params(nc) => {// nothing -> param -> param - let nc = get_single_var(nc,ln)?; - result.push(ExecutableLine::new(ln, "assign".to_string(), cc, Some(nc))); + Chunk::Params(nc) => { + // nothing -> param -> param + let nc = get_single_var(nc, ln)?; + result.push(ExecutableLine::new( + ln, + "assign".to_string(), + cc, + Some(nc), + )); break; - }, + } Chunk::Function(_) => continue, // nothing -> param -> function } - }, + } } - }, // will use in next itration + } // will use in next itration Chunk::Function(cc) => { match nc { - None => { // nothing -> function -> nothing + None => { + // nothing -> function -> nothing result.push(ExecutableLine::new(ln, cc, vec![], None)); break; - }, - Some(nc) => { - match nc.clone()?{ - Chunk::Params(nc) => { - let nc = get_single_var(nc,ln)?; - result.push(ExecutableLine::new(ln, cc, vec![], Some(nc.clone()))); - break; - }, - Chunk::Function(_) => { - result.push(ExecutableLine::new(ln, cc, vec![], Some(self.get_next_tmp()))) - }, + } + Some(nc) => match nc.clone()? { + Chunk::Params(nc) => { + let nc = get_single_var(nc, ln)?; + result.push(ExecutableLine::new( + ln, + cc, + vec![], + Some(nc.clone()), + )); + break; } + Chunk::Function(_) => result.push(ExecutableLine::new( + ln, + cc, + vec![], + Some(self.get_next_tmp()), + )), }, } - }, + } } - }else{ + } else { let pc = pc.unwrap().clone()?; match cc { - Chunk::Params(_) => return Err(ChapError::syntax_with_msg(ln, "this will not happen".to_string())), + Chunk::Params(_) => { + return Err(ChapError::syntax_with_msg( + ln, + "this will not happen".to_string(), + )) + } Chunk::Function(cc) => { match pc { Chunk::Params(pc) => { match nc { - None => { // param -> function -> nothing + None => { + // param -> function -> nothing result.push(ExecutableLine::new(ln, cc, pc, None)); break; - }, + } Some(nc) => { let nc = nc.clone()?; match nc { - Chunk::Params(nc) => { // param -> function -> param - let nc = get_single_var(nc,ln)?; - result.push(ExecutableLine::new(ln, cc, pc, Some(nc.clone()))); + Chunk::Params(nc) => { + // param -> function -> param + let nc = get_single_var(nc, ln)?; + result.push(ExecutableLine::new( + ln, + cc, + pc, + Some(nc.clone()), + )); break; - }, - Chunk::Function(_nc) => { // param -> function -> function - result.push(ExecutableLine::new(ln, cc, pc, Some(self.get_next_tmp()))); - }, + } + Chunk::Function(_nc) => { + // param -> function -> function + result.push(ExecutableLine::new( + ln, + cc, + pc, + Some(self.get_next_tmp()), + )); + } } - }, + } } - }, + } Chunk::Function(_pc) => { match nc { - None => { // function -> function -> nothing + None => { + // function -> function -> nothing let tmp = Param::Variable(self.get_current_tmp()); result.push(ExecutableLine::new(ln, cc, vec![tmp], None)); break; - }, + } Some(nc) => { let nc = nc.clone()?; match nc { - Chunk::Params(nc) => { //function -> function -> param + Chunk::Params(nc) => { + //function -> function -> param let tmp = Param::Variable(self.get_current_tmp()); - let nc = get_single_var(nc,ln)?; - result.push(ExecutableLine::new(ln, cc, vec![tmp], Some(nc.clone()))); + let nc = get_single_var(nc, ln)?; + result.push(ExecutableLine::new( + ln, + cc, + vec![tmp], + Some(nc.clone()), + )); break; - - }, - Chunk::Function(_nc) => { // function -> function -> function + } + Chunk::Function(_nc) => { + // function -> function -> function let tmp = Param::Variable(self.get_current_tmp()); - result.push(ExecutableLine::new(ln, cc, vec![tmp], Some(self.get_next_tmp()))); - }, + result.push(ExecutableLine::new( + ln, + cc, + vec![tmp], + Some(self.get_next_tmp()), + )); + } } - }, + } } - }, + } } - }, + } } } - - }; + } Ok(result) - } - fn get_current_tmp(&mut self) -> String{ - format!("LTMP_{}",self.tmp_var_counter) + fn get_current_tmp(&mut self) -> String { + format!("LTMP_{}", self.tmp_var_counter) } - fn get_next_tmp(&mut self) -> String{ - self.tmp_var_counter+=1; + fn get_next_tmp(&mut self) -> String { + self.tmp_var_counter += 1; self.get_current_tmp() } - - } - #[cfg(test)] -mod tests{ +mod tests { - use crate::common::{param::Param, data_type::DataType}; + use crate::common::{data_type::DataType, param::Param}; use super::*; - - // ---- single chunk ---- + // ---- single chunk ---- #[test] - fn tag_parser(){ + fn tag_parser() { let mut p = Parser::default(); - let result = p.on_new_line(LineOfCode::new(1, " @myTag ".to_string())).unwrap(); - + let result = p + .on_new_line(LineOfCode::new(1, " @myTag ".to_string())) + .unwrap(); + assert_eq!( result.get(0).unwrap(), - &ExecutableLine::new(1,"new_tag".to_string(),vec![Param::Tag("myTag".to_string())],None) + &ExecutableLine::new( + 1, + "new_tag".to_string(), + vec![Param::Tag("myTag".to_string())], + None + ) ); } #[test] - fn print_detector_parser(){ + fn print_detector_parser() { let mut p = Parser::default(); - let result = p.on_new_line(LineOfCode::new(1, " $myVar ".to_string())).unwrap(); + let result = p + .on_new_line(LineOfCode::new(1, " $myVar ".to_string())) + .unwrap(); assert_eq!( result.get(0).unwrap(), - &ExecutableLine::new(1,"print".to_string(), vec![Param::Variable("myVar".to_string())], None) + &ExecutableLine::new( + 1, + "print".to_string(), + vec![Param::Variable("myVar".to_string())], + None + ) ); - let result = p.on_new_line(LineOfCode::new(1, " \"hello\" ".to_string())).unwrap(); + let result = p + .on_new_line(LineOfCode::new(1, " \"hello\" ".to_string())) + .unwrap(); assert_eq!( result.get(0).unwrap(), - &ExecutableLine::new(1,"print".to_string(),vec![Param::Value(DataType::String("hello".to_string()))],None) + &ExecutableLine::new( + 1, + "print".to_string(), + vec![Param::Value(DataType::String("hello".to_string()))], + None + ) ); - } #[test] - fn function_call_paramless(){ + fn function_call_paramless() { let mut p = Parser::default(); - let result = p.on_new_line(LineOfCode::new(1, " exit ".to_string())).unwrap(); + let result = p + .on_new_line(LineOfCode::new(1, " exit ".to_string())) + .unwrap(); assert_eq!( result.get(0).unwrap(), - &ExecutableLine::new(1,"exit".to_string(), vec![], None) + &ExecutableLine::new(1, "exit".to_string(), vec![], None) ); } - - // ---- double chunk ---- + // ---- double chunk ---- #[test] - fn param_param_test(){ + fn param_param_test() { let mut p = Parser::default(); - let result = p.on_new_line(LineOfCode::new(1, " 1 -> $var ".to_string())).unwrap(); + let result = p + .on_new_line(LineOfCode::new(1, " 1 -> $var ".to_string())) + .unwrap(); assert_eq!( result.get(0).unwrap(), - &ExecutableLine::new(1,"assign".to_string(), vec![Param::Value(DataType::Int(1))], Some("var".to_string())) + &ExecutableLine::new( + 1, + "assign".to_string(), + vec![Param::Value(DataType::Int(1))], + Some("var".to_string()) + ) ); } #[test] - fn param_function_test(){ + fn param_function_test() { let mut p = Parser::default(); - let result = p.on_new_line(LineOfCode::new(1, " $var -> function ".to_string())).unwrap(); + let result = p + .on_new_line(LineOfCode::new(1, " $var -> function ".to_string())) + .unwrap(); assert_eq!( result.get(0).unwrap(), - &ExecutableLine::new(1, "function".to_string(), vec![Param::Variable("var".to_string())], None) + &ExecutableLine::new( + 1, + "function".to_string(), + vec![Param::Variable("var".to_string())], + None + ) ); } #[test] - fn function_param_test(){ + fn function_param_test() { let mut p = Parser::default(); - let result = p.on_new_line(LineOfCode::new(1, " input -> $var ".to_string())).unwrap(); + let result = p + .on_new_line(LineOfCode::new(1, " input -> $var ".to_string())) + .unwrap(); assert_eq!( result.get(0).unwrap(), &ExecutableLine::new(1, "input".to_string(), vec![], Some("var".to_string())) ); } - // ---- triplet chunk ---- #[test] - fn valid_expression(){ + fn valid_expression() { let mut p = Parser::default(); - let result = p.on_new_line(LineOfCode::new(1, " 2 -> sum -> $var ".to_string())).unwrap(); + let result = p + .on_new_line(LineOfCode::new(1, " 2 -> sum -> $var ".to_string())) + .unwrap(); assert_eq!( result.get(0).unwrap(), &ExecutableLine::new( @@ -263,35 +358,42 @@ mod tests{ ); } - #[test] - fn piping_test(){ + fn piping_test() { let mut p = Parser::default(); - let result = p.on_new_line(LineOfCode::new(1, "1, 2 -> add -> to_string -> $a".to_string())).unwrap(); + let result = p + .on_new_line(LineOfCode::new( + 1, + "1, 2 -> add -> to_string -> $a".to_string(), + )) + .unwrap(); assert_eq!(result.len(), 2); assert_eq!( result.get(0).unwrap(), &ExecutableLine::new( 1, "add".to_string(), - vec![Param::Value(DataType::Int(1)), Param::Value(DataType::Int(2))], + vec![ + Param::Value(DataType::Int(1)), + Param::Value(DataType::Int(2)) + ], Some("LTMP_1".to_string()) - ) + ) ); assert_eq!( result.get(1).unwrap(), &ExecutableLine::new( 1, "to_string".to_string(), - vec![Param::Variable("LTMP_1".to_string())], + vec![Param::Variable("LTMP_1".to_string())], Some("a".to_string()) - ) + ) ); } #[test] - fn string_includes_arrow(){ + fn string_includes_arrow() { let mut p = Parser::default(); assert_eq!( p.on_new_line(LineOfCode::new(1, "\"hello -> world\"".to_string())), @@ -305,7 +407,7 @@ mod tests{ } #[test] - fn string_includes_comment(){ + fn string_includes_comment() { let mut p = Parser::default(); assert_eq!( p.on_new_line(LineOfCode::new(1, "\"hello // world\"".to_string())), @@ -317,5 +419,4 @@ mod tests{ )]) ); } - -} \ No newline at end of file +} diff --git a/src/preprocessor/mod.rs b/src/preprocessor/mod.rs index ec72f27..dcb17c2 100644 --- a/src/preprocessor/mod.rs +++ b/src/preprocessor/mod.rs @@ -1,100 +1,109 @@ - -use crate::common::errors::{Result, ChapError}; +use crate::common::errors::{ChapError, Result}; use crate::common::line_of_code::LineOfCode; use crate::common::splitter::string_safe_split; - #[derive(Default)] -pub struct Preprocessor{ +pub struct Preprocessor { current_line: u32, buffer: String, - temp_vars: u32 + temp_vars: u32, } // Preprocessor converts users code to parsable code impl Preprocessor { - - pub fn on_new_line(&mut self, actual_line: String) -> Result>{ - - let actual_line = format!("{}{}",self.buffer,actual_line); + pub fn on_new_line(&mut self, actual_line: String) -> Result> { + let actual_line = format!("{}{}", self.buffer, actual_line); self.buffer = String::new(); - self.current_line+=1; + self.current_line += 1; let binding = string_safe_split(actual_line.as_str(), "//".to_string()); let line = binding.first().unwrap(); - let lines = line.split(';') - .map(|line|{ line.trim() }) - .filter(|x|{ !x.is_empty()}); + let lines = line + .split(';') + .map(|line| line.trim()) + .filter(|x| !x.is_empty()); - let mut lines: Vec = lines.map(|x|x.to_string()).collect(); + let mut lines: Vec = lines.map(|x| x.to_string()).collect(); let line = self.current_line; lines = self.multiline_expresion(lines); - + let lines = self.parentheses(lines)?; - Ok(lines.iter().map(|x|{ LineOfCode::new(line,x.to_string()) }) + Ok(lines + .iter() + .map(|x| LineOfCode::new(line, x.to_string())) .collect()) } - fn multiline_expresion(&mut self, mut inp: Vec) -> Vec{ - if let Some(x) = inp.last(){ - if x.ends_with("->") || x.ends_with(',') || x.matches('(').count() > x.matches(')').count(){ + fn multiline_expresion(&mut self, mut inp: Vec) -> Vec { + if let Some(x) = inp.last() { + if x.ends_with("->") + || x.ends_with(',') + || x.matches('(').count() > x.matches(')').count() + { let halfline = inp.pop().unwrap(); self.buffer.push_str(halfline.as_str()); inp - }else{ + } else { inp } - }else{ + } else { vec![] } } - fn parentheses(&mut self, inp: Vec) -> Result>{ + fn parentheses(&mut self, inp: Vec) -> Result> { let mut result: Vec = vec![]; - for l in inp{ - - let end = l.chars().position(|c| c==')'); + for l in inp { + let end = l.chars().position(|c| c == ')'); match end { Some(end) => { let start: Option = Self::find_backward(&l, end); - match start{ + match start { Some(start) => { - let exp = &l[start+1..end]; + let exp = &l[start + 1..end]; let gen = format!("{}->$TMP_{}", exp, self.temp_vars); result.push(gen); - let rest = format!("{}$TMP_{}{}", &l[..start], self.temp_vars, &l[end+1..]); - self.temp_vars+=1; + let rest = + format!("{}$TMP_{}{}", &l[..start], self.temp_vars, &l[end + 1..]); + self.temp_vars += 1; let mut rest = self.parentheses(vec![rest])?; result.append(&mut rest); - }, + } None => { - return Err(ChapError::syntax_with_msg(self.current_line, "parenthese ends without an start".to_string())) - }, + return Err(ChapError::syntax_with_msg( + self.current_line, + "parenthese ends without an start".to_string(), + )) + } } - }, + } None => { - let start = l.chars().position(|c| c=='('); + let start = l.chars().position(|c| c == '('); match start { - Some(_) => - return Err(ChapError::syntax_with_msg(self.current_line, "parenthese starts without an end".to_string())), + Some(_) => { + return Err(ChapError::syntax_with_msg( + self.current_line, + "parenthese starts without an end".to_string(), + )) + } None => { result.push(l.to_string()); - }, + } } - }, + } } } Ok(result) } - fn find_backward(s: &str, from: usize) -> Option{ - for i in (0..from).rev(){ - if s.chars().nth(i).unwrap() == '('{ + fn find_backward(s: &str, from: usize) -> Option { + for i in (0..from).rev() { + if s.chars().nth(i).unwrap() == '(' { return Some(i); } } @@ -102,7 +111,6 @@ impl Preprocessor { } } - #[cfg(test)] mod tests { use crate::common::line_of_code::LineOfCode; @@ -111,7 +119,6 @@ mod tests { #[test] fn remove_comments() { - let mut pp = Preprocessor::default(); let mut all_lines: Vec = Vec::new(); @@ -128,30 +135,47 @@ mod tests { assert_eq!(0, all_lines.len()); } - #[test] fn semicolon_split() { - let mut pp = Preprocessor::default(); - - assert_eq!(0 , pp.on_new_line("//comment".to_string()).unwrap().len() ); - assert_eq!(0 , pp.on_new_line("".to_string()).unwrap().len() ); - assert_eq!(1 , pp.on_new_line(" command1".to_string()).unwrap().len() ); - assert_eq!(2 , pp.on_new_line(" command2 ; command3 ".to_string()).unwrap().len() ); - assert_eq!(1 , pp.on_new_line(" command3 ; //comment ".to_string()).unwrap().len() ); - assert_eq!(1 , pp.on_new_line(" command4 //comment ".to_string()).unwrap().len() ); - assert_eq!(2 , pp.on_new_line(" command5 ; ; command6 //comment ".to_string()).unwrap().len() ); + + assert_eq!(0, pp.on_new_line("//comment".to_string()).unwrap().len()); + assert_eq!(0, pp.on_new_line("".to_string()).unwrap().len()); + assert_eq!(1, pp.on_new_line(" command1".to_string()).unwrap().len()); + assert_eq!( + 2, + pp.on_new_line(" command2 ; command3 ".to_string()) + .unwrap() + .len() + ); + assert_eq!( + 1, + pp.on_new_line(" command3 ; //comment ".to_string()) + .unwrap() + .len() + ); + assert_eq!( + 1, + pp.on_new_line(" command4 //comment ".to_string()) + .unwrap() + .len() + ); + assert_eq!( + 2, + pp.on_new_line(" command5 ; ; command6 //comment ".to_string()) + .unwrap() + .len() + ); assert_eq!(7, pp.current_line); } #[test] - fn currect_line_numbers(){ - + fn currect_line_numbers() { let mut pp = Preprocessor::default(); - assert_eq!(0 , pp.on_new_line("//comment1".to_string()).unwrap().len() ); - assert_eq!(0 , pp.on_new_line("//comment2".to_string()).unwrap().len() ); + assert_eq!(0, pp.on_new_line("//comment1".to_string()).unwrap().len()); + assert_eq!(0, pp.on_new_line("//comment2".to_string()).unwrap().len()); let pped = pp.on_new_line("param -> func -> out".to_string()).unwrap(); @@ -159,18 +183,19 @@ mod tests { } #[test] - fn currect_actual_line(){ - + fn currect_actual_line() { let mut pp = Preprocessor::default(); - let pped = pp.on_new_line("; command1 ; ; command2 ;;//comment;".to_string()).unwrap(); + let pped = pp + .on_new_line("; command1 ; ; command2 ;;//comment;".to_string()) + .unwrap(); assert_eq!("command1", pped.get(0).unwrap().code); assert_eq!("command2", pped.get(1).unwrap().code); } #[test] - fn string_includes_comment(){ + fn string_includes_comment() { let mut p = Preprocessor::default(); let result = p.on_new_line("\"hello // world\"".to_string()).unwrap(); assert_eq!( @@ -180,7 +205,7 @@ mod tests { } #[test] - fn multiline_expresion(){ + fn multiline_expresion() { let mut p = Preprocessor::default(); let result1 = p.on_new_line("1,".to_string()).unwrap(); let result2 = p.on_new_line("2->".to_string()).unwrap(); @@ -192,7 +217,7 @@ mod tests { } #[test] - fn parentheses(){ + fn parentheses() { let mut p = Preprocessor::default(); let result = p.on_new_line("(1,2->add),2->add".to_string()).unwrap(); @@ -202,28 +227,41 @@ mod tests { } #[test] - fn multi_parentheses(){ + fn multi_parentheses() { let mut p = Preprocessor::default(); - let result = p.on_new_line("(1,2->add),(3,4->add)->add".to_string()).unwrap(); + let result = p + .on_new_line("(1,2->add),(3,4->add)->add".to_string()) + .unwrap(); assert_eq!(result.len(), 3); assert_eq!(result.get(0).unwrap().code, "1,2->add->$TMP_0".to_string()); assert_eq!(result.get(1).unwrap().code, "3,4->add->$TMP_1".to_string()); - assert_eq!(result.get(2).unwrap().code, "$TMP_0,$TMP_1->add".to_string()); + assert_eq!( + result.get(2).unwrap().code, + "$TMP_0,$TMP_1->add".to_string() + ); } #[test] - fn nest_parentheses(){ + fn nest_parentheses() { let mut p = Preprocessor::default(); - let result = p.on_new_line("((1,2->add),2->add),(3,4->add)->add".to_string()).unwrap(); + let result = p + .on_new_line("((1,2->add),2->add),(3,4->add)->add".to_string()) + .unwrap(); assert_eq!(result.len(), 4); assert_eq!(result.get(0).unwrap().code, "1,2->add->$TMP_0".to_string()); - assert_eq!(result.get(1).unwrap().code, "$TMP_0,2->add->$TMP_1".to_string()); + assert_eq!( + result.get(1).unwrap().code, + "$TMP_0,2->add->$TMP_1".to_string() + ); assert_eq!(result.get(2).unwrap().code, "3,4->add->$TMP_2".to_string()); - assert_eq!(result.get(3).unwrap().code, "$TMP_1,$TMP_2->add".to_string()); + assert_eq!( + result.get(3).unwrap().code, + "$TMP_1,$TMP_2->add".to_string() + ); } - + #[test] - fn multiline_expresion_parentheses(){ + fn multiline_expresion_parentheses() { let mut p = Preprocessor::default(); let result1 = p.on_new_line("(".to_string()).unwrap(); let result2 = p.on_new_line("(1,2->add),2->add".to_string()).unwrap(); @@ -233,4 +271,4 @@ mod tests { assert_eq!(result2.len(), 0); assert_eq!(result3.len(), 4); } -} \ No newline at end of file +} diff --git a/src/repl/mod.rs b/src/repl/mod.rs index 73ab057..5c67d26 100644 --- a/src/repl/mod.rs +++ b/src/repl/mod.rs @@ -1,16 +1,12 @@ use std::process::exit; use crate::{ - parser::Parser, - preprocessor::Preprocessor, - runtime::Runtime, common::errors::ErrorType + common::errors::ErrorType, parser::Parser, preprocessor::Preprocessor, runtime::Runtime, }; use rustyline::DefaultEditor; - -pub fn start_rpel(){ - +pub fn start_rpel() { // initialize let mut preprocessor = Preprocessor::default(); @@ -18,11 +14,12 @@ pub fn start_rpel(){ let mut reader = DefaultEditor::new().unwrap(); // TODO: handle error - let mut runtime = Runtime::new(|msg|{ - println!("{}", msg); - },||{ - String::from("") - }); + let mut runtime = Runtime::new( + |msg| { + println!("{}", msg); + }, + || String::from(""), + ); loop { // let source: String; @@ -30,41 +27,40 @@ pub fn start_rpel(){ Ok(line) => { let _ = reader.add_history_entry(line.clone()); line - }, + } Err(_) => break, }; let lines = preprocessor.on_new_line(source); - match lines{ + match lines { Ok(lines) => { - for t in lines{ + for t in lines { let el = parser.on_new_line(t); match el { Err(err) => err.show_warning(), Ok(els) => { - for el in els{ - if let Err(e)=runtime.on_new_line(el){ + for el in els { + if let Err(e) = runtime.on_new_line(el) { e.show_warning(); } 'inner: loop { - if let Err(err) = runtime.execution_cycle(){ + if let Err(err) = runtime.execution_cycle() { match err.err_type { ErrorType::NothingToExecute => break 'inner, ErrorType::Stop => exit(0), - _=> { + _ => { err.show_warning(); } } } } } - }, + } } } - }, + } Err(e) => { e.show_warning(); - }, + } } - } } diff --git a/src/runtime/builtin_function/assign.rs b/src/runtime/builtin_function/assign.rs index 38cc524..b533e66 100644 --- a/src/runtime/builtin_function/assign.rs +++ b/src/runtime/builtin_function/assign.rs @@ -1,9 +1,11 @@ -use crate::{runtime::Runtime, common::{executable::ExecutableLine, errors::ChapError}}; use crate::common::errors::Result; use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; +use crate::{ + common::{errors::ChapError, executable::ExecutableLine}, + runtime::Runtime, +}; -pub fn assign(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()>{ - +pub fn assign(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { assign_validator(executable)?; let p1 = param_to_datatype(runtime, executable.params.get(0), executable.line_number)?; @@ -11,27 +13,28 @@ pub fn assign(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()>{ returns(runtime, executable, p1.clone()) } -fn assign_validator(executable: &ExecutableLine) -> Result<()>{ - - if executable.params.len() != 1{ - return Err(ChapError::static_analyzer_with_msg(executable.line_number, "assign function needs one input param".to_string())); +fn assign_validator(executable: &ExecutableLine) -> Result<()> { + if executable.params.len() != 1 { + return Err(ChapError::static_analyzer_with_msg( + executable.line_number, + "assign function needs one input param".to_string(), + )); } Ok(()) } - #[cfg(test)] -mod tests{ +mod tests { use crate::{ + common::{data_type::DataType, param::Param}, runtime::Runtime, - common::{param::Param, data_type::DataType} }; use super::*; #[test] - fn assign_value_and_variable(){ - let mut runtime = Runtime::new(|_|{}, ||{ "".to_string() }); + fn assign_value_and_variable() { + let mut runtime = Runtime::new(|_| {}, || "".to_string()); assign( &mut runtime, @@ -39,9 +42,10 @@ mod tests{ 1, "".to_string(), vec![Param::Value(DataType::Int(2))], - Some("var".to_string()) - ) - ).unwrap(); + Some("var".to_string()), + ), + ) + .unwrap(); assert_eq!( runtime.variables.get("var").unwrap().clone(), DataType::Int(2) @@ -53,13 +57,14 @@ mod tests{ 1, "".to_string(), vec![Param::Variable("var".to_string())], - Some("var2".to_string()) - ) - ).unwrap(); + Some("var2".to_string()), + ), + ) + .unwrap(); assert_eq!( runtime.variables.get("var2").unwrap().clone(), DataType::Int(2) ); } -} \ No newline at end of file +} diff --git a/src/runtime/builtin_function/bools/and.rs b/src/runtime/builtin_function/bools/and.rs index dbecbc2..8d1c2b9 100644 --- a/src/runtime/builtin_function/bools/and.rs +++ b/src/runtime/builtin_function/bools/and.rs @@ -1,23 +1,22 @@ -use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; - - -pub fn and(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ +use crate::common::errors::{ChapError, Result}; +use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; +pub fn and(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let mut result = true; - for param in &executable.params{ + for param in &executable.params { let dt = param_to_datatype(runtime, Some(param), executable.line_number)?; match dt { DataType::Bool(x) => result = result && *x, - _=>{ - return Err( - ChapError::runtime_with_msg(executable.line_number, "and function needs bool params".to_string()) - ); + _ => { + return Err(ChapError::runtime_with_msg( + executable.line_number, + "and function needs bool params".to_string(), + )); } } } - returns(runtime, executable,DataType::Bool(result)) -} \ No newline at end of file + returns(runtime, executable, DataType::Bool(result)) +} diff --git a/src/runtime/builtin_function/bools/equal.rs b/src/runtime/builtin_function/bools/equal.rs index c95ca9e..ee92d91 100644 --- a/src/runtime/builtin_function/bools/equal.rs +++ b/src/runtime/builtin_function/bools/equal.rs @@ -1,13 +1,11 @@ -use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; use crate::common::errors::Result; +use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; - -pub fn equal(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ - +pub fn equal(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let p1 = param_to_datatype(runtime, executable.params.get(0), executable.line_number)?; let p2 = param_to_datatype(runtime, executable.params.get(1), executable.line_number)?; - returns(runtime, executable,DataType::Bool(p1==p2)) -} \ No newline at end of file + returns(runtime, executable, DataType::Bool(p1 == p2)) +} diff --git a/src/runtime/builtin_function/bools/greater_than.rs b/src/runtime/builtin_function/bools/greater_than.rs index d18a932..0b686d4 100644 --- a/src/runtime/builtin_function/bools/greater_than.rs +++ b/src/runtime/builtin_function/bools/greater_than.rs @@ -1,29 +1,26 @@ -use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; - - -pub fn greater_than(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ +use crate::common::errors::{ChapError, Result}; +use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; +pub fn greater_than(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let p1 = param_to_datatype(runtime, executable.params.get(0), executable.line_number)?; let p2 = param_to_datatype(runtime, executable.params.get(1), executable.line_number)?; - let result = greater_than_data_types(p1,p2)?; - + let result = greater_than_data_types(p1, p2)?; + returns(runtime, executable, result) } -pub fn greater_than_data_types(dt1: &DataType, dt2: &DataType) -> Result{ +pub fn greater_than_data_types(dt1: &DataType, dt2: &DataType) -> Result { match (dt1, dt2) { (DataType::Int(x1), DataType::Int(x2)) => Ok(DataType::Bool(x1 > x2)), (DataType::Int(x1), DataType::Float(x2)) => Ok(DataType::Bool(f64::from(*x1) > *x2)), (DataType::Float(x1), DataType::Int(x2)) => Ok(DataType::Bool(*x1 > f64::from(*x2))), (DataType::Float(x1), DataType::Float(x2)) => Ok(DataType::Bool(x1 > x2)), - _=> { - Err( - ChapError::runtime_with_msg(0, "greater_than function works only with numbers int and float".to_string()) - ) - } + _ => Err(ChapError::runtime_with_msg( + 0, + "greater_than function works only with numbers int and float".to_string(), + )), } } diff --git a/src/runtime/builtin_function/bools/less_than.rs b/src/runtime/builtin_function/bools/less_than.rs index d8fa97d..776c9db 100644 --- a/src/runtime/builtin_function/bools/less_than.rs +++ b/src/runtime/builtin_function/bools/less_than.rs @@ -1,30 +1,26 @@ -use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; - - -pub fn less_than(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ +use crate::common::errors::{ChapError, Result}; +use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; +pub fn less_than(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let p1 = param_to_datatype(runtime, executable.params.get(0), executable.line_number)?; let p2 = param_to_datatype(runtime, executable.params.get(1), executable.line_number)?; - let result = less_than_data_types(p1,p2)?; - + let result = less_than_data_types(p1, p2)?; + returns(runtime, executable, result) } -pub fn less_than_data_types(dt1: &DataType, dt2: &DataType) -> Result{ +pub fn less_than_data_types(dt1: &DataType, dt2: &DataType) -> Result { match (dt1, dt2) { (DataType::Int(x1), DataType::Int(x2)) => Ok(DataType::Bool(x1 < x2)), (DataType::Int(x1), DataType::Float(x2)) => Ok(DataType::Bool(f64::from(*x1) < *x2)), (DataType::Float(x1), DataType::Int(x2)) => Ok(DataType::Bool(*x1 < f64::from(*x2))), (DataType::Float(x1), DataType::Float(x2)) => Ok(DataType::Bool(x1 < x2)), - _=> { - Err( - ChapError::runtime_with_msg(0, "less_than function works only with numbers int and float".to_string()) - ) - } + _ => Err(ChapError::runtime_with_msg( + 0, + "less_than function works only with numbers int and float".to_string(), + )), } } - diff --git a/src/runtime/builtin_function/bools/mod.rs b/src/runtime/builtin_function/bools/mod.rs index 2bc2a65..96b1eb5 100644 --- a/src/runtime/builtin_function/bools/mod.rs +++ b/src/runtime/builtin_function/bools/mod.rs @@ -1,8 +1,7 @@ - -pub mod equal; -pub mod not_equal; pub mod and; -pub mod or; -pub mod not; +pub mod equal; pub mod greater_than; pub mod less_than; +pub mod not; +pub mod not_equal; +pub mod or; diff --git a/src/runtime/builtin_function/bools/not.rs b/src/runtime/builtin_function/bools/not.rs index 171b335..37d8cad 100644 --- a/src/runtime/builtin_function/bools/not.rs +++ b/src/runtime/builtin_function/bools/not.rs @@ -1,21 +1,20 @@ -use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; - - -pub fn not(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ +use crate::common::errors::{ChapError, Result}; +use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; +pub fn not(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let p1 = param_to_datatype(runtime, executable.params.get(0), executable.line_number)?; let result = match p1 { DataType::Bool(x) => !x, - _=>{ - return Err( - ChapError::runtime_with_msg(executable.line_number, "not function needs bool params".to_string()) - ); + _ => { + return Err(ChapError::runtime_with_msg( + executable.line_number, + "not function needs bool params".to_string(), + )); } }; - returns(runtime, executable,DataType::Bool(result)) -} \ No newline at end of file + returns(runtime, executable, DataType::Bool(result)) +} diff --git a/src/runtime/builtin_function/bools/not_equal.rs b/src/runtime/builtin_function/bools/not_equal.rs index 6d48e73..1ecb576 100644 --- a/src/runtime/builtin_function/bools/not_equal.rs +++ b/src/runtime/builtin_function/bools/not_equal.rs @@ -1,13 +1,11 @@ -use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; use crate::common::errors::Result; +use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; - -pub fn not_equal(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ - +pub fn not_equal(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let p1 = param_to_datatype(runtime, executable.params.get(0), executable.line_number)?; let p2 = param_to_datatype(runtime, executable.params.get(1), executable.line_number)?; - returns(runtime, executable,DataType::Bool(p1 != p2)) -} \ No newline at end of file + returns(runtime, executable, DataType::Bool(p1 != p2)) +} diff --git a/src/runtime/builtin_function/bools/or.rs b/src/runtime/builtin_function/bools/or.rs index 1b680c7..14ca202 100644 --- a/src/runtime/builtin_function/bools/or.rs +++ b/src/runtime/builtin_function/bools/or.rs @@ -1,24 +1,22 @@ - -use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; - - -pub fn or(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ +use crate::common::errors::{ChapError, Result}; +use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; +pub fn or(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let mut result = true; - for param in &executable.params{ + for param in &executable.params { let dt = param_to_datatype(runtime, Some(param), executable.line_number)?; match dt { DataType::Bool(x) => result = result || *x, - _=>{ - return Err( - ChapError::runtime_with_msg(executable.line_number, "or function needs bool params".to_string()) - ); + _ => { + return Err(ChapError::runtime_with_msg( + executable.line_number, + "or function needs bool params".to_string(), + )); } } } - returns(runtime, executable,DataType::Bool(result)) -} \ No newline at end of file + returns(runtime, executable, DataType::Bool(result)) +} diff --git a/src/runtime/builtin_function/control_flow/jump.rs b/src/runtime/builtin_function/control_flow/jump.rs index 584fcf6..df3cd67 100644 --- a/src/runtime/builtin_function/control_flow/jump.rs +++ b/src/runtime/builtin_function/control_flow/jump.rs @@ -1,38 +1,44 @@ -use crate::{runtime::Runtime, common::{executable::ExecutableLine, errors::ChapError, param::Param}}; use crate::common::errors::Result; +use crate::{ + common::{errors::ChapError, executable::ExecutableLine, param::Param}, + runtime::Runtime, +}; // this function can't jump to a tag that is not added to runtime.executables -pub fn jump(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ - - if let Some(Param::Tag(tag)) = executable.params.get(0){ - - if let Some(line_number) = runtime.tags.get(tag){ +pub fn jump(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { + if let Some(Param::Tag(tag)) = executable.params.get(0) { + if let Some(line_number) = runtime.tags.get(tag) { // jumping back (loop) runtime.current_line = *line_number; - }else{ + } else { // jumping forward (conditional execution) // not possible in repel mode - loop{ - match runtime.executables.get(runtime.current_line){ + loop { + match runtime.executables.get(runtime.current_line) { Some(el) => { - if el.function_name == "new_tag"{ - if let Some(Param::Tag(eltag)) = el.params.get(0){ - if tag == eltag{ + if el.function_name == "new_tag" { + if let Some(Param::Tag(eltag)) = el.params.get(0) { + if tag == eltag { runtime.tags.insert(tag.clone(), runtime.current_line); break; } } } - }, - None => return Err( - ChapError::runtime_with_msg(executable.line_number, format!("cant find tag: {}", tag)) - ), + } + None => { + return Err(ChapError::runtime_with_msg( + executable.line_number, + format!("cant find tag: {}", tag), + )) + } }; runtime.current_line += 1; } } - - }else{ - return Err(ChapError::runtime_with_msg(executable.line_number, "function jump needs a tag for first params".to_string())); + } else { + return Err(ChapError::runtime_with_msg( + executable.line_number, + "function jump needs a tag for first params".to_string(), + )); } Ok(()) -} \ No newline at end of file +} diff --git a/src/runtime/builtin_function/control_flow/jump_if.rs b/src/runtime/builtin_function/control_flow/jump_if.rs index e942e57..73969c4 100644 --- a/src/runtime/builtin_function/control_flow/jump_if.rs +++ b/src/runtime/builtin_function/control_flow/jump_if.rs @@ -1,24 +1,27 @@ -use crate::{runtime::{Runtime, builtin_function::utils::param_to_datatype}, common::{executable::ExecutableLine, errors::ChapError}}; -use crate::common::errors::Result; use crate::common::data_type::DataType; +use crate::common::errors::Result; use crate::runtime::builtin_function::control_flow::jump::jump; +use crate::{ + common::{errors::ChapError, executable::ExecutableLine}, + runtime::{builtin_function::utils::param_to_datatype, Runtime}, +}; // this function can't jump to a tag that is not added to runtime.executables -pub fn jump_if(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ - +pub fn jump_if(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let p2 = param_to_datatype(runtime, executable.params.get(1), executable.line_number)?; let b = match p2 { DataType::Bool(b) => b, _ => { - return Err( - ChapError::runtime_with_msg(executable.line_number, "jump_if function needs bool as second param".to_string()) - ); + return Err(ChapError::runtime_with_msg( + executable.line_number, + "jump_if function needs bool as second param".to_string(), + )); } }; - if *b { - jump(runtime,executable)?; - } + if *b { + jump(runtime, executable)?; + } Ok(()) -} \ No newline at end of file +} diff --git a/src/runtime/builtin_function/control_flow/jump_if_equal.rs b/src/runtime/builtin_function/control_flow/jump_if_equal.rs index 59297f6..d8dd6fb 100644 --- a/src/runtime/builtin_function/control_flow/jump_if_equal.rs +++ b/src/runtime/builtin_function/control_flow/jump_if_equal.rs @@ -1,15 +1,18 @@ -use crate::{runtime::{Runtime, builtin_function::utils}, common::executable::ExecutableLine}; use crate::common::errors::Result; use crate::runtime::builtin_function::control_flow::jump::jump; +use crate::{ + common::executable::ExecutableLine, + runtime::{builtin_function::utils, Runtime}, +}; -pub fn jump_if_equal(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ - +pub fn jump_if_equal(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let p1 = utils::param_to_datatype(runtime, executable.params.get(1), executable.line_number)?; let p2 = utils::param_to_datatype(runtime, executable.params.get(2), executable.line_number)?; - if p1 == p2{ //Datatype impelements PartialEq + if p1 == p2 { + //Datatype impelements PartialEq jump(runtime, executable)?; } - Ok(()) -} \ No newline at end of file + Ok(()) +} diff --git a/src/runtime/builtin_function/control_flow/jump_if_not.rs b/src/runtime/builtin_function/control_flow/jump_if_not.rs index 8ad19cb..e396f33 100644 --- a/src/runtime/builtin_function/control_flow/jump_if_not.rs +++ b/src/runtime/builtin_function/control_flow/jump_if_not.rs @@ -1,24 +1,27 @@ -use crate::{runtime::{Runtime, builtin_function::utils::param_to_datatype}, common::{executable::ExecutableLine, errors::ChapError}}; -use crate::common::errors::Result; use crate::common::data_type::DataType; +use crate::common::errors::Result; use crate::runtime::builtin_function::control_flow::jump::jump; +use crate::{ + common::{errors::ChapError, executable::ExecutableLine}, + runtime::{builtin_function::utils::param_to_datatype, Runtime}, +}; // this function can't jump to a tag that is not added to runtime.executables -pub fn jump_if_not(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ - +pub fn jump_if_not(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let p2 = param_to_datatype(runtime, executable.params.get(1), executable.line_number)?; let b = match p2 { DataType::Bool(b) => b, _ => { - return Err( - ChapError::runtime_with_msg(executable.line_number, "jump_if_not function needs bool as second param".to_string()) - ); + return Err(ChapError::runtime_with_msg( + executable.line_number, + "jump_if_not function needs bool as second param".to_string(), + )); } }; - if !b { - jump(runtime,executable)?; - } + if !b { + jump(runtime, executable)?; + } Ok(()) -} \ No newline at end of file +} diff --git a/src/runtime/builtin_function/control_flow/jump_if_not_equal.rs b/src/runtime/builtin_function/control_flow/jump_if_not_equal.rs index b0aed52..fa552f2 100644 --- a/src/runtime/builtin_function/control_flow/jump_if_not_equal.rs +++ b/src/runtime/builtin_function/control_flow/jump_if_not_equal.rs @@ -1,15 +1,18 @@ -use crate::{runtime::{Runtime, builtin_function::utils::param_to_datatype}, common::executable::ExecutableLine}; use crate::common::errors::Result; use crate::runtime::builtin_function::control_flow::jump::jump; +use crate::{ + common::executable::ExecutableLine, + runtime::{builtin_function::utils::param_to_datatype, Runtime}, +}; -pub fn jump_if_not_equal(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ - +pub fn jump_if_not_equal(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let p1 = param_to_datatype(runtime, executable.params.get(1), executable.line_number)?; let p2 = param_to_datatype(runtime, executable.params.get(2), executable.line_number)?; - if p1 != p2{//Datatype impelements PartialEq + if p1 != p2 { + //Datatype impelements PartialEq jump(runtime, executable)?; } - Ok(()) -} \ No newline at end of file + Ok(()) +} diff --git a/src/runtime/builtin_function/control_flow/mod.rs b/src/runtime/builtin_function/control_flow/mod.rs index 9f50038..eaf05d0 100644 --- a/src/runtime/builtin_function/control_flow/mod.rs +++ b/src/runtime/builtin_function/control_flow/mod.rs @@ -1,9 +1,6 @@ - - - pub mod jump; -pub mod new_tag; pub mod jump_if; -pub mod jump_if_not; pub mod jump_if_equal; -pub mod jump_if_not_equal; \ No newline at end of file +pub mod jump_if_not; +pub mod jump_if_not_equal; +pub mod new_tag; diff --git a/src/runtime/builtin_function/control_flow/new_tag.rs b/src/runtime/builtin_function/control_flow/new_tag.rs index 9018a92..f2a4301 100644 --- a/src/runtime/builtin_function/control_flow/new_tag.rs +++ b/src/runtime/builtin_function/control_flow/new_tag.rs @@ -1,27 +1,34 @@ -use crate::{runtime::Runtime, common::{executable::ExecutableLine, errors::ChapError}}; use crate::common::errors::Result; use crate::common::param::Param; +use crate::{ + common::{errors::ChapError, executable::ExecutableLine}, + runtime::Runtime, +}; -pub fn new_tag(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ - - if let Some(Param::Tag(tag)) = executable.params.get(0){ +pub fn new_tag(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { + if let Some(Param::Tag(tag)) = executable.params.get(0) { runtime.tags.insert(tag.clone(), runtime.current_line); } else { - return Err(ChapError::runtime_with_msg(executable.line_number, "error while creating a tag".to_string())); + return Err(ChapError::runtime_with_msg( + executable.line_number, + "error while creating a tag".to_string(), + )); } Ok(()) } - #[cfg(test)] -mod tests{ - use crate::{runtime::Runtime, common::{executable::ExecutableLine, param::Param}}; +mod tests { + use crate::{ + common::{executable::ExecutableLine, param::Param}, + runtime::Runtime, + }; use super::new_tag; #[test] - fn new_tag_test(){ - let mut runtime = Runtime::new(|_|{}, ||{ "".to_string() }); + fn new_tag_test() { + let mut runtime = Runtime::new(|_| {}, || "".to_string()); new_tag( &mut runtime, @@ -29,14 +36,11 @@ mod tests{ 6, "".to_string(), vec![Param::Tag("new_tag".to_string())], - None - ) - ).unwrap(); - - assert_eq!( - runtime.tags.get("new_tag").unwrap(), - &0usize - ); + None, + ), + ) + .unwrap(); + assert_eq!(runtime.tags.get("new_tag").unwrap(), &0usize); } -} \ No newline at end of file +} diff --git a/src/runtime/builtin_function/date_time/mod.rs b/src/runtime/builtin_function/date_time/mod.rs index 8acc1aa..9f27512 100644 --- a/src/runtime/builtin_function/date_time/mod.rs +++ b/src/runtime/builtin_function/date_time/mod.rs @@ -1,3 +1 @@ - - pub mod now; diff --git a/src/runtime/builtin_function/date_time/now.rs b/src/runtime/builtin_function/date_time/now.rs index de5b44d..ced1c02 100644 --- a/src/runtime/builtin_function/date_time/now.rs +++ b/src/runtime/builtin_function/date_time/now.rs @@ -1,12 +1,11 @@ use crate::common::data_type::DataType; -use crate::runtime::builtin_function::utils::returns; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; use crate::common::errors::Result; +use crate::runtime::builtin_function::utils::returns; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; use std::time::{SystemTime, UNIX_EPOCH}; -pub fn now_sec(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ - +pub fn now_sec(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let now = SystemTime::now() .duration_since(UNIX_EPOCH) .expect("Time went backwards") diff --git a/src/runtime/builtin_function/debugger/dump.rs b/src/runtime/builtin_function/debugger/dump.rs index 047e24c..6dacc35 100644 --- a/src/runtime/builtin_function/debugger/dump.rs +++ b/src/runtime/builtin_function/debugger/dump.rs @@ -1,24 +1,16 @@ use crate::{ - runtime::{ - Runtime - }, - common::{ - executable::{ - ExecutableLine - }, - errors::Result - } + common::{errors::Result, executable::ExecutableLine}, + runtime::Runtime, }; -pub fn dump(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()>{ - - runtime.std_out(format!("------- Memory dump line: {}",executable.line_number).as_str()); - for variable in runtime.variables.iter(){ +pub fn dump(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { + runtime.std_out(format!("------- Memory dump line: {}", executable.line_number).as_str()); + for variable in runtime.variables.iter() { let name = variable.0; let value = variable.1; runtime.std_out(format!("{} -> ${}", value.to_string(), name).as_str()) } runtime.std_out("------- Memory dump ends"); - + Ok(()) -} \ No newline at end of file +} diff --git a/src/runtime/builtin_function/debugger/mod.rs b/src/runtime/builtin_function/debugger/mod.rs index 1dc2f17..b54be6d 100644 --- a/src/runtime/builtin_function/debugger/mod.rs +++ b/src/runtime/builtin_function/debugger/mod.rs @@ -1,65 +1,57 @@ - pub mod dump; use crate::{ + common::{ + errors::Result, + executable::{BuiltinFunction, ExecutableLine}, + param::Param, + }, runtime::{ - Runtime, builtin_function::{ - utils::{ - param_to_datatype, - get_var - }, - closure_gen - } - }, - common::{ - executable::{ - ExecutableLine, - BuiltinFunction + closure_gen, + utils::{get_var, param_to_datatype}, }, - param::Param, - errors::Result - } + Runtime, + }, }; - -pub fn debugger(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()>{ - +pub fn debugger(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { // inputs let mut params_values = Vec::new(); - for param in &executable.params{ - let param_str = if let Param::Tag(tag_name) = param{ + for param in &executable.params { + let param_str = if let Param::Tag(tag_name) = param { ("@".to_string() + tag_name).to_string() - }else{ + } else { param_to_datatype(runtime, Some(param), executable.line_number)?.to_string() }; params_values.push(param_str); } - let params_str = if params_values.is_empty(){ + let params_str = if params_values.is_empty() { "Nothing".to_string() - }else{ + } else { params_values.join(", ") }; - // run actual function let mut executable = executable.clone(); executable.function_name = executable.function_name.replace("?", ""); let real_function: BuiltinFunction = closure_gen(&executable)?; real_function(runtime, &executable)?; - + // output - let return_str = if let Some(var_name) = &executable.output_var{ + let return_str = if let Some(var_name) = &executable.output_var { get_var(runtime, var_name, executable.line_number)?.to_string() - }else{ + } else { "Nothing".to_string() }; - // print - runtime.std_out(format!( - "debugger on line {}: {} -> {} -> {}", - executable.line_number, params_str, executable.function_name, return_str - ).as_str()); + runtime.std_out( + format!( + "debugger on line {}: {} -> {} -> {}", + executable.line_number, params_str, executable.function_name, return_str + ) + .as_str(), + ); Ok(()) -} \ No newline at end of file +} diff --git a/src/runtime/builtin_function/delay/mod.rs b/src/runtime/builtin_function/delay/mod.rs index bfa43b3..72cef16 100644 --- a/src/runtime/builtin_function/delay/mod.rs +++ b/src/runtime/builtin_function/delay/mod.rs @@ -1,6 +1,4 @@ - - +pub mod wait_hour; pub mod wait_millis; -pub mod wait_second; pub mod wait_minute; -pub mod wait_hour; \ No newline at end of file +pub mod wait_second; diff --git a/src/runtime/builtin_function/delay/wait_hour.rs b/src/runtime/builtin_function/delay/wait_hour.rs index 232c28f..bfb623c 100644 --- a/src/runtime/builtin_function/delay/wait_hour.rs +++ b/src/runtime/builtin_function/delay/wait_hour.rs @@ -1,21 +1,24 @@ use crate::common::data_type::DataType; +use crate::common::errors::{ChapError, Result}; use crate::runtime::builtin_function::utils::param_to_datatype; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; use std::{thread, time}; -pub fn wait_hour(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ - +pub fn wait_hour(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let p1 = param_to_datatype(runtime, executable.params.get(0), executable.line_number)?; - if let DataType::Int(x) = p1{ + if let DataType::Int(x) = p1 { let hour = x * 60 * 24; let ten_millis = time::Duration::from_secs((hour).try_into().unwrap()); thread::sleep(ten_millis); - }else{ - return Err( - ChapError::runtime_with_msg(executable.line_number, format!("function {} needs int param as input", executable.function_name)) - ); + } else { + return Err(ChapError::runtime_with_msg( + executable.line_number, + format!( + "function {} needs int param as input", + executable.function_name + ), + )); } Ok(()) diff --git a/src/runtime/builtin_function/delay/wait_millis.rs b/src/runtime/builtin_function/delay/wait_millis.rs index ce5576f..00e7292 100644 --- a/src/runtime/builtin_function/delay/wait_millis.rs +++ b/src/runtime/builtin_function/delay/wait_millis.rs @@ -1,20 +1,23 @@ use crate::common::data_type::DataType; +use crate::common::errors::{ChapError, Result}; use crate::runtime::builtin_function::utils::param_to_datatype; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; use std::{thread, time}; -pub fn wait_millis(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ - +pub fn wait_millis(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let p1 = param_to_datatype(runtime, executable.params.get(0), executable.line_number)?; - if let DataType::Int(x) = p1{ + if let DataType::Int(x) = p1 { let ten_millis = time::Duration::from_millis((*x).try_into().unwrap()); thread::sleep(ten_millis); - }else{ - return Err( - ChapError::runtime_with_msg(executable.line_number, format!("function {} needs int param as input", executable.function_name)) - ); + } else { + return Err(ChapError::runtime_with_msg( + executable.line_number, + format!( + "function {} needs int param as input", + executable.function_name + ), + )); } Ok(()) diff --git a/src/runtime/builtin_function/delay/wait_minute.rs b/src/runtime/builtin_function/delay/wait_minute.rs index 2d70bd0..030f9a4 100644 --- a/src/runtime/builtin_function/delay/wait_minute.rs +++ b/src/runtime/builtin_function/delay/wait_minute.rs @@ -1,23 +1,25 @@ use crate::common::data_type::DataType; +use crate::common::errors::{ChapError, Result}; use crate::runtime::builtin_function::utils::param_to_datatype; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; use std::{thread, time}; -pub fn wait_minute(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ - +pub fn wait_minute(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let p1 = param_to_datatype(runtime, executable.params.get(0), executable.line_number)?; - if let DataType::Int(x) = p1{ + if let DataType::Int(x) = p1 { let min = x * 60; let ten_millis = time::Duration::from_secs((min).try_into().unwrap()); thread::sleep(ten_millis); - }else{ - return Err( - ChapError::runtime_with_msg(executable.line_number, format!("function {} needs int param as input", executable.function_name)) - ); + } else { + return Err(ChapError::runtime_with_msg( + executable.line_number, + format!( + "function {} needs int param as input", + executable.function_name + ), + )); } Ok(()) } - diff --git a/src/runtime/builtin_function/delay/wait_second.rs b/src/runtime/builtin_function/delay/wait_second.rs index 54bebb1..85cc94e 100644 --- a/src/runtime/builtin_function/delay/wait_second.rs +++ b/src/runtime/builtin_function/delay/wait_second.rs @@ -1,22 +1,24 @@ use crate::common::data_type::DataType; +use crate::common::errors::{ChapError, Result}; use crate::runtime::builtin_function::utils::param_to_datatype; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; use std::{thread, time}; -pub fn wait_second(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ - +pub fn wait_second(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let p1 = param_to_datatype(runtime, executable.params.get(0), executable.line_number)?; - if let DataType::Int(x) = p1{ + if let DataType::Int(x) = p1 { let ten_millis = time::Duration::from_secs((*x).try_into().unwrap()); thread::sleep(ten_millis); - }else{ - return Err( - ChapError::runtime_with_msg(executable.line_number, format!("function {} needs int param as input", executable.function_name)) - ); + } else { + return Err(ChapError::runtime_with_msg( + executable.line_number, + format!( + "function {} needs int param as input", + executable.function_name + ), + )); } Ok(()) } - diff --git a/src/runtime/builtin_function/error_handling/mod.rs b/src/runtime/builtin_function/error_handling/mod.rs index 7c25834..e459eff 100644 --- a/src/runtime/builtin_function/error_handling/mod.rs +++ b/src/runtime/builtin_function/error_handling/mod.rs @@ -1,4 +1,3 @@ - // pub mod jump_on_error; // pub mod dont_worry; // pub mod be_careful; @@ -12,4 +11,4 @@ // @end -> jump // @successfull // $a -// @end \ No newline at end of file +// @end diff --git a/src/runtime/builtin_function/list/get.rs b/src/runtime/builtin_function/list/get.rs index 15627ab..0bf3056 100644 --- a/src/runtime/builtin_function/list/get.rs +++ b/src/runtime/builtin_function/list/get.rs @@ -1,31 +1,40 @@ -use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; - - -pub fn get(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()>{ +use crate::common::errors::{ChapError, Result}; +use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; +pub fn get(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let p1 = param_to_datatype(runtime, executable.params.get(0), executable.line_number)?; let p2 = param_to_datatype(runtime, executable.params.get(1), executable.line_number)?; - if let (DataType::List(list),DataType::Int(index)) = (p1,p2){ - if let Ok(x) = usize::try_from(*index){ - if x==0 { - return Err(ChapError::runtime_with_msg(executable.line_number, "list index starts from 1".to_string())); + if let (DataType::List(list), DataType::Int(index)) = (p1, p2) { + if let Ok(x) = usize::try_from(*index) { + if x == 0 { + return Err(ChapError::runtime_with_msg( + executable.line_number, + "list index starts from 1".to_string(), + )); } let x = x - 1; let value = list.get(x); - if let Some(value) = value{ + if let Some(value) = value { returns(runtime, executable, value.clone()) - }else{ - Err(ChapError::runtime_with_msg(executable.line_number, "index out of bound".to_string())) + } else { + Err(ChapError::runtime_with_msg( + executable.line_number, + "index out of bound".to_string(), + )) } - }else{ - Err(ChapError::runtime_with_msg(executable.line_number, "negative index".to_string())) + } else { + Err(ChapError::runtime_with_msg( + executable.line_number, + "negative index".to_string(), + )) } - }else{ - Err(ChapError::runtime_with_msg(executable.line_number, "correct form of 'get' function: , -> get -> $item".to_string())) + } else { + Err(ChapError::runtime_with_msg( + executable.line_number, + "correct form of 'get' function: , -> get -> $item".to_string(), + )) } - -} \ No newline at end of file +} diff --git a/src/runtime/builtin_function/list/has.rs b/src/runtime/builtin_function/list/has.rs index 28e12f1..b51d34c 100644 --- a/src/runtime/builtin_function/list/has.rs +++ b/src/runtime/builtin_function/list/has.rs @@ -1,25 +1,26 @@ -use crate::runtime::builtin_function::utils::{returns, param_to_datatype}; use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; - - -pub fn has(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ +use crate::common::errors::{ChapError, Result}; +use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; +pub fn has(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let p1 = param_to_datatype(runtime, executable.params.get(0), executable.line_number)?; let p2 = param_to_datatype(runtime, executable.params.get(1), executable.line_number)?; let mut result = DataType::Bool(false); - if let DataType::List(list)= p1{ - for item in list{ - if item == p2{ + if let DataType::List(list) = p1 { + for item in list { + if item == p2 { result = DataType::Bool(true); break; } } - }else{ - return Err(ChapError::runtime_with_msg(executable.line_number, "has first param should be a list".to_string())); + } else { + return Err(ChapError::runtime_with_msg( + executable.line_number, + "has first param should be a list".to_string(), + )); } returns(runtime, executable, result) -} \ No newline at end of file +} diff --git a/src/runtime/builtin_function/list/index_of.rs b/src/runtime/builtin_function/list/index_of.rs index f13c99f..1b3d535 100644 --- a/src/runtime/builtin_function/list/index_of.rs +++ b/src/runtime/builtin_function/list/index_of.rs @@ -1,24 +1,28 @@ -use crate::runtime::builtin_function::utils::{returns, param_to_datatype}; use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; - - -pub fn index_of(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()>{ +use crate::common::errors::{ChapError, Result}; +use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; +pub fn index_of(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let p1 = param_to_datatype(runtime, executable.params.get(0), executable.line_number)?; let p2 = param_to_datatype(runtime, executable.params.get(1), executable.line_number)?; - let result = if let DataType::List(list) = p1{ + let result = if let DataType::List(list) = p1 { if let Some(index) = list.iter().position(|x| *x == *p2) { i32::try_from(index).unwrap_or(-1) + 1 - }else { + } else { -1 - } - }else{ - return Err(ChapError::runtime_with_msg(executable.line_number, format!("correct form of {0} function: , -> {0}", executable.function_name))); + } + } else { + return Err(ChapError::runtime_with_msg( + executable.line_number, + format!( + "correct form of {0} function: , -> {0}", + executable.function_name + ), + )); }; let result = DataType::Int(result); returns(runtime, executable, result) -} \ No newline at end of file +} diff --git a/src/runtime/builtin_function/list/insert.rs b/src/runtime/builtin_function/list/insert.rs index 350dbcc..336b067 100644 --- a/src/runtime/builtin_function/list/insert.rs +++ b/src/runtime/builtin_function/list/insert.rs @@ -1,20 +1,24 @@ -use crate::runtime::builtin_function::utils::{param_to_datatype, param_to_datatype_mut}; use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; - - -pub fn insert(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ +use crate::common::errors::{ChapError, Result}; +use crate::runtime::builtin_function::utils::{param_to_datatype, param_to_datatype_mut}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; - let p2 = param_to_datatype(runtime, executable.params.get(1), executable.line_number)? - .clone(); - let p1 = param_to_datatype_mut(&mut (*runtime), executable.params.get(0), executable.line_number)?; +pub fn insert(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { + let p2 = param_to_datatype(runtime, executable.params.get(1), executable.line_number)?.clone(); + let p1 = param_to_datatype_mut( + &mut (*runtime), + executable.params.get(0), + executable.line_number, + )?; - if let DataType::List(x) = p1{ + if let DataType::List(x) = p1 { x.push(p2); - }else{ - return Err(ChapError::runtime_with_msg(executable.line_number, "insert first param should be a list".to_string())); + } else { + return Err(ChapError::runtime_with_msg( + executable.line_number, + "insert first param should be a list".to_string(), + )); } - + Ok(()) -} \ No newline at end of file +} diff --git a/src/runtime/builtin_function/list/last.rs b/src/runtime/builtin_function/list/last.rs index ee1964b..69b2feb 100644 --- a/src/runtime/builtin_function/list/last.rs +++ b/src/runtime/builtin_function/list/last.rs @@ -1,22 +1,30 @@ -use crate::runtime::builtin_function::utils::{param_to_datatype_mut, returns}; use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; - - -pub fn last(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ +use crate::common::errors::{ChapError, Result}; +use crate::runtime::builtin_function::utils::{param_to_datatype_mut, returns}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; - let p1 = param_to_datatype_mut(&mut (*runtime), executable.params.get(0), executable.line_number)?; +pub fn last(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { + let p1 = param_to_datatype_mut( + &mut (*runtime), + executable.params.get(0), + executable.line_number, + )?; - if let DataType::List(x) = p1{ + if let DataType::List(x) = p1 { let last = x.last(); - if let Some(last) = last{ + if let Some(last) = last { let result = last.clone(); returns(runtime, executable, result) - }else{ - Err(ChapError::runtime_with_msg(executable.line_number, "list is empty".to_string())) + } else { + Err(ChapError::runtime_with_msg( + executable.line_number, + "list is empty".to_string(), + )) } - }else{ - Err(ChapError::runtime_with_msg(executable.line_number, "insert first param should be a list".to_string())) + } else { + Err(ChapError::runtime_with_msg( + executable.line_number, + "insert first param should be a list".to_string(), + )) } -} \ No newline at end of file +} diff --git a/src/runtime/builtin_function/list/mod.rs b/src/runtime/builtin_function/list/mod.rs index fba22f5..b8f8cc0 100644 --- a/src/runtime/builtin_function/list/mod.rs +++ b/src/runtime/builtin_function/list/mod.rs @@ -1,11 +1,10 @@ - // index starts from 1 -pub mod insert; // [1 2 3 4], 5 -> insert -pub mod get; // [1 2 3 4], 1 -> get -> $int -pub mod pop; // [1 2 3 4] -> pop -> $int -pub mod last; // [1 2 3 4] -> last -> $int -//pub mod len; // string function -pub mod has; // [1 2 3 4], 5 -> has -> $bool -pub mod remove; // [1 2 3 4], 2 -> remove -pub mod remove_at; // [1 2 3 4], 2 -> remove_at -pub mod index_of; // [1 2 3 4], 2 -> remove_at \ No newline at end of file +pub mod get; // [1 2 3 4], 1 -> get -> $int +pub mod insert; // [1 2 3 4], 5 -> insert +pub mod last; +pub mod pop; // [1 2 3 4] -> pop -> $int // [1 2 3 4] -> last -> $int + //pub mod len; // string function +pub mod has; // [1 2 3 4], 5 -> has -> $bool +pub mod index_of; +pub mod remove; // [1 2 3 4], 2 -> remove +pub mod remove_at; // [1 2 3 4], 2 -> remove_at // [1 2 3 4], 2 -> remove_at diff --git a/src/runtime/builtin_function/list/pop.rs b/src/runtime/builtin_function/list/pop.rs index a4e2565..bb917b6 100644 --- a/src/runtime/builtin_function/list/pop.rs +++ b/src/runtime/builtin_function/list/pop.rs @@ -1,23 +1,31 @@ -use crate::runtime::builtin_function::utils::{param_to_datatype_mut, returns}; use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; - - -pub fn pop(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ +use crate::common::errors::{ChapError, Result}; +use crate::runtime::builtin_function::utils::{param_to_datatype_mut, returns}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; - let p1 = param_to_datatype_mut(&mut (*runtime), executable.params.get(0), executable.line_number)?; +pub fn pop(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { + let p1 = param_to_datatype_mut( + &mut (*runtime), + executable.params.get(0), + executable.line_number, + )?; - if let DataType::List(x) = p1{ + if let DataType::List(x) = p1 { let last = x.last(); - if let Some(last) = last{ + if let Some(last) = last { let result = last.clone(); x.pop(); returns(runtime, executable, result) - }else{ - Err(ChapError::runtime_with_msg(executable.line_number, "list is empty".to_string())) + } else { + Err(ChapError::runtime_with_msg( + executable.line_number, + "list is empty".to_string(), + )) } - }else{ - Err(ChapError::runtime_with_msg(executable.line_number, "insert first param should be a list".to_string())) + } else { + Err(ChapError::runtime_with_msg( + executable.line_number, + "insert first param should be a list".to_string(), + )) } -} \ No newline at end of file +} diff --git a/src/runtime/builtin_function/list/remove.rs b/src/runtime/builtin_function/list/remove.rs index ba487fa..119de68 100644 --- a/src/runtime/builtin_function/list/remove.rs +++ b/src/runtime/builtin_function/list/remove.rs @@ -1,22 +1,29 @@ -use crate::runtime::builtin_function::utils::{param_to_datatype_mut, param_to_datatype}; use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; +use crate::common::errors::{ChapError, Result}; +use crate::runtime::builtin_function::utils::{param_to_datatype, param_to_datatype_mut}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; +pub fn remove(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { + let p2 = param_to_datatype(runtime, executable.params.get(1), executable.line_number)?.clone(); + let p1 = param_to_datatype_mut( + &mut (*runtime), + executable.params.get(0), + executable.line_number, + )?; -pub fn remove(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()>{ - - let p2 = param_to_datatype(runtime, executable.params.get(1), executable.line_number)? - .clone(); - let p1 = param_to_datatype_mut(&mut (*runtime), executable.params.get(0), executable.line_number)?; - - if let DataType::List(list) = p1{ + if let DataType::List(list) = p1 { if let Some(index) = list.iter().position(|x| *x == p2) { list.remove(index); } // ignore if item not founded - }else{ - return Err(ChapError::runtime_with_msg(executable.line_number, format!("correct form of {0} function: , -> {0}", executable.function_name))); + } else { + return Err(ChapError::runtime_with_msg( + executable.line_number, + format!( + "correct form of {0} function: , -> {0}", + executable.function_name + ), + )); } Ok(()) -} \ No newline at end of file +} diff --git a/src/runtime/builtin_function/list/remove_at.rs b/src/runtime/builtin_function/list/remove_at.rs index befb60d..6662436 100644 --- a/src/runtime/builtin_function/list/remove_at.rs +++ b/src/runtime/builtin_function/list/remove_at.rs @@ -1,28 +1,40 @@ -use crate::runtime::builtin_function::utils::{param_to_datatype_mut, returns, param_to_datatype}; use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; +use crate::common::errors::{ChapError, Result}; +use crate::runtime::builtin_function::utils::{param_to_datatype, param_to_datatype_mut, returns}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; +pub fn remove_at(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { + let p2 = param_to_datatype(runtime, executable.params.get(1), executable.line_number)?.clone(); + let p1 = param_to_datatype_mut( + &mut (*runtime), + executable.params.get(0), + executable.line_number, + )?; -pub fn remove_at(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ - - let p2 = param_to_datatype(runtime, executable.params.get(1), executable.line_number)? - .clone(); - let p1 = param_to_datatype_mut(&mut (*runtime), executable.params.get(0), executable.line_number)?; - - let result= - if let (DataType::List(list), DataType::Int(index)) = (p1, p2){ - if let Ok(index) = usize::try_from(index){ - if index==0 { - return Err(ChapError::runtime_with_msg(executable.line_number, "list index starts from 1".to_string())); + let result = if let (DataType::List(list), DataType::Int(index)) = (p1, p2) { + if let Ok(index) = usize::try_from(index) { + if index == 0 { + return Err(ChapError::runtime_with_msg( + executable.line_number, + "list index starts from 1".to_string(), + )); } - list.remove(index-1) // this is returning result - }else{ - return Err(ChapError::runtime_with_msg(executable.line_number, format!("{} function negative index", executable.function_name))); + list.remove(index - 1) // this is returning result + } else { + return Err(ChapError::runtime_with_msg( + executable.line_number, + format!("{} function negative index", executable.function_name), + )); } - }else{ - return Err(ChapError::runtime_with_msg(executable.line_number, format!("correct form of {0} function: , -> {0} -> $var", executable.function_name))); + } else { + return Err(ChapError::runtime_with_msg( + executable.line_number, + format!( + "correct form of {0} function: , -> {0} -> $var", + executable.function_name + ), + )); }; returns(runtime, executable, result) -} \ No newline at end of file +} diff --git a/src/runtime/builtin_function/math/add.rs b/src/runtime/builtin_function/math/add.rs index 49d41fc..c67eb6a 100644 --- a/src/runtime/builtin_function/math/add.rs +++ b/src/runtime/builtin_function/math/add.rs @@ -1,29 +1,26 @@ -use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; - - -pub fn add(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ +use crate::common::errors::{ChapError, Result}; +use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; +pub fn add(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let p1 = param_to_datatype(runtime, executable.params.get(0), executable.line_number)?; let p2 = param_to_datatype(runtime, executable.params.get(1), executable.line_number)?; - let sum = add_data_types(p1,p2)?; - + let sum = add_data_types(p1, p2)?; + returns(runtime, executable, sum) } -pub fn add_data_types(dt1: &DataType, dt2: &DataType) -> Result{ +pub fn add_data_types(dt1: &DataType, dt2: &DataType) -> Result { match (dt1, dt2) { - (DataType::Int(x1), DataType::Int(x2)) => Ok(DataType::Int(x1+x2)), - (DataType::Int(x1), DataType::Float(x2)) => Ok(DataType::Float(f64::from(*x1)+x2)), + (DataType::Int(x1), DataType::Int(x2)) => Ok(DataType::Int(x1 + x2)), + (DataType::Int(x1), DataType::Float(x2)) => Ok(DataType::Float(f64::from(*x1) + x2)), (DataType::Float(x1), DataType::Int(x2)) => Ok(DataType::Float(x1 + f64::from(*x2))), - (DataType::Float(x1), DataType::Float(x2)) => Ok(DataType::Float(x1+x2)), - _=> { - Err( - ChapError::runtime_with_msg(0, "add function works only with numbers int and float".to_string()) - ) - } + (DataType::Float(x1), DataType::Float(x2)) => Ok(DataType::Float(x1 + x2)), + _ => Err(ChapError::runtime_with_msg( + 0, + "add function works only with numbers int and float".to_string(), + )), } } diff --git a/src/runtime/builtin_function/math/add_many.rs b/src/runtime/builtin_function/math/add_many.rs index 085e6a3..ae082c5 100644 --- a/src/runtime/builtin_function/math/add_many.rs +++ b/src/runtime/builtin_function/math/add_many.rs @@ -1,16 +1,15 @@ -use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; use crate::common::errors::Result; use crate::runtime::builtin_function::math::add::add_data_types; +use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; -pub fn add_many(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ - +pub fn add_many(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let mut sum = DataType::Int(0); - for param in &executable.params{ + for param in &executable.params { let new_value = param_to_datatype(runtime, Some(param), executable.line_number)?; sum = add_data_types(&sum, new_value)?; } - returns(runtime, executable, sum) -} \ No newline at end of file + returns(runtime, executable, sum) +} diff --git a/src/runtime/builtin_function/math/decrease.rs b/src/runtime/builtin_function/math/decrease.rs index 815e9d5..8b83b74 100644 --- a/src/runtime/builtin_function/math/decrease.rs +++ b/src/runtime/builtin_function/math/decrease.rs @@ -1,24 +1,32 @@ use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; +use crate::common::errors::{ChapError, Result}; use crate::common::param::Param; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; -pub fn decrease(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ - - if let Some(Param::Variable(name)) = executable.params.get(0){ - match runtime.variables.get(name){ +pub fn decrease(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { + if let Some(Param::Variable(name)) = executable.params.get(0) { + match runtime.variables.get(name) { Some(x) => match x { DataType::Int(x) => { - runtime.variables.insert(name.to_string(), DataType::Int(x-1)); + runtime + .variables + .insert(name.to_string(), DataType::Int(x - 1)); Ok(()) - }, - _ => { - Err(ChapError::runtime_with_msg(executable.line_number, "decrease function needs one integer variable as input param".to_string())) } + _ => Err(ChapError::runtime_with_msg( + executable.line_number, + "decrease function needs one integer variable as input param".to_string(), + )), }, - None => Err(ChapError::runtime_with_msg(executable.line_number, format!("variable {} is not defind",name))), + None => Err(ChapError::runtime_with_msg( + executable.line_number, + format!("variable {} is not defind", name), + )), } - }else { - Err(ChapError::runtime_with_msg(executable.line_number, "decrease function need one variable".to_string())) + } else { + Err(ChapError::runtime_with_msg( + executable.line_number, + "decrease function need one variable".to_string(), + )) } } diff --git a/src/runtime/builtin_function/math/divide.rs b/src/runtime/builtin_function/math/divide.rs index b32dbdf..1e32770 100644 --- a/src/runtime/builtin_function/math/divide.rs +++ b/src/runtime/builtin_function/math/divide.rs @@ -1,29 +1,28 @@ -use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; - - -pub fn divide(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ +use crate::common::errors::{ChapError, Result}; +use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; +pub fn divide(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let p1 = param_to_datatype(runtime, executable.params.get(0), executable.line_number)?; let p2 = param_to_datatype(runtime, executable.params.get(1), executable.line_number)?; - let result = divide_data_types(p1,p2)?; - + let result = divide_data_types(p1, p2)?; + returns(runtime, executable, result) } -fn divide_data_types(dt1: &DataType, dt2: &DataType) -> Result{ +fn divide_data_types(dt1: &DataType, dt2: &DataType) -> Result { match (dt1, dt2) { - (DataType::Int(x1), DataType::Int(x2)) => Ok(DataType::Float(f64::from(*x1)/f64::from(*x2))), - (DataType::Int(x1), DataType::Float(x2)) => Ok(DataType::Float(f64::from(*x1)/x2)), - (DataType::Float(x1), DataType::Int(x2)) => Ok(DataType::Float(x1 / f64::from(*x2))), - (DataType::Float(x1), DataType::Float(x2)) => Ok(DataType::Float(x1/x2)), - _=> { - Err( - ChapError::runtime_with_msg(0, "divide function works only with numbers int and float".to_string()) - ) + (DataType::Int(x1), DataType::Int(x2)) => { + Ok(DataType::Float(f64::from(*x1) / f64::from(*x2))) } + (DataType::Int(x1), DataType::Float(x2)) => Ok(DataType::Float(f64::from(*x1) / x2)), + (DataType::Float(x1), DataType::Int(x2)) => Ok(DataType::Float(x1 / f64::from(*x2))), + (DataType::Float(x1), DataType::Float(x2)) => Ok(DataType::Float(x1 / x2)), + _ => Err(ChapError::runtime_with_msg( + 0, + "divide function works only with numbers int and float".to_string(), + )), } } diff --git a/src/runtime/builtin_function/math/increase.rs b/src/runtime/builtin_function/math/increase.rs index 948271e..d38f988 100644 --- a/src/runtime/builtin_function/math/increase.rs +++ b/src/runtime/builtin_function/math/increase.rs @@ -1,25 +1,32 @@ - use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; +use crate::common::errors::{ChapError, Result}; use crate::common::param::Param; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; -pub fn increase(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ - - if let Some(Param::Variable(name)) = executable.params.get(0){ - match runtime.variables.get(name){ +pub fn increase(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { + if let Some(Param::Variable(name)) = executable.params.get(0) { + match runtime.variables.get(name) { Some(x) => match x { DataType::Int(x) => { - runtime.variables.insert(name.to_string(), DataType::Int(x+1)); + runtime + .variables + .insert(name.to_string(), DataType::Int(x + 1)); Ok(()) - }, - _ => { - Err(ChapError::runtime_with_msg(executable.line_number, "increase function needs one integer variable as input param".to_string())) } + _ => Err(ChapError::runtime_with_msg( + executable.line_number, + "increase function needs one integer variable as input param".to_string(), + )), }, - None => Err(ChapError::runtime_with_msg(executable.line_number, format!("variable {} is not defind", name))), + None => Err(ChapError::runtime_with_msg( + executable.line_number, + format!("variable {} is not defind", name), + )), } - }else { - Err(ChapError::runtime_with_msg(executable.line_number, "increase function need one variable".to_string())) + } else { + Err(ChapError::runtime_with_msg( + executable.line_number, + "increase function need one variable".to_string(), + )) } -} \ No newline at end of file +} diff --git a/src/runtime/builtin_function/math/minus.rs b/src/runtime/builtin_function/math/minus.rs index 1438581..252b051 100644 --- a/src/runtime/builtin_function/math/minus.rs +++ b/src/runtime/builtin_function/math/minus.rs @@ -1,29 +1,26 @@ -use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; - - -pub fn minus(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ +use crate::common::errors::{ChapError, Result}; +use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; +pub fn minus(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let p1 = param_to_datatype(runtime, executable.params.get(0), executable.line_number)?; let p2 = param_to_datatype(runtime, executable.params.get(1), executable.line_number)?; - let result = minus_data_types(p1,p2)?; - + let result = minus_data_types(p1, p2)?; + returns(runtime, executable, result) } -fn minus_data_types(dt1: &DataType, dt2: &DataType) -> Result{ +fn minus_data_types(dt1: &DataType, dt2: &DataType) -> Result { match (dt1, dt2) { - (DataType::Int(x1), DataType::Int(x2)) => Ok(DataType::Int(x1-x2)), - (DataType::Int(x1), DataType::Float(x2)) => Ok(DataType::Float(f64::from(*x1)-x2)), + (DataType::Int(x1), DataType::Int(x2)) => Ok(DataType::Int(x1 - x2)), + (DataType::Int(x1), DataType::Float(x2)) => Ok(DataType::Float(f64::from(*x1) - x2)), (DataType::Float(x1), DataType::Int(x2)) => Ok(DataType::Float(x1 - f64::from(*x2))), - (DataType::Float(x1), DataType::Float(x2)) => Ok(DataType::Float(x1-x2)), - _=> { - Err( - ChapError::runtime_with_msg(0, "minus function works only with numbers int and float".to_string()) - ) - } + (DataType::Float(x1), DataType::Float(x2)) => Ok(DataType::Float(x1 - x2)), + _ => Err(ChapError::runtime_with_msg( + 0, + "minus function works only with numbers int and float".to_string(), + )), } } diff --git a/src/runtime/builtin_function/math/mod.rs b/src/runtime/builtin_function/math/mod.rs index 7eaa977..fb2138e 100644 --- a/src/runtime/builtin_function/math/mod.rs +++ b/src/runtime/builtin_function/math/mod.rs @@ -1,15 +1,13 @@ - - // simple math pub mod add; -pub mod minus; pub mod divide; -pub mod multiply; -pub mod modulus; // Divide remaining +pub mod minus; +pub mod modulus; +pub mod multiply; // Divide remaining // more math +pub mod add_many; +pub mod decrease; +pub mod increase; pub mod power; pub mod sqrt; -pub mod increase; -pub mod decrease; -pub mod add_many; diff --git a/src/runtime/builtin_function/math/modulus.rs b/src/runtime/builtin_function/math/modulus.rs index dc560d5..c471d77 100644 --- a/src/runtime/builtin_function/math/modulus.rs +++ b/src/runtime/builtin_function/math/modulus.rs @@ -1,29 +1,26 @@ -use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; - - -pub fn modulus(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ +use crate::common::errors::{ChapError, Result}; +use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; +pub fn modulus(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let p1 = param_to_datatype(runtime, executable.params.get(0), executable.line_number)?; let p2 = param_to_datatype(runtime, executable.params.get(1), executable.line_number)?; - let result = modulus_data_types(p1,p2)?; - + let result = modulus_data_types(p1, p2)?; + returns(runtime, executable, result) } -fn modulus_data_types(dt1: &DataType, dt2: &DataType) -> Result{ +fn modulus_data_types(dt1: &DataType, dt2: &DataType) -> Result { match (dt1, dt2) { - (DataType::Int(x1), DataType::Int(x2)) => Ok(DataType::Int(x1%x2)), - (DataType::Int(x1), DataType::Float(x2)) => Ok(DataType::Float(f64::from(*x1)%x2)), + (DataType::Int(x1), DataType::Int(x2)) => Ok(DataType::Int(x1 % x2)), + (DataType::Int(x1), DataType::Float(x2)) => Ok(DataType::Float(f64::from(*x1) % x2)), (DataType::Float(x1), DataType::Int(x2)) => Ok(DataType::Float(x1 % f64::from(*x2))), (DataType::Float(x1), DataType::Float(x2)) => Ok(DataType::Float(x1 % x2)), - _=> { - Err( - ChapError::runtime_with_msg(0, "modulus function works only with numbers int and float".to_string()) - ) - } + _ => Err(ChapError::runtime_with_msg( + 0, + "modulus function works only with numbers int and float".to_string(), + )), } } diff --git a/src/runtime/builtin_function/math/multiply.rs b/src/runtime/builtin_function/math/multiply.rs index 08fdfbd..2e3cc09 100644 --- a/src/runtime/builtin_function/math/multiply.rs +++ b/src/runtime/builtin_function/math/multiply.rs @@ -1,28 +1,25 @@ -use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; - - -pub fn multiply(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ +use crate::common::errors::{ChapError, Result}; +use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; +pub fn multiply(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let p1 = param_to_datatype(runtime, executable.params.get(0), executable.line_number)?; let p2 = param_to_datatype(runtime, executable.params.get(1), executable.line_number)?; - let result = multiply_data_types(p1,p2)?; + let result = multiply_data_types(p1, p2)?; returns(runtime, executable, result) } -fn multiply_data_types(dt1: &DataType, dt2: &DataType) -> Result{ +fn multiply_data_types(dt1: &DataType, dt2: &DataType) -> Result { match (dt1, dt2) { (DataType::Int(x1), DataType::Int(x2)) => Ok(DataType::Int(x1 * x2)), (DataType::Int(x1), DataType::Float(x2)) => Ok(DataType::Float(f64::from(*x1) * x2)), (DataType::Float(x1), DataType::Int(x2)) => Ok(DataType::Float(x1 * f64::from(*x2))), (DataType::Float(x1), DataType::Float(x2)) => Ok(DataType::Float(x1 * x2)), - _=> { - Err( - ChapError::runtime_with_msg(0, "multiply function works only with numbers int and float".to_string()) - ) - } + _ => Err(ChapError::runtime_with_msg( + 0, + "multiply function works only with numbers int and float".to_string(), + )), } } diff --git a/src/runtime/builtin_function/math/power.rs b/src/runtime/builtin_function/math/power.rs index 122448d..5fae18a 100644 --- a/src/runtime/builtin_function/math/power.rs +++ b/src/runtime/builtin_function/math/power.rs @@ -1,28 +1,25 @@ -use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; - - -pub fn power(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ +use crate::common::errors::{ChapError, Result}; +use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; +pub fn power(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let p1 = param_to_datatype(runtime, executable.params.get(0), executable.line_number)?; let p2 = param_to_datatype(runtime, executable.params.get(1), executable.line_number)?; - let result = power_data_types(p1,p2)?; + let result = power_data_types(p1, p2)?; returns(runtime, executable, result) } -fn power_data_types(dt1: &DataType, dt2: &DataType) -> Result{ +fn power_data_types(dt1: &DataType, dt2: &DataType) -> Result { match (dt1, dt2) { (DataType::Int(x1), DataType::Int(x2)) => { let x2: u32 = u32::try_from(*x2).unwrap(); Ok(DataType::Int(i32::pow(*x1, x2))) - }, - _=> { - Err( - ChapError::runtime_with_msg(0, "power function works only with numbers int and float".to_string()) - ) } + _ => Err(ChapError::runtime_with_msg( + 0, + "power function works only with numbers int and float".to_string(), + )), } } diff --git a/src/runtime/builtin_function/math/sqrt.rs b/src/runtime/builtin_function/math/sqrt.rs index 1a6fcd8..450d961 100644 --- a/src/runtime/builtin_function/math/sqrt.rs +++ b/src/runtime/builtin_function/math/sqrt.rs @@ -1,25 +1,22 @@ -use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; - - -pub fn sqrt(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ +use crate::common::errors::{ChapError, Result}; +use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; +pub fn sqrt(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let p1 = param_to_datatype(runtime, executable.params.get(0), executable.line_number)?; let result = sqrt_data_type(p1)?; returns(runtime, executable, result) } -fn sqrt_data_type(dt: &DataType) -> Result{ +fn sqrt_data_type(dt: &DataType) -> Result { match dt { DataType::Int(x) => Ok(DataType::Float(f64::sqrt(f64::from(*x)))), DataType::Float(x) => Ok(DataType::Float(f64::sqrt(*x))), - _=>{ - Err( - ChapError::runtime_with_msg(0, "sqrt function works only with numbers int and float".to_string()) - ) - } + _ => Err(ChapError::runtime_with_msg( + 0, + "sqrt function works only with numbers int and float".to_string(), + )), } } diff --git a/src/runtime/builtin_function/mod.rs b/src/runtime/builtin_function/mod.rs index f143735..32559ce 100644 --- a/src/runtime/builtin_function/mod.rs +++ b/src/runtime/builtin_function/mod.rs @@ -1,86 +1,88 @@ -use crate::common::{executable::{BuiltinFunction, ExecutableLine}, errors::ChapError}; use crate::common::errors::Result; +use crate::common::{ + errors::ChapError, + executable::{BuiltinFunction, ExecutableLine}, +}; mod assign; -mod utils; mod type_of; +mod utils; -mod control_flow; -mod math; -mod std; mod bools; -mod strings; -mod type_conversion; +mod control_flow; mod date_time; -mod delay; mod debugger; +mod delay; mod error_handling; mod list; +mod math; +mod std; +mod strings; +mod type_conversion; -pub fn closure_gen(executable: &ExecutableLine) -> Result{ - +pub fn closure_gen(executable: &ExecutableLine) -> Result { let debug_mode = executable.function_name.ends_with("?"); - let function_name = executable.function_name + let function_name = executable + .function_name .clone() .to_lowercase() .replace([' ', '_', '?'], ""); - - let function = match function_match(&function_name){ + let function = match function_match(&function_name) { Some(f) => f, - None => return Err( - ChapError::static_analyzer_with_msg( + None => { + return Err(ChapError::static_analyzer_with_msg( executable.line_number, - format!("there is no function with name: {}", executable.function_name) - ) - ) + format!( + "there is no function with name: {}", + executable.function_name + ), + )) + } }; - if debug_mode{ + if debug_mode { Ok(debugger::debugger) - }else { + } else { Ok(function) } } - #[cfg(target_family = "unix")] -pub fn function_match(function_name: &str) -> Option{ - if let Some(f) = common_functions(function_name){ +pub fn function_match(function_name: &str) -> Option { + if let Some(f) = common_functions(function_name) { Some(f) - }else { + } else { random_functions(function_name) } } #[cfg(target_family = "windows")] -pub fn function_match(function_name: &str) -> Option{ - if let Some(f) = common_functions(function_name){ +pub fn function_match(function_name: &str) -> Option { + if let Some(f) = common_functions(function_name) { return Some(f); - }else if let Some(f) = random_functions(function_name) { + } else if let Some(f) = random_functions(function_name) { return Some(f); - }else{ + } else { None } } #[cfg(target_family = "wasm")] -pub fn function_match(function_name: &str) -> Option{ - if let Some(f) = common_functions(function_name){ +pub fn function_match(function_name: &str) -> Option { + if let Some(f) = common_functions(function_name) { return Some(f); - }else{ + } else { None } } - -pub fn common_functions(function_name: &str) -> Option{ - +pub fn common_functions(function_name: &str) -> Option { match function_name { "assign" => Some(assign::assign), - "jump" =>Some( control_flow::jump::jump), - "jumpif" =>Some( control_flow::jump_if::jump_if), - "jumpifnot" =>Some( control_flow::jump_if_not::jump_if_not), + "jump" => Some(control_flow::jump::jump), + "jumpif" => Some(control_flow::jump_if::jump_if), + "jumpifnot" => Some(control_flow::jump_if_not::jump_if_not), "jumpifequal" | "jeq" => Some(control_flow::jump_if_equal::jump_if_equal), "jumpifnotequal" | "jneq" => Some(control_flow::jump_if_not_equal::jump_if_not_equal), "newtag" => Some(control_flow::new_tag::new_tag), @@ -102,10 +104,10 @@ pub fn common_functions(function_name: &str) -> Option{ "gt" | "greaterthan" => Some(bools::greater_than::greater_than), "lt" | "lessthan" => Some(bools::less_than::less_than), "concat" | "cat" => Some(strings::contact::concat), - "repeat" => Some(strings::repeat::repeat), - "length" | "len" => Some(strings::length::length), - "contains" | "has" => Some(strings::contains::contains), - "slice" | "substring" => Some(strings::slice::slice), + "repeat" => Some(strings::repeat::repeat), + "length" | "len" => Some(strings::length::length), + "contains" | "has" => Some(strings::contains::contains), + "slice" | "substring" => Some(strings::slice::slice), "insert" | "push" => Some(list::insert::insert), "get" | "at" => Some(list::get::get), "pop" => Some(list::pop::pop), @@ -113,13 +115,13 @@ pub fn common_functions(function_name: &str) -> Option{ "includes" | "in" => Some(list::has::has), "removeat" | "rmat" => Some(list::remove_at::remove_at), "removeitem" | "rmit" => Some(list::remove::remove), - "indexof" => Some(list::index_of::index_of), + "indexof" => Some(list::index_of::index_of), "dump" | "dumpmemory" => Some(debugger::dump::dump), "typeof" | "type" => Some(type_of::type_of), "tostring" | "tostr" => Some(type_conversion::to_string::to_string), - "tofloat" => Some(type_conversion::to_float::to_float), - "toint" => Some(type_conversion::to_int::to_int), - "now" | "nowsec" | "unixtime" => Some(date_time::now::now_sec), + "tofloat" => Some(type_conversion::to_float::to_float), + "toint" => Some(type_conversion::to_int::to_int), + "now" | "nowsec" | "unixtime" => Some(date_time::now::now_sec), "waitmil" | "waitmillis" => Some(delay::wait_millis::wait_millis), "waitsec" | "waitseconds" => Some(delay::wait_second::wait_second), "waitmin" | "waitminutes" => Some(delay::wait_minute::wait_minute), @@ -127,9 +129,7 @@ pub fn common_functions(function_name: &str) -> Option{ "print" | "show" | "stdout" => Some(std::println::println), "input" | "stdin" => Some(std::input::input), "exit" | "quit" | "kill" | "end" => Some(std::exit::exit), - _=>{ - None - } + _ => None, } } @@ -137,15 +137,12 @@ pub fn common_functions(function_name: &str) -> Option{ #[cfg(not(target_family = "wasm"))] mod random; #[cfg(not(target_family = "wasm"))] -pub fn random_functions(function_name: &str) -> Option{ - +pub fn random_functions(function_name: &str) -> Option { match function_name { "randomnumber" | "randnum" => Some(random::random_number::random_number), "randomstring" | "randstr" => Some(random::random_string::random_string), "randombool" | "randbool" => Some(random::random_bool::random_bool), "randomchoice" | "randchoice" => Some(random::random_choice::random_choice), - _=>{ - None - } + _ => None, } } diff --git a/src/runtime/builtin_function/random/mod.rs b/src/runtime/builtin_function/random/mod.rs index cdb4b74..733db16 100644 --- a/src/runtime/builtin_function/random/mod.rs +++ b/src/runtime/builtin_function/random/mod.rs @@ -1,5 +1,4 @@ - -pub mod random_number; -pub mod random_string; pub mod random_bool; -pub mod random_choice; \ No newline at end of file +pub mod random_choice; +pub mod random_number; +pub mod random_string; diff --git a/src/runtime/builtin_function/random/random_bool.rs b/src/runtime/builtin_function/random/random_bool.rs index a947330..e221fe9 100644 --- a/src/runtime/builtin_function/random/random_bool.rs +++ b/src/runtime/builtin_function/random/random_bool.rs @@ -1,11 +1,10 @@ -use crate::runtime::builtin_function::utils::returns; use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; use crate::common::errors::Result; +use crate::runtime::builtin_function::utils::returns; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; use rand::Rng; -pub fn random_bool(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()>{ - - let mut rng = rand::thread_rng(); +pub fn random_bool(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { + let mut rng = rand::thread_rng(); returns(runtime, executable, DataType::Bool(rng.gen_bool(0.5))) } diff --git a/src/runtime/builtin_function/random/random_choice.rs b/src/runtime/builtin_function/random/random_choice.rs index e214a89..2d3308a 100644 --- a/src/runtime/builtin_function/random/random_choice.rs +++ b/src/runtime/builtin_function/random/random_choice.rs @@ -1,26 +1,24 @@ +use crate::common::errors::{ChapError, Result}; use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; use rand::Rng; -pub fn random_choice(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()>{ - +pub fn random_choice(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let mut choices = Vec::new(); - for param in &executable.params{ + for param in &executable.params { let value = param_to_datatype(runtime, Some(param), executable.line_number)?; choices.push(value); } - if choices.len() < 2{ - return Err( - ChapError::runtime_with_msg(executable.line_number, "random_choice needs many input params".to_string()) - ); + if choices.len() < 2 { + return Err(ChapError::runtime_with_msg( + executable.line_number, + "random_choice needs many input params".to_string(), + )); } - let mut rng = rand::thread_rng(); - let result = choices.get( - rng.gen_range(0..choices.len()) - ).unwrap(); + let mut rng = rand::thread_rng(); + let result = choices.get(rng.gen_range(0..choices.len())).unwrap(); returns(runtime, executable, (*result).clone()) } diff --git a/src/runtime/builtin_function/random/random_number.rs b/src/runtime/builtin_function/random/random_number.rs index ec6c63f..a2bc37b 100644 --- a/src/runtime/builtin_function/random/random_number.rs +++ b/src/runtime/builtin_function/random/random_number.rs @@ -1,24 +1,24 @@ -use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; +use crate::common::errors::{ChapError, Result}; +use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; use rand::Rng; -pub fn random_number(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()>{ - - let p1 = param_to_datatype(runtime, executable.params.get(0), executable.line_number)?; - let p2 = param_to_datatype(runtime, executable.params.get(1), executable.line_number)?; +pub fn random_number(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { + let p1 = param_to_datatype(runtime, executable.params.get(0), executable.line_number)?; + let p2 = param_to_datatype(runtime, executable.params.get(1), executable.line_number)?; - let mut rng = rand::thread_rng(); + let mut rng = rand::thread_rng(); - let result = match (p1, p2) { - (DataType::Int(x1), DataType::Int(x2)) => DataType::Int(rng.gen_range(*x1..*x2)), - (DataType::Float(x1), DataType::Float(x2)) => DataType::Float(rng.gen_range(*x1..*x2)), - _=>{ - return Err( - ChapError::runtime_with_msg(executable.line_number, "random_number supports int,int or float,float in input".to_string()) - ); - } - }; + let result = match (p1, p2) { + (DataType::Int(x1), DataType::Int(x2)) => DataType::Int(rng.gen_range(*x1..*x2)), + (DataType::Float(x1), DataType::Float(x2)) => DataType::Float(rng.gen_range(*x1..*x2)), + _ => { + return Err(ChapError::runtime_with_msg( + executable.line_number, + "random_number supports int,int or float,float in input".to_string(), + )); + } + }; returns(runtime, executable, result) } diff --git a/src/runtime/builtin_function/random/random_string.rs b/src/runtime/builtin_function/random/random_string.rs index a41c47c..57e8567 100644 --- a/src/runtime/builtin_function/random/random_string.rs +++ b/src/runtime/builtin_function/random/random_string.rs @@ -1,35 +1,33 @@ -use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; -use rand::Rng; +use crate::common::errors::{ChapError, Result}; +use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; use rand::rngs::ThreadRng; +use rand::Rng; -pub fn random_string(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()>{ - - let p1 = param_to_datatype(runtime, executable.params.get(0), executable.line_number)?; - let p2 = param_to_datatype(runtime, executable.params.get(1), executable.line_number)?; +pub fn random_string(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { + let p1 = param_to_datatype(runtime, executable.params.get(0), executable.line_number)?; + let p2 = param_to_datatype(runtime, executable.params.get(1), executable.line_number)?; - let mut rng = rand::thread_rng(); + let mut rng = rand::thread_rng(); - let result = match (p1, p2) { - (DataType::String(x1), DataType::Int(x2)) => { - DataType::String( - (0..*x2).map(|_|{ get_random_char(&mut rng,x1)}).collect() - ) - }, - _=>{ - return Err( + let result = match (p1, p2) { + (DataType::String(x1), DataType::Int(x2)) => { + DataType::String((0..*x2).map(|_| get_random_char(&mut rng, x1)).collect()) + } + _ => { + return Err( ChapError::runtime_with_msg(executable.line_number, "random_string function needs string, int as param (first one is alphabet and second one is length of generated string) ".to_string()) ); - } - }; + } + }; returns(runtime, executable, result) } -fn get_random_char(rng: &mut ThreadRng, alphabet: &String) -> char{ - alphabet.chars().nth( - rng.gen_range(0..alphabet.len()) - ).unwrap() +fn get_random_char(rng: &mut ThreadRng, alphabet: &String) -> char { + alphabet + .chars() + .nth(rng.gen_range(0..alphabet.len())) + .unwrap() } diff --git a/src/runtime/builtin_function/std/exit.rs b/src/runtime/builtin_function/std/exit.rs index 7062a1c..2566482 100644 --- a/src/runtime/builtin_function/std/exit.rs +++ b/src/runtime/builtin_function/std/exit.rs @@ -1,7 +1,6 @@ -use crate::{runtime::Runtime, common::executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; - -pub fn exit(_runtime: &mut Runtime,_executable: &ExecutableLine)-> Result<()>{ +use crate::common::errors::{ChapError, Result}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; +pub fn exit(_runtime: &mut Runtime, _executable: &ExecutableLine) -> Result<()> { Err(ChapError::stop()) -} \ No newline at end of file +} diff --git a/src/runtime/builtin_function/std/input.rs b/src/runtime/builtin_function/std/input.rs index 990a0b3..31a033f 100644 --- a/src/runtime/builtin_function/std/input.rs +++ b/src/runtime/builtin_function/std/input.rs @@ -1,41 +1,35 @@ use crate::common::data_type::DataType; -use crate::runtime::builtin_function::utils::returns; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; use crate::common::errors::Result; +use crate::runtime::builtin_function::utils::returns; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; - -pub fn input(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ - +pub fn input(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let inp = runtime.std_in(); returns(runtime, executable, DataType::String(inp)) } - #[cfg(test)] -mod tests{ - use crate::{runtime::Runtime, common::{executable::ExecutableLine, data_type::DataType}}; +mod tests { + use crate::{ + common::{data_type::DataType, executable::ExecutableLine}, + runtime::Runtime, + }; use super::input; - #[test] - fn input_test(){ - - let mut runtime = Runtime::new(|_|{}, ||{ "test".to_string() }); + fn input_test() { + let mut runtime = Runtime::new(|_| {}, || "test".to_string()); input( &mut runtime, - &ExecutableLine::new( - 1, - "".to_string(), - vec![], - Some("test_var".to_string()) - ) - ).unwrap(); + &ExecutableLine::new(1, "".to_string(), vec![], Some("test_var".to_string())), + ) + .unwrap(); assert_eq!( runtime.variables.get("test_var").unwrap(), &DataType::String("test".to_string()) ) } -} \ No newline at end of file +} diff --git a/src/runtime/builtin_function/std/mod.rs b/src/runtime/builtin_function/std/mod.rs index 893526c..060dd18 100644 --- a/src/runtime/builtin_function/std/mod.rs +++ b/src/runtime/builtin_function/std/mod.rs @@ -1,5 +1,3 @@ - - pub mod exit; +pub mod input; pub mod println; -pub mod input; \ No newline at end of file diff --git a/src/runtime/builtin_function/std/println.rs b/src/runtime/builtin_function/std/println.rs index 7160b95..617c07c 100644 --- a/src/runtime/builtin_function/std/println.rs +++ b/src/runtime/builtin_function/std/println.rs @@ -1,74 +1,88 @@ -use crate::{runtime::Runtime, common::executable::ExecutableLine}; -use crate::runtime::builtin_function::utils::param_to_datatype; use crate::common::errors::Result; +use crate::runtime::builtin_function::utils::param_to_datatype; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; - -pub fn println(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ - +pub fn println(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let mut result: Vec = Vec::new(); for param in &executable.params { let dt = param_to_datatype(runtime, Some(param), executable.line_number)?; result.push(dt.to_string()); } runtime.std_out(result.join(", ").as_str()); - + Ok(()) } - #[cfg(test)] -mod tests{ +mod tests { + use super::*; use crate::common::data_type::DataType; use crate::common::param::Param; - use super::*; #[test] - fn print_string(){ - let mut runtime = Runtime::new(|x|{ - assert_eq!(x, "test"); - }, ||{ "".to_string() }); - + fn print_string() { + let mut runtime = Runtime::new( + |x| { + assert_eq!(x, "test"); + }, + || "".to_string(), + ); println( &mut runtime, - &ExecutableLine::new(1, + &ExecutableLine::new( + 1, "".to_string(), vec![Param::Value(DataType::String("test".to_string()))], - None - ) - ).unwrap(); + None, + ), + ) + .unwrap(); } #[test] - fn print_int(){ - let mut runtime = Runtime::new(|x|{ - assert_eq!(x, "2"); - }, ||{ "".to_string() }); + fn print_int() { + let mut runtime = Runtime::new( + |x| { + assert_eq!(x, "2"); + }, + || "".to_string(), + ); println( &mut runtime, - &ExecutableLine::new(1, + &ExecutableLine::new( + 1, "".to_string(), vec![Param::Value(DataType::Int(2))], - None - ) - ).unwrap(); + None, + ), + ) + .unwrap(); } #[test] - fn print_many(){ - let mut runtime = Runtime::new(|x|{ - assert_eq!(x, "2, false"); - }, ||{ "".to_string() }); + fn print_many() { + let mut runtime = Runtime::new( + |x| { + assert_eq!(x, "2, false"); + }, + || "".to_string(), + ); println( &mut runtime, - &ExecutableLine::new(1, + &ExecutableLine::new( + 1, "".to_string(), - vec![Param::Value(DataType::Int(2)),Param::Value(DataType::Bool(false))], - None - ) - ).unwrap(); + vec![ + Param::Value(DataType::Int(2)), + Param::Value(DataType::Bool(false)), + ], + None, + ), + ) + .unwrap(); } -} \ No newline at end of file +} diff --git a/src/runtime/builtin_function/strings/contact.rs b/src/runtime/builtin_function/strings/contact.rs index 171acad..854110f 100644 --- a/src/runtime/builtin_function/strings/contact.rs +++ b/src/runtime/builtin_function/strings/contact.rs @@ -1,13 +1,11 @@ -use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; use crate::common::errors::Result; +use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; - -pub fn concat(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ - +pub fn concat(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let mut result = String::new(); - for param in &executable.params{ + for param in &executable.params { let dt = param_to_datatype(runtime, Some(param), executable.line_number)?; result.push_str(dt.to_string().as_str()); } diff --git a/src/runtime/builtin_function/strings/contains.rs b/src/runtime/builtin_function/strings/contains.rs index 0551414..cde239f 100644 --- a/src/runtime/builtin_function/strings/contains.rs +++ b/src/runtime/builtin_function/strings/contains.rs @@ -1,11 +1,9 @@ -use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; use crate::common::errors::Result; +use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; - -pub fn contains(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ - +pub fn contains(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let p1 = param_to_datatype(runtime, executable.params.get(0), executable.line_number)?; let p2 = param_to_datatype(runtime, executable.params.get(1), executable.line_number)?; @@ -16,5 +14,3 @@ pub fn contains(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()> returns(runtime, executable, result) } - - diff --git a/src/runtime/builtin_function/strings/length.rs b/src/runtime/builtin_function/strings/length.rs index 912cb85..b573395 100644 --- a/src/runtime/builtin_function/strings/length.rs +++ b/src/runtime/builtin_function/strings/length.rs @@ -1,19 +1,23 @@ -use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; - - -pub fn length(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ +use crate::common::errors::{ChapError, Result}; +use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; +pub fn length(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let p1 = param_to_datatype(runtime, executable.params.get(0), executable.line_number)?; let result = match p1 { - DataType::String(s) => s.len(), - DataType::List(l) => l.len(), - _ => { - return Err(ChapError::runtime_with_msg(executable.line_number, format!("{} function input param should be string or list",executable.function_name))); - } + DataType::String(s) => s.len(), + DataType::List(l) => l.len(), + _ => { + return Err(ChapError::runtime_with_msg( + executable.line_number, + format!( + "{} function input param should be string or list", + executable.function_name + ), + )); + } }; let result = DataType::Int(result.try_into().unwrap()); diff --git a/src/runtime/builtin_function/strings/mod.rs b/src/runtime/builtin_function/strings/mod.rs index 550d5c0..ccf0397 100644 --- a/src/runtime/builtin_function/strings/mod.rs +++ b/src/runtime/builtin_function/strings/mod.rs @@ -1,7 +1,5 @@ - - pub mod contact; -pub mod repeat; -pub mod length; pub mod contains; -pub mod slice; \ No newline at end of file +pub mod length; +pub mod repeat; +pub mod slice; diff --git a/src/runtime/builtin_function/strings/repeat.rs b/src/runtime/builtin_function/strings/repeat.rs index 7071c54..39cc690 100644 --- a/src/runtime/builtin_function/strings/repeat.rs +++ b/src/runtime/builtin_function/strings/repeat.rs @@ -1,26 +1,24 @@ -use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; - - -pub fn repeat(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ +use crate::common::errors::{ChapError, Result}; +use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; +pub fn repeat(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let p1 = param_to_datatype(runtime, executable.params.get(0), executable.line_number)?; let p2 = param_to_datatype(runtime, executable.params.get(1), executable.line_number)?; let p1 = p1.to_string(); let mut result = String::new(); if let DataType::Int(x) = p2 { - for _ in 0..(*x){ + for _ in 0..(*x) { result.push_str(p1.as_str()); } - }else{ - return Err( - ChapError::runtime_with_msg(executable.line_number, "repeat function second param should be int".to_string()) - ); + } else { + return Err(ChapError::runtime_with_msg( + executable.line_number, + "repeat function second param should be int".to_string(), + )); } returns(runtime, executable, DataType::String(result)) } - diff --git a/src/runtime/builtin_function/strings/slice.rs b/src/runtime/builtin_function/strings/slice.rs index 95c87ae..44b813c 100644 --- a/src/runtime/builtin_function/strings/slice.rs +++ b/src/runtime/builtin_function/strings/slice.rs @@ -1,11 +1,9 @@ -use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; - - -pub fn slice(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ +use crate::common::errors::{ChapError, Result}; +use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; +pub fn slice(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let p1 = param_to_datatype(runtime, executable.params.get(0), executable.line_number)?; let p2 = param_to_datatype(runtime, executable.params.get(1), executable.line_number)?; let p3 = param_to_datatype(runtime, executable.params.get(2), executable.line_number)?; @@ -16,13 +14,14 @@ pub fn slice(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ let from = usize::try_from(*from).unwrap(); let to = usize::try_from(*to).unwrap(); &p1[(from)..to] - }, - _=>{ - return Err( - ChapError::runtime_with_msg(executable.line_number, "slice function needs output variable".to_string()) - ) + } + _ => { + return Err(ChapError::runtime_with_msg( + executable.line_number, + "slice function needs output variable".to_string(), + )) } }; returns(runtime, executable, DataType::String(result.to_string())) -} \ No newline at end of file +} diff --git a/src/runtime/builtin_function/type_conversion/mod.rs b/src/runtime/builtin_function/type_conversion/mod.rs index 6d6c655..04eb3e8 100644 --- a/src/runtime/builtin_function/type_conversion/mod.rs +++ b/src/runtime/builtin_function/type_conversion/mod.rs @@ -1,5 +1,3 @@ - - -pub mod to_string; pub mod to_float; -pub mod to_int; \ No newline at end of file +pub mod to_int; +pub mod to_string; diff --git a/src/runtime/builtin_function/type_conversion/to_float.rs b/src/runtime/builtin_function/type_conversion/to_float.rs index a8e1622..5dc65b6 100644 --- a/src/runtime/builtin_function/type_conversion/to_float.rs +++ b/src/runtime/builtin_function/type_conversion/to_float.rs @@ -1,29 +1,27 @@ -use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; - - -pub fn to_float(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ +use crate::common::errors::{ChapError, Result}; +use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; +pub fn to_float(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let p1 = param_to_datatype(runtime, executable.params.get(0), executable.line_number)?; let result = match p1 { - DataType::String(s) => { - match s.parse(){ - Ok(x) => DataType::Float(x), - Err(_) => { - return Err( - ChapError::runtime_with_msg(executable.line_number, format!("can not parse {} to float", s)) - ); - }, + DataType::String(s) => match s.parse() { + Ok(x) => DataType::Float(x), + Err(_) => { + return Err(ChapError::runtime_with_msg( + executable.line_number, + format!("can not parse {} to float", s), + )); } }, _ => { - return Err( - ChapError::runtime_with_msg(executable.line_number, format!("can not convert {} to float", p1.type_name())) - ); + return Err(ChapError::runtime_with_msg( + executable.line_number, + format!("can not convert {} to float", p1.type_name()), + )); } }; - + returns(runtime, executable, result) } diff --git a/src/runtime/builtin_function/type_conversion/to_int.rs b/src/runtime/builtin_function/type_conversion/to_int.rs index cb97543..77e402c 100644 --- a/src/runtime/builtin_function/type_conversion/to_int.rs +++ b/src/runtime/builtin_function/type_conversion/to_int.rs @@ -1,33 +1,28 @@ -use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; - - -pub fn to_int(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ +use crate::common::errors::{ChapError, Result}; +use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; +pub fn to_int(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let p1 = param_to_datatype(runtime, executable.params.get(0), executable.line_number)?; let result = match p1 { - DataType::String(s) => { - match s.parse(){ - Ok(x) => DataType::Int(x), - Err(_) => { - return Err( - ChapError::runtime_with_msg(executable.line_number, format!("can not parse {} to int", s)) - ); - }, + DataType::String(s) => match s.parse() { + Ok(x) => DataType::Int(x), + Err(_) => { + return Err(ChapError::runtime_with_msg( + executable.line_number, + format!("can not parse {} to int", s), + )); } }, - DataType::Float(f) => { - DataType::Int(*f as i32) - }, + DataType::Float(f) => DataType::Int(*f as i32), _ => { - return Err( - ChapError::runtime_with_msg(executable.line_number, format!("can not convert {} to int", p1.type_name())) - ); + return Err(ChapError::runtime_with_msg( + executable.line_number, + format!("can not convert {} to int", p1.type_name()), + )); } }; - + returns(runtime, executable, result) } - diff --git a/src/runtime/builtin_function/type_conversion/to_string.rs b/src/runtime/builtin_function/type_conversion/to_string.rs index 43500f4..2d26be7 100644 --- a/src/runtime/builtin_function/type_conversion/to_string.rs +++ b/src/runtime/builtin_function/type_conversion/to_string.rs @@ -1,11 +1,9 @@ -use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; use crate::common::errors::Result; +use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; - -pub fn to_string(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ - +pub fn to_string(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let p1 = param_to_datatype(runtime, executable.params.get(0), executable.line_number)?; let result = p1.to_string(); diff --git a/src/runtime/builtin_function/type_of.rs b/src/runtime/builtin_function/type_of.rs index 9562d2e..021e13c 100644 --- a/src/runtime/builtin_function/type_of.rs +++ b/src/runtime/builtin_function/type_of.rs @@ -1,11 +1,9 @@ -use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; use crate::common::data_type::DataType; -use crate::{runtime::Runtime, common::executable::ExecutableLine}; use crate::common::errors::Result; +use crate::runtime::builtin_function::utils::{param_to_datatype, returns}; +use crate::{common::executable::ExecutableLine, runtime::Runtime}; - -pub fn type_of(runtime: &mut Runtime, executable: &ExecutableLine)-> Result<()>{ - +pub fn type_of(runtime: &mut Runtime, executable: &ExecutableLine) -> Result<()> { let p1 = param_to_datatype(runtime, executable.params.get(0), executable.line_number)?; let result = p1.type_name(); returns(runtime, executable, DataType::String(result)) diff --git a/src/runtime/builtin_function/utils.rs b/src/runtime/builtin_function/utils.rs index dbddeae..87f0820 100644 --- a/src/runtime/builtin_function/utils.rs +++ b/src/runtime/builtin_function/utils.rs @@ -1,63 +1,90 @@ -use crate::{runtime::Runtime, common::{data_type::DataType, errors::ChapError, param::Param, executable::ExecutableLine}}; use crate::common::errors::Result; +use crate::{ + common::{data_type::DataType, errors::ChapError, executable::ExecutableLine, param::Param}, + runtime::Runtime, +}; #[allow(dead_code)] -pub fn get_var(runtime: &Runtime, name: &str, line_number: u32) -> Result{ - - match runtime.variables.get(name){ +pub fn get_var(runtime: &Runtime, name: &str, line_number: u32) -> Result { + match runtime.variables.get(name) { Some(x) => Ok(x.clone()), - None => Err( - ChapError::runtime_with_msg(line_number, format!("variable {} is not defind",name)) - ), + None => Err(ChapError::runtime_with_msg( + line_number, + format!("variable {} is not defind", name), + )), } } -pub fn param_to_datatype<'a>(runtime: &'a Runtime, param: Option<&'a Param>, line_number: u32) -> Result<&'a DataType>{ - +pub fn param_to_datatype<'a>( + runtime: &'a Runtime, + param: Option<&'a Param>, + line_number: u32, +) -> Result<&'a DataType> { let param = match param { Some(x) => x, - None => return Err(ChapError::static_analyzer_with_msg(line_number, "function needs more params".to_string())), + None => { + return Err(ChapError::static_analyzer_with_msg( + line_number, + "function needs more params".to_string(), + )) + } }; match param { - Param::Tag(_) => Err(ChapError::runtime_with_msg(line_number, "can not convert a tag to datatype".to_string())), + Param::Tag(_) => Err(ChapError::runtime_with_msg( + line_number, + "can not convert a tag to datatype".to_string(), + )), Param::Value(value) => Ok(value), - Param::Variable(name) => match runtime.variables.get(name){ + Param::Variable(name) => match runtime.variables.get(name) { Some(x) => Ok(x), - None => Err( - ChapError::runtime_with_msg(line_number, format!("variable {} is not defind", name)) - ), + None => Err(ChapError::runtime_with_msg( + line_number, + format!("variable {} is not defind", name), + )), }, } - } -pub fn param_to_datatype_mut<'a>(runtime: &'a mut Runtime, param: Option<&'a Param>, line_number: u32) -> Result<&'a mut DataType>{ - +pub fn param_to_datatype_mut<'a>( + runtime: &'a mut Runtime, + param: Option<&'a Param>, + line_number: u32, +) -> Result<&'a mut DataType> { let param = match param { Some(x) => x, - None => return Err(ChapError::static_analyzer_with_msg(line_number, "function needs more params".to_string())), + None => { + return Err(ChapError::static_analyzer_with_msg( + line_number, + "function needs more params".to_string(), + )) + } }; match param { - Param::Tag(_) => Err(ChapError::runtime_with_msg(line_number, "can not convert a tag to datatype".to_string())), - Param::Value(_) => Err(ChapError::runtime_with_msg(line_number, "variable expected.".to_string())), - Param::Variable(name) => match runtime.variables.get_mut(name){ + Param::Tag(_) => Err(ChapError::runtime_with_msg( + line_number, + "can not convert a tag to datatype".to_string(), + )), + Param::Value(_) => Err(ChapError::runtime_with_msg( + line_number, + "variable expected.".to_string(), + )), + Param::Variable(name) => match runtime.variables.get_mut(name) { Some(x) => Ok(x), - None => Err( - ChapError::runtime_with_msg(line_number, format!("variable {} is not defind", name)) - ), + None => Err(ChapError::runtime_with_msg( + line_number, + format!("variable {} is not defind", name), + )), }, } - } -pub fn returns(runtime: &mut Runtime, executable: &ExecutableLine, result: DataType) -> Result<()>{ - - if let Some(var_name) = &executable.output_var{ +pub fn returns(runtime: &mut Runtime, executable: &ExecutableLine, result: DataType) -> Result<()> { + if let Some(var_name) = &executable.output_var { runtime.variables.insert(var_name.clone(), result); - }else{ + } else { runtime.std_out(result.to_string().as_str()); } Ok(()) -} \ No newline at end of file +} diff --git a/src/runtime/mod.rs b/src/runtime/mod.rs index c46794a..acb73ad 100644 --- a/src/runtime/mod.rs +++ b/src/runtime/mod.rs @@ -1,23 +1,20 @@ - pub mod builtin_function; -use std::collections::HashMap; +use crate::common::errors::{ChapError, Result}; use crate::common::{data_type::DataType, executable::ExecutableLine}; -use crate::common::errors::{Result, ChapError}; - +use std::collections::HashMap; -pub struct Runtime{ - pub executables: Vec, - pub variables: HashMap, // - pub tags: HashMap, // +pub struct Runtime { + pub executables: Vec, + pub variables: HashMap, // + pub tags: HashMap, // pub current_line: usize, pub std_out: fn(&str), pub std_in: fn() -> String, } -impl Runtime{ - - pub fn new(std_out: fn(&str), std_in: fn() -> String) -> Self{ +impl Runtime { + pub fn new(std_out: fn(&str), std_in: fn() -> String) -> Self { Self { executables: vec![], variables: HashMap::new(), @@ -28,92 +25,88 @@ impl Runtime{ } } - pub fn on_new_line(&mut self, mut line: ExecutableLine) -> Result<()>{ + pub fn on_new_line(&mut self, mut line: ExecutableLine) -> Result<()> { line.bind_closure()?; self.executables.push(line); Ok(()) } - pub fn execution_cycle(&mut self) -> Result<()>{ - + pub fn execution_cycle(&mut self) -> Result<()> { match self.executables.get(self.current_line) { Some(l) => { let l = l.clone(); self.current_line += 1; (l.closure)(self, &l)?; // execute(self, &l)?; - }, + } None => { return Err(ChapError::no_more_line()); - }, + } } Ok(()) } - pub fn std_out(&self,msg:&str){ + pub fn std_out(&self, msg: &str) { (self.std_out)(msg); } - pub fn std_in(&self) -> String{ - (self.std_in)() + pub fn std_in(&self) -> String { + (self.std_in)() } } - #[cfg(test)] -mod tests{ +mod tests { - use crate::common::{executable::ExecutableLine, param::Param, data_type::DataType}; + use crate::common::{data_type::DataType, executable::ExecutableLine, param::Param}; use super::Runtime; #[test] - fn simple_executaion_test(){ - - let mut rt = Runtime::new(|_|{},||{"".to_string()}); + fn simple_executaion_test() { + let mut rt = Runtime::new(|_| {}, || "".to_string()); assert_eq!(rt.current_line, 0); rt.on_new_line(ExecutableLine::new( 1, "assign".to_string(), vec![Param::Value(DataType::Int(2))], - Some("my_variable".to_string()) - )).unwrap(); + Some("my_variable".to_string()), + )) + .unwrap(); assert_eq!(rt.current_line, 0); rt.execution_cycle().unwrap(); assert_eq!(rt.current_line, 1); - assert_eq!( - rt.variables.get("my_variable"), - Some(&DataType::Int(2)) - ) + assert_eq!(rt.variables.get("my_variable"), Some(&DataType::Int(2))) } #[test] - fn runtime_std_test(){ - - let mut rt = Runtime::new(|x|{ - assert_eq!(x, "the text"); - },||{ - "the text".to_string() - }); + fn runtime_std_test() { + let mut rt = Runtime::new( + |x| { + assert_eq!(x, "the text"); + }, + || "the text".to_string(), + ); - rt.on_new_line(ExecutableLine::new( + rt.on_new_line(ExecutableLine::new( 1, "input".to_string(), vec![], - Some("name".to_string()) - )).unwrap(); + Some("name".to_string()), + )) + .unwrap(); rt.execution_cycle().unwrap(); - rt.on_new_line(ExecutableLine::new( + rt.on_new_line(ExecutableLine::new( 2, "print".to_string(), vec![Param::Variable("name".to_string())], - None - )).unwrap(); + None, + )) + .unwrap(); rt.execution_cycle().unwrap(); - } -} \ No newline at end of file +}