fix test.sus

This commit is contained in:
MeexReay 2024-07-28 17:18:29 +03:00
parent fb9e7d0fae
commit 7c668f875b
3 changed files with 83 additions and 25 deletions

View File

@ -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<Variable, ScriptError> {
pub fn not_inited_var(var_type: VarType) -> Result<Variable, ScriptError> {
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<Variable, ScriptError> {
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<Variable, ScriptError> {
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<CommandType, ScriptError> {
pub fn from_name(name: &str) -> Result<CommandType, ScriptError> {
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<String> {
.collect()
}
fn parse_commands(lines: Vec<String>) -> Result<Vec<Command>, ScriptError> {
fn parse_commands(lines: Vec<String>) -> Result<Vec<Command>, (ScriptError, usize)> {
let mut commands = Vec::new();
let mut line_num = 0;
@ -1074,7 +1108,7 @@ fn parse_commands(lines: Vec<String>) -> Result<Vec<Command>, ScriptError> {
let params: Vec<String> = line.split(" ").map(|v| v.to_string()).collect();
let command_type = CommandType::from_name(&params[0], line_num)?;
let command_type = CommandType::from_name(&params[0]).map_err(|f| (f, line_num))?;
let args = if params.is_empty() {
Vec::new()
@ -1088,7 +1122,7 @@ fn parse_commands(lines: Vec<String>) -> Result<Vec<Command>, ScriptError> {
Ok(commands)
}
fn cut_funcs(commands: &mut Vec<Command>) -> Result<Vec<Function>, ScriptError> {
fn cut_funcs(commands: &mut Vec<Command>) -> Result<Vec<Function>, (ScriptError, usize)> {
let mut functions: Vec<Function> = Vec::new();
let mut now_func: Option<Function> = None;
@ -1115,14 +1149,18 @@ fn cut_funcs(commands: &mut Vec<Command>) -> Result<Vec<Function>, 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<String> = None;
for i in &command.args[2..] {
match &param_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<Script, ScriptError> {
pub fn parse(text: String) -> Result<Script, (ScriptError, usize)> {
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<Function> {
pub fn get_function(&self, name: String) -> Result<Function, ScriptError> {
for func in &self.functions {
if func.name == name {
return Some(func.clone());
return Ok(func.clone());
}
}
None
Err(ScriptError::FunctionUnknownError)
}
fn exec_command(

View File

@ -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

View File

@ -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