forked from n3tael/labast
		
	изменен стиль кода, изменено расположение инструкций
This commit is contained in:
		
							parent
							
								
									061238db49
								
							
						
					
					
						commit
						48b53dc991
					
				@ -27,23 +27,34 @@ pub enum RunError {
 | 
				
			|||||||
    InvalidExpressionUnknownOperator(String),
 | 
					    InvalidExpressionUnknownOperator(String),
 | 
				
			||||||
    AttemptToInsertHashOrStringInst,
 | 
					    AttemptToInsertHashOrStringInst,
 | 
				
			||||||
    AttemptToInsertEmptyConst,
 | 
					    AttemptToInsertEmptyConst,
 | 
				
			||||||
    AttemptToInsertALabel
 | 
					    AttemptToInsertALabel,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Display for RunError {
 | 
					impl Display for RunError {
 | 
				
			||||||
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 | 
					    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 | 
				
			||||||
        match self {
 | 
					        match self {
 | 
				
			||||||
            RunError::RequestArgsInMainModule => write!(f, "Can't require arguments in the main module"),
 | 
					            RunError::RequestArgsInMainModule => {
 | 
				
			||||||
            RunError::ExecuteItself(mod_name) => write!(f, "Module {}: Can't execute itself", mod_name),
 | 
					                write!(f, "Can't require arguments in the main module")
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            RunError::ExecuteItself(mod_name) => {
 | 
				
			||||||
 | 
					                write!(f, "Module {}: Can't execute itself", mod_name)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            RunError::FailToReadFile => write!(f, "Unable to read file"),
 | 
					            RunError::FailToReadFile => write!(f, "Unable to read file"),
 | 
				
			||||||
            RunError::FailToGetCharFromConsole => write!(f, "Failed to get character from console"),
 | 
					            RunError::FailToGetCharFromConsole => write!(f, "Failed to get character from console"),
 | 
				
			||||||
            RunError::InvalidInputUShortInt => write!(f, "Invalid input. Please enter a valid unsigned short integer"),
 | 
					            RunError::InvalidInputUShortInt => write!(
 | 
				
			||||||
 | 
					                f,
 | 
				
			||||||
 | 
					                "Invalid input. Please enter a valid unsigned short integer"
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
            RunError::PickTooDeep => write!(f, "Picking too deep"),
 | 
					            RunError::PickTooDeep => write!(f, "Picking too deep"),
 | 
				
			||||||
            RunError::PickOutOfBounds => write!(f, "Trying to get a value out of bounds"),
 | 
					            RunError::PickOutOfBounds => write!(f, "Trying to get a value out of bounds"),
 | 
				
			||||||
            RunError::FailToReadLineFromConsole => write!(f, "Failed to read line from console"),
 | 
					            RunError::FailToReadLineFromConsole => write!(f, "Failed to read line from console"),
 | 
				
			||||||
            RunError::UnknownLabel(label_name) => write!(f, "Unknown label: {}", label_name),
 | 
					            RunError::UnknownLabel(label_name) => write!(f, "Unknown label: {}", label_name),
 | 
				
			||||||
            RunError::InvalidExpressionUnknownOperator(name) => write!(f, "Invalid expression: unknown operator '{}'", name),
 | 
					            RunError::InvalidExpressionUnknownOperator(name) => {
 | 
				
			||||||
            RunError::AttemptToInsertHashOrStringInst => write!(f, "Attempt to insert a hash/string-instruction"),
 | 
					                write!(f, "Invalid expression: unknown operator '{}'", name)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            RunError::AttemptToInsertHashOrStringInst => {
 | 
				
			||||||
 | 
					                write!(f, "Attempt to insert a hash/string-instruction")
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            RunError::AttemptToInsertEmptyConst => write!(f, "Attempt to insert an empty constant"),
 | 
					            RunError::AttemptToInsertEmptyConst => write!(f, "Attempt to insert an empty constant"),
 | 
				
			||||||
            RunError::AttemptToInsertALabel => write!(f, "Attempt to insert a label"),
 | 
					            RunError::AttemptToInsertALabel => write!(f, "Attempt to insert a label"),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -51,13 +62,17 @@ impl Display for RunError {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub enum ParseError {
 | 
					pub enum ParseError {
 | 
				
			||||||
    ArgumentNotRequired(String, usize, String)
 | 
					    ArgumentNotRequired(String, usize, String),
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Display for ParseError {
 | 
					impl Display for ParseError {
 | 
				
			||||||
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 | 
					    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 | 
				
			||||||
        match self {
 | 
					        match self {
 | 
				
			||||||
            ParseError::ArgumentNotRequired(name, line_number, line) => write!(f, "ParseError:\n{1} | {2}\nerror: string argument for {0} not required", name, line_number, line),
 | 
					            ParseError::ArgumentNotRequired(name, line_number, line) => write!(
 | 
				
			||||||
 | 
					                f,
 | 
				
			||||||
 | 
					                "ParseError:\n{1} | {2}\nerror: string argument for {0} not required",
 | 
				
			||||||
 | 
					                name, line_number, line
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										148
									
								
								src/execute.rs
									
									
									
									
									
								
							
							
						
						
									
										148
									
								
								src/execute.rs
									
									
									
									
									
								
							@ -1,10 +1,13 @@
 | 
				
			|||||||
use crate::{instructions, stack::{Instruction, Stack, StackVec}};
 | 
					use crate::{
 | 
				
			||||||
 | 
					    instructions,
 | 
				
			||||||
 | 
					    stack::{Instruction, Stack, StackVec},
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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) {
 | 
				
			||||||
        let label = &stack.program[stack.program_counter as usize];
 | 
					        let label = &stack.program[stack.program_counter as usize];
 | 
				
			||||||
        stack.program_counter += 1;
 | 
					        stack.program_counter += 1;
 | 
				
			||||||
        
 | 
					
 | 
				
			||||||
        if !label.name.starts_with('@') {
 | 
					        if !label.name.starts_with('@') {
 | 
				
			||||||
            continue;
 | 
					            continue;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -30,7 +33,7 @@ fn find_prefix_operators(instruction: &mut Instruction, memory: &mut StackVec) {
 | 
				
			|||||||
        Some('|') => {
 | 
					        Some('|') => {
 | 
				
			||||||
            instruction.name = instruction.name.chars().skip(1).collect();
 | 
					            instruction.name = instruction.name.chars().skip(1).collect();
 | 
				
			||||||
            instruction.data = memory.pop();
 | 
					            instruction.data = memory.pop();
 | 
				
			||||||
        },
 | 
					        }
 | 
				
			||||||
        Some('^') => {
 | 
					        Some('^') => {
 | 
				
			||||||
            instruction.name = instruction.name.chars().skip(1).collect();
 | 
					            instruction.name = instruction.name.chars().skip(1).collect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -60,84 +63,113 @@ pub fn execute(stack: &mut Stack, mut origin_stack: Option<&mut Stack>, mod_name
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        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::stack_manage::push(&mut stack.memory, instruction.data),
 | 
				
			||||||
            "pop"  => instructions::pop::pop(&mut stack.memory),
 | 
					            "pop" => instructions::stack_manage::pop(&mut stack.memory),
 | 
				
			||||||
            "dup"  => instructions::dup::dup(&mut stack.memory),
 | 
					            "dup" => instructions::stack_manage::dup(&mut stack.memory),
 | 
				
			||||||
            "swap" => instructions::swap::swap(&mut stack.memory),
 | 
					            "swap" => instructions::stack_manage::swap(&mut stack.memory),
 | 
				
			||||||
            "pick" => instructions::pick::pick(&mut stack.memory, instruction.data),
 | 
					            "pick" => instructions::stack_manage::pick(&mut stack.memory, instruction.data),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Math
 | 
					            // Math operations
 | 
				
			||||||
            "add" => instructions::add::add(&mut stack.memory),
 | 
					            "add" => instructions::math::add(&mut stack.memory),
 | 
				
			||||||
            "sub" => instructions::sub::sub(&mut stack.memory),
 | 
					            "sub" => instructions::math::sub(&mut stack.memory),
 | 
				
			||||||
            "mul" => instructions::mul::mul(&mut stack.memory),
 | 
					            "mul" => instructions::math::mul(&mut stack.memory),
 | 
				
			||||||
            "div" => instructions::div::div(&mut stack.memory),
 | 
					            "div" => instructions::math::div(&mut stack.memory),
 | 
				
			||||||
            "mod" => instructions::modulo::modulo(&mut stack.memory),
 | 
					            "mod" => instructions::math::modulo(&mut stack.memory),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Logic
 | 
					            // Logic
 | 
				
			||||||
            "and"   => instructions::and::and(&mut stack.memory),
 | 
					            "and" => instructions::logic::and(&mut stack.memory),
 | 
				
			||||||
            "or"    => instructions::or::or(&mut stack.memory),
 | 
					            "or" => instructions::logic::or(&mut stack.memory),
 | 
				
			||||||
            "xor"   => instructions::xor::xor(&mut stack.memory),
 | 
					            "xor" => instructions::logic::xor(&mut stack.memory),
 | 
				
			||||||
            "nand"  => instructions::nand::nand(&mut stack.memory),
 | 
					            "nand" => instructions::logic::nand(&mut stack.memory),
 | 
				
			||||||
            "not"   => instructions::not::not(&mut stack.memory),
 | 
					            "not" => instructions::logic::not(&mut stack.memory),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Bitwise
 | 
					            // Bitwise
 | 
				
			||||||
            "band"  => instructions::band::band(&mut stack.memory),
 | 
					            "band" => instructions::bitwise::band(&mut stack.memory),
 | 
				
			||||||
            "bor"   => instructions::bor::bor(&mut stack.memory),
 | 
					            "bor" => instructions::bitwise::bor(&mut stack.memory),
 | 
				
			||||||
            "bxor"  => instructions::bxor::bxor(&mut stack.memory),
 | 
					            "bxor" => instructions::bitwise::bxor(&mut stack.memory),
 | 
				
			||||||
            "bnand" => instructions::bnand::bnand(&mut stack.memory),
 | 
					            "bnand" => instructions::bitwise::bnand(&mut stack.memory),
 | 
				
			||||||
            "bnot"   => instructions::not::not(&mut stack.memory),
 | 
					            "bnot" => instructions::logic::not(&mut stack.memory),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Labels
 | 
					            // Flow-control
 | 
				
			||||||
            "jmp"  => instructions::jmp::jmp(&mut stack.labels, &mut stack.program_counter, instruction.data),
 | 
					            "jmp" => instructions::flow_control::jmp(
 | 
				
			||||||
            "rjmp" => instructions::rjmp::rjmp(&mut stack.memory, &mut stack.labels, &mut stack.program_counter),
 | 
					                &mut stack.labels,
 | 
				
			||||||
            "jnz"  => instructions::jnz::jnz(&mut stack.memory, &mut stack.labels, &mut stack.program_counter, instruction.data),
 | 
					                &mut stack.program_counter,
 | 
				
			||||||
            "jz"   => instructions::jz::jz(&mut stack.memory, &mut stack.labels, &mut stack.program_counter, instruction.data),
 | 
					                instruction.data,
 | 
				
			||||||
            "kjnz" => instructions::kjnz::kjnz(&mut stack.memory, &mut stack.labels, &mut stack.program_counter, instruction.data),
 | 
					            ),
 | 
				
			||||||
            "kjz"  => instructions::kjz::kjz(&mut stack.memory, &mut stack.labels, &mut stack.program_counter, instruction.data),
 | 
					            "rjmp" => instructions::specific::rjmp(
 | 
				
			||||||
 | 
					                &mut stack.memory,
 | 
				
			||||||
 | 
					                &mut stack.labels,
 | 
				
			||||||
 | 
					                &mut stack.program_counter,
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					            "jnz" => instructions::flow_control::jnz(
 | 
				
			||||||
 | 
					                &mut stack.memory,
 | 
				
			||||||
 | 
					                &mut stack.labels,
 | 
				
			||||||
 | 
					                &mut stack.program_counter,
 | 
				
			||||||
 | 
					                instruction.data,
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					            "jz" => instructions::flow_control::jz(
 | 
				
			||||||
 | 
					                &mut stack.memory,
 | 
				
			||||||
 | 
					                &mut stack.labels,
 | 
				
			||||||
 | 
					                &mut stack.program_counter,
 | 
				
			||||||
 | 
					                instruction.data,
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					            "kjnz" => instructions::flow_control::kjnz(
 | 
				
			||||||
 | 
					                &mut stack.memory,
 | 
				
			||||||
 | 
					                &mut stack.labels,
 | 
				
			||||||
 | 
					                &mut stack.program_counter,
 | 
				
			||||||
 | 
					                instruction.data,
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					            "kjz" => instructions::flow_control::kjz(
 | 
				
			||||||
 | 
					                &mut stack.memory,
 | 
				
			||||||
 | 
					                &mut stack.labels,
 | 
				
			||||||
 | 
					                &mut stack.program_counter,
 | 
				
			||||||
 | 
					                instruction.data,
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Input/Output
 | 
					            // Input/Output
 | 
				
			||||||
            "putc"     => instructions::putc::putc(&mut stack.memory),
 | 
					            "putc" => instructions::io::putc(&mut stack.memory),
 | 
				
			||||||
            "getc"     => instructions::getc::getc(&mut stack.memory),
 | 
					            "getc" => instructions::io::getc(&mut stack.memory),
 | 
				
			||||||
            "scan"     => instructions::scan::scan(&mut stack.memory),
 | 
					            "scan" => instructions::io::scan(&mut stack.memory),
 | 
				
			||||||
            "meow"     => instructions::meow::meow(&mut stack.memory),
 | 
					            "meow" => instructions::io::meow(&mut stack.memory),
 | 
				
			||||||
            "#print"   => instructions::print::print(instruction.arg.clone()),
 | 
					            "#print" => instructions::io::print(instruction.arg.clone()),
 | 
				
			||||||
            "$print"   => instructions::print::print(instruction.arg.clone()),
 | 
					            "$print" => instructions::io::print(instruction.arg.clone()),
 | 
				
			||||||
            "#println" => instructions::println::println(instruction.arg.clone()),
 | 
					            "#println" => instructions::io::println(instruction.arg.clone()),
 | 
				
			||||||
            "$println" => instructions::println::println(instruction.arg.clone()),
 | 
					            "$println" => instructions::io::println(instruction.arg.clone()),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Modules
 | 
					            // Modules
 | 
				
			||||||
            "args"  => instructions::args::args(&mut stack.memory, &mut origin_stack, instruction.data),
 | 
					            "args" => {
 | 
				
			||||||
 | 
					                instructions::modules::args(&mut stack.memory, &mut origin_stack, instruction.data)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            "#exec" => {
 | 
					            "#exec" => {
 | 
				
			||||||
                let arg = instruction.arg.clone();
 | 
					                let arg = instruction.arg.clone();
 | 
				
			||||||
                instructions::exec::exec(stack, arg, mod_name.clone())
 | 
					                instructions::modules::exec(stack, arg, mod_name.clone())
 | 
				
			||||||
            },
 | 
					            }
 | 
				
			||||||
            
 | 
					
 | 
				
			||||||
            // Self-modifying
 | 
					            // Self-modifying
 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            "#insert" => {
 | 
					            "#insert" => {
 | 
				
			||||||
                let arg = instruction.arg.clone();
 | 
					                let arg = instruction.arg.clone();
 | 
				
			||||||
                let data = instruction.data.clone();
 | 
					                let data = instruction.data.clone();
 | 
				
			||||||
                instructions::insert::insert(&mut stack.program, arg, data)
 | 
					                instructions::self_modify::insert(&mut stack.program, arg, data)
 | 
				
			||||||
            },
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Special
 | 
					            // Special
 | 
				
			||||||
            "dump"    => instructions::dump::dump(&mut stack.memory),
 | 
					            "dump" => instructions::special::dump(&mut stack.memory),
 | 
				
			||||||
            "size"    => instructions::size::size(&mut stack.memory),
 | 
					            "size" => instructions::special::size(&mut stack.memory),
 | 
				
			||||||
            "maxsize" => instructions::maxsize::maxsize(&mut stack.memory),
 | 
					            "maxsize" => instructions::special::maxsize(&mut stack.memory),
 | 
				
			||||||
            "#expr"   => instructions::expr::expr(&mut stack.memory, instruction.arg.clone()),
 | 
					            "#expr" => instructions::special::expr(&mut stack.memory, instruction.arg.clone()),
 | 
				
			||||||
            "nop"     => continue,
 | 
					            "nop" => continue,
 | 
				
			||||||
            "quit"    => break,
 | 
					            "quit" => break,
 | 
				
			||||||
            "exit"    => instructions::exit::exit(instruction.data),
 | 
					            "exit" => instructions::special::exit(instruction.data),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Platform-specific
 | 
					            // Platform-specific
 | 
				
			||||||
            #[cfg(target_family = "unix")] 
 | 
					            #[cfg(target_family = "unix")]
 | 
				
			||||||
            "_unix_random" => instructions::_unix_random::_unix_random(&mut stack.memory),
 | 
					            "_unix_random" => instructions::platform_specific::_unix_random(&mut stack.memory),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            #[cfg(not(target_family = "unix"))] 
 | 
					            #[cfg(not(target_family = "unix"))]
 | 
				
			||||||
            "_unix_random" => instructions::random::random(&mut stack.memory),
 | 
					            "_unix_random" => instructions::specific::random(&mut stack.memory),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Labast-specific
 | 
					            // Labast-specific
 | 
				
			||||||
            "random" => instructions::random::random(&mut stack.memory),
 | 
					            "random" => instructions::specific::random(&mut stack.memory),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            _ => {
 | 
					            _ => {
 | 
				
			||||||
                eprintln!("Unknown instruction: {}", instruction.name);
 | 
					                eprintln!("Unknown instruction: {}", instruction.name);
 | 
				
			||||||
 | 
				
			|||||||
@ -1,8 +0,0 @@
 | 
				
			|||||||
use crate::stack::StackVec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn add(memory: &mut StackVec) {
 | 
					 | 
				
			||||||
    let a: u16 = memory.pop();
 | 
					 | 
				
			||||||
    let b: u16 = memory.pop();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    memory.push(a + b);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,14 +0,0 @@
 | 
				
			|||||||
use crate::stack::StackVec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn and(memory: &mut StackVec) {
 | 
					 | 
				
			||||||
    let a: bool = memory.pop() == 1;
 | 
					 | 
				
			||||||
    let b: bool = memory.pop() == 1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let c: u16 = if a && b {
 | 
					 | 
				
			||||||
        1
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        0
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    memory.push(c);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,18 +0,0 @@
 | 
				
			|||||||
use crate::{errors::RunError, stack::{Stack, StackVec}};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn args(memory: &mut StackVec, origin_stack: &mut Option<&mut Stack>, data: u16) {
 | 
					 | 
				
			||||||
    if let Some(origin_stack) = origin_stack.as_mut() {
 | 
					 | 
				
			||||||
        let mut data = data;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if data == 0 {
 | 
					 | 
				
			||||||
            data = origin_stack.memory.pop();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        for _ in 0..data {
 | 
					 | 
				
			||||||
            memory.push(origin_stack.memory.pop());
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        eprintln!("{}", RunError::RequestArgsInMainModule);
 | 
					 | 
				
			||||||
        std::process::exit(2);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,8 +0,0 @@
 | 
				
			|||||||
use crate::stack::StackVec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn band(memory: &mut StackVec) {
 | 
					 | 
				
			||||||
    let a: u16 = memory.pop();
 | 
					 | 
				
			||||||
    let b: u16 = memory.pop();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    memory.push(a & b);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										29
									
								
								src/instructions/bitwise.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/instructions/bitwise.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,29 @@
 | 
				
			|||||||
 | 
					use crate::stack::StackVec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn band(memory: &mut StackVec) {
 | 
				
			||||||
 | 
					    let a: u16 = memory.pop();
 | 
				
			||||||
 | 
					    let b: u16 = memory.pop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memory.push(a & b);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn bor(memory: &mut StackVec) {
 | 
				
			||||||
 | 
					    let a: u16 = memory.pop();
 | 
				
			||||||
 | 
					    let b: u16 = memory.pop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memory.push(a | b);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn bxor(memory: &mut StackVec) {
 | 
				
			||||||
 | 
					    let a: u16 = memory.pop();
 | 
				
			||||||
 | 
					    let b: u16 = memory.pop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memory.push(a ^ b);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn bnand(memory: &mut StackVec) {
 | 
				
			||||||
 | 
					    let a: u16 = memory.pop();
 | 
				
			||||||
 | 
					    let b: u16 = memory.pop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memory.push(!(a & b));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,8 +0,0 @@
 | 
				
			|||||||
use crate::stack::StackVec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn bnand(memory: &mut StackVec) {
 | 
					 | 
				
			||||||
    let a: u16 = memory.pop();
 | 
					 | 
				
			||||||
    let b: u16 = memory.pop();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    memory.push(!(a & b));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,8 +0,0 @@
 | 
				
			|||||||
use crate::stack::StackVec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn bor(memory: &mut StackVec) {
 | 
					 | 
				
			||||||
    let a: u16 = memory.pop();
 | 
					 | 
				
			||||||
    let b: u16 = memory.pop();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    memory.push(a | b);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,8 +0,0 @@
 | 
				
			|||||||
use crate::stack::StackVec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn bxor(memory: &mut StackVec) {
 | 
					 | 
				
			||||||
    let a: u16 = memory.pop();
 | 
					 | 
				
			||||||
    let b: u16 = memory.pop();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    memory.push(a ^ b);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,8 +0,0 @@
 | 
				
			|||||||
use crate::stack::StackVec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn div(memory: &mut StackVec) {
 | 
					 | 
				
			||||||
    let a: u16 = memory.pop();
 | 
					 | 
				
			||||||
    let b: u16 = memory.pop();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    memory.push(b / a);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,12 +0,0 @@
 | 
				
			|||||||
use crate::stack::StackVec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn dump(memory: &mut StackVec) {
 | 
					 | 
				
			||||||
    if memory.is_empty() {
 | 
					 | 
				
			||||||
        println!("Stack is empty.");
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for (i, entry) in memory.iter().enumerate() {
 | 
					 | 
				
			||||||
        println!("{0}: {1}", i, entry);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,6 +0,0 @@
 | 
				
			|||||||
use crate::stack::StackVec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn dup(memory: &mut StackVec) {
 | 
					 | 
				
			||||||
    let data = memory.last();
 | 
					 | 
				
			||||||
    memory.push(data);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,3 +0,0 @@
 | 
				
			|||||||
pub fn exit(data: u16) {
 | 
					 | 
				
			||||||
    std::process::exit(data as i32);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										74
									
								
								src/instructions/flow_control.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								src/instructions/flow_control.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,74 @@
 | 
				
			|||||||
 | 
					use crate::{errors::RunError, stack::StackVec};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn jmp(labels: &mut [Option<i16>; 256], program_counter: &mut u16, data: u16) {
 | 
				
			||||||
 | 
					    if labels[data as usize].is_none() {
 | 
				
			||||||
 | 
					        eprintln!("{}", RunError::UnknownLabel(data));
 | 
				
			||||||
 | 
					        std::process::exit(2);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    *program_counter = (labels[data as usize].unwrap() - 1) as u16;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn jnz(
 | 
				
			||||||
 | 
					    memory: &mut StackVec,
 | 
				
			||||||
 | 
					    labels: &mut [Option<i16>; 256],
 | 
				
			||||||
 | 
					    program_counter: &mut u16,
 | 
				
			||||||
 | 
					    data: u16,
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
					    if labels[data as usize].is_none() {
 | 
				
			||||||
 | 
					        eprintln!("{}", RunError::UnknownLabel(data));
 | 
				
			||||||
 | 
					        std::process::exit(2);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if memory.pop() != 0 {
 | 
				
			||||||
 | 
					        *program_counter = (labels[data as usize].unwrap() - 1) as u16;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn jz(
 | 
				
			||||||
 | 
					    memory: &mut StackVec,
 | 
				
			||||||
 | 
					    labels: &mut [Option<i16>; 256],
 | 
				
			||||||
 | 
					    program_counter: &mut u16,
 | 
				
			||||||
 | 
					    data: u16,
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
					    if labels[data as usize].is_none() {
 | 
				
			||||||
 | 
					        eprintln!("{}", RunError::UnknownLabel(data));
 | 
				
			||||||
 | 
					        std::process::exit(2);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if memory.pop() == 0 {
 | 
				
			||||||
 | 
					        *program_counter = (labels[data as usize].unwrap() - 1) as u16;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn kjnz(
 | 
				
			||||||
 | 
					    memory: &mut StackVec,
 | 
				
			||||||
 | 
					    labels: &mut [Option<i16>; 256],
 | 
				
			||||||
 | 
					    program_counter: &mut u16,
 | 
				
			||||||
 | 
					    data: u16,
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
					    if labels[data as usize].is_none() {
 | 
				
			||||||
 | 
					        eprintln!("{}", RunError::UnknownLabel(data));
 | 
				
			||||||
 | 
					        std::process::exit(2);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if memory.last() != 0 {
 | 
				
			||||||
 | 
					        *program_counter = (labels[data as usize].unwrap() - 1) as u16;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn kjz(
 | 
				
			||||||
 | 
					    memory: &mut StackVec,
 | 
				
			||||||
 | 
					    labels: &mut [Option<i16>; 256],
 | 
				
			||||||
 | 
					    program_counter: &mut u16,
 | 
				
			||||||
 | 
					    data: u16,
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
					    if labels[data as usize].is_none() {
 | 
				
			||||||
 | 
					        eprintln!("{}", RunError::UnknownLabel(data));
 | 
				
			||||||
 | 
					        std::process::exit(2);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if memory.last() == 0 {
 | 
				
			||||||
 | 
					        *program_counter = (labels[data as usize].unwrap() - 1) as u16;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,13 +0,0 @@
 | 
				
			|||||||
use std::io::Read;
 | 
					 | 
				
			||||||
use crate::{errors::RunError, stack::StackVec};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn getc(memory: &mut StackVec) {
 | 
					 | 
				
			||||||
    let char = std::io::stdin()
 | 
					 | 
				
			||||||
        .bytes()
 | 
					 | 
				
			||||||
        .next()
 | 
					 | 
				
			||||||
        .and_then(|result| result.ok())
 | 
					 | 
				
			||||||
        .map(|byte| byte as u16)
 | 
					 | 
				
			||||||
        .expect(&format!("{}", RunError::FailToGetCharFromConsole));
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    memory.push(char);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										43
									
								
								src/instructions/io.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								src/instructions/io.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,43 @@
 | 
				
			|||||||
 | 
					use crate::{errors::RunError, stack::StackVec};
 | 
				
			||||||
 | 
					use std::io::Read;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn putc(memory: &mut StackVec) {
 | 
				
			||||||
 | 
					    print!("{}", memory.pop() as u8 as char);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn getc(memory: &mut StackVec) {
 | 
				
			||||||
 | 
					    let char = std::io::stdin()
 | 
				
			||||||
 | 
					        .bytes()
 | 
				
			||||||
 | 
					        .next()
 | 
				
			||||||
 | 
					        .and_then(|result| result.ok())
 | 
				
			||||||
 | 
					        .map(|byte| byte as u16)
 | 
				
			||||||
 | 
					        .expect(&format!("{}", RunError::FailToGetCharFromConsole));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memory.push(char);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn scan(memory: &mut StackVec) {
 | 
				
			||||||
 | 
					    let mut input = String::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::io::stdin()
 | 
				
			||||||
 | 
					        .read_line(&mut input)
 | 
				
			||||||
 | 
					        .expect(&format!("{}", RunError::FailToReadLineFromConsole));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let num = input
 | 
				
			||||||
 | 
					        .trim()
 | 
				
			||||||
 | 
					        .parse()
 | 
				
			||||||
 | 
					        .expect(&format!("{}", RunError::InvalidInputUShortInt));
 | 
				
			||||||
 | 
					    memory.push(num);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn meow(memory: &mut StackVec) {
 | 
				
			||||||
 | 
					    println!("{}", memory.pop());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn print(arg: String) {
 | 
				
			||||||
 | 
					    print!("{}", arg);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn println(arg: String) {
 | 
				
			||||||
 | 
					    println!("{}", arg);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,10 +0,0 @@
 | 
				
			|||||||
use crate::errors::RunError;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn jmp(labels: &mut [Option<i16>; 256], program_counter: &mut u16, data: u16) {
 | 
					 | 
				
			||||||
    if labels[data as usize].is_none() {
 | 
					 | 
				
			||||||
        eprintln!("{}", RunError::UnknownLabel(data));
 | 
					 | 
				
			||||||
        std::process::exit(2);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    *program_counter = (labels[data as usize].unwrap() - 1) as u16;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,12 +0,0 @@
 | 
				
			|||||||
use crate::{errors::RunError, stack::StackVec};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn jnz(memory: &mut StackVec, labels: &mut [Option<i16>; 256], program_counter: &mut u16, data: u16) {
 | 
					 | 
				
			||||||
    if labels[data as usize].is_none() {
 | 
					 | 
				
			||||||
        eprintln!("{}", RunError::UnknownLabel(data));
 | 
					 | 
				
			||||||
        std::process::exit(2);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if memory.pop() != 0 {
 | 
					 | 
				
			||||||
        *program_counter = (labels[data as usize].unwrap() - 1) as u16;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,12 +0,0 @@
 | 
				
			|||||||
use crate::{errors::RunError, stack::StackVec};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn jz(memory: &mut StackVec, labels: &mut [Option<i16>; 256], program_counter: &mut u16, data: u16) {
 | 
					 | 
				
			||||||
    if labels[data as usize].is_none() {
 | 
					 | 
				
			||||||
        eprintln!("{}", RunError::UnknownLabel(data));
 | 
					 | 
				
			||||||
        std::process::exit(2);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if memory.pop() == 0 {
 | 
					 | 
				
			||||||
        *program_counter = (labels[data as usize].unwrap() - 1) as u16;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,12 +0,0 @@
 | 
				
			|||||||
use crate::{errors::RunError, stack::StackVec};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn kjnz(memory: &mut StackVec, labels: &mut [Option<i16>; 256], program_counter: &mut u16, data: u16) {
 | 
					 | 
				
			||||||
    if labels[data as usize].is_none() {
 | 
					 | 
				
			||||||
        eprintln!("{}", RunError::UnknownLabel(data));
 | 
					 | 
				
			||||||
        std::process::exit(2);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if memory.last() != 0 {
 | 
					 | 
				
			||||||
        *program_counter = (labels[data as usize].unwrap() - 1) as u16;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,12 +0,0 @@
 | 
				
			|||||||
use crate::{errors::RunError, stack::StackVec};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn kjz(memory: &mut StackVec, labels: &mut [Option<i16>; 256], program_counter: &mut u16, data: u16) {
 | 
					 | 
				
			||||||
    if labels[data as usize].is_none() {
 | 
					 | 
				
			||||||
        eprintln!("{}", RunError::UnknownLabel(data));
 | 
					 | 
				
			||||||
        std::process::exit(2);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if memory.last() == 0 {
 | 
					 | 
				
			||||||
        *program_counter = (labels[data as usize].unwrap() - 1) as u16;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										45
									
								
								src/instructions/logic.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/instructions/logic.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,45 @@
 | 
				
			|||||||
 | 
					use crate::stack::StackVec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn and(memory: &mut StackVec) {
 | 
				
			||||||
 | 
					    let a: bool = memory.pop() == 1;
 | 
				
			||||||
 | 
					    let b: bool = memory.pop() == 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let c: u16 = if a && b { 1 } else { 0 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memory.push(c);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn or(memory: &mut StackVec) {
 | 
				
			||||||
 | 
					    let a: bool = memory.pop() == 1;
 | 
				
			||||||
 | 
					    let b: bool = memory.pop() == 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let c: u16 = if a || b { 1 } else { 0 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memory.push(c);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn xor(memory: &mut StackVec) {
 | 
				
			||||||
 | 
					    let a: bool = memory.pop() == 1;
 | 
				
			||||||
 | 
					    let b: bool = memory.pop() == 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let c: u16 = if !a != !b { 1 } else { 0 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memory.push(c);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn nand(memory: &mut StackVec) {
 | 
				
			||||||
 | 
					    let a: bool = memory.pop() == 1;
 | 
				
			||||||
 | 
					    let b: bool = memory.pop() == 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let c: u16 = if !(a && b) { 1 } else { 0 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memory.push(c);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn not(memory: &mut StackVec) {
 | 
				
			||||||
 | 
					    let a: bool = memory.pop() == 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let c: u16 = if !a { 1 } else { 0 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memory.push(c);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										36
									
								
								src/instructions/math.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/instructions/math.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					use crate::stack::StackVec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn add(memory: &mut StackVec) {
 | 
				
			||||||
 | 
					    let a: u16 = memory.pop();
 | 
				
			||||||
 | 
					    let b: u16 = memory.pop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memory.push(a + b);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn sub(memory: &mut StackVec) {
 | 
				
			||||||
 | 
					    let a: u16 = memory.pop();
 | 
				
			||||||
 | 
					    let b: u16 = memory.pop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memory.push(b - a);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn mul(memory: &mut StackVec) {
 | 
				
			||||||
 | 
					    let a: u16 = memory.pop();
 | 
				
			||||||
 | 
					    let b: u16 = memory.pop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memory.push(b * a);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn div(memory: &mut StackVec) {
 | 
				
			||||||
 | 
					    let a: u16 = memory.pop();
 | 
				
			||||||
 | 
					    let b: u16 = memory.pop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memory.push(b / a);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn modulo(memory: &mut StackVec) {
 | 
				
			||||||
 | 
					    let a: u16 = memory.pop();
 | 
				
			||||||
 | 
					    let b: u16 = memory.pop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memory.push(b % a);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,5 +0,0 @@
 | 
				
			|||||||
use crate::stack::StackVec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn maxsize(memory: &mut StackVec) {
 | 
					 | 
				
			||||||
    memory.push(memory.size() as u16);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,5 +0,0 @@
 | 
				
			|||||||
use crate::stack::StackVec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn meow(memory: &mut StackVec) {
 | 
					 | 
				
			||||||
    println!("{}", memory.pop());
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,42 +1,11 @@
 | 
				
			|||||||
pub mod push;
 | 
					pub mod bitwise;
 | 
				
			||||||
pub mod pop;
 | 
					pub mod flow_control;
 | 
				
			||||||
pub mod dup;
 | 
					pub mod io;
 | 
				
			||||||
pub mod swap;
 | 
					pub mod logic;
 | 
				
			||||||
pub mod add;
 | 
					pub mod math;
 | 
				
			||||||
pub mod sub;
 | 
					pub mod modules;
 | 
				
			||||||
pub mod mul;
 | 
					pub mod platform_specific;
 | 
				
			||||||
pub mod div;
 | 
					pub mod self_modify;
 | 
				
			||||||
pub mod jmp;
 | 
					pub mod special;
 | 
				
			||||||
pub mod jnz;
 | 
					pub mod specific;
 | 
				
			||||||
pub mod jz;
 | 
					pub mod stack_manage;
 | 
				
			||||||
pub mod pick;
 | 
					 | 
				
			||||||
pub mod putc;
 | 
					 | 
				
			||||||
pub mod getc;
 | 
					 | 
				
			||||||
pub mod meow;
 | 
					 | 
				
			||||||
pub mod dump;
 | 
					 | 
				
			||||||
pub mod scan;
 | 
					 | 
				
			||||||
pub mod exec;
 | 
					 | 
				
			||||||
pub mod args;
 | 
					 | 
				
			||||||
pub mod expr;
 | 
					 | 
				
			||||||
pub mod size;
 | 
					 | 
				
			||||||
pub mod exit;
 | 
					 | 
				
			||||||
pub mod maxsize;
 | 
					 | 
				
			||||||
#[cfg(target_family = "unix")]
 | 
					 | 
				
			||||||
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;
 | 
					 | 
				
			||||||
pub mod kjnz;
 | 
					 | 
				
			||||||
pub mod kjz;
 | 
					 | 
				
			||||||
pub mod print;
 | 
					 | 
				
			||||||
pub mod println;
 | 
					 | 
				
			||||||
pub mod insert;
 | 
					 | 
				
			||||||
pub mod random;
 | 
					 | 
				
			||||||
pub mod rjmp;
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,22 @@
 | 
				
			|||||||
 | 
					use crate::{errors::RunError, execute, parse, stack::StackVec, Stack};
 | 
				
			||||||
use std::fs;
 | 
					use std::fs;
 | 
				
			||||||
use crate::{parse, execute, Stack, errors::RunError};
 | 
					
 | 
				
			||||||
 | 
					pub fn args(memory: &mut StackVec, origin_stack: &mut Option<&mut Stack>, data: u16) {
 | 
				
			||||||
 | 
					    if let Some(origin_stack) = origin_stack.as_mut() {
 | 
				
			||||||
 | 
					        let mut data = data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if data == 0 {
 | 
				
			||||||
 | 
					            data = origin_stack.memory.pop();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for _ in 0..data {
 | 
				
			||||||
 | 
					            memory.push(origin_stack.memory.pop());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        eprintln!("{}", RunError::RequestArgsInMainModule);
 | 
				
			||||||
 | 
					        std::process::exit(2);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn exec(mut stack: &mut Stack, arg: String, mod_name: String) {
 | 
					pub fn exec(mut stack: &mut Stack, arg: String, mod_name: String) {
 | 
				
			||||||
    if mod_name == arg {
 | 
					    if mod_name == arg {
 | 
				
			||||||
@ -16,4 +33,4 @@ pub fn exec(mut stack: &mut Stack, arg: String, mod_name: String) {
 | 
				
			|||||||
    for item in temp_stack.memory.iter() {
 | 
					    for item in temp_stack.memory.iter() {
 | 
				
			||||||
        stack.memory.push(*item);
 | 
					        stack.memory.push(*item);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -1,8 +0,0 @@
 | 
				
			|||||||
use crate::stack::StackVec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn modulo(memory: &mut StackVec) {
 | 
					 | 
				
			||||||
    let a: u16 = memory.pop();
 | 
					 | 
				
			||||||
    let b: u16 = memory.pop();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    memory.push(b % a);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,8 +0,0 @@
 | 
				
			|||||||
use crate::stack::StackVec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn mul(memory: &mut StackVec) {
 | 
					 | 
				
			||||||
    let a: u16 = memory.pop();
 | 
					 | 
				
			||||||
    let b: u16 = memory.pop();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    memory.push(b * a);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,14 +0,0 @@
 | 
				
			|||||||
use crate::stack::StackVec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn nand(memory: &mut StackVec) {
 | 
					 | 
				
			||||||
    let a: bool = memory.pop() == 1;
 | 
					 | 
				
			||||||
    let b: bool = memory.pop() == 1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let c: u16 = if !(a && b) {
 | 
					 | 
				
			||||||
        1
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        0
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    memory.push(c);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,13 +0,0 @@
 | 
				
			|||||||
use crate::stack::StackVec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn not(memory: &mut StackVec) {
 | 
					 | 
				
			||||||
    let a: bool = memory.pop() == 1;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    let c: u16 = if !a {
 | 
					 | 
				
			||||||
        1
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        0
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    memory.push(c);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,14 +0,0 @@
 | 
				
			|||||||
use crate::stack::StackVec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn or(memory: &mut StackVec) {
 | 
					 | 
				
			||||||
    let a: bool = memory.pop() == 1;
 | 
					 | 
				
			||||||
    let b: bool = memory.pop() == 1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let c: u16 = if a || b {
 | 
					 | 
				
			||||||
        1
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        0
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    memory.push(c);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,11 +0,0 @@
 | 
				
			|||||||
use crate::{errors::RunError, stack::StackVec};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn pick(memory: &mut StackVec, data: u16) {
 | 
					 | 
				
			||||||
    if data > memory.len() as u16 {
 | 
					 | 
				
			||||||
        eprintln!("{}", RunError::PickTooDeep);
 | 
					 | 
				
			||||||
        std::process::exit(2);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let arg = memory.pop();
 | 
					 | 
				
			||||||
    memory.push(*memory.get(memory.len() - (arg as usize) - 1).expect(&format!("{}", RunError::PickOutOfBounds)));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,6 +1,9 @@
 | 
				
			|||||||
use std::fs::File;
 | 
					#[cfg(target_family = "unix")]
 | 
				
			||||||
use std::io::Read;
 | 
					 | 
				
			||||||
use crate::stack::StackVec;
 | 
					use crate::stack::StackVec;
 | 
				
			||||||
 | 
					#[cfg(target_family = "unix")]
 | 
				
			||||||
 | 
					use std::fs::File;
 | 
				
			||||||
 | 
					#[cfg(target_family = "unix")]
 | 
				
			||||||
 | 
					use std::io::Read;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[cfg(target_family = "unix")]
 | 
					#[cfg(target_family = "unix")]
 | 
				
			||||||
pub fn _unix_random(memory: &mut StackVec) {
 | 
					pub fn _unix_random(memory: &mut StackVec) {
 | 
				
			||||||
@ -11,4 +14,4 @@ pub fn _unix_random(memory: &mut StackVec) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    let data = memory.pop();
 | 
					    let data = memory.pop();
 | 
				
			||||||
    memory.push((u16::from_ne_bytes(buffer)) % (data - 1));
 | 
					    memory.push((u16::from_ne_bytes(buffer)) % (data - 1));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -1,5 +0,0 @@
 | 
				
			|||||||
use crate::stack::StackVec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn pop(memory: &mut StackVec) {
 | 
					 | 
				
			||||||
    memory.pop();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,3 +0,0 @@
 | 
				
			|||||||
pub fn print(arg: String) {
 | 
					 | 
				
			||||||
    print!("{}", arg);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,3 +0,0 @@
 | 
				
			|||||||
pub fn println(arg: String) {
 | 
					 | 
				
			||||||
    println!("{}", arg);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,5 +0,0 @@
 | 
				
			|||||||
use crate::stack::StackVec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn push(memory: &mut StackVec, data: u16) {
 | 
					 | 
				
			||||||
    memory.push(data);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,5 +0,0 @@
 | 
				
			|||||||
use crate::stack::StackVec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn putc(memory: &mut StackVec) {
 | 
					 | 
				
			||||||
    print!("{}", memory.pop() as u8 as char);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,7 +0,0 @@
 | 
				
			|||||||
use fastrand;
 | 
					 | 
				
			||||||
use crate::stack::StackVec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn random(memory: &mut StackVec) {
 | 
					 | 
				
			||||||
    let data = memory.pop();
 | 
					 | 
				
			||||||
    memory.push(fastrand::u16(..) % (data - 1));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,9 +0,0 @@
 | 
				
			|||||||
use crate::{errors::RunError, stack::StackVec};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn rjmp(memory: &mut StackVec, labels: &mut [Option<i16>; 256], program_counter: &mut u16) {
 | 
					 | 
				
			||||||
    let start = memory.pop() as usize;
 | 
					 | 
				
			||||||
    let end   = memory.pop() as usize;
 | 
					 | 
				
			||||||
    let rand  = fastrand::usize(start..end + 1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    *program_counter = (labels[rand].expect(&format!("{}", RunError::UnknownLabel(rand as u16))) - 1) as u16;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,10 +0,0 @@
 | 
				
			|||||||
use crate::{errors::RunError, stack::StackVec};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn scan(memory: &mut StackVec) {
 | 
					 | 
				
			||||||
    let mut input = String::new();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    std::io::stdin().read_line(&mut input).expect(&format!("{}", RunError::FailToReadLineFromConsole));
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
    let num = input.trim().parse().expect(&format!("{}", RunError::InvalidInputUShortInt));
 | 
					 | 
				
			||||||
    memory.push(num);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -2,25 +2,25 @@ use crate::{errors::RunError, stack::Instruction};
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
pub fn insert(program: &mut Vec<Instruction>, arg: String, data: u16) {
 | 
					pub fn insert(program: &mut Vec<Instruction>, arg: String, data: u16) {
 | 
				
			||||||
    let args: Vec<char> = arg.chars().collect();
 | 
					    let args: Vec<char> = arg.chars().collect();
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    if args[0] == '#' || args[0] == '$' {
 | 
					    if args[0] == '#' || args[0] == '$' {
 | 
				
			||||||
        eprintln!("{}", RunError::AttemptToInsertHashOrStringInst);
 | 
					        eprintln!("{}", RunError::AttemptToInsertHashOrStringInst);
 | 
				
			||||||
        std::process::exit(2);
 | 
					        std::process::exit(2);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    if args[0] == '\n' {
 | 
					    if args[0] == '\n' {
 | 
				
			||||||
        eprintln!("{}", RunError::AttemptToInsertEmptyConst);
 | 
					        eprintln!("{}", RunError::AttemptToInsertEmptyConst);
 | 
				
			||||||
        std::process::exit(2);
 | 
					        std::process::exit(2);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    if args[0] == '@' || args[1] == ' ' {
 | 
					    if args[0] == '@' || args[1] == ' ' {
 | 
				
			||||||
        eprintln!("{}", RunError::AttemptToInsertALabel);
 | 
					        eprintln!("{}", RunError::AttemptToInsertALabel);
 | 
				
			||||||
        std::process::exit(2);
 | 
					        std::process::exit(2);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    program.push(Instruction {
 | 
					    program.push(Instruction {
 | 
				
			||||||
        name:  arg.to_string(),
 | 
					        name: arg.to_string(),
 | 
				
			||||||
        arg:  "\n".to_string(),
 | 
					        arg: "\n".to_string(),
 | 
				
			||||||
        data
 | 
					        data,
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -1,5 +0,0 @@
 | 
				
			|||||||
use crate::stack::StackVec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn size(memory: &mut StackVec) {
 | 
					 | 
				
			||||||
    memory.push(memory.len() as u16);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,5 +1,24 @@
 | 
				
			|||||||
use crate::{errors::RunError, stack::StackVec};
 | 
					use crate::{errors::RunError, stack::StackVec};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn dump(memory: &mut StackVec) {
 | 
				
			||||||
 | 
					    if memory.is_empty() {
 | 
				
			||||||
 | 
					        println!("Stack is empty.");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i, entry) in memory.iter().enumerate() {
 | 
				
			||||||
 | 
					        println!("{0}: {1}", i, entry);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn size(memory: &mut StackVec) {
 | 
				
			||||||
 | 
					    memory.push(memory.len() as u16);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn maxsize(memory: &mut StackVec) {
 | 
				
			||||||
 | 
					    memory.push(memory.size() as u16);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn expr(memory: &mut StackVec, arg: String) {
 | 
					pub fn expr(memory: &mut StackVec, arg: String) {
 | 
				
			||||||
    for code in arg.chars() {
 | 
					    for code in arg.chars() {
 | 
				
			||||||
        match code {
 | 
					        match code {
 | 
				
			||||||
@ -12,7 +31,7 @@ pub fn expr(memory: &mut StackVec, arg: String) {
 | 
				
			|||||||
            '\\' => {
 | 
					            '\\' => {
 | 
				
			||||||
                let ax = memory.pop();
 | 
					                let ax = memory.pop();
 | 
				
			||||||
                let ax2 = memory.pop();
 | 
					                let ax2 = memory.pop();
 | 
				
			||||||
                
 | 
					
 | 
				
			||||||
                memory.push(ax);
 | 
					                memory.push(ax);
 | 
				
			||||||
                memory.push(ax2);
 | 
					                memory.push(ax2);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -31,4 +50,8 @@ pub fn expr(memory: &mut StackVec, arg: String) {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn exit(data: u16) {
 | 
				
			||||||
 | 
					    std::process::exit(data as i32);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										16
									
								
								src/instructions/specific.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/instructions/specific.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					use crate::{errors::RunError, stack::StackVec};
 | 
				
			||||||
 | 
					use fastrand;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn random(memory: &mut StackVec) {
 | 
				
			||||||
 | 
					    let data = memory.pop();
 | 
				
			||||||
 | 
					    memory.push(fastrand::u16(..) % (data - 1));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn rjmp(memory: &mut StackVec, labels: &mut [Option<i16>; 256], program_counter: &mut u16) {
 | 
				
			||||||
 | 
					    let start = memory.pop() as usize;
 | 
				
			||||||
 | 
					    let end = memory.pop() as usize;
 | 
				
			||||||
 | 
					    let rand = fastrand::usize(start..end + 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    *program_counter =
 | 
				
			||||||
 | 
					        (labels[rand].expect(&format!("{}", RunError::UnknownLabel(rand as u16))) - 1) as u16;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										36
									
								
								src/instructions/stack_manage.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/instructions/stack_manage.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					use crate::{errors::RunError, stack::StackVec};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn push(memory: &mut StackVec, data: u16) {
 | 
				
			||||||
 | 
					    memory.push(data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn pop(memory: &mut StackVec) {
 | 
				
			||||||
 | 
					    memory.pop();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn dup(memory: &mut StackVec) {
 | 
				
			||||||
 | 
					    let data = memory.last();
 | 
				
			||||||
 | 
					    memory.push(data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn swap(memory: &mut StackVec) {
 | 
				
			||||||
 | 
					    let a: u16 = memory.pop();
 | 
				
			||||||
 | 
					    let b: u16 = memory.pop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memory.push(a);
 | 
				
			||||||
 | 
					    memory.push(b);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn pick(memory: &mut StackVec, data: u16) {
 | 
				
			||||||
 | 
					    if data > memory.len() as u16 {
 | 
				
			||||||
 | 
					        eprintln!("{}", RunError::PickTooDeep);
 | 
				
			||||||
 | 
					        std::process::exit(2);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let arg = memory.pop();
 | 
				
			||||||
 | 
					    memory.push(
 | 
				
			||||||
 | 
					        *memory
 | 
				
			||||||
 | 
					            .get(memory.len() - (arg as usize) - 1)
 | 
				
			||||||
 | 
					            .expect(&format!("{}", RunError::PickOutOfBounds)),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,8 +0,0 @@
 | 
				
			|||||||
use crate::stack::StackVec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn sub(memory: &mut StackVec) {
 | 
					 | 
				
			||||||
    let a: u16 = memory.pop();
 | 
					 | 
				
			||||||
    let b: u16 = memory.pop();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    memory.push(b - a);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,9 +0,0 @@
 | 
				
			|||||||
use crate::stack::StackVec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn swap(memory: &mut StackVec) {
 | 
					 | 
				
			||||||
    let a: u16 = memory.pop();
 | 
					 | 
				
			||||||
    let b: u16 = memory.pop();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    memory.push(a);
 | 
					 | 
				
			||||||
    memory.push(b);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,14 +0,0 @@
 | 
				
			|||||||
use crate::stack::StackVec;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn xor(memory: &mut StackVec) {
 | 
					 | 
				
			||||||
    let a: bool = memory.pop() == 1;
 | 
					 | 
				
			||||||
    let b: bool = memory.pop() == 1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let c: u16 = if !a != !b {
 | 
					 | 
				
			||||||
        1
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
        0
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    memory.push(c);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										44
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								src/main.rs
									
									
									
									
									
								
							@ -1,15 +1,18 @@
 | 
				
			|||||||
use std::{fs, io::{BufRead, Write}};
 | 
					use std::{
 | 
				
			||||||
 | 
					    fs,
 | 
				
			||||||
 | 
					    io::{BufRead, Write},
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use errors::RunError;
 | 
					use errors::RunError;
 | 
				
			||||||
use execute::execute;
 | 
					use execute::execute;
 | 
				
			||||||
use parse::parse;
 | 
					use parse::parse;
 | 
				
			||||||
use stack::Stack;
 | 
					use stack::Stack;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
mod stack;
 | 
					mod errors;
 | 
				
			||||||
mod parse;
 | 
					 | 
				
			||||||
mod execute;
 | 
					mod execute;
 | 
				
			||||||
mod instructions;
 | 
					mod instructions;
 | 
				
			||||||
mod errors;
 | 
					mod parse;
 | 
				
			||||||
 | 
					mod stack;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const HELP: &str = "\
 | 
					const HELP: &str = "\
 | 
				
			||||||
labast - Labaski interpreter written in Rust.
 | 
					labast - Labaski interpreter written in Rust.
 | 
				
			||||||
@ -39,9 +42,9 @@ fn main() {
 | 
				
			|||||||
        loop {
 | 
					        loop {
 | 
				
			||||||
            line.clear();
 | 
					            line.clear();
 | 
				
			||||||
            stack.program.clear();
 | 
					            stack.program.clear();
 | 
				
			||||||
            
 | 
					
 | 
				
			||||||
            let stdin = std::io::stdin();
 | 
					            let stdin = std::io::stdin();
 | 
				
			||||||
            
 | 
					
 | 
				
			||||||
            print!("> ");
 | 
					            print!("> ");
 | 
				
			||||||
            std::io::stdout().flush().expect("Cannot flush the buffer.");
 | 
					            std::io::stdout().flush().expect("Cannot flush the buffer.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -55,7 +58,17 @@ fn main() {
 | 
				
			|||||||
        let lines = fs::read_to_string(&input).expect(&format!("{}", RunError::FailToReadFile));
 | 
					        let lines = fs::read_to_string(&input).expect(&format!("{}", RunError::FailToReadFile));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        parse(&mut stack, &lines);
 | 
					        parse(&mut stack, &lines);
 | 
				
			||||||
        execute(&mut stack, None, String::from(input.file_name().expect("Failed to read file name.").to_str().expect("Failed to convert file name to string")));
 | 
					        execute(
 | 
				
			||||||
 | 
					            &mut stack,
 | 
				
			||||||
 | 
					            None,
 | 
				
			||||||
 | 
					            String::from(
 | 
				
			||||||
 | 
					                input
 | 
				
			||||||
 | 
					                    .file_name()
 | 
				
			||||||
 | 
					                    .expect("Failed to read file name.")
 | 
				
			||||||
 | 
					                    .to_str()
 | 
				
			||||||
 | 
					                    .expect("Failed to convert file name to string"),
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -74,12 +87,17 @@ fn parse_args() -> Result<AppArgs, pico_args::Error> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if pargs.contains(["-v", "--version"]) {
 | 
					    if pargs.contains(["-v", "--version"]) {
 | 
				
			||||||
        println!("labast version {}", option_env!("CARGO_PKG_VERSION").unwrap_or("unknown"));
 | 
					        println!(
 | 
				
			||||||
 | 
					            "labast version {}",
 | 
				
			||||||
 | 
					            option_env!("CARGO_PKG_VERSION").unwrap_or("unknown")
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
        std::process::exit(0);
 | 
					        std::process::exit(0);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let args = AppArgs {
 | 
					    let args = AppArgs {
 | 
				
			||||||
        stack_size: pargs.opt_value_from_fn("--stack-size", parse_stack_size)?.unwrap_or(256),
 | 
					        stack_size: pargs
 | 
				
			||||||
 | 
					            .opt_value_from_fn("--stack-size", parse_stack_size)?
 | 
				
			||||||
 | 
					            .unwrap_or(256),
 | 
				
			||||||
        input: pargs.opt_free_from_str()?,
 | 
					        input: pargs.opt_free_from_str()?,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -92,12 +110,14 @@ fn parse_args() -> Result<AppArgs, pico_args::Error> {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn parse_stack_size(s: &str) -> Result<usize, &'static str> {
 | 
					fn parse_stack_size(s: &str) -> Result<usize, &'static str> {
 | 
				
			||||||
    let number = s.parse().map_err(|_| "Argument for stack size is not a number");
 | 
					    let number = s
 | 
				
			||||||
    
 | 
					        .parse()
 | 
				
			||||||
 | 
					        .map_err(|_| "Argument for stack size is not a number");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if number > Ok(u16::MAX) {
 | 
					    if number > Ok(u16::MAX) {
 | 
				
			||||||
        eprintln!("Stack size cannot be more than 65535");
 | 
					        eprintln!("Stack size cannot be more than 65535");
 | 
				
			||||||
        std::process::exit(2);
 | 
					        std::process::exit(2);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Ok(number?.into())
 | 
					    Ok(number?.into())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										30
									
								
								src/parse.rs
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								src/parse.rs
									
									
									
									
									
								
							@ -1,4 +1,7 @@
 | 
				
			|||||||
use crate::{errors::ParseError, stack::{Instruction, Stack}};
 | 
					use crate::{
 | 
				
			||||||
 | 
					    errors::ParseError,
 | 
				
			||||||
 | 
					    stack::{Instruction, Stack},
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn parse(stack: &mut Stack, file_content: &str) {
 | 
					pub fn parse(stack: &mut Stack, file_content: &str) {
 | 
				
			||||||
    for (i, line) in file_content.lines().enumerate() {
 | 
					    for (i, line) in file_content.lines().enumerate() {
 | 
				
			||||||
@ -13,26 +16,33 @@ pub fn parse(stack: &mut Stack, file_content: &str) {
 | 
				
			|||||||
            inst_line = line.trim().chars().collect();
 | 
					            inst_line = line.trim().chars().collect();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let command: [String; 2] = inst_line.split_once(char::is_whitespace)
 | 
					        let command: [String; 2] = inst_line.split_once(char::is_whitespace).map_or_else(
 | 
				
			||||||
        .map_or_else(|| [inst_line.trim().to_string(), "".to_string()],
 | 
					            || [inst_line.trim().to_string(), "".to_string()],
 | 
				
			||||||
        |(first, second)| [first.trim().to_string(), second.trim().to_string()]);
 | 
					            |(first, second)| [first.trim().to_string(), second.trim().to_string()],
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let name: String;
 | 
					        let name: String = command[0].clone();
 | 
				
			||||||
        let mut arg: String = String::new();
 | 
					        let mut arg: String = String::new();
 | 
				
			||||||
        let mut data: u16 = 0;
 | 
					        let mut data: u16 = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        name = command[0].clone();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if !command[1].is_empty() {
 | 
					        if !command[1].is_empty() {
 | 
				
			||||||
            if name.chars().nth(0) == Some('#') || name.chars().nth(1) == Some('#') {    
 | 
					            if name.chars().nth(0) == Some('#') || name.chars().nth(1) == Some('#') {
 | 
				
			||||||
                let splited_data: Vec<String> = command[1].split_whitespace().map(String::from).collect();
 | 
					                let splited_data: Vec<String> =
 | 
				
			||||||
 | 
					                    command[1].split_whitespace().map(String::from).collect();
 | 
				
			||||||
                arg = splited_data.get(0).unwrap().clone();
 | 
					                arg = splited_data.get(0).unwrap().clone();
 | 
				
			||||||
            } else if name.chars().nth(0) == Some('$') || name.chars().nth(1) == Some('$') {
 | 
					            } else if name.chars().nth(0) == Some('$') || name.chars().nth(1) == Some('$') {
 | 
				
			||||||
                arg = command[1].clone();
 | 
					                arg = command[1].clone();
 | 
				
			||||||
            } else if let Ok(number) = command[1].parse::<i32>() {
 | 
					            } else if let Ok(number) = command[1].parse::<i32>() {
 | 
				
			||||||
                data = number as u16;
 | 
					                data = number as u16;
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                eprintln!("{}", ParseError::ArgumentNotRequired(command[0].to_string(), i + 1, line.to_string()));
 | 
					                eprintln!(
 | 
				
			||||||
 | 
					                    "{}",
 | 
				
			||||||
 | 
					                    ParseError::ArgumentNotRequired(
 | 
				
			||||||
 | 
					                        command[0].to_string(),
 | 
				
			||||||
 | 
					                        i + 1,
 | 
				
			||||||
 | 
					                        line.to_string()
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
                std::process::exit(2);
 | 
					                std::process::exit(2);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										19
									
								
								src/stack.rs
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								src/stack.rs
									
									
									
									
									
								
							@ -6,14 +6,14 @@ use crate::errors::StackError;
 | 
				
			|||||||
pub struct Instruction {
 | 
					pub struct Instruction {
 | 
				
			||||||
    pub name: String,
 | 
					    pub name: String,
 | 
				
			||||||
    pub arg: String,
 | 
					    pub arg: String,
 | 
				
			||||||
    pub data: u16
 | 
					    pub data: u16,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct Stack {
 | 
					pub struct Stack {
 | 
				
			||||||
    pub program: Vec<Instruction>,
 | 
					    pub program: Vec<Instruction>,
 | 
				
			||||||
    pub program_counter: u16,
 | 
					    pub program_counter: u16,
 | 
				
			||||||
    pub labels: [Option<i16>; 256],
 | 
					    pub labels: [Option<i16>; 256],
 | 
				
			||||||
    pub memory: StackVec
 | 
					    pub memory: StackVec,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Stack {
 | 
					impl Stack {
 | 
				
			||||||
@ -22,14 +22,14 @@ impl Stack {
 | 
				
			|||||||
            program: Vec::new(),
 | 
					            program: Vec::new(),
 | 
				
			||||||
            program_counter: 0,
 | 
					            program_counter: 0,
 | 
				
			||||||
            labels: [None; 256],
 | 
					            labels: [None; 256],
 | 
				
			||||||
            memory: StackVec::new(stack_size)
 | 
					            memory: StackVec::new(stack_size),
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct StackVec {
 | 
					pub struct StackVec {
 | 
				
			||||||
    data: Vec<u16>,
 | 
					    data: Vec<u16>,
 | 
				
			||||||
    max_size: usize
 | 
					    max_size: usize,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl StackVec {
 | 
					impl StackVec {
 | 
				
			||||||
@ -53,11 +53,16 @@ impl StackVec {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn pop(&mut self) -> u16 {
 | 
					    pub fn pop(&mut self) -> u16 {
 | 
				
			||||||
        self.data.pop().expect(&format!("{}", StackError::StackUnderflow))
 | 
					        self.data
 | 
				
			||||||
 | 
					            .pop()
 | 
				
			||||||
 | 
					            .expect(&format!("{}", StackError::StackUnderflow))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn last(&mut self) -> u16 {
 | 
					    pub fn last(&mut self) -> u16 {
 | 
				
			||||||
        *self.data.last().expect(&format!("{}", StackError::StackUnderflow))
 | 
					        *self
 | 
				
			||||||
 | 
					            .data
 | 
				
			||||||
 | 
					            .last()
 | 
				
			||||||
 | 
					            .expect(&format!("{}", StackError::StackUnderflow))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -67,4 +72,4 @@ impl Deref for StackVec {
 | 
				
			|||||||
    fn deref(&self) -> &Self::Target {
 | 
					    fn deref(&self) -> &Self::Target {
 | 
				
			||||||
        &self.data
 | 
					        &self.data
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user