input read

This commit is contained in:
MeexReay 2024-07-29 17:52:22 +03:00
parent 931fa4bf9d
commit ee94ba13e2
7 changed files with 222 additions and 12 deletions

View File

@ -189,8 +189,11 @@ FUNC_END
| Команда | Параметры | Описание |
|--------------------------|------------|-------------|
| `WRITE` | `name_var`, `stream_var` | Вывести переменную `name_var` в `stream_var` |
| `READ` | `name_var`, `size_var`, `stream_var` | Прочитать с `stream_var` ровно `size_var` байтов в переменную `name_var` типа `list[char]`/`string` |
| `READ` | `name_var`, `stream_var` | Прочитать с `stream_var` в переменную `name_var` типа `list[char]`/`string` |
| `READ_CHAR` | `name_var`, `stream_var` | Прочитать с `stream_var` один символ в переменную `name_var` типа `char` |
| `READ_LENGTH` | `name_var`, `length_var`, `stream_var` | Прочитать с `stream_var` ровно `length_var` байтов в переменную `name_var` типа `list[char]`/`string` |
| `READ_ALL` | `name_var`, `stream_var` | Прочитать с `stream_var` все имеющиеся байты в переменную `name_var` типа `list[char]`/`string` |
| `READ_LINE` | `name_var`, `stream_var` | Прочитать с `stream_var` одну строку в переменную `name_var` типа `list[char]`/`string` |
### Файлы

14
input.sus Normal file
View File

@ -0,0 +1,14 @@
FUNC null println text string
TEMP_VAR char new_line 10
ADD_STR text new_line
WRITE text cout
FUNC_END
FUNC string input
READ_LINE result cin
FUNC_END
INIT_VAR string read
USE_FUNC input read
USE_FUNC println null read

View File

