Skip to content

Commit

Permalink
Move content of instructions (loops and functions) to the Instruction…
Browse files Browse the repository at this point in the history
… struct instead of the InstructionType struct
  • Loading branch information
Sellig6792 committed Dec 27, 2022
1 parent d5a5af2 commit 63f8653
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 92 deletions.
14 changes: 7 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
[package]
name = "brainfuck"
name = "fuckbrainfuck"
version = "0.1.0"
edition = "2021"
authors = ["Sellig6792 <[email protected]>"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[[bin]]
name = "fbf"
path = "src/main.rs"

[dependencies]
rand = "0.8.5"
45 changes: 24 additions & 21 deletions src/ast/instructions.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::fmt;

#[derive(Debug, Clone, Default)]
#[derive(Debug, Clone)]
pub enum InstructionType {
Increment,
Decrement,
Expand All @@ -11,32 +11,41 @@ pub enum InstructionType {
Input,
Output,

Loop {
instructions: Vec<Instruction>,
},
Loop,

Function {
instructions: Vec<Instruction>,
},
Function,
CallFunction,

MoveLeftScope,
MoveRightScope,

Random,

#[default]
Default,
}

#[derive(Clone, Default)]
#[derive(Clone)]
pub struct Instruction {
pub instruction: InstructionType,
content: Option<Vec<Instruction>>,
}

impl Instruction {
pub fn new(instruction: InstructionType) -> Instruction {
Instruction { instruction }
pub fn new(instruction: InstructionType, content: Option<Vec<Instruction>>) -> Instruction {
Instruction {
instruction,
content,
}
}
pub fn get_content(&self) -> Vec<Instruction> {
match &self.content {
Some(content) => content.clone(),
None => panic!("Instruction has no content"),
}
}
pub fn get_content_ref(&self) -> &Vec<Instruction> {
match &self.content {
Some(content) => content,
None => panic!("Instruction has no content"),
}
}
}

Expand All @@ -52,21 +61,15 @@ impl fmt::Display for Instruction {
InstructionType::Input => write!(f, "Input"),
InstructionType::Output => write!(f, "Output"),

InstructionType::Loop { instructions } => {
write!(f, "Loop{:?}", instructions)
}
InstructionType::Loop => write!(f, "Loop{:?}", self.get_content_ref()),

InstructionType::Function { instructions } => {
write!(f, "Function{:?}", instructions)
}
InstructionType::Function => write!(f, "Function{:?}", self.get_content_ref()),
InstructionType::CallFunction => write!(f, "CallFunction"),

InstructionType::MoveLeftScope => write!(f, "MoveLeftScope"),
InstructionType::MoveRightScope => write!(f, "MoveRightScope"),

InstructionType::Random => write!(f, "Random"),

InstructionType::Default => write!(f, "Default"),
}
}
}
Expand Down
33 changes: 14 additions & 19 deletions src/ast/parser.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::ast::instructions::Instruction;
use crate::ast::instructions::InstructionType::*;
use crate::ast::instructions::{Instruction, InstructionType};

pub struct Parser {
program: String,
Expand All @@ -23,7 +22,7 @@ impl Parser {

fn _parse(&self, index: Option<usize>, stop_char: Option<char>) -> (Vec<Instruction>, usize) {
let mut index = index.unwrap_or(0);
let mut instructions = Vec::new();
let mut instructions = vec![];

while index < self.program.len() {
let char = match self.program.chars().nth(index) {
Expand All @@ -35,37 +34,33 @@ impl Parser {
}

match char {
'+' => instructions.push(Instruction::new(Increment)),
'-' => instructions.push(Instruction::new(Decrement)),
'+' => instructions.push(Instruction::new(InstructionType::Increment, None)),
'-' => instructions.push(Instruction::new(InstructionType::Decrement, None)),

'<' => instructions.push(Instruction::new(MoveLeft)),
'>' => instructions.push(Instruction::new(MoveRight)),
'<' => instructions.push(Instruction::new(InstructionType::MoveLeft, None)),
'>' => instructions.push(Instruction::new(InstructionType::MoveRight, None)),

'.' => instructions.push(Instruction::new(Output)),
',' => instructions.push(Instruction::new(Input)),
'.' => instructions.push(Instruction::new(InstructionType::Output, None)),
',' => instructions.push(Instruction::new(InstructionType::Input, None)),

'[' => {
let (loop_instructions, new_index) = self._parse(Some(index + 1), Some(']'));
instructions.push(Instruction::new(Loop {
instructions: loop_instructions,
}));
instructions.push(Instruction::new(InstructionType::Loop, Some(loop_instructions)));
index = new_index;
}
'{' => {
let (function_instructions, new_index) =
self._parse(Some(index + 1), Some('}'));
instructions.push(Instruction::new(Function {
instructions: function_instructions,
}));
instructions.push(Instruction::new(InstructionType::Function, Some(function_instructions)));
index = new_index;
}

'=' => instructions.push(Instruction::new(CallFunction)),
'=' => instructions.push(Instruction::new(InstructionType::CallFunction, None)),

'?' => instructions.push(Instruction::new(Random)),
'?' => instructions.push(Instruction::new(InstructionType::Random, None)),

'´' => instructions.push(Instruction::new(MoveLeftScope)),
'`' => instructions.push(Instruction::new(MoveRightScope)),
'´' => instructions.push(Instruction::new(InstructionType::MoveLeftScope, None)),
'`' => instructions.push(Instruction::new(InstructionType::MoveRightScope, None)),

':' => {
// The end of the comment is ';'
Expand Down
64 changes: 23 additions & 41 deletions src/evaluation/evaluator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,15 @@ impl Evaluator {

memory_pointer: 0,

input: Vec::new(),
output_buffer: Vec::new(),
input: vec![],
output_buffer: vec![],
}
}

pub fn evaluate(&mut self, loop_: Option<InstructionType>, show_output: Option<bool>) {
let instructions = if loop_.is_some() {
match loop_.unwrap() {
InstructionType::Loop { instructions } => instructions,
_ => panic!("Invalid instruction type"),
}
} else {
self.program.clone()
pub fn evaluate(&mut self, container_to_execute: Option<Instruction>, show_output: Option<bool>) {
let instructions = match container_to_execute {
Some(container) => container.get_content(),
None => self.program.clone(),
};

for instruction in instructions.iter() {
Expand Down Expand Up @@ -88,43 +84,31 @@ impl Evaluator {
.push(self.scopes[self.scope_pointer].memory[self.memory_pointer]);
}

InstructionType::Loop { ref instructions } => {
InstructionType::Loop => {
while self.scopes[self.scope_pointer].memory[self.memory_pointer] != 0 {
self.evaluate(
Some(InstructionType::Loop {
instructions: instructions.clone(),
}),
Some(false),
);
Some(instruction.clone()),
Some(false)
)
}
}
InstructionType::Function { ref instructions } => {
InstructionType::Function => {
self.scopes[self.scope_pointer].function_memory[self.memory_pointer] =
Instruction::new(InstructionType::Function {
instructions: instructions.clone(),
});
Instruction::new(
InstructionType::Function,
Some(instruction.get_content())
);
}

InstructionType::CallFunction => {
match self.scopes[self.scope_pointer].function_memory[self.memory_pointer]
.instruction
.clone()
{
InstructionType::Function { ref instructions } => {
self.scopes.push(Scope::new());
self.scope_pointer = self.scopes.len() - 1;
self.evaluate(
Some(InstructionType::Loop {
instructions: instructions.clone(),
}),
Some(false),
);
self.scopes.pop();
self.scope_pointer -= 1;
}
InstructionType::Default => (),
_ => panic!("Invalid instruction type in function memory"),
}
self.scopes.push(Scope::new());
self.scope_pointer += 1;
self.evaluate(
Some(self.scopes[self.scope_pointer - 1].function_memory[self.memory_pointer].clone()),
Some(false)
);
self.scopes.pop();
self.scope_pointer -= 1;
}

InstructionType::MoveLeftScope => {
Expand Down Expand Up @@ -166,8 +150,6 @@ impl Evaluator {
}
}
}

InstructionType::Default => (),
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/evaluation/scope.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::ast::instructions::Instruction;
use crate::ast::instructions::{Instruction, InstructionType};

#[derive(Debug)]
pub struct Scope {
Expand All @@ -8,9 +8,9 @@ pub struct Scope {

impl Scope {
pub fn new() -> Scope {
let mut function_memory_vec = Vec::new();
let mut function_memory_vec = vec![];
for _ in 0..30000 {
function_memory_vec.push(Instruction::default());
function_memory_vec.push(Instruction::new(InstructionType::Function, Some(vec![])));
}

Scope {
Expand Down

0 comments on commit 63f8653

Please sign in to comment.