mirror of
https://github.com/MeexReay/sustlang.git
synced 2025-06-24 18:43:01 +03:00
more commands
This commit is contained in:
parent
b29952bec8
commit
6a4c92b671
75
README.md
75
README.md
@ -5,10 +5,12 @@
|
|||||||
код хеллоу ворлда:
|
код хеллоу ворлда:
|
||||||
|
|
||||||
```
|
```
|
||||||
INIT_VAR string text
|
INIT_VAR string text # init text var
|
||||||
SET_VAR text Hello World!
|
SET_VAR text Hello World! # set text to var
|
||||||
WRITE text cout
|
TEMP_VAR char br 10 # create temp var with line break
|
||||||
DROP_VAR text
|
ADD_STR text br # add line break to text
|
||||||
|
WRITE text cout # write text to console
|
||||||
|
DROP_VAR text # drop text var
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@ -21,39 +23,86 @@ WRITE text cout
|
|||||||
|
|
||||||
## Команды
|
## Команды
|
||||||
|
|
||||||
|
### Переменные
|
||||||
|
|
||||||
| Команда | Параметры | Описание |
|
| Команда | Параметры | Описание |
|
||||||
|--------------------------|------------|-------------|
|
|--------------------------|------------|-------------|
|
||||||
| `INIT_VAR` | `type_var`, `name_var` | Инициализировать переменную `name_var` с типом `type_var` |
|
| `INIT_VAR` | `type_var`, `name_var` | Инициализировать переменную `name_var` с типом `type_var` |
|
||||||
| `SET_VAR` | `name_var`, `value_var` | Установить значение переменной в `name_var` |
|
| `SET_VAR` | `name_var`, `value_var` | Установить значение переменной в `name_var` |
|
||||||
| `TEMP_VAR` | `type_var`, `name_var`, `value_var` | Переменная `name_var` инициализируется с типом `type_var` и присваивается `value_var`, переменная дропается после первого же использования |
|
| `TEMP_VAR` | `type_var`, `name_var`, `value_var` | Переменная `name_var` инициализируется с типом `type_var` и присваивается `value_var`, переменная дропается через одну команду |
|
||||||
| `MOVE_VAR` | `source_var`, `target_var` | Переместить значение переменной с `source_var` в `target_var` |
|
| `MOVE_VAR` | `source_var`, `target_var` | Переместить значение переменной с `source_var` в `target_var` |
|
||||||
| `COPY_VAR` | `source_var`, `target_var` | Скопировать значение переменной с `source_var` в `target_var` |
|
| `COPY_VAR` | `source_var`, `target_var` | Скопировать значение переменной с `source_var` в `target_var` |
|
||||||
| `DROP_VAR` | `name_var` | Дропнуть переменную `name_var` |
|
| `DROP_VAR` | `name_var` | Дропнуть переменную `name_var` |
|
||||||
| `HAS_VAR` | `name_var`, `result_var` | В переменную `result_var` записывается `bool` существует ли переменная `name_var` |
|
| `HAS_VAR` | `name_var`, `result_var` | В переменную `result_var` записывается `bool` существует ли переменная `name_var` |
|
||||||
|
| `LIST_SIZE` | `list_var`, `result_var` | Получить размер списка и записать в переменную `result_var` типа `int` |
|
||||||
|
|
||||||
|
### Преобразование переменных
|
||||||
|
|
||||||
|
| Команда | Параметры | Описание |
|
||||||
|
|--------------------------|------------|-------------|
|
||||||
| `TO_STRING` | `source_var`, `target_var` | Скопировать значение переменной с `source_var` в `target_var`, переводя в строку |
|
| `TO_STRING` | `source_var`, `target_var` | Скопировать значение переменной с `source_var` в `target_var`, переводя в строку |
|
||||||
| `ADD_INT` | `int_var1`, `int_var2` | Прибавить к числу `int_var1` значение `int_var2` |
|
| `ADD_INT` | `int_var1`, `int_var2` | Прибавить к числу `int_var1` значение `int_var2` |
|
||||||
| `ADD_FLOAT` | `float_var1`, `float_var2` | Прибавить к числу `float_var1` значение `float_var2` |
|
| `ADD_FLOAT` | `float_var1`, `float_var2` | Прибавить к числу `float_var1` значение `float_var2` |
|
||||||
| `ADD_STR` | `str_var`, `value_var` | Прибавить к строке `str_var` значение `value_var` (может быть типа `string/char/list[char]`) |
|
| `ADD_STR` | `str_var`, `value_var` | Прибавить к строке `str_var` значение `value_var` (может быть типа `string/char/list[char]`) |
|
||||||
| `SUB_STR` | `str_var`, `start_index`, `end_index` | Сделать подстроку из строки `str_var` и сохранить туда же |
|
| `SUB_STR` | `str_var`, `start_index`, `end_index` | Сделать подстроку из строки `str_var` и сохранить туда же |
|
||||||
| `SUB_LIST` | `list_var`, `start_index`, `end_index` | Сделать подсписок из списка `list_var` и сохранить туда же |
|
| `SUB_LIST` | `list_var`, `start_index`, `end_index` | Сделать подсписок из списка `list_var` и сохранить туда же |
|
||||||
| `LIST_SIZE` | `list_var`, `result_var` | Получить размер списка и записать в переменную `result_var` типа `int` |
|
|
||||||
|
### Циклы
|
||||||
|
|
||||||
|
| Команда | Параметры | Описание |
|
||||||
|
|--------------------------|------------|-------------|
|
||||||
|
| `FOR` | `func(int)`, `start_index`, `end_index` | Функция `func` (с единственным аргументом с типом `int`) вызывается с `start_index` до `end_index` включительно, `start_index` и `end_index` это названия переменных |
|
||||||
|
| `FOR_MAP` | `func(any, any)`, `map_var` | Функция `func` вызывается для каждого `key`, `value` переменной `map_var` |
|
||||||
|
| `FOR_LIST` | `func(any)`, `list_var` | Функция `func` вызывается для каждого предмета переменной `list_var` |
|
||||||
|
| `WHILE` | `func -> bool` | Функция `func` (с результатом `bool`) вызывается, пока функция выдает `true` |
|
||||||
|
|
||||||
|
### Работа со стримами
|
||||||
|
|
||||||
|
| Команда | Параметры | Описание |
|
||||||
|
|--------------------------|------------|-------------|
|
||||||
| `WRITE` | `name_var`, `stream_var` | Вывести переменную `name_var` в `stream_var` |
|
| `WRITE` | `name_var`, `stream_var` | Вывести переменную `name_var` в `stream_var` |
|
||||||
| `READ` | `name_var`, `size_var`, `stream_var` | Прочитать с `stream_var` ровно `size_var` байтов в переменную `name_var` типа `list[char]` |
|
| `READ` | `name_var`, `size_var`, `stream_var` | Прочитать с `stream_var` ровно `size_var` байтов в переменную `name_var` типа `list[char]` |
|
||||||
| `READ_ALL` | `name_var`, `stream_var` | Прочитать с `stream_var` все имеющиеся байты в переменную `name_var` типа `list[char]` |
|
| `READ_ALL` | `name_var`, `stream_var` | Прочитать с `stream_var` все имеющиеся байты в переменную `name_var` типа `list[char]` |
|
||||||
| `READ_STR` | `name_var`, `size_var`, `stream_var` | Прочитать с `stream_var` ровно `size_var` байтов в переменную `name_var` типа `string` |
|
| `READ_STR` | `name_var`, `size_var`, `stream_var` | Прочитать с `stream_var` ровно `size_var` байтов в переменную `name_var` типа `string` |
|
||||||
| `READ_STR_ALL` | `name_var`, `stream_var` | Прочитать с `stream_var` все имеющиеся байты в переменную `name_var` типа `string` |
|
| `READ_STR_ALL` | `name_var`, `stream_var` | Прочитать с `stream_var` все имеющиеся байты в переменную `name_var` типа `string` |
|
||||||
| `FOR` | `func(int)`, `start_index`, `end_index` | Функция `func` (с единственным аргументом с типом `int`) вызывается с `start_index` до `end_index` включительно, `start_index` и `end_index` это названия переменных |
|
|
||||||
| `FOR_MAP` | `func(any, any)`, `map_var` | Функция `func` вызывается для каждого `key`, `value` переменной `map_var` |
|
|
||||||
| `FOR_LIST` | `func(any)`, `list_var` | Функция `func` вызывается для каждого предмета переменной `list_var` |
|
|
||||||
| `WHILE` | `func -> bool` | Функция `func` (с результатом `bool`) вызывается, пока функция выдает `true` |
|
|
||||||
| `USE_FUNC` | `func`, `result_var`, `[arg_var1] ... [arg_varN]` | Функция `func` вызывается с переданными аргументами и устанавливает результат в переменную `result_var` |
|
|
||||||
| `OPEN_FILE_IN` | `path_var`, `stream_var` | Открыть файл по пути `path_var` (`path_var`, `stream_var` - переменные) для чтения и записать стрим для чтения в переменную `stream_var` |
|
| `OPEN_FILE_IN` | `path_var`, `stream_var` | Открыть файл по пути `path_var` (`path_var`, `stream_var` - переменные) для чтения и записать стрим для чтения в переменную `stream_var` |
|
||||||
| `OPEN_FILE_OUT` | `path_var`, `stream_var` | Открыть файл по пути `path_var` (`path_var`, `stream_var` - переменные) для записи и записать стрим для записи в переменную `stream_var` |
|
| `OPEN_FILE_OUT` | `path_var`, `stream_var` | Открыть файл по пути `path_var` (`path_var`, `stream_var` - переменные) для записи и записать стрим для записи в переменную `stream_var` |
|
||||||
| `OPEN_TCP_CONNECTION` | `addr_var`, `port_var`, `in_stream`, `out_stream` | Подключиться по `addr_var:port_var` (`addr_var: string`, `port_var: int`, `in_stream: in_stream`, `out_stream: out_stream` - переменные) и записать стримы для чтения и записи в `in_stream` и `out_stream` |
|
| `OPEN_TCP_CONNECTION` | `addr_var`, `port_var`, `in_stream`, `out_stream` | Подключиться по `addr_var:port_var` (`addr_var: string`, `port_var: int`, `in_stream: in_stream`, `out_stream: out_stream` - переменные) и записать стримы для чтения и записи в `in_stream` и `out_stream` |
|
||||||
| `OPEN_TCP_LISTENER` | `addr_var`, `port_var`, `accept_func(string,int,in_stream,out_stream)` | Ожидание подключений с `addr_var:port_var` (`addr_var: string`, `port_var: int` - переменные), при подключениях вызывается функция `accept_func` |
|
| `OPEN_TCP_LISTENER` | `addr_var`, `port_var`, `accept_func(string,int,in_stream,out_stream)` | Ожидание подключений с `addr_var:port_var` (`addr_var: string`, `port_var: int` - переменные), при подключениях вызывается функция `accept_func` |
|
||||||
| `HAS_OPTIONAL` | `optional_var`, `result_var` | Узнать, имеет ли данные опшнл `optional_var` и записать результат в `result_var: bool` |
|
|
||||||
| `WHEN_OPTIONAL` | `optional_var`, `func(option[any])` | Когда опшнл `optional_var` имеет данные, вызывается `func` |
|
### Логические операции
|
||||||
|
|
||||||
|
| Команда | Параметры | Описание |
|
||||||
|
|--------------------------|------------|-------------|
|
||||||
|
| `EQUALS` | `var`, `other_var`, `result_var` | Узнать, равен ли `var` и `other_var` записать результат в `result_var` |
|
||||||
|
| `MORE` | `var`, `other_var`, `result_var` | Узнать, больше ли в `var` чем в `other_var` записать результат в `result_var` |
|
||||||
|
| `LESS` | `var`, `other_var`, `result_var` | Узнать, меньше ли в `var` чем в `other_var` записать результат в `result_var` |
|
||||||
|
| `AND` | `var`, `other_var`, `result_var` | Если `var` и `other_var` равны `true`, то результат `true`, иначе `false`, записать результат в `result_var` |
|
||||||
|
| `OR` | `var`, `other_var`, `result_var` | Если `var` или `other_var` равен `true`, то результат `true`, иначе `false`, записать результат в `result_var` |
|
||||||
|
| `IF` | `bool_var`, `func` | Если `var` равен `true` то вызвать функцию `func` |
|
||||||
|
| `HAS_STR` | `string_var`, `substring`, `result_var` | Узнать, имеет ли строка `var` в себе подстроку `substring` и записать результат в `result_var` |
|
||||||
|
| `HAS_ITEM` | `list_var`, `item_var`, `result_var` | Узнать, имеет ли список `list_var` значение `item_var` и записать результат в `result_var` |
|
||||||
|
| `HAS_ENTRY` | `map_var`, `key_var`, `value_var`, `result_var` | Узнать, имеет ли мап `map_var` поле с ключом `key_var` и значением `value_var` и записать результат в `result_var` |
|
||||||
|
| `HAS_KEY` | `map_var`, `key_var`, `result_var` | Узнать, имеет ли мап `map_var` поле с ключом `key_var` и записать результат в `result_var` |
|
||||||
|
| `HAS_VALUE` | `map_var`, `value_var`, `result_var` | Узнать, имеет ли мап `map_var` поле с значением `value_var` и записать результат в `result_var` |
|
||||||
|
| `HAS_OPTIONAL` | `optional_var`, `result_var` | Узнать, имеет ли данные опшнл `optional_var` и записать результат в `result_var` |
|
||||||
|
|
||||||
|
|
||||||
|
### Функции
|
||||||
|
|
||||||
|
| Команда | Параметры | Описание |
|
||||||
|
|--------------------------|------------|-------------|
|
||||||
|
| `USE_FUNC` | `func_name`, `result_var`, `[arg_var1] ... [arg_varN]` | Функция `func` вызывается с переданными аргументами и устанавливает результат в переменную `result_var` |
|
||||||
|
| `FUNC` | `result_type`, `func_name`, `[arg_name_1 arg_type] ... [arg_name_N arg_type]` | Создать функцию с типом результата `result_type`, названием `func_name` и аргументами `[arg_name_1 arg_type] ... [arg_name_N arg_type]`. Установить результат переменной можно изменив переменную `result` внутри функции. Все команды после этой и до `FUNC_END` будут командами функции. Функции внутри функций не могут быть. |
|
||||||
|
| `RETURN` | | Досрочно выйти из функции, также работает как выход из скрипта |
|
||||||
|
| `FUNC_END` | | Маркер, что команды функции тут заканчиваются |
|
||||||
|
|
||||||
|
### Прочее
|
||||||
|
|
||||||
|
| Команда | Параметры | Описание |
|
||||||
|
|--------------------------|------------|-------------|
|
||||||
| `SLEEP` | `time_var` | Ждать миллисекунд из переменной `time_var` (тип переменной: int) |
|
| `SLEEP` | `time_var` | Ждать миллисекунд из переменной `time_var` (тип переменной: int) |
|
||||||
|
| `NEW_THREAD` | `func` | Вызвать функцию `func` в новом потоке |
|
||||||
|
|
||||||
## Типы переменных
|
## Типы переменных
|
||||||
|
|
||||||
|
529
src/lib.rs
529
src/lib.rs
@ -91,6 +91,21 @@ pub enum Variable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Variable {
|
impl Variable {
|
||||||
|
pub fn get_type(&self) -> VarType {
|
||||||
|
match self {
|
||||||
|
Variable::Bool(t, _) => t.clone(),
|
||||||
|
Variable::String(t, _) => t.clone(),
|
||||||
|
Variable::Integer(t, _) => t.clone(),
|
||||||
|
Variable::Float(t, _) => t.clone(),
|
||||||
|
Variable::Char(t, _) => t.clone(),
|
||||||
|
Variable::List(t, _) => t.clone(),
|
||||||
|
Variable::Map(t, _) => t.clone(),
|
||||||
|
Variable::Optional(t, _) => t.clone(),
|
||||||
|
Variable::InStream(t, _) => t.clone(),
|
||||||
|
Variable::OutStream(t, _) => t.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn empty_var(var_type: VarType) -> Option<Variable> {
|
pub fn empty_var(var_type: VarType) -> Option<Variable> {
|
||||||
match var_type {
|
match var_type {
|
||||||
VarType::Bool => Some(Variable::Bool(VarType::Bool, None)),
|
VarType::Bool => Some(Variable::Bool(VarType::Bool, None)),
|
||||||
@ -309,38 +324,273 @@ impl PartialEq for Variable {
|
|||||||
|
|
||||||
#[derive(PartialEq, Clone, Debug, Copy, Hash)]
|
#[derive(PartialEq, Clone, Debug, Copy, Hash)]
|
||||||
pub enum CommandType {
|
pub enum CommandType {
|
||||||
|
/// Инициализировать переменную `name_var` с типом `type_var`
|
||||||
|
///
|
||||||
|
/// Название: INIT_VAR
|
||||||
|
/// Параметры: `type_var`, `name_var`
|
||||||
InitVar,
|
InitVar,
|
||||||
|
|
||||||
|
/// Установить значение переменной в `name_var`
|
||||||
|
///
|
||||||
|
/// Название: SET_VAR
|
||||||
|
/// Параметры: `name_var`, `value_var`
|
||||||
SetVar,
|
SetVar,
|
||||||
|
|
||||||
|
/// Переменная `name_var` инициализируется с типом `type_var` и присваивается `value_var`, переменная дропается через одну команду
|
||||||
|
///
|
||||||
|
/// Название: TEMP_VAR
|
||||||
|
/// Параметры: `type_var`, `name_var`, `value_var`
|
||||||
TempVar,
|
TempVar,
|
||||||
|
|
||||||
|
/// Переместить значение переменной с `source_var` в `target_var`
|
||||||
|
///
|
||||||
|
/// Название: MOVE_VAR
|
||||||
|
/// Параметры: `source_var`, `target_var`
|
||||||
MoveVar,
|
MoveVar,
|
||||||
|
|
||||||
|
/// Скопировать значение переменной с `source_var` в `target_var`
|
||||||
|
///
|
||||||
|
/// Название: COPY_VAR
|
||||||
|
/// Параметры: `source_var`, `target_var`
|
||||||
CopyVar,
|
CopyVar,
|
||||||
|
|
||||||
|
/// Дропнуть переменную `name_var`
|
||||||
|
///
|
||||||
|
/// Название: DROP_VAR
|
||||||
|
/// Параметры: `name_var`
|
||||||
DropVar,
|
DropVar,
|
||||||
|
|
||||||
|
/// В переменную `result_var` записывается `bool` существует ли переменная `name_var`
|
||||||
|
///
|
||||||
|
/// Название: HAS_VAR
|
||||||
|
/// Параметры: `name_var`, `result_var`
|
||||||
HasVar,
|
HasVar,
|
||||||
|
|
||||||
|
/// Скопировать значение переменной с `source_var` в `target_var`, переводя в строку
|
||||||
|
///
|
||||||
|
/// Название: TO_STRING
|
||||||
|
/// Параметры: `source_var`, `target_var`
|
||||||
ToString,
|
ToString,
|
||||||
|
|
||||||
|
/// Прибавить к числу `var` значение `other_var`
|
||||||
|
///
|
||||||
|
/// Название: ADD_INT
|
||||||
|
/// Параметры: `var`, `other_var`
|
||||||
AddInt,
|
AddInt,
|
||||||
|
|
||||||
|
/// Прибавить к числу `var` значение `other_var`
|
||||||
|
///
|
||||||
|
/// Название: ADD_FLOAT
|
||||||
|
/// Параметры: `var`, `other_var`
|
||||||
AddFloat,
|
AddFloat,
|
||||||
|
|
||||||
|
/// Прибавить к числу `var` значение `other_var`
|
||||||
|
///
|
||||||
|
/// Название: ADD_STR
|
||||||
|
/// Параметры: `var`, `other_var`
|
||||||
|
AddStr,
|
||||||
|
|
||||||
|
/// Сделать подстроку из строки `str_var` и сохранить туда же
|
||||||
|
///
|
||||||
|
/// Название: SUB_STR
|
||||||
|
/// Параметры: `str_var`, `start_index`, `end_index`
|
||||||
SubStr,
|
SubStr,
|
||||||
|
|
||||||
|
/// Сделать подсписок из списка `list_var` и сохранить туда же
|
||||||
|
///
|
||||||
|
/// Название: SUB_LIST
|
||||||
|
/// Параметры: `list_var`, `start_index`, `end_index`
|
||||||
SubList,
|
SubList,
|
||||||
|
|
||||||
|
/// Получить размер списка и записать в переменную `result_var` типа `int`
|
||||||
|
///
|
||||||
|
/// Название: LIST_SIZE
|
||||||
|
/// Параметры: `list_var`, `result_var`
|
||||||
ListSize,
|
ListSize,
|
||||||
|
|
||||||
|
/// Вывести переменную `name_var` в `stream_var`
|
||||||
|
///
|
||||||
|
/// Название: WRITE
|
||||||
|
/// Параметры: `name_var`, `stream_var`
|
||||||
Write,
|
Write,
|
||||||
|
|
||||||
|
/// Прочитать с `stream_var` ровно `size_var` байтов в переменную `name_var` типа `list[char]`
|
||||||
|
///
|
||||||
|
/// Название: READ
|
||||||
|
/// Параметры: `name_var`, `size_var`, `stream_var`
|
||||||
Read,
|
Read,
|
||||||
|
|
||||||
|
/// Прочитать с `stream_var` все имеющиеся байты в переменную `name_var` типа `list[char]`
|
||||||
|
///
|
||||||
|
/// Название: READ_ALL
|
||||||
|
/// Параметры: `name_var`, `stream_var`
|
||||||
ReadAll,
|
ReadAll,
|
||||||
|
|
||||||
|
/// Прочитать с `stream_var` ровно `size_var` байтов в переменную `name_var` типа `string`
|
||||||
|
///
|
||||||
|
/// Название: READ_STR
|
||||||
|
/// Параметры: `name_var`, `size_var`, `stream_var`
|
||||||
ReadStr,
|
ReadStr,
|
||||||
|
|
||||||
|
/// Прочитать с `stream_var` все имеющиеся байты в переменную `name_var` типа `string`
|
||||||
|
///
|
||||||
|
/// Название: READ_STR_ALL
|
||||||
|
/// Параметры: `name_var`, `stream_var`
|
||||||
ReadStrAll,
|
ReadStrAll,
|
||||||
|
|
||||||
|
/// Функция `func` (с единственным аргументом с типом `int`) вызывается с `start_index` до `end_index` включительно, `start_index` и `end_index` это названия переменных
|
||||||
|
///
|
||||||
|
/// Название: FOR
|
||||||
|
/// Параметры: `func(int)`, `start_index`, `end_index`
|
||||||
For,
|
For,
|
||||||
|
|
||||||
|
/// Функция `func` вызывается для каждого `key`, `value` переменной `map_var`
|
||||||
|
///
|
||||||
|
/// Название: FOR_MAP
|
||||||
|
/// Параметры: `func(any, any)`, `map_var`
|
||||||
ForMap,
|
ForMap,
|
||||||
|
|
||||||
|
/// Функция `func` вызывается для каждого предмета переменной `list_var`
|
||||||
|
///
|
||||||
|
/// Название: FOR_LIST
|
||||||
|
/// Параметры: `func(any)`, `list_var`
|
||||||
ForList,
|
ForList,
|
||||||
|
|
||||||
|
/// Функция `func` (с результатом `bool`) вызывается, пока функция выдает `true`
|
||||||
|
///
|
||||||
|
/// Название: WHILE
|
||||||
|
/// Параметры: `func -> bool`
|
||||||
While,
|
While,
|
||||||
UseFunc,
|
|
||||||
|
/// Открыть файл по пути `path_var` (`path_var`, `stream_var` - переменные) для чтения и записать стрим для чтения в переменную `stream_var`
|
||||||
|
///
|
||||||
|
/// Название: OPEN_FILE_IN
|
||||||
|
/// Параметры: `path_var`, `stream_var`
|
||||||
OpenFileIn,
|
OpenFileIn,
|
||||||
|
|
||||||
|
/// Открыть файл по пути `path_var` (`path_var`, `stream_var` - переменные) для записи и записать стрим для записи в переменную `stream_var`
|
||||||
|
///
|
||||||
|
/// Название: OPEN_FILE_OUT
|
||||||
|
/// Параметры: `path_var`, `stream_var`
|
||||||
OpenFileOut,
|
OpenFileOut,
|
||||||
|
|
||||||
|
/// Подключиться по `addr_var:port_var` (`addr_var: string`, `port_var: int`, `in_stream: in_stream`, `out_stream: out_stream` - переменные) и записать стримы для чтения и записи в `in_stream` и `out_stream`
|
||||||
|
///
|
||||||
|
/// Название: OPEN_TCP_CONNECTION
|
||||||
|
/// Параметры: `addr_var`, `port_var`, `in_stream`, `out_stream`
|
||||||
OpenTcpConnection,
|
OpenTcpConnection,
|
||||||
|
|
||||||
|
/// Ожидание подключений с `addr_var:port_var` (`addr_var: string`, `port_var: int` - переменные), при подключениях вызывается функция `accept_func`
|
||||||
|
///
|
||||||
|
/// Название: OPEN_TCP_LISTENER
|
||||||
|
/// Параметры: `addr_var`, `port_var`, `accept_func(string,int,in_stream,out_stream)`
|
||||||
OpenTcpListener,
|
OpenTcpListener,
|
||||||
HasOptional,
|
|
||||||
WhenOptional,
|
/// Ждать миллисекунд из переменной `time_var` (тип переменной: int)
|
||||||
|
///
|
||||||
|
/// Название: SLEEP
|
||||||
|
/// Параметры: `time_var`
|
||||||
Sleep,
|
Sleep,
|
||||||
|
|
||||||
|
/// Вызвать функцию `func` в новом потоке
|
||||||
|
///
|
||||||
|
/// Название: NEW_THREAD
|
||||||
|
/// Параметры: `func`
|
||||||
|
NewThread,
|
||||||
|
|
||||||
|
/// Функция `func` вызывается с переданными аргументами и устанавливает результат в переменную `result_var`
|
||||||
|
///
|
||||||
|
/// Название: USE_FUNC
|
||||||
|
/// Параметры: `func_name`, `result_var`, `[arg_var1] ... [arg_varN]`
|
||||||
|
UseFunc,
|
||||||
|
|
||||||
|
/// Создать функцию с типом результата `result_type`, названием `func_name` и аргументами `[arg_name_1 arg_type] ... [arg_name_N arg_type]`. Установить результат переменной можно изменив переменную `result` внутри функции. Все команды после этой и до `FUNC_END` будут командами функции. Функции внутри функций не могут быть.
|
||||||
|
///
|
||||||
|
/// Название: FUNC
|
||||||
|
/// Параметры: `result_type`, `func_name`, `[arg_name_1 arg_type] ... [arg_name_N arg_type]`
|
||||||
Func,
|
Func,
|
||||||
|
|
||||||
|
/// Досрочно выйти из функции, также работает как выход из скрипта
|
||||||
|
///
|
||||||
|
/// Название: RETURN
|
||||||
|
Return,
|
||||||
|
|
||||||
|
/// Маркер, что команды функции тут заканчиваются
|
||||||
|
///
|
||||||
|
/// Название: FUNC_END
|
||||||
FuncEnd,
|
FuncEnd,
|
||||||
|
|
||||||
|
/// Узнать, равен ли `var` и `other_var` записать результат в `result_var`
|
||||||
|
///
|
||||||
|
/// Название: EQUALS
|
||||||
|
/// Параметры: `var`, `other_var`, `result_var`
|
||||||
|
Equals,
|
||||||
|
|
||||||
|
/// Узнать, больше ли в `var` чем в `other_var` записать результат в `result_var`
|
||||||
|
///
|
||||||
|
/// Название: MORE
|
||||||
|
/// Параметры: `var`, `other_var`, `result_var`
|
||||||
|
More,
|
||||||
|
|
||||||
|
/// Узнать, меньше ли в `var` чем в `other_var` записать результат в `result_var`
|
||||||
|
///
|
||||||
|
/// Название: LESS
|
||||||
|
/// Параметры: `var`, `other_var`, `result_var`
|
||||||
|
Less,
|
||||||
|
|
||||||
|
/// Если `var` и `other_var` равны `true`, то результат `true`, иначе `false`, записать результат в `result_var`
|
||||||
|
///
|
||||||
|
/// Название: AND
|
||||||
|
/// Параметры: `var`, `other_var`, `result_var`
|
||||||
|
And,
|
||||||
|
|
||||||
|
/// Если `var` или `other_var` равен `true`, то результат `true`, иначе `false`, записать результат в `result_var`
|
||||||
|
///
|
||||||
|
/// Название: OR
|
||||||
|
/// Параметры: `var`, `other_var`, `result_var`
|
||||||
|
Or,
|
||||||
|
|
||||||
|
/// Если `var` равен `true` то вызвать функцию `func`
|
||||||
|
///
|
||||||
|
/// Название: IF
|
||||||
|
/// Параметры: `bool_var`, `func`
|
||||||
|
If,
|
||||||
|
|
||||||
|
/// Узнать, имеет ли строка `var` в себе подстроку `substring` и записать результат в `result_var`
|
||||||
|
///
|
||||||
|
/// Название: HAS_STR
|
||||||
|
/// Параметры: `string_var`, `substring`, `result_var`
|
||||||
|
HasStr,
|
||||||
|
|
||||||
|
/// Узнать, имеет ли список `list_var` значение `item_var` и записать результат в `result_var`
|
||||||
|
///
|
||||||
|
/// Название: HAS_ITEM
|
||||||
|
/// Параметры: `list_var`, `item_var`, `result_var`
|
||||||
|
HasItem,
|
||||||
|
|
||||||
|
/// Узнать, имеет ли мап `map_var` поле с ключом `key_var` и значением `value_var` и записать результат в `result_var`
|
||||||
|
///
|
||||||
|
/// Название: HAS_ENTRY
|
||||||
|
/// Параметры: `map_var`, `key_var`, `value_var`, `result_var`
|
||||||
|
HasEntry,
|
||||||
|
|
||||||
|
/// Узнать, имеет ли мап `map_var` поле с ключом `key_var` и записать результат в `result_var`
|
||||||
|
///
|
||||||
|
/// Название: HAS_KEY
|
||||||
|
/// Параметры: `map_var`, `key_var`, `result_var`
|
||||||
|
HasKey,
|
||||||
|
|
||||||
|
/// Узнать, имеет ли мап `map_var` поле с значением `value_var` и записать результат в `result_var`
|
||||||
|
///
|
||||||
|
/// Название: HAS_VALUE
|
||||||
|
/// Параметры: `map_var`, `value_var`, `result_var`
|
||||||
|
HasValue,
|
||||||
|
|
||||||
|
/// Узнать, имеет ли данные опшнл `optional_var` и записать результат в `result_var`
|
||||||
|
///
|
||||||
|
/// Название: HAS_OPTIONAL
|
||||||
|
/// Параметры: `optional_var`, `result_var`
|
||||||
|
HasOptional,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CommandType {
|
impl CommandType {
|
||||||
@ -356,6 +606,7 @@ impl CommandType {
|
|||||||
"TO_STRING" => Some(CommandType::ToString),
|
"TO_STRING" => Some(CommandType::ToString),
|
||||||
"ADD_INT" => Some(CommandType::AddInt),
|
"ADD_INT" => Some(CommandType::AddInt),
|
||||||
"ADD_FLOAT" => Some(CommandType::AddFloat),
|
"ADD_FLOAT" => Some(CommandType::AddFloat),
|
||||||
|
"ADD_STR" => Some(CommandType::AddStr),
|
||||||
"SUB_STR" => Some(CommandType::SubStr),
|
"SUB_STR" => Some(CommandType::SubStr),
|
||||||
"SUB_LIST" => Some(CommandType::SubList),
|
"SUB_LIST" => Some(CommandType::SubList),
|
||||||
"LIST_SIZE" => Some(CommandType::ListSize),
|
"LIST_SIZE" => Some(CommandType::ListSize),
|
||||||
@ -368,16 +619,28 @@ impl CommandType {
|
|||||||
"FOR_MAP" => Some(CommandType::ForMap),
|
"FOR_MAP" => Some(CommandType::ForMap),
|
||||||
"FOR_LIST" => Some(CommandType::ForList),
|
"FOR_LIST" => Some(CommandType::ForList),
|
||||||
"WHILE" => Some(CommandType::While),
|
"WHILE" => Some(CommandType::While),
|
||||||
"USE_FUNC" => Some(CommandType::UseFunc),
|
|
||||||
"OPEN_FILE_IN" => Some(CommandType::OpenFileIn),
|
"OPEN_FILE_IN" => Some(CommandType::OpenFileIn),
|
||||||
"OPEN_FILE_OUT" => Some(CommandType::OpenFileOut),
|
"OPEN_FILE_OUT" => Some(CommandType::OpenFileOut),
|
||||||
"OPEN_TCP_CONNECTION" => Some(CommandType::OpenTcpConnection),
|
"OPEN_TCP_CONNECTION" => Some(CommandType::OpenTcpConnection),
|
||||||
"OPEN_TCP_LISTENER" => Some(CommandType::OpenTcpListener),
|
"OPEN_TCP_LISTENER" => Some(CommandType::OpenTcpListener),
|
||||||
"HAS_OPTIONAL" => Some(CommandType::HasOptional),
|
|
||||||
"WHEN_OPTIONAL" => Some(CommandType::WhenOptional),
|
|
||||||
"SLEEP" => Some(CommandType::Sleep),
|
"SLEEP" => Some(CommandType::Sleep),
|
||||||
|
"NEW_THREAD" => Some(CommandType::NewThread),
|
||||||
|
"USE_FUNC" => Some(CommandType::UseFunc),
|
||||||
"FUNC" => Some(CommandType::Func),
|
"FUNC" => Some(CommandType::Func),
|
||||||
"FUNC_END" => Some(CommandType::FuncEnd),
|
"FUNC_END" => Some(CommandType::FuncEnd),
|
||||||
|
"RETURN" => Some(CommandType::Return),
|
||||||
|
"EQUALS" => Some(CommandType::Equals),
|
||||||
|
"MORE" => Some(CommandType::More),
|
||||||
|
"LESS" => Some(CommandType::Less),
|
||||||
|
"AND" => Some(CommandType::And),
|
||||||
|
"OR" => Some(CommandType::Or),
|
||||||
|
"IF" => Some(CommandType::If),
|
||||||
|
"HAS_STR" => Some(CommandType::HasStr),
|
||||||
|
"HAS_ITEM" => Some(CommandType::HasItem),
|
||||||
|
"HAS_ENTRY" => Some(CommandType::HasEntry),
|
||||||
|
"HAS_KEY" => Some(CommandType::HasKey),
|
||||||
|
"HAS_VALUE" => Some(CommandType::HasValue),
|
||||||
|
"HAS_OPTIONAL" => Some(CommandType::HasOptional),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -426,7 +689,7 @@ fn prepare_script(text: String) -> Vec<String> {
|
|||||||
None => s,
|
None => s,
|
||||||
})
|
})
|
||||||
.filter(|s| !s.trim().is_empty())
|
.filter(|s| !s.trim().is_empty())
|
||||||
.map(|s| s.to_string())
|
.map(|s| s.trim_end_matches(" ").to_string())
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -640,34 +903,233 @@ impl RunningScript {
|
|||||||
var
|
var
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exec_command(
|
pub fn exec_commands(
|
||||||
&mut self,
|
&mut self,
|
||||||
command: Command,
|
commands: Vec<Command>,
|
||||||
global: bool,
|
global: bool,
|
||||||
locals: &mut HashMap<String, Variable>,
|
locals: &mut HashMap<String, Variable>,
|
||||||
) {
|
) {
|
||||||
|
let mut temp_vars: Vec<String> = Vec::new();
|
||||||
|
|
||||||
|
for command in commands {
|
||||||
match command.command_type {
|
match command.command_type {
|
||||||
CommandType::InitVar => {
|
CommandType::InitVar => {
|
||||||
// TODO: for hello world
|
let type_var = command.args[0].clone();
|
||||||
|
let type_var = VarType::from_name(&type_var).unwrap();
|
||||||
|
let name_var = command.args[1].clone();
|
||||||
|
|
||||||
|
self.variables
|
||||||
|
.insert(name_var, Variable::empty_var(type_var).unwrap());
|
||||||
}
|
}
|
||||||
CommandType::SetVar => {
|
CommandType::SetVar => {
|
||||||
// TODO: for hello world
|
let name_var = command.args[0].clone();
|
||||||
|
let value_var = command.args[1..].join(" ");
|
||||||
|
|
||||||
|
let type_var = self.get_var(name_var.clone(), locals).unwrap().get_type();
|
||||||
|
let var = Variable::parse_var(type_var, value_var).unwrap();
|
||||||
|
|
||||||
|
if self.variables.contains_key(&name_var) {
|
||||||
|
self.variables.insert(name_var, var);
|
||||||
|
} else if locals.contains_key(&name_var) {
|
||||||
|
locals.insert(name_var, var);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
CommandType::TempVar => {
|
CommandType::TempVar => {
|
||||||
// TODO: for hello world
|
let type_var = command.args[0].clone();
|
||||||
|
let name_var = command.args[1].clone();
|
||||||
|
let value_var = command.args[2..].join(" ");
|
||||||
|
|
||||||
|
self.variables.insert(
|
||||||
|
name_var.clone(),
|
||||||
|
Variable::parse_var(VarType::from_name(&type_var).unwrap(), value_var)
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
|
|
||||||
|
temp_vars.push(name_var);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
CommandType::MoveVar => {
|
||||||
|
let source_var = command.args[0].clone();
|
||||||
|
let target_var = command.args[1].clone();
|
||||||
|
|
||||||
|
let var = self.get_var(source_var.clone(), locals).unwrap();
|
||||||
|
|
||||||
|
if self.variables.contains_key(&source_var) {
|
||||||
|
self.variables.remove(&source_var);
|
||||||
|
} else if locals.contains_key(&source_var) {
|
||||||
|
locals.remove(&source_var);
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.variables.contains_key(&target_var) {
|
||||||
|
self.variables.insert(target_var, var);
|
||||||
|
} else if locals.contains_key(&target_var) {
|
||||||
|
locals.insert(target_var, var);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CommandType::CopyVar => {
|
||||||
|
let source_var = command.args[0].clone();
|
||||||
|
let target_var = command.args[1].clone();
|
||||||
|
|
||||||
|
let var = self.get_var(source_var.clone(), locals).unwrap();
|
||||||
|
|
||||||
|
if self.variables.contains_key(&target_var) {
|
||||||
|
self.variables.insert(target_var, var);
|
||||||
|
} else if locals.contains_key(&target_var) {
|
||||||
|
locals.insert(target_var, var);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CommandType::DropVar => {
|
||||||
|
let name_var = command.args[0].clone();
|
||||||
|
|
||||||
|
if self.variables.contains_key(&name_var) {
|
||||||
|
self.variables.remove(&name_var);
|
||||||
|
} else if locals.contains_key(&name_var) {
|
||||||
|
locals.remove(&name_var);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CommandType::HasVar => {
|
||||||
|
let name_var = command.args[0].clone();
|
||||||
|
let result_var = command.args[1].clone();
|
||||||
|
|
||||||
|
let result =
|
||||||
|
self.variables.contains_key(&name_var) || locals.contains_key(&name_var);
|
||||||
|
|
||||||
|
if self.variables.contains_key(&result_var) {
|
||||||
|
self.variables
|
||||||
|
.insert(name_var, Variable::Bool(VarType::Bool, Some(result)));
|
||||||
|
} else if locals.contains_key(&result_var) {
|
||||||
|
locals.insert(name_var, Variable::Bool(VarType::Bool, Some(result)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
CommandType::MoveVar => {}
|
|
||||||
CommandType::CopyVar => {}
|
|
||||||
CommandType::DropVar => {}
|
|
||||||
CommandType::HasVar => {}
|
|
||||||
CommandType::ToString => {}
|
CommandType::ToString => {}
|
||||||
CommandType::AddInt => {}
|
CommandType::AddInt => {}
|
||||||
CommandType::AddFloat => {}
|
CommandType::AddFloat => {}
|
||||||
|
CommandType::AddStr => {
|
||||||
|
let var_name = command.args[0].clone();
|
||||||
|
let other_var = command.args[1].clone();
|
||||||
|
|
||||||
|
let other_var = self.get_var(other_var.clone(), locals).unwrap();
|
||||||
|
let other_var = match other_var {
|
||||||
|
Variable::String(_, s) => match s {
|
||||||
|
Some(s) => s,
|
||||||
|
None => {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Variable::Char(_, c) => match c {
|
||||||
|
Some(c) => String::from_utf8(vec![c]).unwrap(),
|
||||||
|
None => {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Variable::List(list_type, list) => match list_type {
|
||||||
|
VarType::List(mut list_type) => match list_type.as_mut() {
|
||||||
|
VarType::Char => String::from_utf8(
|
||||||
|
match list {
|
||||||
|
Some(i) => i,
|
||||||
|
None => {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.iter()
|
||||||
|
.map(|f| match f {
|
||||||
|
Variable::Char(_, c) => match c {
|
||||||
|
Some(c) => *c,
|
||||||
|
None => 0u8,
|
||||||
|
},
|
||||||
|
_ => 0u8,
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
|
_ => {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let var = self.get_var(var_name.clone(), locals).unwrap();
|
||||||
|
let var = match var {
|
||||||
|
Variable::String(t, s) => match s {
|
||||||
|
Some(s) => Variable::String(t, Some(s + &other_var)),
|
||||||
|
None => {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if self.variables.contains_key(&var_name) {
|
||||||
|
self.variables.insert(var_name, var);
|
||||||
|
} else if locals.contains_key(&var_name) {
|
||||||
|
locals.insert(var_name, var);
|
||||||
|
}
|
||||||
|
}
|
||||||
CommandType::SubStr => {}
|
CommandType::SubStr => {}
|
||||||
CommandType::SubList => {}
|
CommandType::SubList => {}
|
||||||
CommandType::ListSize => {}
|
CommandType::ListSize => {}
|
||||||
CommandType::Write => {
|
CommandType::Write => {
|
||||||
// TODO: for hello world
|
let name_var = command.args[0].clone();
|
||||||
|
let stream_var = command.args[1].clone();
|
||||||
|
|
||||||
|
let text = self.get_var(name_var.clone(), locals).unwrap();
|
||||||
|
let text: Vec<u8> = match text {
|
||||||
|
Variable::List(list_type, list) => match list_type {
|
||||||
|
VarType::List(mut list_type) => match list_type.as_mut() {
|
||||||
|
VarType::Char => match list {
|
||||||
|
Some(i) => i,
|
||||||
|
None => {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.iter()
|
||||||
|
.map(|f| match f {
|
||||||
|
Variable::Char(_, c) => match c {
|
||||||
|
Some(c) => *c,
|
||||||
|
None => 0u8,
|
||||||
|
},
|
||||||
|
_ => 0u8,
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
_ => {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Variable::String(_, text) => match text {
|
||||||
|
Some(i) => i.as_bytes().to_vec(),
|
||||||
|
None => {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let stream = self.get_var(stream_var.clone(), locals).unwrap();
|
||||||
|
|
||||||
|
match stream {
|
||||||
|
Variable::OutStream(_, stream) => match stream {
|
||||||
|
Some(stream) => {
|
||||||
|
stream.lock().unwrap().write_all(&text).unwrap();
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
|
},
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
CommandType::Read => {}
|
CommandType::Read => {}
|
||||||
CommandType::ReadAll => {}
|
CommandType::ReadAll => {}
|
||||||
@ -677,16 +1139,35 @@ impl RunningScript {
|
|||||||
CommandType::ForMap => {}
|
CommandType::ForMap => {}
|
||||||
CommandType::ForList => {}
|
CommandType::ForList => {}
|
||||||
CommandType::While => {}
|
CommandType::While => {}
|
||||||
CommandType::UseFunc => {}
|
|
||||||
CommandType::OpenFileIn => {}
|
CommandType::OpenFileIn => {}
|
||||||
CommandType::OpenFileOut => {}
|
CommandType::OpenFileOut => {}
|
||||||
CommandType::OpenTcpConnection => {}
|
CommandType::OpenTcpConnection => {}
|
||||||
CommandType::OpenTcpListener => {}
|
CommandType::OpenTcpListener => {}
|
||||||
CommandType::HasOptional => {}
|
|
||||||
CommandType::WhenOptional => {}
|
|
||||||
CommandType::Sleep => {}
|
CommandType::Sleep => {}
|
||||||
|
CommandType::NewThread => {}
|
||||||
|
CommandType::UseFunc => {}
|
||||||
|
CommandType::Return => {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
CommandType::Equals => {}
|
||||||
|
CommandType::More => {}
|
||||||
|
CommandType::Less => {}
|
||||||
|
CommandType::And => {}
|
||||||
|
CommandType::Or => {}
|
||||||
|
CommandType::If => {}
|
||||||
|
CommandType::HasStr => {}
|
||||||
|
CommandType::HasItem => {}
|
||||||
|
CommandType::HasEntry => {}
|
||||||
|
CommandType::HasKey => {}
|
||||||
|
CommandType::HasValue => {}
|
||||||
|
CommandType::HasOptional => {}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for ele in temp_vars.clone() {
|
||||||
|
self.variables.remove(&ele);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exec_function(&mut self, function: Function, result_var: String, args: Vec<Variable>) {
|
pub fn exec_function(&mut self, function: Function, result_var: String, args: Vec<Variable>) {
|
||||||
@ -701,17 +1182,13 @@ impl RunningScript {
|
|||||||
Variable::empty_var(function.result_type).unwrap(),
|
Variable::empty_var(function.result_type).unwrap(),
|
||||||
);
|
);
|
||||||
|
|
||||||
for command in function.commands.clone() {
|
self.exec_commands(function.commands, false, &mut locals);
|
||||||
self.exec_command(command, false, &mut locals);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.variables
|
self.variables
|
||||||
.insert(result_var, locals.get("result").unwrap().clone());
|
.insert(result_var, locals.get("result").unwrap().clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(&mut self) {
|
pub fn run(&mut self) {
|
||||||
for command in self.commands.clone() {
|
self.exec_commands(self.commands.clone(), true, &mut HashMap::new());
|
||||||
self.exec_command(command, true, &mut HashMap::new());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
15
src/main.rs
15
src/main.rs
@ -1 +1,14 @@
|
|||||||
fn main() {}
|
use std::{
|
||||||
|
env::args,
|
||||||
|
fs,
|
||||||
|
io::{stdin, stdout},
|
||||||
|
};
|
||||||
|
|
||||||
|
use sustlang::{RunningScript, Script};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let script = Script::parse(fs::read_to_string("test.sus").unwrap());
|
||||||
|
let mut running_script = RunningScript::new(script);
|
||||||
|
running_script.set_standard_vars(args().collect(), Box::new(stdout()), Box::new(stdin()));
|
||||||
|
running_script.run()
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user