forked from n3tael/labast
		
	update 1.0.2
This commit is contained in:
		
							parent
							
								
									317fa500b8
								
							
						
					
					
						commit
						a6fbe841f1
					
				@ -1,5 +1,5 @@
 | 
				
			|||||||
# Labast
 | 
					# Labast
 | 
				
			||||||
A zero-dependencies Labaski interpreter written in Rust. Fully supports [Labashki specs 1.4.1](./SPECIFICATION.md).
 | 
					A zero-dependencies Labaski interpreter written in Rust. Fully supports Labashki specs 1.7.1.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Examples
 | 
					## Examples
 | 
				
			||||||
See `scripts` directory.
 | 
					See `scripts` directory.
 | 
				
			||||||
@ -1,51 +0,0 @@
 | 
				
			|||||||
# Labaski specification
 | 
					 | 
				
			||||||
Last update: 2024-02-05
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Программа состоит из команд в формате `ИНСТРУКЦИЯ АРГУМЕНТ` (assembler-like)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Аргумент всегда должен быть `uint16` (`unsigned short`, `u16`)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Все данные которые программа использует хранятся в стеке, сам стек это массив из этих `unsigned short`'ов
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Размер стека без разницы, но желательно минимум 256
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Выполнение программы начинается либо с начала файла, либо с лейбла 0, если он есть
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Почти каждая инструкция которые читает что-то стека должна POP'ать прочитаннное значение
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Если название инструкции начинается с #, то парсер программы должен прочитать аргумент к инструкции как строку(до первого пробела)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Инструкции
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| Инструкция  | Аргумент       | Описание                                                             |
 | 
					 | 
				
			||||||
|-------------|----------------|----------------------------------------------------------------------|
 | 
					 | 
				
			||||||
| PUSH        | `uint16`       | Добавить в стек                                                      |
 | 
					 | 
				
			||||||
| POP         | -              | Удалить из стека                                                     |
 | 
					 | 
				
			||||||
| DUP         | -              | Дублировать последнее значение в стеке                               |
 | 
					 | 
				
			||||||
| SWAP        | -              | Поменять местами последние 2 значения в стеке                        |
 | 
					 | 
				
			||||||
| ADD         | -              | Прибавление последних 2-х значений из стека                          |
 | 
					 | 
				
			||||||
| SUB         | -              | Вычитание последних 2-х значений из стека                            |
 | 
					 | 
				
			||||||
| MUL         | -              | Умножение последних 2-х значений из стека                            |
 | 
					 | 
				
			||||||
| DIV         | -              | Деление последних 2-х значений из стека                              |
 | 
					 | 
				
			||||||
| JMP         | `uint16` лейбл | Перейти к лейблу <имя>                                               |
 | 
					 | 
				
			||||||
| JNZ         | `uint16` лейбл | Перейти к лейблу <имя> если значение с верхушки стека не 0           |
 | 
					 | 
				
			||||||
| JZ          | `uint16` лейбл | Перейти к лейблу <имя> если значение с верхушки стека 0              |
 | 
					 | 
				
			||||||
| NOP         | -              | Ничего не делает                                                     |
 | 
					 | 
				
			||||||
| EXIT        | -              | Выход из программы с кодом 0                                         |
 | 
					 | 
				
			||||||
| PUTC        | -              | Вывести символ в консоль                                             |
 | 
					 | 
				
			||||||
| GETC        | -              | Получить символ с консоли, добавить символ в стек                    |
 | 
					 | 
				
			||||||
| MEOW        | -              | Принт, POP'ает со стека                                              |
 | 
					 | 
				
			||||||
| DUMP        | -              | Вывести весь стек в консоль, понятное дело не попает со стека        |
 | 
					 | 
				
			||||||
| SCAN        | -              | Сканирует ввод из консоли на `short`'ы и пушит в стек                |
 | 
					 | 
				
			||||||
| #EXEC       | arg            | Выполнить код из файла, указанного в аргументе*                      |
 | 
					 | 
				
			||||||
| ARGS        | `uint16`       | POP'ает аргумент значений с основного стека и пушит их в стек модуля, если указать аргумент 0, то нужное кол-во аргументов она возьмет(попнув) с оригинального стека  |
 | 
					 | 
				
			||||||
| SIZE        |                | Пушит в стек значение размера стека                                     |
 | 
					 | 
				
			||||||