@ -1,13 +1,14 @@
use bytebuffer::ByteBuffer;
use rand::Rng;
use crate::{variable, FileOutStream, Pohuy};
use crate::{variable, FileOutStream, IgnoreResult};
use super::super::command::CommandType;
use super::super::script::{RunningScript, ScriptError};
use super::super::var::{VarType, Variable};
use std::collections::HashMap;
use std::io::{BufRead, BufReader};
use std::sync::{Arc, Mutex};
use std::time::Duration;
use std::{fs, thread};
@ -1831,7 +1832,176 @@ impl Command {
)
.map_err(|f| (f, self.clone()))?;
}
CommandType::ReadLine => {
let name_var = self
.args
.get(0)
.ok_or((ScriptError::CommandArgsInvalidError, self.clone()))?
.clone();
let stream_var = self
.args
.get(1)
.ok_or((ScriptError::CommandArgsInvalidError, self.clone()))?
.clone();
let var = script
.lock()
.unwrap()
.get_var(name_var.clone(), locals)
.map_err(|f| (f, self.clone()))?;
let stream = script
.lock()
.unwrap()
.get_var(stream_var.clone(), locals)
.map_err(|f| (f, self.clone()))?
.as_in_stream()
.map_err(|f| (f, self.clone()))?;
let mut line = String::new();
let mut buffer = [0; 1];
while stream
.lock()
.unwrap()
.read(&mut buffer)
.map_err(|_| (ScriptError::StreamReadError, self.clone()))?
> 0
{
if buffer[0] == b'\n' {
break;
}
line.push(buffer[0] as char);
}
let buffer = line.as_bytes().to_vec();
script
.lock()
.unwrap()
.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)),
),
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::ReadChar => {
let name_var = self
.args
.get(0)
.ok_or((ScriptError::CommandArgsInvalidError, self.clone()))?
.clone();
let stream_var = self
.args
.get(1)
.ok_or((ScriptError::CommandArgsInvalidError, self.clone()))?
.clone();
let stream = script
.lock()
.unwrap()
.get_var(stream_var.clone(), locals)
.map_err(|f| (f, self.clone()))?
.as_in_stream()
.map_err(|f| (f, self.clone()))?;
let mut buffer = [0; 1];
let read = stream
.lock()
.unwrap()
.read(&mut buffer)
.map_err(|_| (ScriptError::StreamReadError, self.clone()))?
> 0;
let variable = if read {
Variable::from_char(Some(buffer[0]))
} else {
Variable::from_char(None)
};
script
.lock()
.unwrap()
.set_var(name_var, variable, global, false, locals)
.map_err(|f| (f, self.clone()))?;
}
CommandType::Read => {
let name_var = self
.args
.get(0)
.ok_or((ScriptError::CommandArgsInvalidError, self.clone()))?
.clone();
let stream_var = self
.args
.get(1)
.ok_or((ScriptError::CommandArgsInvalidError, self.clone()))?
.clone();
let var = script
.lock()
.unwrap()
.get_var(name_var.clone(), locals)
.map_err(|f| (f, self.clone()))?;
let stream = script
.lock()
.unwrap()
.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<u8> = Vec::new();
stream.lock().unwrap().read(&mut buffer).unwrap();
script
.lock()
.unwrap()
.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)),
),
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::ReadLength => {
let name_var = self
.args
.get(0)

View File

@ -134,18 +134,36 @@ pub enum CommandType {
/// Параметры: `name_var`, `stream_var`
Write,
/// Прочитать с `stream_var` ровно `size_var` байтов в переменную `name_var` типа `list[char]`
/// Прочитать с `stream_var` ровно `length_var` байтов в переменную `name_var` типа `string`/`list[char]`
///
/// Название: READ \
/// Параметры: `name_var`, `size_var`, `stream_var`
Read,
/// Название: READ_LENGTH \
/// Параметры: `name_var`, `length_var`, `stream_var`
ReadLength,
/// Прочитать с `stream_var` все имеющиеся байты в переменную `name_var` типа `list[char]`
/// Прочитать с `stream_var` все имеющиеся байты в переменную `name_var` типа `string`/`list[char]`
///
/// Название: READ_ALL \
/// Параметры: `name_var`, `stream_var`
ReadAll,
/// Прочитать с `stream_var` в переменную `name_var` типа `list[char]`/`string`
///
/// Название: READ \
/// Параметры: `name_var`, `stream_var`
Read,
/// Прочитать с `stream_var` один символ в переменную `name_var` типа `char`
///
/// Название: READ_CHAR \
/// Параметры: `name_var`, `stream_var`
ReadChar,
/// Прочитать с `stream_var` одну строку в переменную `name_var` типа `list[char]`/`string`
///
/// Название: READ_LINE \
/// Параметры: `name_var`, `stream_var`
ReadLine,
/// Функция `func` (с единственным аргументом с типом `int`) вызывается с `start_index` до `end_index` включительно, `start_index` и `end_index` это названия переменных
///
/// Название: FOR \
@ -415,6 +433,9 @@ impl CommandType {
"WRITE" => Ok(CommandType::Write),
"READ" => Ok(CommandType::Read),
"READ_ALL" => Ok(CommandType::ReadAll),
"READ_LINE" => Ok(CommandType::ReadLine),
"READ_CHAR" => Ok(CommandType::ReadChar),
"READ_LENGTH" => Ok(CommandType::ReadLength),
"FOR" => Ok(CommandType::For),
"FOR_MAP" => Ok(CommandType::ForMap),
"FOR_LIST" => Ok(CommandType::ForList),

View File

@ -1,10 +1,10 @@
use std::{fs, io::Write};
pub trait Pohuy<T, E> {
fn pohuy(&self) {}
pub trait IgnoreResult<T, E> {
fn ignore(&self) {}
}
impl<T, E> Pohuy<T, E> for Result<T, E> {}
impl<T, E> IgnoreResult<T, E> for Result<T, E> {}
pub struct FileOutStream {
bytes: Vec<u8>,

View File

@ -14,6 +14,8 @@ pub enum ScriptError {
FunctionUnknownError,
FileReadError,
FileWriteError,
StreamReadError,
StreamWriteError,
}
impl Display for ScriptError {

View File

@ -1,5 +1,5 @@
use super::super::command::{Command, CommandType};
use super::super::other::Pohuy;
use super::super::other::IgnoreResult;
use super::super::var::{VarType, Variable};
use super::{RunningScript, ScriptError};
@ -67,7 +67,7 @@ impl Function {
.unwrap()
.drop_var(ele, &mut locals)
.map_err(|f| (f, command.clone()))
.pohuy();
.ignore();
}
}