From 8897ccfb0a9af4aaf7fff38e70cb9087656562a9 Mon Sep 17 00:00:00 2001 From: MeexReay Date: Mon, 29 Jul 2024 00:57:34 +0300 Subject: [PATCH] fix problem with Pohuy trait --- src/sustlang/command/command.rs | 1098 ++++++++++++++++--------- src/sustlang/mod.rs | 2 + src/sustlang/other.rs | 5 + src/sustlang/script/function.rs | 30 +- src/sustlang/script/running_script.rs | 3 +- 5 files changed, 726 insertions(+), 412 deletions(-) create mode 100644 src/sustlang/other.rs diff --git a/src/sustlang/command/command.rs b/src/sustlang/command/command.rs index 515fa2c..87dc48d 100644 --- a/src/sustlang/command/command.rs +++ b/src/sustlang/command/command.rs @@ -27,46 +27,57 @@ impl Command { script: &mut RunningScript, global: bool, locals: &mut HashMap, - globals: &mut HashMap, temp_vars: &mut Vec, - ) -> Result<(), ScriptError> { + ) -> Result<(), (ScriptError, Command)> { match self.command_type { CommandType::InitVar => { let type_var = self.args[0].clone(); - let type_var = VarType::from_name(&type_var)?; + let type_var = VarType::from_name(&type_var).map_err(|f| (f, self.clone()))?; let name_var = self.args[1].clone(); - script.set_var( - name_var, - Variable::empty_var(type_var)?, - global, - true, - locals, - )?; + script + .set_var( + name_var, + Variable::empty_var(type_var).map_err(|f| (f, self.clone()))?, + global, + true, + locals, + ) + .map_err(|f| (f, self.clone()))?; } CommandType::SetVar => { let name_var = self.args[0].clone(); let value_var = self.args[1..].join(" "); let type_var = script - .get_var(name_var.clone(), &mut locals.clone())? + .get_var(name_var.clone(), &mut locals.clone()) + .map_err(|f| (f, self.clone()))? .get_type(); - let var = Variable::parse_var(type_var, value_var)?; + let var = + Variable::parse_var(type_var, value_var).map_err(|f| (f, self.clone()))?; - script.set_var(name_var, var, global, false, locals)?; + script + .set_var(name_var, var, global, false, locals) + .map_err(|f| (f, self.clone()))?; } CommandType::TempVar => { let type_var = self.args[0].clone(); let name_var = self.args[1].clone(); let value_var = self.args[2..].join(" "); - script.set_var( - name_var.clone(), - Variable::parse_var(VarType::from_name(&type_var)?, value_var)?, - global, - true, - locals, - )?; + script + .set_var( + name_var.clone(), + Variable::parse_var( + VarType::from_name(&type_var).map_err(|f| (f, self.clone()))?, + value_var, + ) + .map_err(|f| (f, self.clone()))?, + global, + true, + locals, + ) + .map_err(|f| (f, self.clone()))?; temp_vars.push(name_var); } @@ -74,23 +85,35 @@ impl Command { let source_var = self.args[0].clone(); let target_var = self.args[1].clone(); - let var = script.get_var(source_var.clone(), locals)?; + let var = script + .get_var(source_var.clone(), locals) + .map_err(|f| (f, self.clone()))?; - script.set_var(target_var, var, global, false, locals)?; - script.drop_var(source_var, locals)?; + script + .set_var(target_var, var, global, false, locals) + .map_err(|f| (f, self.clone()))?; + script + .drop_var(source_var, locals) + .map_err(|f| (f, self.clone()))?; } CommandType::CopyVar => { let source_var = self.args[0].clone(); let target_var = self.args[1].clone(); - let var = script.get_var(source_var.clone(), locals)?; + let var = script + .get_var(source_var.clone(), locals) + .map_err(|f| (f, self.clone()))?; - script.set_var(target_var, var, global, false, locals)?; + script + .set_var(target_var, var, global, false, locals) + .map_err(|f| (f, self.clone()))?; } CommandType::DropVar => { let name_var = self.args[0].clone(); - script.drop_var(name_var, locals)?; + script + .drop_var(name_var, locals) + .map_err(|f| (f, self.clone()))?; } CommandType::HasVar => { let name_var = self.args[0].clone(); @@ -98,53 +121,69 @@ impl Command { let result = script.get_var(name_var, locals).is_ok(); - script.set_var( - result_var, - Variable::from_bool(Some(result)), - global, - false, - locals, - )?; + script + .set_var( + result_var, + Variable::from_bool(Some(result)), + global, + false, + locals, + ) + .map_err(|f| (f, self.clone()))?; } CommandType::AddStr => { let var_name = self.args[0].clone(); let other_var = self.args[1].clone(); - let other_var = script.get_var(other_var.clone(), locals)?; + let other_var = script + .get_var(other_var.clone(), locals) + .map_err(|f| (f, self.clone()))?; let other_var: String = if let Variable::List(VarType::Char, Some(list)) = other_var { let mut bytes = Vec::new(); for ele in list { - bytes.push(ele.as_char()?); + bytes.push(ele.as_char().map_err(|f| (f, self.clone()))?); } - String::from_utf8(bytes).or(Err(ScriptError::StringUTF8Error))? + String::from_utf8(bytes) + .or(Err(ScriptError::StringUTF8Error)) + .map_err(|f| (f, self.clone()))? } else if let Variable::String(_, Some(string)) = other_var { string } else if let Variable::Char(_, Some(value)) = other_var { - String::from_utf8(vec![value]).or(Err(ScriptError::StringUTF8Error))? + String::from_utf8(vec![value]) + .or(Err(ScriptError::StringUTF8Error)) + .map_err(|f| (f, self.clone()))? } else { - return Err(ScriptError::TypeMismatchError); + return Err((ScriptError::TypeMismatchError, self.clone())); }; - let var = script.get_var(var_name.clone(), locals)?.as_str()?; + let var = script + .get_var(var_name.clone(), locals) + .map_err(|f| (f, self.clone()))? + .as_str() + .map_err(|f| (f, self.clone()))?; - script.set_var( - var_name, - Variable::from_str(Some(var + &other_var)), - global, - false, - locals, - )?; + script + .set_var( + var_name.clone(), + Variable::from_str(Some(var.clone() + &other_var)), + global, + false, + locals, + ) + .map_err(|f| (f, self.clone()))?; } CommandType::Write => { let name_var = self.args[0].clone(); let stream_var = self.args[1].clone(); - let text = script.get_var(name_var.clone(), locals)?; + let text = script + .get_var(name_var.clone(), locals) + .map_err(|f| (f, self.clone()))?; let text: Vec = if let Variable::List(VarType::Char, Some(list)) = text { let mut bytes = Vec::new(); for ele in list { - bytes.push(ele.as_char()?); + bytes.push(ele.as_char().map_err(|f| (f, self.clone()))?); } bytes } else if let Variable::String(_, Some(string)) = text { @@ -152,12 +191,14 @@ impl Command { } else if let Variable::Char(_, Some(value)) = text { vec![value] } else { - return Err(ScriptError::TypeMismatchError); + return Err((ScriptError::TypeMismatchError, self.clone())); }; let stream = script - .get_var(stream_var.clone(), locals)? - .as_out_stream()?; + .get_var(stream_var.clone(), locals) + .map_err(|f| (f, self.clone()))? + .as_out_stream() + .map_err(|f| (f, self.clone()))?; stream.lock().unwrap().write_all(&text).unwrap(); } CommandType::UseFunc => { @@ -165,61 +206,81 @@ impl Command { let result_name = self.args[1].clone(); let args_names = self.args[2..].to_vec(); - let func = script.get_function(func_name)?; + let func = script + .get_function(func_name) + .map_err(|f| (f, self.clone()))?; let mut args = Vec::new(); for name in args_names { - args.push(script.get_var(name, locals)?); + args.push( + script + .get_var(name, locals) + .map_err(|f| (f, self.clone()))?, + ); } - func.execute(script, result_name, args, globals, global) - .map_err(|f| f.0)?; + func.execute(script, result_name, args, false)?; } CommandType::Return => { return Ok(()); } CommandType::For => { let func_name = self.args[0].clone(); - let start_index = script.get_var(self.args[1].clone(), locals)?.as_int()?; - let end_index = script.get_var(self.args[2].clone(), locals)?.as_int()?; + let start_index = script + .get_var(self.args[1].clone(), locals) + .map_err(|f| (f, self.clone()))? + .as_int() + .map_err(|f| (f, self.clone()))?; + let end_index = script + .get_var(self.args[2].clone(), locals) + .map_err(|f| (f, self.clone()))? + .as_int() + .map_err(|f| (f, self.clone()))?; - let func = script.get_function(func_name)?; + let func = script + .get_function(func_name) + .map_err(|f| (f, self.clone()))?; for index in start_index..=end_index { func.execute( script, "null".to_string(), vec![Variable::from_int(Some(index))], - globals, - global, - ) - .map_err(|f| f.0)?; + false, + )?; } } CommandType::ToString => { let source_var = self.args[0].clone(); let result_var = self.args[1].clone(); - let source_var = script.get_var(source_var, locals)?; + let source_var = script + .get_var(source_var, locals) + .map_err(|f| (f, self.clone()))?; - let result = source_var.to_string()?; + let result = source_var.to_string().map_err(|f| (f, self.clone()))?; - script.set_var( - result_var, - Variable::from_str(Some(result)), - global, - false, - locals, - )?; + script + .set_var( + result_var, + Variable::from_str(Some(result)), + global, + false, + locals, + ) + .map_err(|f| (f, self.clone()))?; } CommandType::ToChars => { let source_var = self.args[0].clone(); let result_var = self.args[1].clone(); - let source_var = script.get_var(source_var, locals)?; + let source_var = script + .get_var(source_var, locals) + .map_err(|f| (f, self.clone()))?; let result = source_var - .as_str()? + .as_str() + .map_err(|f| (f, self.clone()))? .as_bytes() .iter() .map(|f| Variable::from_char(Some(*f))) @@ -227,41 +288,57 @@ impl Command { let result = Variable::from_list(Some(result), VarType::List(Box::new(VarType::Char))); - script.set_var(result_var, result, global, false, locals)?; + script + .set_var(result_var, result, global, false, locals) + .map_err(|f| (f, self.clone()))?; } CommandType::ToInteger => { let source_var = self.args[0].clone(); let result_var = self.args[1].clone(); - let source_var = script.get_var(source_var, locals)?; + let source_var = script + .get_var(source_var, locals) + .map_err(|f| (f, self.clone()))?; let result = source_var - .as_str()? + .as_str() + .map_err(|f| (f, self.clone()))? .parse::() - .or(Err(ScriptError::ParseVarError))?; + .or(Err(ScriptError::ParseVarError)) + .map_err(|f| (f, self.clone()))?; let result = Variable::from_int(Some(result)); - script.set_var(result_var, result, global, false, locals)?; + script + .set_var(result_var, result, global, false, locals) + .map_err(|f| (f, self.clone()))?; } CommandType::ToFloat => { let source_var = self.args[0].clone(); let result_var = self.args[1].clone(); - let source_var = script.get_var(source_var, locals)?; + let source_var = script + .get_var(source_var, locals) + .map_err(|f| (f, self.clone()))?; let result = source_var - .as_str()? + .as_str() + .map_err(|f| (f, self.clone()))? .parse::() - .or(Err(ScriptError::ParseVarError))?; + .or(Err(ScriptError::ParseVarError)) + .map_err(|f| (f, self.clone()))?; let result = Variable::from_float(Some(result)); - script.set_var(result_var, result, global, false, locals)?; + script + .set_var(result_var, result, global, false, locals) + .map_err(|f| (f, self.clone()))?; } CommandType::ToBool => { let source_var = self.args[0].clone(); let result_var = self.args[1].clone(); - let source_var = script.get_var(source_var, locals)?; + let source_var = script + .get_var(source_var, locals) + .map_err(|f| (f, self.clone()))?; let result = if let Variable::List(_, Some(value)) = source_var { !value.is_empty() @@ -289,19 +366,23 @@ impl Command { false }; - script.set_var( - result_var, - Variable::from_bool(Some(result)), - global, - false, - locals, - )?; + script + .set_var( + result_var, + Variable::from_bool(Some(result)), + global, + false, + locals, + ) + .map_err(|f| (f, self.clone()))?; } CommandType::ToChar => { let source_var = self.args[0].clone(); let result_var = self.args[1].clone(); - let source_var = script.get_var(source_var, locals)?; + let source_var = script + .get_var(source_var, locals) + .map_err(|f| (f, self.clone()))?; let result = if let Variable::String(_, Some(value)) = source_var { value.as_bytes()[0] @@ -310,184 +391,232 @@ impl Command { } else if let Variable::Integer(_, Some(value)) = source_var { value as u8 } else { - return Err(ScriptError::TypeMismatchError); + return Err((ScriptError::TypeMismatchError, self.clone())); }; - script.set_var( - result_var, - Variable::from_char(Some(result)), - global, - false, - locals, - )?; + script + .set_var( + result_var, + Variable::from_char(Some(result)), + global, + false, + locals, + ) + .map_err(|f| (f, self.clone()))?; } CommandType::GetSymbol => { let str_var = self.args[0].clone(); let index_var = self.args[1].clone(); let result_var = self.args[2].clone(); - let str_var = script.get_var(str_var, locals)?; - let index_var = script.get_var(index_var, locals)?; + let str_var = script + .get_var(str_var, locals) + .map_err(|f| (f, self.clone()))?; + let index_var = script + .get_var(index_var, locals) + .map_err(|f| (f, self.clone()))?; - let index = index_var.as_int()?; + let index = index_var.as_int().map_err(|f| (f, self.clone()))?; let result = if let Variable::String(_, Some(value)) = str_var { value.as_bytes()[index as usize] } else { - return Err(ScriptError::TypeMismatchError); + return Err((ScriptError::TypeMismatchError, self.clone())); }; - script.set_var( - result_var, - Variable::from_char(Some(result)), - global, - false, - locals, - )?; + script + .set_var( + result_var, + Variable::from_char(Some(result)), + global, + false, + locals, + ) + .map_err(|f| (f, self.clone()))?; } CommandType::GetItem => { let list_var = self.args[0].clone(); let index_var = self.args[1].clone(); let result_var = self.args[2].clone(); - let list_var = script.get_var(list_var, locals)?; - let index_var = script.get_var(index_var, locals)?; + let list_var = script + .get_var(list_var, locals) + .map_err(|f| (f, self.clone()))?; + let index_var = script + .get_var(index_var, locals) + .map_err(|f| (f, self.clone()))?; - let index = index_var.as_int()?; + let index = index_var.as_int().map_err(|f| (f, self.clone()))?; let result = if let Variable::List(_, Some(value)) = list_var { value[index as usize].clone() } else { - return Err(ScriptError::TypeMismatchError); + return Err((ScriptError::TypeMismatchError, self.clone())); }; - script.set_var(result_var, result, global, false, locals)?; + script + .set_var(result_var, result, global, false, locals) + .map_err(|f| (f, self.clone()))?; } CommandType::GetValue => { let map_var = self.args[0].clone(); let key_var = self.args[1].clone(); let result_var = self.args[2].clone(); - let map_var = script.get_var(map_var, locals)?; - let key_var = script.get_var(key_var, locals)?; + let map_var = script + .get_var(map_var, locals) + .map_err(|f| (f, self.clone()))?; + let key_var = script + .get_var(key_var, locals) + .map_err(|f| (f, self.clone()))?; let result = if let Variable::Map(_, Some(value)) = map_var { value[&key_var].clone() } else { - return Err(ScriptError::TypeMismatchError); + return Err((ScriptError::TypeMismatchError, self.clone())); }; - script.set_var(result_var, result, global, false, locals)?; + script + .set_var(result_var, result, global, false, locals) + .map_err(|f| (f, self.clone()))?; } CommandType::ListSize => { let list_var = self.args[0].clone(); let result_var = self.args[1].clone(); - let list_var = script.get_var(list_var, locals)?; - let list_size = list_var.as_list()?.len(); + let list_var = script + .get_var(list_var, locals) + .map_err(|f| (f, self.clone()))?; + let list_size = list_var.as_list().map_err(|f| (f, self.clone()))?.len(); - script.set_var( - result_var, - Variable::from_int(Some(list_size as isize)), - global, - false, - locals, - )?; + script + .set_var( + result_var, + Variable::from_int(Some(list_size as isize)), + global, + false, + locals, + ) + .map_err(|f| (f, self.clone()))?; } CommandType::MapSize => { let map_var = self.args[0].clone(); let result_var = self.args[1].clone(); - let map_var = script.get_var(map_var, locals)?; - let map_size = map_var.as_list()?.len(); + let map_var = script + .get_var(map_var, locals) + .map_err(|f| (f, self.clone()))?; + let map_size = map_var.as_list().map_err(|f| (f, self.clone()))?.len(); - script.set_var( - result_var, - Variable::from_int(Some(map_size as isize)), - global, - false, - locals, - )?; + script + .set_var( + result_var, + Variable::from_int(Some(map_size as isize)), + global, + false, + locals, + ) + .map_err(|f| (f, self.clone()))?; } CommandType::StringSize => { let string_var = self.args[0].clone(); let result_var = self.args[1].clone(); - let string_var = script.get_var(string_var, locals)?; - let string_size = string_var.as_list()?.len(); + let string_var = script + .get_var(string_var, locals) + .map_err(|f| (f, self.clone()))?; + let string_size = string_var.as_list().map_err(|f| (f, self.clone()))?.len(); - script.set_var( - result_var, - Variable::from_int(Some(string_size as isize)), - global, - false, - locals, - )?; + script + .set_var( + result_var, + Variable::from_int(Some(string_size as isize)), + global, + false, + locals, + ) + .map_err(|f| (f, self.clone()))?; } CommandType::ForMap => { let func_name = self.args[0].clone(); let map_var = self.args[1].clone(); - let map_var = script.get_var(map_var, locals)?; - let map_var = map_var.as_map()?; + let map_var = script + .get_var(map_var, locals) + .map_err(|f| (f, self.clone()))?; + let map_var = map_var.as_map().map_err(|f| (f, self.clone()))?; - let func = script.get_function(func_name)?; + let func = script + .get_function(func_name) + .map_err(|f| (f, self.clone()))?; for (k, v) in map_var { - func.execute(script, "null".to_string(), vec![k, v], globals, global) - .map_err(|f| f.0)?; + func.execute(script, "null".to_string(), vec![k, v], false)?; } } CommandType::ForList => { let func_name = self.args[0].clone(); let list_var = self.args[1].clone(); - let list_var = script.get_var(list_var, locals)?; - let list_var = list_var.as_list()?; + let list_var = script + .get_var(list_var, locals) + .map_err(|f| (f, self.clone()))?; + let list_var = list_var.as_list().map_err(|f| (f, self.clone()))?; - let func = script.get_function(func_name)?; + let func = script + .get_function(func_name) + .map_err(|f| (f, self.clone()))?; for i in list_var { - func.execute(script, "null".to_string(), vec![i], globals, global) - .map_err(|f| f.0)?; + func.execute(script, "null".to_string(), vec![i], false)?; } } CommandType::ForString => { let func_name = self.args[0].clone(); let string_var = self.args[1].clone(); - let string_var = script.get_var(string_var, locals)?; - let string_var = string_var.as_str()?; + let string_var = script + .get_var(string_var, locals) + .map_err(|f| (f, self.clone()))?; + let string_var = string_var.as_str().map_err(|f| (f, self.clone()))?; - let func = script.get_function(func_name)?; + let func = script + .get_function(func_name) + .map_err(|f| (f, self.clone()))?; for c in string_var.as_bytes() { func.execute( script, "null".to_string(), vec![Variable::from_char(Some(*c))], - globals, - global, - ) - .map_err(|f| f.0)?; + false, + )?; } } CommandType::While => { let func_name = self.args[0].clone(); - let func = script.get_function(func_name)?; + let func = script + .get_function(func_name) + .map_err(|f| (f, self.clone()))?; - script.set_var( - "while".to_string(), - Variable::from_bool(Some(true)), - global, - false, - locals, - )?; + script + .set_var( + "while".to_string(), + Variable::from_bool(Some(true)), + global, + false, + locals, + ) + .map_err(|f| (f, self.clone()))?; - while script.get_var("while".to_string(), locals)?.as_bool()? { - func.execute(script, "while".to_string(), vec![], globals, global) - .map_err(|f| f.0)?; + while script + .get_var("while".to_string(), locals) + .map_err(|f| (f, self.clone()))? + .as_bool() + .map_err(|f| (f, self.clone()))? + { + func.execute(script, "while".to_string(), vec![], false)?; } } CommandType::Equals => { @@ -495,24 +624,30 @@ impl Command { let other_var = self.args[1].clone(); let result_var = self.args[2].clone(); - let var = script.get_var(var, locals)?; - let other_var = script.get_var(other_var, locals)?; + let var = script.get_var(var, locals).map_err(|f| (f, self.clone()))?; + let other_var = script + .get_var(other_var, locals) + .map_err(|f| (f, self.clone()))?; - script.set_var( - result_var, - Variable::from_bool(Some(var == other_var)), - global, - false, - locals, - )?; + script + .set_var( + result_var, + Variable::from_bool(Some(var == other_var)), + global, + false, + locals, + ) + .map_err(|f| (f, self.clone()))?; } CommandType::More => { let var = self.args[0].clone(); let other_var = self.args[1].clone(); let result_var = self.args[2].clone(); - let var = script.get_var(var, locals)?; - let other_var = script.get_var(other_var, locals)?; + let var = script.get_var(var, locals).map_err(|f| (f, self.clone()))?; + let other_var = script + .get_var(other_var, locals) + .map_err(|f| (f, self.clone()))?; let result = if let Variable::Float(_, Some(v1)) = var { if let Variable::Float(_, Some(v2)) = other_var { @@ -522,7 +657,7 @@ impl Command { } else if let Variable::Char(_, Some(v2)) = other_var { v1 > v2 as f64 } else { - return Err(ScriptError::TypeMismatchError); + return Err((ScriptError::TypeMismatchError, self.clone())); } } else if let Variable::Integer(_, Some(v1)) = var { if let Variable::Float(_, Some(v2)) = other_var { @@ -532,7 +667,7 @@ impl Command { } else if let Variable::Char(_, Some(v2)) = other_var { v1 > v2 as isize } else { - return Err(ScriptError::TypeMismatchError); + return Err((ScriptError::TypeMismatchError, self.clone())); } } else if let Variable::Char(_, Some(v1)) = var { if let Variable::Float(_, Some(v2)) = other_var { @@ -542,27 +677,31 @@ impl Command { } else if let Variable::Char(_, Some(v2)) = other_var { v1 > v2 } else { - return Err(ScriptError::TypeMismatchError); + return Err((ScriptError::TypeMismatchError, self.clone())); } } else { - return Err(ScriptError::TypeMismatchError); + return Err((ScriptError::TypeMismatchError, self.clone())); }; - script.set_var( - result_var, - Variable::from_bool(Some(result)), - global, - false, - locals, - )?; + script + .set_var( + result_var, + Variable::from_bool(Some(result)), + global, + false, + locals, + ) + .map_err(|f| (f, self.clone()))?; } CommandType::Less => { let var = self.args[0].clone(); let other_var = self.args[1].clone(); let result_var = self.args[2].clone(); - let var = script.get_var(var, locals)?; - let other_var = script.get_var(other_var, locals)?; + let var = script.get_var(var, locals).map_err(|f| (f, self.clone()))?; + let other_var = script + .get_var(other_var, locals) + .map_err(|f| (f, self.clone()))?; let result = if let Variable::Float(_, Some(v1)) = var { if let Variable::Float(_, Some(v2)) = other_var { @@ -572,7 +711,7 @@ impl Command { } else if let Variable::Char(_, Some(v2)) = other_var { v1 < v2 as f64 } else { - return Err(ScriptError::TypeMismatchError); + return Err((ScriptError::TypeMismatchError, self.clone())); } } else if let Variable::Integer(_, Some(v1)) = var { if let Variable::Float(_, Some(v2)) = other_var { @@ -582,7 +721,7 @@ impl Command { } else if let Variable::Char(_, Some(v2)) = other_var { v1 < v2 as isize } else { - return Err(ScriptError::TypeMismatchError); + return Err((ScriptError::TypeMismatchError, self.clone())); } } else if let Variable::Char(_, Some(v1)) = var { if let Variable::Float(_, Some(v2)) = other_var { @@ -592,77 +731,110 @@ impl Command { } else if let Variable::Char(_, Some(v2)) = other_var { v1 < v2 } else { - return Err(ScriptError::TypeMismatchError); + return Err((ScriptError::TypeMismatchError, self.clone())); } } else { - return Err(ScriptError::TypeMismatchError); + return Err((ScriptError::TypeMismatchError, self.clone())); }; - script.set_var( - result_var, - Variable::from_bool(Some(result)), - global, - false, - locals, - )?; + script + .set_var( + result_var, + Variable::from_bool(Some(result)), + global, + false, + locals, + ) + .map_err(|f| (f, self.clone()))?; } CommandType::And => { let var = self.args[0].clone(); let other_var = self.args[1].clone(); let result_var = self.args[2].clone(); - let var = script.get_var(var, locals)?.as_bool()?; - let other_var = script.get_var(other_var, locals)?.as_bool()?; + let var = script + .get_var(var, locals) + .map_err(|f| (f, self.clone()))? + .as_bool() + .map_err(|f| (f, self.clone()))?; + let other_var = script + .get_var(other_var, locals) + .map_err(|f| (f, self.clone()))? + .as_bool() + .map_err(|f| (f, self.clone()))?; - script.set_var( - result_var, - Variable::from_bool(Some(var && other_var)), - global, - false, - locals, - )?; + script + .set_var( + result_var, + Variable::from_bool(Some(var && other_var)), + global, + false, + locals, + ) + .map_err(|f| (f, self.clone()))?; } CommandType::Or => { let var = self.args[0].clone(); let other_var = self.args[1].clone(); let result_var = self.args[2].clone(); - let var = script.get_var(var, locals)?.as_bool()?; - let other_var = script.get_var(other_var, locals)?.as_bool()?; + let var = script + .get_var(var, locals) + .map_err(|f| (f, self.clone()))? + .as_bool() + .map_err(|f| (f, self.clone()))?; + let other_var = script + .get_var(other_var, locals) + .map_err(|f| (f, self.clone()))? + .as_bool() + .map_err(|f| (f, self.clone()))?; - script.set_var( - result_var, - Variable::from_bool(Some(var || other_var)), - global, - false, - locals, - )?; + script + .set_var( + result_var, + Variable::from_bool(Some(var || other_var)), + global, + false, + locals, + ) + .map_err(|f| (f, self.clone()))?; } CommandType::Not => { let var = self.args[0].clone(); let result_var = self.args[1].clone(); - let var = script.get_var(var, locals)?.as_bool()?; + let var = script + .get_var(var, locals) + .map_err(|f| (f, self.clone()))? + .as_bool() + .map_err(|f| (f, self.clone()))?; - script.set_var( - result_var, - Variable::from_bool(Some(!var)), - global, - false, - locals, - )?; + script + .set_var( + result_var, + Variable::from_bool(Some(!var)), + global, + false, + locals, + ) + .map_err(|f| (f, self.clone()))?; } CommandType::If => { let bool_var = self.args[0].clone(); let func_name = self.args[1].clone(); - let func = script.get_function(func_name)?; + let func = script + .get_function(func_name) + .map_err(|f| (f, self.clone()))?; - let bool_var = script.get_var(bool_var, locals)?.as_bool()?; + let bool_var = script + .get_var(bool_var, locals) + .map_err(|f| (f, self.clone()))? + .as_bool() + .map_err(|f| (f, self.clone()))?; if bool_var { - func.execute(script, "null".to_string(), vec![], globals, global) - .map_err(|f| f.0)?; + func.execute(script, "null".to_string(), vec![], false)?; } } CommandType::HasStr => { @@ -670,32 +842,50 @@ impl Command { let substring = self.args[1].clone(); let result_var = self.args[2].clone(); - let string_var = script.get_var(string_var, locals)?.as_str()?; - let substring = script.get_var(substring, locals)?.as_str()?; + let string_var = script + .get_var(string_var, locals) + .map_err(|f| (f, self.clone()))? + .as_str() + .map_err(|f| (f, self.clone()))?; + let substring = script + .get_var(substring, locals) + .map_err(|f| (f, self.clone()))? + .as_str() + .map_err(|f| (f, self.clone()))?; - script.set_var( - result_var, - Variable::from_bool(Some(string_var.contains(&substring))), - global, - false, - locals, - )?; + script + .set_var( + result_var, + Variable::from_bool(Some(string_var.contains(&substring))), + global, + false, + locals, + ) + .map_err(|f| (f, self.clone()))?; } CommandType::HasItem => { let list_var = self.args[0].clone(); let item_var = self.args[1].clone(); let result_var = self.args[2].clone(); - let list_var = script.get_var(list_var, locals)?.as_list()?; - let item_var = script.get_var(item_var, locals)?; + let list_var = script + .get_var(list_var, locals) + .map_err(|f| (f, self.clone()))? + .as_list() + .map_err(|f| (f, self.clone()))?; + let item_var = script + .get_var(item_var, locals) + .map_err(|f| (f, self.clone()))?; - script.set_var( - result_var, - Variable::from_bool(Some(list_var.contains(&item_var))), - global, - false, - locals, - )?; + script + .set_var( + result_var, + Variable::from_bool(Some(list_var.contains(&item_var))), + global, + false, + locals, + ) + .map_err(|f| (f, self.clone()))?; } CommandType::HasEntry => { let map_var = self.args[0].clone(); @@ -703,9 +893,17 @@ impl Command { let value_var = self.args[2].clone(); let result_var = self.args[3].clone(); - let map_var = script.get_var(map_var, locals)?.as_map()?; - let key_var = script.get_var(key_var, locals)?; - let value_var = script.get_var(value_var, locals)?; + let map_var = script + .get_var(map_var, locals) + .map_err(|f| (f, self.clone()))? + .as_map() + .map_err(|f| (f, self.clone()))?; + let key_var = script + .get_var(key_var, locals) + .map_err(|f| (f, self.clone()))?; + let value_var = script + .get_var(value_var, locals) + .map_err(|f| (f, self.clone()))?; let mut has = false; @@ -716,21 +914,29 @@ impl Command { } } - script.set_var( - result_var, - Variable::from_bool(Some(has)), - global, - false, - locals, - )?; + script + .set_var( + result_var, + Variable::from_bool(Some(has)), + global, + false, + locals, + ) + .map_err(|f| (f, self.clone()))?; } CommandType::HasKey => { let map_var = self.args[0].clone(); let key_var = self.args[1].clone(); let result_var = self.args[2].clone(); - let map_var = script.get_var(map_var, locals)?.as_map()?; - let key_var = script.get_var(key_var, locals)?; + let map_var = script + .get_var(map_var, locals) + .map_err(|f| (f, self.clone()))? + .as_map() + .map_err(|f| (f, self.clone()))?; + let key_var = script + .get_var(key_var, locals) + .map_err(|f| (f, self.clone()))?; let mut has = false; @@ -741,21 +947,29 @@ impl Command { } } - script.set_var( - result_var, - Variable::from_bool(Some(has)), - global, - false, - locals, - )?; + script + .set_var( + result_var, + Variable::from_bool(Some(has)), + global, + false, + locals, + ) + .map_err(|f| (f, self.clone()))?; } CommandType::HasValue => { let map_var = self.args[0].clone(); let value_var = self.args[1].clone(); let result_var = self.args[2].clone(); - let map_var = script.get_var(map_var, locals)?.as_map()?; - let value_var = script.get_var(value_var, locals)?; + let map_var = script + .get_var(map_var, locals) + .map_err(|f| (f, self.clone()))? + .as_map() + .map_err(|f| (f, self.clone()))?; + let value_var = script + .get_var(value_var, locals) + .map_err(|f| (f, self.clone()))?; let mut has = false; @@ -766,53 +980,71 @@ impl Command { } } - script.set_var( - result_var, - Variable::from_bool(Some(has)), - global, - false, - locals, - )?; + script + .set_var( + result_var, + Variable::from_bool(Some(has)), + global, + false, + locals, + ) + .map_err(|f| (f, self.clone()))?; } CommandType::HasOptional => { let optional_var = self.args[0].clone(); let result_var = self.args[1].clone(); - let optional_var = script.get_var(optional_var, locals)?.as_option()?; + let optional_var = script + .get_var(optional_var, locals) + .map_err(|f| (f, self.clone()))? + .as_option() + .map_err(|f| (f, self.clone()))?; - script.set_var( - result_var, - Variable::from_bool(Some(optional_var.is_some())), - global, - false, - locals, - )?; + script + .set_var( + result_var, + Variable::from_bool(Some(optional_var.is_some())), + global, + false, + locals, + ) + .map_err(|f| (f, self.clone()))?; } CommandType::UnpackOptional => { let optional_var = self.args[0].clone(); let result_var = self.args[1].clone(); - let optional_var = script.get_var(optional_var, locals)?.as_option()?; + let optional_var = script + .get_var(optional_var, locals) + .map_err(|f| (f, self.clone()))? + .as_option() + .map_err(|f| (f, self.clone()))?; - script.set_var( - result_var, - optional_var - .ok_or(ScriptError::ParseVarError)? - .as_mut() - .clone(), - global, - false, - locals, - )?; + script + .set_var( + result_var, + optional_var + .ok_or(ScriptError::ParseVarError) + .map_err(|f| (f, self.clone()))? + .as_mut() + .clone(), + global, + false, + locals, + ) + .map_err(|f| (f, self.clone()))?; } CommandType::Sleep => { let time_var = self.args[0].clone(); - let time_var = match script.get_var(time_var, locals)? { + let time_var = match script + .get_var(time_var, locals) + .map_err(|f| (f, self.clone()))? + { Variable::Integer(_, Some(v)) => Duration::from_millis(v as u64), Variable::Float(_, Some(v)) => Duration::from_millis(v as u64), _ => { - return Err(ScriptError::TypeMismatchError); + return Err((ScriptError::TypeMismatchError, self.clone())); } }; @@ -822,138 +1054,212 @@ impl Command { let var_name = self.args[0].clone(); let other_var = self.args[1].clone(); - let other_var = script.get_var(other_var, locals)?.as_int()?; - let var = script.get_var(var_name.clone(), locals)?.as_int()?; + let other_var = script + .get_var(other_var, locals) + .map_err(|f| (f, self.clone()))? + .as_int() + .map_err(|f| (f, self.clone()))?; + let var = script + .get_var(var_name.clone(), locals) + .map_err(|f| (f, self.clone()))? + .as_int() + .map_err(|f| (f, self.clone()))?; - script.set_var( - var_name, - Variable::from_int(Some(var + other_var)), - global, - false, - locals, - )?; + script + .set_var( + var_name, + Variable::from_int(Some(var + other_var)), + global, + false, + locals, + ) + .map_err(|f| (f, self.clone()))?; } CommandType::AddFloat => { let var_name = self.args[0].clone(); let other_var = self.args[1].clone(); - let other_var = script.get_var(other_var, locals)?.as_float()?; - let var = script.get_var(var_name.clone(), locals)?.as_float()?; + let other_var = script + .get_var(other_var, locals) + .map_err(|f| (f, self.clone()))? + .as_float() + .map_err(|f| (f, self.clone()))?; + let var = script + .get_var(var_name.clone(), locals) + .map_err(|f| (f, self.clone()))? + .as_float() + .map_err(|f| (f, self.clone()))?; - script.set_var( - var_name, - Variable::from_float(Some(var + other_var)), - global, - false, - locals, - )?; + script + .set_var( + var_name, + Variable::from_float(Some(var + other_var)), + global, + false, + locals, + ) + .map_err(|f| (f, self.clone()))?; } CommandType::SubStr => { let str_var_name = self.args[0].clone(); let start_index = self.args[1].clone(); let end_index = self.args[1].clone(); - let str_var = script.get_var(str_var_name.clone(), locals)?.as_str()?; - let start_index = script.get_var(start_index, locals)?.as_int()? as usize; - let end_index = script.get_var(end_index, locals)?.as_int()? as usize; + let str_var = script + .get_var(str_var_name.clone(), locals) + .map_err(|f| (f, self.clone()))? + .as_str() + .map_err(|f| (f, self.clone()))?; + let start_index = script + .get_var(start_index, locals) + .map_err(|f| (f, self.clone()))? + .as_int() + .map_err(|f| (f, self.clone()))? as usize; + let end_index = script + .get_var(end_index, locals) + .map_err(|f| (f, self.clone()))? + .as_int() + .map_err(|f| (f, self.clone()))? as usize; - script.set_var( - str_var_name, - Variable::from_str(Some(str_var[start_index..end_index].to_string())), - global, - false, - locals, - )?; + script + .set_var( + str_var_name, + Variable::from_str(Some(str_var[start_index..end_index].to_string())), + global, + false, + locals, + ) + .map_err(|f| (f, self.clone()))?; } CommandType::SubList => { let list_var_name = self.args[0].clone(); let start_index = self.args[1].clone(); let end_index = self.args[1].clone(); - let list_var = script.get_var(list_var_name.clone(), locals)?; - let start_index = script.get_var(start_index, locals)?.as_int()? as usize; - let end_index = script.get_var(end_index, locals)?.as_int()? as usize; + let list_var = script + .get_var(list_var_name.clone(), locals) + .map_err(|f| (f, self.clone()))?; + let start_index = script + .get_var(start_index, locals) + .map_err(|f| (f, self.clone()))? + .as_int() + .map_err(|f| (f, self.clone()))? as usize; + let end_index = script + .get_var(end_index, locals) + .map_err(|f| (f, self.clone()))? + .as_int() + .map_err(|f| (f, self.clone()))? as usize; - script.set_var( - list_var_name, - Variable::from_list( - Some(list_var.as_list()?[start_index..end_index].to_vec()), - list_var.get_type(), - ), - global, - false, - locals, - )?; + script + .set_var( + list_var_name, + Variable::from_list( + Some( + list_var.as_list().map_err(|f| (f, self.clone()))? + [start_index..end_index] + .to_vec(), + ), + list_var.get_type(), + ), + global, + false, + locals, + ) + .map_err(|f| (f, self.clone()))?; } CommandType::Read => { let name_var = self.args[0].clone(); let size_var = self.args[1].clone(); let stream_var = self.args[2].clone(); - let var = script.get_var(name_var.clone(), locals)?; - let size_var = script.get_var(size_var.clone(), locals)?.as_int()?; - let stream = script.get_var(stream_var.clone(), locals)?.as_in_stream()?; + let var = script + .get_var(name_var.clone(), locals) + .map_err(|f| (f, self.clone()))?; + let size_var = script + .get_var(size_var.clone(), locals) + .map_err(|f| (f, self.clone()))? + .as_int() + .map_err(|f| (f, self.clone()))?; + let stream = script + .get_var(stream_var.clone(), locals) + .map_err(|f| (f, self.clone()))? + .as_in_stream() + .map_err(|f| (f, self.clone()))?; let mut buffer: Vec = Vec::with_capacity(size_var as usize); stream.lock().unwrap().read_exact(&mut buffer).unwrap(); - script.set_var( - name_var, - match var { - Variable::List(VarType::Char, _) => Variable::from_list( - Some( - buffer - .iter() - .map(|f| Variable::from_char(Some(*f))) - .collect(), + script + .set_var( + name_var, + match var { + Variable::List(VarType::Char, _) => Variable::from_list( + Some( + buffer + .iter() + .map(|f| Variable::from_char(Some(*f))) + .collect(), + ), + VarType::List(Box::new(VarType::Char)), ), - VarType::List(Box::new(VarType::Char)), - ), - Variable::String(_, _) => Variable::from_str(Some( - String::from_utf8(buffer).or(Err(ScriptError::StringUTF8Error))?, - )), - _ => { - return Err(ScriptError::TypeMismatchError); - } - }, - global, - false, - locals, - )?; + Variable::String(_, _) => Variable::from_str(Some( + String::from_utf8(buffer) + .or(Err(ScriptError::StringUTF8Error)) + .map_err(|f| (f, self.clone()))?, + )), + _ => { + return Err((ScriptError::TypeMismatchError, self.clone())); + } + }, + global, + false, + locals, + ) + .map_err(|f| (f, self.clone()))?; } CommandType::ReadAll => { let name_var = self.args[0].clone(); let stream_var = self.args[1].clone(); - let var = script.get_var(name_var.clone(), locals)?; - let stream = script.get_var(stream_var.clone(), locals)?.as_in_stream()?; + let var = script + .get_var(name_var.clone(), locals) + .map_err(|f| (f, self.clone()))?; + let stream = script + .get_var(stream_var.clone(), locals) + .map_err(|f| (f, self.clone()))? + .as_in_stream() + .map_err(|f| (f, self.clone()))?; let mut buffer: Vec = Vec::new(); stream.lock().unwrap().read_to_end(&mut buffer).unwrap(); - script.set_var( - name_var, - match var { - Variable::List(VarType::Char, _) => Variable::from_list( - Some( - buffer - .iter() - .map(|f| Variable::from_char(Some(*f))) - .collect(), + script + .set_var( + name_var, + match var { + Variable::List(VarType::Char, _) => Variable::from_list( + Some( + buffer + .iter() + .map(|f| Variable::from_char(Some(*f))) + .collect(), + ), + VarType::List(Box::new(VarType::Char)), ), - VarType::List(Box::new(VarType::Char)), - ), - Variable::String(_, _) => Variable::from_str(Some( - String::from_utf8(buffer).or(Err(ScriptError::StringUTF8Error))?, - )), - _ => { - return Err(ScriptError::TypeMismatchError); - } - }, - global, - false, - locals, - )?; + Variable::String(_, _) => Variable::from_str(Some( + String::from_utf8(buffer) + .or(Err(ScriptError::StringUTF8Error)) + .map_err(|f| (f, self.clone()))?, + )), + _ => { + return Err((ScriptError::TypeMismatchError, self.clone())); + } + }, + global, + false, + locals, + ) + .map_err(|f| (f, self.clone()))?; } CommandType::OpenFileIn => { let path_var = self.args[0].clone(); diff --git a/src/sustlang/mod.rs b/src/sustlang/mod.rs index 5076ed8..5cdb7a3 100644 --- a/src/sustlang/mod.rs +++ b/src/sustlang/mod.rs @@ -1,7 +1,9 @@ pub mod command; +pub mod other; pub mod script; pub mod var; pub use command::*; +pub use other::*; pub use script::*; pub use var::*; diff --git a/src/sustlang/other.rs b/src/sustlang/other.rs new file mode 100644 index 0000000..e27f974 --- /dev/null +++ b/src/sustlang/other.rs @@ -0,0 +1,5 @@ +pub trait Pohuy { + fn pohuy(&self) {} +} + +impl Pohuy for Result {} diff --git a/src/sustlang/script/function.rs b/src/sustlang/script/function.rs index 161299f..3c57688 100644 --- a/src/sustlang/script/function.rs +++ b/src/sustlang/script/function.rs @@ -1,7 +1,7 @@ use super::super::command::{Command, CommandType}; -use super::super::script::ScriptError; +use super::super::other::Pohuy; use super::super::var::{VarType, Variable}; -use super::RunningScript; +use super::{RunningScript, ScriptError}; use std::collections::HashMap; @@ -33,7 +33,6 @@ impl Function { script: &mut RunningScript, result_var: String, args: Vec, - globals: &mut HashMap, is_global: bool, ) -> Result<(), (ScriptError, Command)> { let mut locals: HashMap = HashMap::new(); @@ -54,27 +53,30 @@ impl Function { return Ok(()); } - command - .execute(script, is_global, &mut locals, globals, &mut temp_vars) - .map_err(|f| (f, command.clone()))?; + command.execute(script, is_global, &mut locals, &mut temp_vars)?; if let CommandType::TempVar = command.command_type { continue; } for ele in temp_vars.clone() { - script.drop_var(ele, &mut locals); + script + .drop_var(ele, &mut locals) + .map_err(|f| (f, command.clone())) + .pohuy(); } } if result_var != "null" { - script.set_var( - result_var, - locals.get("result").unwrap().clone(), - is_global, - false, - &mut locals, - ); + script + .set_var( + result_var, + locals.get("result").unwrap().clone(), + is_global, + false, + &mut locals, + ) + .unwrap(); } Ok(()) diff --git a/src/sustlang/script/running_script.rs b/src/sustlang/script/running_script.rs index cb221e4..bb38cf9 100644 --- a/src/sustlang/script/running_script.rs +++ b/src/sustlang/script/running_script.rs @@ -288,9 +288,8 @@ impl RunningScript { } pub fn run(&mut self) -> Result<(), (ScriptError, Command)> { - let globals = &mut self.variables.clone(); let main_function = self.main_function.clone(); - main_function.execute(self, "null".to_string(), Vec::new(), globals, true) + main_function.execute(self, "null".to_string(), Vec::new(), true) } }