| QUIT        | `uint16`       | Полностью завершает выполнение программы. Как аргумент попает exit-код. |
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
> \*путь относительно места вызова интерпретатора. Создает отдельный стек для модуля, но передает основной для того чтобы взять оттуда аргументы. После того как модуль выполнился, пушит весь стек модуля в основной.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Лейблы
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Лейблы могут быть только `unsigned short`'ами
 | 
					 | 
				
			||||||
От 0 (main-лейбл) до минимум 256
 | 
					 | 
				
			||||||
Если юзер высрал два лейбла с одинаковыми идентификаторами, то интерпретатор/компилятор должен выдать ошибку
 | 
					 | 
				
			||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
; written by Labashki developer - aeris
 | 
					; written by Labashki developer - aeris
 | 
				
			||||||
@ 0
 | 
					@ 0
 | 
				
			||||||
    #EXPR >++:+\
 | 
					    #expr >++:+\
 | 
				
			||||||
    DUMP
 | 
					    dump
 | 
				
			||||||
 | 
					
 | 
				
			||||||
; Expected output
 | 
					; Expected output
 | 
				
			||||||
;
 | 
					;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,30 +1,30 @@
 | 
				
			|||||||
PUSH 72  ; H
 | 
					push 72  ; H
 | 
				
			||||||
PUTC     ; Print to console
 | 
					putc     ; Print to console
 | 
				
			||||||
PUSH 101 ; e
 | 
					push 101 ; e
 | 
				
			||||||
PUTC
 | 
					putc
 | 
				
			||||||
PUSH 108 ; l
 | 
					push 108 ; l
 | 
				
			||||||
PUTC
 | 
					putc
 | 
				
			||||||
PUSH 108 ; l
 | 
					push 108 ; l
 | 
				
			||||||
PUTC
 | 
					putc
 | 
				
			||||||
PUSH 111 ; o
 | 
					push 111 ; o
 | 
				
			||||||
PUTC
 | 
					putc
 | 
				
			||||||
PUSH 32  ; <space>
 | 
					push 32  ; <space>
 | 
				
			||||||
PUTC
 | 
					putc
 | 
				
			||||||
PUSH 76  ; L
 | 
					push 76  ; L
 | 
				
			||||||
PUTC
 | 
					putc
 | 
				
			||||||
PUSH 97  ; a
 | 
					push 97  ; a
 | 
				
			||||||
PUTC
 | 
					putc
 | 
				
			||||||
PUSH 98  ; b
 | 
					push 98  ; b
 | 
				
			||||||
PUTC
 | 
					putc
 | 
				
			||||||
PUSH 97  ; a
 | 
					push 97  ; a
 | 
				
			||||||
PUTC
 | 
					putc
 | 
				
			||||||
PUSH 115 ; s
 | 
					push 115 ; s
 | 
				
			||||||
PUTC
 | 
					putc
 | 
				
			||||||
PUSH 104 ; h
 | 
					push 104 ; h
 | 
				
			||||||
PUTC
 | 
					putc
 | 
				
			||||||
PUSH 107 ; k
 | 
					push 107 ; k
 | 
				
			||||||
PUTC
 | 
					putc
 | 
				
			||||||
PUSH 105 ; i
 | 
					push 105 ; i
 | 
				
			||||||
PUTC
 | 
					putc
 | 
				
			||||||
PUSH 33  ; !
 | 
					push 33  ; !
 | 
				
			||||||
PUTC
 | 
					putc
 | 
				
			||||||
@ -1,20 +1,20 @@
 | 
				
			|||||||
@ 1
 | 
					@ 1
 | 
				
			||||||
  PUSH 115 ; s
 | 
					  push 115 ; s
 | 
				
			||||||
  PUTC
 | 
					  putc
 | 
				
			||||||
  PUSH 104 ; h
 | 
					  push 104 ; h
 | 
				
			||||||
  PUTC
 | 
					  putc
 | 
				
			||||||
  PUSH 107 ; k
 | 
					  push 107 ; k
 | 
				
			||||||
  PUTC
 | 
					  putc
 | 
				
			||||||
  PUSH 105 ; i
 | 
					  push 105 ; i
 | 
				
			||||||
  PUTC
 | 
					  putc
 | 
				
			||||||
  EXIT
 | 
					  exit
 | 
				
			||||||
