From 7c668f875b15be9c60b4dc8f6b5c65817a222e24 Mon Sep 17 00:00:00 2001 From: MeexReay Date: Sun, 28 Jul 2024 17:18:29 +0300 Subject: [PATCH] fix test.sus --- src/lib.rs | 66 +++++++++++++++++++++++++++++++++++++++++------------ src/main.rs | 8 ++++++- test.sus | 34 +++++++++++++++++++-------- 3 files changed, 83 insertions(+), 25 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index fa23640..65d6d7e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,13 +16,14 @@ use std::{ pub enum ScriptError { ParseVarError, TypeUnknownError, - CommandUnknownError(usize), - CommandArgsInvalidError(usize), + CommandUnknownError, + CommandArgsInvalidError, UnknownVarError, TypeMismatchError, VarNotInitedError, StringUTF8Error, VarInitedError, + FunctionUnknownError, } impl Display for ScriptError { @@ -92,12 +93,21 @@ impl VarType { match name { "bool" => Ok(VarType::Bool), + "b" => Ok(VarType::Bool), "string" => Ok(VarType::String), + "str" => Ok(VarType::String), + "s" => Ok(VarType::String), "integer" => Ok(VarType::Integer), + "int" => Ok(VarType::Integer), + "i" => Ok(VarType::Integer), "float" => Ok(VarType::Float), + "f" => Ok(VarType::Float), "char" => Ok(VarType::Char), + "c" => Ok(VarType::Char), "in_stream" => Ok(VarType::InStream), + "in" => Ok(VarType::InStream), "out_stream" => Ok(VarType::OutStream), + "out" => Ok(VarType::OutStream), "null" => Ok(VarType::Null), _ => Err(ScriptError::TypeUnknownError), } @@ -378,7 +388,7 @@ impl Variable { } } - pub fn empty_var(var_type: VarType) -> Result { + pub fn not_inited_var(var_type: VarType) -> Result { match var_type { VarType::Bool => Ok(Variable::Bool(VarType::Bool, None)), VarType::String => Ok(Variable::String(VarType::String, None)), @@ -398,6 +408,30 @@ impl Variable { } } + pub fn empty_var(var_type: VarType) -> Result { + match var_type { + VarType::Bool => Ok(Variable::Bool(VarType::Bool, None)), + VarType::String => Ok(Variable::String(VarType::String, None)), + VarType::Integer => Ok(Variable::Integer(VarType::Integer, None)), + VarType::Float => Ok(Variable::Float(VarType::Float, None)), + VarType::Char => Ok(Variable::Char(VarType::Char, None)), + VarType::Optional(optional_type) => Ok(Variable::Optional( + VarType::Optional(optional_type), + Some(None), + )), + VarType::List(value_type) => { + Ok(Variable::List(VarType::List(value_type), Some(Vec::new()))) + } + VarType::Map(key_type, value_type) => Ok(Variable::Map( + VarType::Map(key_type, value_type), + Some(HashMap::new()), + )), + VarType::InStream => Ok(Variable::InStream(VarType::InStream, None)), + VarType::OutStream => Ok(Variable::OutStream(VarType::OutStream, None)), + VarType::Null => Ok(Variable::Null(VarType::Null)), + } + } + pub fn parse_var(var_type: VarType, text: String) -> Result { match var_type { VarType::Bool => Ok(Variable::Bool( @@ -941,7 +975,7 @@ pub enum CommandType { } impl CommandType { - pub fn from_name(name: &str, line: usize) -> Result { + pub fn from_name(name: &str) -> Result { match name { "INIT_VAR" => Ok(CommandType::InitVar), "SET_VAR" => Ok(CommandType::SetVar), @@ -999,7 +1033,7 @@ impl CommandType { "HAS_VALUE" => Ok(CommandType::HasValue), "HAS_OPTIONAL" => Ok(CommandType::HasOptional), "UNPACK_OPTIONAL" => Ok(CommandType::UnpackOptional), - _ => Err(ScriptError::CommandUnknownError(line)), + _ => Err(ScriptError::CommandUnknownError), } } } @@ -1061,7 +1095,7 @@ fn prepare_script(text: String) -> Vec { .collect() } -fn parse_commands(lines: Vec) -> Result, ScriptError> { +fn parse_commands(lines: Vec) -> Result, (ScriptError, usize)> { let mut commands = Vec::new(); let mut line_num = 0; @@ -1074,7 +1108,7 @@ fn parse_commands(lines: Vec) -> Result, ScriptError> { let params: Vec = line.split(" ").map(|v| v.to_string()).collect(); - let command_type = CommandType::from_name(¶ms[0], line_num)?; + let command_type = CommandType::from_name(¶ms[0]).map_err(|f| (f, line_num))?; let args = if params.is_empty() { Vec::new() @@ -1088,7 +1122,7 @@ fn parse_commands(lines: Vec) -> Result, ScriptError> { Ok(commands) } -fn cut_funcs(commands: &mut Vec) -> Result, ScriptError> { +fn cut_funcs(commands: &mut Vec) -> Result, (ScriptError, usize)> { let mut functions: Vec = Vec::new(); let mut now_func: Option = None; @@ -1115,14 +1149,18 @@ fn cut_funcs(commands: &mut Vec) -> Result, ScriptError> commands.remove(index); let name = command.args[1].clone(); - let result_type = VarType::from_name(&command.args[0])?; + let result_type = + VarType::from_name(&command.args[0]).map_err(|f| (f, command.line))?; let mut parameters = HashMap::new(); let mut param_key: Option = None; for i in &command.args[2..] { match ¶m_key { Some(key) => { - parameters.insert(key.to_string(), VarType::from_name(i)?); + parameters.insert( + key.to_string(), + VarType::from_name(i).map_err(|f| (f, command.line))?, + ); param_key = None; } None => { @@ -1146,7 +1184,7 @@ pub struct Script { } impl Script { - pub fn parse(text: String) -> Result { + pub fn parse(text: String) -> Result { let lines = prepare_script(text); let mut commands = parse_commands(lines)?; let functions = cut_funcs(&mut commands)?; @@ -1424,13 +1462,13 @@ impl RunningScript { Err(ScriptError::UnknownVarError) } - pub fn get_function(&self, name: String) -> Option { + pub fn get_function(&self, name: String) -> Result { for func in &self.functions { if func.name == name { - return Some(func.clone()); + return Ok(func.clone()); } } - None + Err(ScriptError::FunctionUnknownError) } fn exec_command( diff --git a/src/main.rs b/src/main.rs index 6c2c23e..1f8b4fc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,7 +12,13 @@ fn main() { let filename = args[1].clone(); let args = args[1..].to_vec(); - let script = Script::parse(fs::read_to_string(filename).unwrap()).unwrap(); + let script = match Script::parse(fs::read_to_string(filename).unwrap()) { + Ok(i) => i, + Err((e, c)) => { + println!("error ({:?}) line: {}", e, c); + return; + } + }; let mut running_script = RunningScript::new(script); running_script diff --git a/test.sus b/test.sus index fafcc71..e9caa96 100644 --- a/test.sus +++ b/test.sus @@ -4,6 +4,9 @@ SET_VAR space 32 INIT_VAR char new_line SET_VAR new_line 10 +INIT_VAR int one +SET_VAR one 1 + FUNC null println text string # println function ADD_STR text new_line # add line break to text var WRITE text cout # write text var to console @@ -48,25 +51,36 @@ DROP_VAR args_size FUNC null print_arg_finally - USE_FUNC println null now_arg + INIT_VAR string prefix + SET_VAR prefix - + ADD_STR prefix space + ADD_STR prefix now_arg + USE_FUNC println null prefix FUNC_END FUNC null print_arg index integer INIT_VAR bool is_first SET_VAR is_first false - TEMP_VAR int first 0 + TEMP_VAR integer first 0 MORE index first is_first GET_ITEM args index now_arg IF is_first print_arg_finally FUNC_END -TEMP_VAR string text Args: -USE_FUNC println null text +FUNC null print_args_list + TEMP_VAR string text Args: + USE_FUNC println null text + INIT_VAR integer end_index + LIST_SIZE args end_index + TEMP_VAR integer add -1 + ADD_INT end_index add + TEMP_VAR integer start_index 0 + FOR print_arg start_index end_index +FUNC_END +INIT_VAR integer args_size +LIST_SIZE args args_size INIT_VAR string now_arg -INIT_VAR integer end_index -LIST_SIZE args end_index -TEMP_VAR integer add -1 -ADD_INT end_index add -TEMP_VAR integer start_index 0 -FOR print_arg start_index end_index +INIT_VAR bool is_args_more_than_one +MORE args_size one is_args_more_than_one +IF is_args_more_than_one print_args_list