@ 0
 | 
					@ 0
 | 
				
			||||||
  PUSH 76  ; L
 | 
					  push 76  ; L
 | 
				
			||||||
  PUTC
 | 
					  putc
 | 
				
			||||||
  PUSH 97  ; a
 | 
					  push 97  ; a
 | 
				
			||||||
  PUTC
 | 
					  putc
 | 
				
			||||||
  PUSH 98  ; b
 | 
					  push 98  ; b
 | 
				
			||||||
  PUTC
 | 
					  putc
 | 
				
			||||||
  PUSH 97  ; a
 | 
					  push 97  ; a
 | 
				
			||||||
  PUTC
 | 
					  putc
 | 
				
			||||||
  JMP 1
 | 
					  jmp 1
 | 
				
			||||||
@ -1,23 +1,23 @@
 | 
				
			|||||||
; Addition
 | 
					; Addition
 | 
				
			||||||
PUSH 2 ; a = 2
 | 
					push 2 ; a = 2
 | 
				
			||||||
PUSH 3 ; b = 2
 | 
					push 3 ; b = 2
 | 
				
			||||||
ADD    ; a + b
 | 
					add    ; a + b
 | 
				
			||||||
MEOW   ; = 5
 | 
					meow   ; = 5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
; Subtraction
 | 
					; Subtraction
 | 
				
			||||||
PUSH 9 ; a = 9
 | 
					push 9 ; a = 9
 | 
				
			||||||
PUSH 4 ; b = 4
 | 
					push 4 ; b = 4
 | 
				
			||||||
SUB    ; b - a
 | 
					sub    ; b - a
 | 
				
			||||||
MEOW   ; = 5
 | 
					meow   ; = 5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
; Multiplication
 | 
					; Multiplication
 | 
				
			||||||
PUSH 9 ; a = 9
 | 
					push 9 ; a = 9
 | 
				
			||||||
PUSH 5 ; b = 5
 | 
					push 5 ; b = 5
 | 
				
			||||||
MUL    ; b * a
 | 
					mul    ; b * a
 | 
				
			||||||
MEOW   ; = 45
 | 
					meow   ; = 45
 | 
				
			||||||
 | 
					
 | 
				
			||||||
; Division
 | 
					; Division
 | 
				
			||||||
PUSH 81; a = 81
 | 
					push 81; a = 81
 | 
				
			||||||
PUSH 9 ; b = 9
 | 
					push 9 ; b = 9
 | 
				
			||||||
DIV    ; b / a
 | 
					div    ; b / a
 | 
				
			||||||
MEOW   ; = 9
 | 
					meow   ; = 9
 | 
				
			||||||
@ -1,12 +1,12 @@
 | 
				
			|||||||
PUSH 76 ; L
 | 
					push 76 ; L
 | 
				
			||||||
PUTC
 | 
					putc
 | 
				
			||||||
PUSH 97 ; a
 | 
					push 97 ; a
 | 
				
			||||||
PUTC
 | 
					putc
 | 
				
			||||||
PUSH 98 ; b
 | 
					push 98 ; b
 | 
				
			||||||
PUTC
 | 
					putc
 | 
				
			||||||
PUSH 97 ; a
 | 
					push 97 ; a
 | 
				
			||||||
PUTC
 | 
					putc
 | 
				
			||||||
#EXEC second_part.lb
 | 
					#exec second_part.lb
 | 
				
			||||||
PUSH 33 ; !
 | 
					push 33 ; !
 | 
				
			||||||
PUTC
 | 
					putc
 | 
				
			||||||
QUIT
 | 
					quit
 | 
				
			||||||
@ -1,8 +1,8 @@
 | 
				
			|||||||
PUSH 115 ; s
 | 
					push 115 ; s
 | 
				
			||||||
PUTC
 | 
					putc
 | 
				
			||||||
PUSH 104 ; h
 | 
					push 104 ; h
 | 
				
			||||||
PUTC
 | 
					putc
 | 
				
			||||||
PUSH 107 ; k
 | 
					push 107 ; k
 | 
				
			||||||
PUTC
 | 
					putc
 | 
				
			||||||
PUSH 105 ; i
 | 
					push 105 ; i
 | 
				
			||||||
PUTC
 | 
					putc
 | 
				
			||||||
@ -1,11 +1,11 @@
 | 
				
			|||||||
; written by Labashki developer - aeris
 | 
					; written by Labashki developer - aeris
 | 
				
			||||||
@ 0
 | 
					@ 0
 | 
				
			||||||
    PUSH 2
 | 
					    push 2
 | 
				
			||||||
    PUSH 3
 | 
					    push 3
 | 
				
			||||||
    PUSH 4
 | 
					    push 4
 | 
				
			||||||
    PUSH 1
 | 
					    push 1
 | 
				
			||||||
    PICK
 | 
					    pick
 | 
				
			||||||
    DUMP
 | 
					    dump
 | 
				
			||||||
 | 
					
 | 
				
			||||||
; Expected output
 | 
					; Expected output
 | 
				
			||||||
;
 | 
					;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,9 +1,9 @@
 | 
				
			|||||||
@ 0
 | 
					@ 0
 | 
				
			||||||
    PUSH 1
 | 
					    push 1
 | 
				
			||||||
    PUSH 2
 | 
					    push 2
 | 
				
			||||||
    PUSH 3
 | 
					    push 3
 | 
				
			||||||
    SIZE
 | 
					    size
 | 
				
			||||||
    MEOW
 | 
					    meow
 | 
				
			||||||
 | 
					
 | 
				
			||||||
; Expected output
 | 
					; Expected output
 | 
				
			||||||
;
 | 
					;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
; Labashki standard library
 | 
					; Labashki standard library
 | 
				
			||||||
; Written by Labashki developer - aeris
 | 
					; Written by Labashki developer - aeris
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ARGS 0
 | 
					args 0
 | 
				
			||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
; Labashki standard library
 | 
					; Labashki standard library
 | 
				
			||||||
; Written by Labashki developer - aeris
 | 
					; Written by Labashki developer - aeris
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ARGS 3
 | 
					args 3
 | 
				
			||||||
@ -1,17 +1,17 @@
 | 
				
			|||||||
; Labashki standard library
 | 
					; Labashki standard library
 | 
				
			||||||
; Written by Labashki developer - aeris
 | 
					; Written by Labashki developer - aeris
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MAXSIZE
 | 
					maxsize
 | 
				
			||||||
ARGS 1 ; Насколько сварить носок
 | 
					args 1 ; Насколько сварить носок
 | 
				
			||||||
SUB
 | 
					sub
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ 1
 | 
					@ 1
 | 
				
			||||||
    JNZ 2
 | 
					    jnz 2
 | 
				
			||||||
    QUIT
 | 
					    quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ 2
 | 
					@ 2
 | 
				
			||||||
    #EXPR -
 | 
					    #expr -
 | 
				
			||||||
    PUSH -1
 | 
					    push -1
 | 
				
			||||||
    _UNIX_RANDOM
 | 
					    _unix_random
 | 
				
			||||||
    SWAP
 | 
					    swap
 | 
				
			||||||
    JMP 1
 | 
					    jmp 1
 | 
				
			||||||
@ -1,2 +1,2 @@
 | 
				
			|||||||
SIZE
 | 
					size
 | 
				
			||||||
#EXEC std\unix\ВАРЁНЫЙНОСОК.lb
 | 
					#exec std\unix\ВАРЁНЫЙНОСОК.lb
 | 
				
			||||||
							
								
								
									
										100
									
								
								src/execute.rs
									
									
									
									
									
								
							
							
						
						
									
										100
									
								
								src/execute.rs
									
									
									
									
									
								
							@ -1,4 +1,6 @@
 | 
				
			|||||||
use crate::{instructions, stack::Stack};
 | 
					use std::io::Read;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use crate::{errors::RunError, instructions, stack::{Instruction, Stack}};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn find_labels(stack: &mut Stack) {
 | 
					fn find_labels(stack: &mut Stack) {
 | 
				
			||||||
    while stack.program_counter < (stack.program.len() as u16) {
 | 
					    while stack.program_counter < (stack.program.len() as u16) {
 | 
				
			||||||
@ -29,62 +31,102 @@ fn find_labels(stack: &mut Stack) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn find_prefix_operators(instruction: &mut Instruction, memory: &mut Vec<u16>) {
 | 
				
			||||||
 | 
					    match instruction.name.chars().nth(0) {
 | 
				
			||||||
 | 
					        Some('|') => {
 | 
				
			||||||
 | 
					            instruction.name = instruction.name.chars().skip(1).collect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            instruction.data = memory.pop().expect(&format!("{}", RunError::MemoryEmpty));
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        Some('^') => {
 | 
				
			||||||
 | 
					            instruction.name = instruction.name.chars().skip(1).collect();
 | 
				
			||||||
 | 
					            //dbg!(&instruction);
 | 
				
			||||||
 | 
					            if instruction.name.chars().nth(0) != Some('#') {
 | 
				
			||||||
 | 
					                println!("{0} {1}", instruction.name, instruction.data.to_string());
 | 
				
			||||||
 | 
					            } else if instruction.arg.is_empty() {
 | 
				
			||||||
 | 
					                println!("{}", instruction.name);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                println!("{0} {1}", instruction.name, instruction.arg);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        _ => {}
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn execute(stack: &mut Stack, mut origin_stack: Option<&mut Stack>, mod_name: &String) {
 | 
					pub fn execute(stack: &mut Stack, mut origin_stack: Option<&mut Stack>, mod_name: &String) {
 | 
				
			||||||
    find_labels(stack);
 | 
					    find_labels(stack);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    while let Some(instruction) = stack.program.get(stack.program_counter as usize) {
 | 
					    while let Some(mut instruction) = stack.program.get_mut(stack.program_counter as usize) {
 | 
				
			||||||
        stack.program_counter += 1;
 | 
					        stack.program_counter += 1;
 | 
				
			||||||
        
 | 
					
 | 
				
			||||||
 | 
					        find_prefix_operators(&mut instruction, &mut stack.memory);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if instruction.name.starts_with('@') {
 | 
					        if instruction.name.starts_with('@') {
 | 
				
			||||||
            continue;
 | 
					            continue;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        match instruction.name.as_str() {
 | 
					        match instruction.name.as_str() {
 | 
				
			||||||
            // Stack operations
 | 
					            // Stack operations
 | 
				
			||||||
            "PUSH" => instructions::push::push(&mut stack.memory, &instruction.data),
 | 
					            "push" => instructions::push::push(&mut stack.memory, &instruction.data),
 | 
				
			||||||
            "PICK" => instructions::pick::pick(&mut stack.memory, &instruction.data),
 | 
					            "pick" => instructions::pick::pick(&mut stack.memory, &instruction.data),
 | 
				
			||||||
            "POP"  => instructions::pop::pop(&mut stack.memory),
 | 
					            "pop"  => instructions::pop::pop(&mut stack.memory),
 | 
				
			||||||
            "DUP"  => instructions::dup::dup(&mut stack.memory),
 | 
					            "dup"  => instructions::dup::dup(&mut stack.memory),
 | 
				
			||||||
            "SWAP" => instructions::swap::swap(&mut stack.memory),
 | 
					            "swap" => instructions::swap::swap(&mut stack.memory),
 | 
				
			||||||
            "MEOW" => instructions::meow::meow(&mut stack.memory),
 | 
					            "meow" => instructions::meow::meow(&mut stack.memory),
 | 
				
			||||||
            "DUMP" => instructions::dump::dump(&mut stack.memory),
 | 
					            "dump" => instructions::dump::dump(&mut stack.memory),
 | 
				
			||||||
            "SIZE" => instructions::size::size(&mut stack.memory),
 | 
					            "size" => instructions::size::size(&mut stack.memory),
 | 
				
			||||||
            "MAXSIZE" => instructions::maxsize::maxsize(&mut stack.memory),
 | 
					            "maxsize" => instructions::maxsize::maxsize(&mut stack.memory),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            "#EXPR" => instructions::expr::expr(&mut stack.memory, &instruction.arg),
 | 
					            "#expr" => instructions::expr::expr(&mut stack.memory, &instruction.arg),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Labels
 | 
					            // Labels
 | 
				
			||||||
            "JMP" => instructions::jmp::jmp(&mut stack.labels, &mut stack.program_counter, &instruction.data),
 | 
					            "jmp" => instructions::jmp::jmp(&mut stack.labels, &mut stack.program_counter, &instruction.data),
 | 
				
			||||||
            "JNZ" => instructions::jnz::jnz(&mut stack.memory, &mut stack.labels, &mut stack.program_counter, &instruction.data),
 | 
					            "jnz" => instructions::jnz::jnz(&mut stack.memory, &mut stack.labels, &mut stack.program_counter, &instruction.data),
 | 
				
			||||||
            "JZ"  => instructions::jz::jz(&mut stack.memory, &mut stack.labels, &mut stack.program_counter, &instruction.data),
 | 
					            "jz"  => instructions::jz::jz(&mut stack.memory, &mut stack.labels, &mut stack.program_counter, &instruction.data),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Math operations
 | 
					            // Math operations
 | 
				
			||||||
            "ADD" => instructions::add::add(&mut stack.memory),
 | 
					            "add" => instructions::add::add(&mut stack.memory),
 | 
				
			||||||
            "SUB" => instructions::sub::sub(&mut stack.memory),
 | 
					            "sub" => instructions::sub::sub(&mut stack.memory),
 | 
				
			||||||
            "MUL" => instructions::mul::mul(&mut stack.memory),
 | 
					            "mul" => instructions::mul::mul(&mut stack.memory),
 | 
				
			||||||
            "DIV" => instructions::div::div(&mut stack.memory),
 | 
					            "div" => instructions::div::div(&mut stack.memory),
 | 
				
			||||||
 | 
					            "mod" => instructions::modulo::modulo(&mut stack.memory),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            "and"   => instructions::and::and(&mut stack.memory),
 | 
				
			||||||
 | 
					            "or"    => instructions::or::or(&mut stack.memory),
 | 
				
			||||||
 | 
					            "xor"   => instructions::xor::xor(&mut stack.memory),
 | 
				
			||||||
 | 
					            "nand"  => instructions::nand::nand(&mut stack.memory),
 | 
				
			||||||
 | 
					            "band"  => instructions::band::band(&mut stack.memory),
 | 
				
			||||||
 | 
					            "bor"   => instructions::bor::bor(&mut stack.memory),
 | 
				
			||||||
 | 
					            "bxor"  => instructions::bxor::bxor(&mut stack.memory),
 | 
				
			||||||
 | 
					            "bnand" => instructions::bnand::bnand(&mut stack.memory),
 | 
				
			||||||
 | 
					            "not"   => instructions::not::not(&mut stack.memory),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Console operations
 | 
					            // Console operations
 | 
				
			||||||
            "PUTC" => instructions::putc::putc(&mut stack.memory),
 | 
					            "putc" => instructions::putc::putc(&mut stack.memory),
 | 
				
			||||||
            "GETC" => instructions::getc::getc(&mut stack.memory),
 | 
					            "getc" => instructions::getc::getc(&mut stack.memory),
 | 
				
			||||||
            "SCAN" => instructions::scan::scan(&mut stack.memory),
 | 
					            "scan" => instructions::scan::scan(&mut stack.memory),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Modules
 | 
					            // Modules
 | 
				
			||||||
            "ARGS"  => instructions::args::args(&mut stack.memory, &mut origin_stack, &instruction.data),
 | 
					            "args"  => instructions::args::args(&mut stack.memory, &mut origin_stack, &instruction.data),
 | 
				
			||||||
            "#EXEC" => instructions::exec::exec(stack, &instruction.arg.clone(), &mod_name),
 | 
					            "#exec" => {
 | 
				
			||||||
 | 
					                let arg = instruction.arg.clone();
 | 
				
			||||||
 | 
					                instructions::exec::exec(stack, &arg, &mod_name);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            #[cfg(target_family = "unix")] 
 | 
					            #[cfg(target_family = "unix")] 
 | 
				
			||||||
            "_UNIX_RANDOM" => instructions::_unix_random::_unix_random(&mut stack.memory),
 | 
					            "_unix_random" => instructions::_unix_random::_unix_random(&mut stack.memory),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // ?
 | 
					            // ?
 | 
				
			||||||
            "NOP"  => continue,
 | 
					            "nop"  => continue,
 | 
				
			||||||
            "EXIT" => instructions::exit::exit(&instruction.data),
 | 
					            "exit" => instructions::exit::exit(&instruction.data),
 | 
				
			||||||
            "QUIT" => std::process::exit(0),
 | 
					            "quit" => std::process::exit(0),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            _ => {
 | 
					            _ => {
 | 
				
			||||||
                eprintln!("Unknown instruction: {}", instruction.name);
 | 
					                eprintln!("Unknown instruction: {}", instruction.name);
 | 
				
			||||||
                std::process::exit(2);
 | 
					                std::process::exit(2);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        std::io::stdin().bytes();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										14
									
								
								src/instructions/and.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/instructions/and.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					use crate::errors::RunError;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn and(memory: &mut Vec<u16>) {
 | 
				
			||||||
 | 
					    let a: bool = memory.pop().expect(&format!("{}", RunError::MemoryEmpty)) == 1;
 | 
				
			||||||
 | 
					    let b: bool = memory.pop().expect(&format!("{}", RunError::MemoryEmpty)) == 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let c: u16 = if a && b {
 | 
				
			||||||
 | 
					        1
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        0
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memory.push(c);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										14
									
								
								src/instructions/band.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/instructions/band.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					use crate::errors::RunError;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn band(memory: &mut Vec<u16>) {
 | 
				
			||||||
 | 
					    let a: bool = memory.pop().expect(&format!("{}", RunError::MemoryEmpty)) == 1;
 | 
				
			||||||
 | 
					    let b: bool = memory.pop().expect(&format!("{}", RunError::MemoryEmpty)) == 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let c: u16 = if a & b {
 | 
				
			||||||
 | 
					        1
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        0
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memory.push(c);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										14
									
								
								src/instructions/bnand.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/instructions/bnand.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					use crate::errors::RunError;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn bnand(memory: &mut Vec<u16>) {
 | 
				
			||||||
 | 
					    let a: bool = memory.pop().expect(&format!("{}", RunError::MemoryEmpty)) == 1;
 | 
				
			||||||
 | 
					    let b: bool = memory.pop().expect(&format!("{}", RunError::MemoryEmpty)) == 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let c: u16 = if !(a & b) {
 | 
				
			||||||
 | 
					        1
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        0
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memory.push(c);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										14
									
								
								src/instructions/bor.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/instructions/bor.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					use crate::errors::RunError;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn bor(memory: &mut Vec<u16>) {
 | 
				
			||||||
 | 
					    let a: bool = memory.pop().expect(&format!("{}", RunError::MemoryEmpty)) == 1;
 | 
				
			||||||
 | 
					    let b: bool = memory.pop().expect(&format!("{}", RunError::MemoryEmpty)) == 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let c: u16 = if a | b {
 | 
				
			||||||
 | 
					        1
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        0
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memory.push(c);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										14
									
								
								src/instructions/bxor.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/instructions/bxor.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					use crate::errors::RunError;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn bxor(memory: &mut Vec<u16>) {
 | 
				
			||||||
 | 
					    let a: bool = memory.pop().expect(&format!("{}", RunError::MemoryEmpty)) == 1;
 | 
				
			||||||
 | 
					    let b: bool = memory.pop().expect(&format!("{}", RunError::MemoryEmpty)) == 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let c: u16 = if a ^ b {
 | 
				
			||||||
 | 
					        1
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        0
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memory.push(c);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -23,3 +23,13 @@ pub mod exit;
 | 
				
			|||||||
pub mod maxsize;
 | 
					pub mod maxsize;
 | 
				
			||||||
#[cfg(target_family = "unix")]
 | 
					#[cfg(target_family = "unix")]
 | 
				
			||||||
pub mod _unix_random;
 | 
					pub mod _unix_random;
 | 
				
			||||||
 | 
					pub mod modulo;
 | 
				
			||||||
 | 
					pub mod and;
 | 
				
			||||||
 | 
					pub mod or;
 | 
				
			||||||
 | 
					pub mod xor;
 | 
				
			||||||
 | 
					pub mod nand;
 | 
				
			||||||
 | 
					pub mod band;
 | 
				
			||||||
 | 
					pub mod bor;
 | 
				
			||||||
 | 
					pub mod bxor;
 | 
				
			||||||
 | 
					pub mod bnand;
 | 
				
			||||||
 | 
					pub mod not;
 | 
				
			||||||
							
								
								
									
										8
									
								
								src/instructions/modulo.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/instructions/modulo.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					use crate::errors::RunError;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn modulo(memory: &mut Vec<u16>) {
 | 
				
			||||||
 | 
					    let a: u16 = memory.pop().expect(&format!("{}", RunError::MemoryEmpty));
 | 
				
			||||||
 | 
					    let b: u16 = memory.pop().expect(&format!("{}", RunError::MemoryEmpty));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memory.push(b % a);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										14
									
								
								src/instructions/nand.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/instructions/nand.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					use crate::errors::RunError;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn nand(memory: &mut Vec<u16>) {
 | 
				
			||||||
 | 
					    let a: bool = memory.pop().expect(&format!("{}", RunError::MemoryEmpty)) == 1;
 | 
				
			||||||
 | 
					    let b: bool = memory.pop().expect(&format!("{}", RunError::MemoryEmpty)) == 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let c: u16 = if !(a && b) {
 | 
				
			||||||
 | 
					        1
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        0
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memory.push(c);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										13
									
								
								src/instructions/not.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/instructions/not.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					use crate::errors::RunError;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn not(memory: &mut Vec<u16>) {
 | 
				
			||||||
 | 
					    let a: bool = memory.pop().expect(&format!("{}", RunError::MemoryEmpty)) == 1;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    let c: u16 = if !a {
 | 
				
			||||||
 | 
					        1
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        0
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memory.push(c);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										14
									
								
								src/instructions/or.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/instructions/or.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					use crate::errors::RunError;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn or(memory: &mut Vec<u16>) {
 | 
				
			||||||
 | 
					    let a: bool = memory.pop().expect(&format!("{}", RunError::MemoryEmpty)) == 1;
 | 
				
			||||||
 | 
					    let b: bool = memory.pop().expect(&format!("{}", RunError::MemoryEmpty)) == 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let c: u16 = if a || b {
 | 
				
			||||||
 | 
					        1
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        0
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memory.push(c);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										14
									
								
								src/instructions/xor.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/instructions/xor.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					use crate::errors::RunError;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn xor(memory: &mut Vec<u16>) {
 | 
				
			||||||
 | 
					    let a: bool = memory.pop().expect(&format!("{}", RunError::MemoryEmpty)) == 1;
 | 
				
			||||||
 | 
					    let b: bool = memory.pop().expect(&format!("{}", RunError::MemoryEmpty)) == 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let c: u16 = if !a != !b {
 | 
				
			||||||
 | 
					        1
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        0
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memory.push(c);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										29
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								src/main.rs
									
									
									
									
									
								
							@ -1,4 +1,4 @@
 | 
				
			|||||||
use std::{env, fs};
 | 
					use std::{env, fs, io::{BufRead, Write}};
 | 
				
			||||||
use errors::RunError;
 | 
					use errors::RunError;
 | 
				
			||||||
use execute::execute;
 | 
					use execute::execute;
 | 
				
			||||||
use parse::parse;
 | 
					use parse::parse;
 | 
				
			||||||
@ -12,12 +12,33 @@ mod errors;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
fn main() {
 | 
					fn main() {
 | 
				
			||||||
    let args: Vec<String> = env::args().collect();
 | 
					    let args: Vec<String> = env::args().collect();
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    if args.len() < 2 {
 | 
					    if args.get(2) == Some(&String::from("-h"))
 | 
				
			||||||
        eprintln!("Usage: {0} [FILE]", args[0]);
 | 
					    || args.get(2) == Some(&String::from("--help")) {
 | 
				
			||||||
 | 
					        eprintln!("Usage: {0} [file]", args[0]);
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if args.len() < 2 {
 | 
				
			||||||
 | 
					        let mut stack = Stack::new();
 | 
				
			||||||
 | 
					        let mut line = String::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        loop {
 | 
				
			||||||
 | 
					            line.clear();
 | 
				
			||||||
 | 
					            stack.program.clear();
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            let stdin = std::io::stdin();
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            print!("> ");
 | 
				
			||||||
 | 
					            std::io::stdout().flush().expect("Cannot flush the buffer.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            stdin.lock().read_line(&mut line).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            parse(&mut stack, &line.trim());
 | 
				
			||||||
 | 
					            execute(&mut stack, None, &"inline".to_string());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let mut stack = Stack::new();
 | 
					    let mut stack = Stack::new();
 | 
				
			||||||
    let lines = fs::read_to_string(&args[1]).expect(&format!("{}", RunError::FailToReadFile));
 | 
					    let lines = fs::read_to_string(&args[1]).expect(&format!("{}", RunError::FailToReadFile));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user