Skip to content

Commit

Permalink
New version: v2.5
Browse files Browse the repository at this point in the history
  • Loading branch information
d3r1n committed Apr 22, 2022
1 parent 44e6633 commit 220b09a
Show file tree
Hide file tree
Showing 20 changed files with 534 additions and 157 deletions.
16 changes: 16 additions & 0 deletions Benchmarks.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Mandelbrot Set
--------------
Optimized: took 5.399 seconds with 1024 bytes of memory at pointer location 512 (no auto-allocation)
Unoptimized: took 13.773 seconds with 1024 bytes of memory at pointer location 512 (no auto-allocation)

Hello World
-----------
Optimized: took 0.002 seconds with 1024 bytes of memory at pointer location 512 (no auto-allocation)
Unoptimized: took 0.012 seconds with 1024 bytes of memory at pointer location 512 (no auto-allocation)

Factorial
---------
TERMINATION AFTER 1 SECOND

Optimized: reached "354996793146960497053355363383973425965094809743694491885455534984190204750249968830591340591162785093141951525209177997501478084577063512837513105442388103085116949108248219929177667335850225156399124325817472036634653562449665740610033707601842063277098323069015230061026956365247457276593902258859903874498560000000000000000000000000000000000000000000000" with auto-allocation
Unoptimized: reaced "68514381077363375931297585133106871211263298280533036933892918251948709516798243984304128734094417522976396644365371353517785270323373257977640029350380903895427571177891906446331289795819093455185030994882772103070488137552785487937736505567155518212479976352319939401778202578492759254382623135959961447778222080000000000000000000000000000000000000000000000" with auto-allocation
4 changes: 2 additions & 2 deletions Cargo.lock

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

21 changes: 17 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,23 @@ $ brainsuck <INPUT FILE> [OPTIONS]
- **[-m, --mem-size]:** Sets the program's memory size. (default: 1024)
- **[-p, --ptr-loc]:** Sets the program's memory pointer location. (default: 512)
- **[-a, --auto]:** Automatically allocates memory for the program. (default: false)
- **[-o, --optimize]:** Optimize the Parser and Interpreter (default: 1024)

<h2>Versions History</h2>

- **v3.0** *[Next]*
* Adding custom keywords and functions to the brainsuck
- **v2.0** *[Now]*
* Adding more functionality and more keywords (Main Feature)
* Adding a compiler based on LLVM (Main Feature)
* Adding a transpiler to C and Rust (Main Feature)
* Adding JiT compilation (Main Feature)
- **v2.5** *[Now]*
* Optimized the Parser and Interpreter (Main Feature)
* Improved speed (3x-100x times faster optimized) (Main Feature)
* Bug fixes
- **v2.0** *[Previous]*
* Added **Interactive Shell** (Main Feature) `see Usage ^`
* More bug fixes
- **v1.5** *[Previous]*
- **v1.5**
* Automatic Memory Allocation (Main Feature)
* New way of argument handling
* Some bug fixes
Expand Down Expand Up @@ -91,6 +99,7 @@ $ brainsuck <INPUT FILE> [OPTIONS]

<h3>Memory Overflow Errors</h3>
<img src="./assets/memory_overflow.png" alt="">
<img src="./assets/neg_ptr.png" alt="">

---

Expand All @@ -99,7 +108,11 @@ $ brainsuck <INPUT FILE> [OPTIONS]
- [X] Add basic brainfuck commands.
- [X] Add automatic memory allocation.
- [X] Add repl
- [ ] Add lots of custom commands and features.
- [ ] Add optimization
- [ ] Add custom keywords
- [ ] Add macros
- [ ] Add a compiler
- [ ] Add a JiT compiler

---

Expand Down
Binary file added assets/neg_ptr.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion bs_bin/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "bs_bin"
version = "2.0.0"
version = "2.5.0"
edition = "2021"

[dependencies]
Expand Down
58 changes: 45 additions & 13 deletions bs_bin/src/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,17 @@ extern crate clap;
use clap::{App, Arg};
use colored::Colorize;

use bs_lib::utils::{BrainsuckError, BrainsuckErrorType, BrainsuckMessage, BrainsuckMessageType};
use bs_lib::{
utils::*,
lexer::lex,
parser::parse,
interpreter::interpret,
optimizer::{
lexer::optimized_lex,
parser::optimized_parse,
interpreter::optimized_interpret,
}
};

use std::fs::File;
use std::io::Read;
Expand Down Expand Up @@ -41,6 +51,13 @@ pub fn handle() {
.long("auto")
.multiple(false)
.help("If enabled, program will automatically allocate memory size"),
)
.arg(
Arg::with_name("optimize")
.short("o")
.long("optimize")
.multiple(false)
.help("If enabled, program will optimize the application to make it faster"),
)
.get_matches();

Expand Down Expand Up @@ -76,16 +93,17 @@ pub fn handle() {
})
.unwrap();

let ops = bs_lib::lexer::lex(&src);
let program = bs_lib::parser::parse(&ops, false);

let mem_str = matches.value_of("mem-size").unwrap_or("1024");
let mem_size = mem_str.parse::<usize>().unwrap();

let ptr_str = matches.value_of("ptr-loc").unwrap_or("512");
let ptr_loc = ptr_str.parse::<usize>().unwrap();

let auto_alloc = matches.is_present("auto");
let optimize = matches.is_present("optimize");

let mut memory: Vec<u8> = vec![0; mem_size];
let mut memory_pointer: usize = ptr_loc;

if auto_alloc {
BrainsuckMessage::throw_message(
Expand All @@ -94,15 +112,29 @@ pub fn handle() {
);
}

let mut memory: Vec<u8> = vec![0; mem_size];
let mut memory_pointer: usize = ptr_loc;
if !optimize {
let ops = lex(&src);
let program = parse(&ops, &false);

bs_lib::interpreter::interpret(
&program,
&mut memory,
&mut memory_pointer,
auto_alloc,
false,
)
interpret(
&program,
&mut memory,
&mut memory_pointer,
false,
auto_alloc,
)
} else {
let tokens = optimized_lex(&src);
let program = optimized_parse(&tokens, &false);

optimized_interpret(
&program,
&mut memory,
&mut memory_pointer,
false,
auto_alloc,
)
}

}
}
2 changes: 1 addition & 1 deletion bs_bin/src/repl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub fn repl() {
let mut memory_pointer: usize = 512;

interpret(
&parse(&lex(&input), true),
&parse(&lex(&input), &true),
&mut memory,
&mut memory_pointer,
true,
Expand Down
2 changes: 1 addition & 1 deletion bs_lib/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "bs_lib"
version = "2.0.0"
version = "2.5.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
148 changes: 66 additions & 82 deletions bs_lib/src/interpreter.rs
Original file line number Diff line number Diff line change
@@ -1,87 +1,71 @@
use crate::types::Instruction;
use crate::utils::{BrainsuckError, BrainsuckErrorType};
use crate::{
types::Instruction as I,
utils::{BrainsuckError, BrainsuckErrorType}
};
use std::{io::{self, Read}, vec};

use std::io::{self, Read};
pub fn alloc(memory: &mut Vec<u8>, amount: usize) {
memory.resize(memory.len() + amount, 0);
}

pub fn interpret(
instructions: &[Instruction],
memory: &mut Vec<u8>,
memory_pointer: &mut usize,
auto_alloc: bool,
repl_mode: bool,
) {
for inst in instructions {
if *memory_pointer - 1 > memory.len() || *memory_pointer - 1 > memory.len() + 1 {
if auto_alloc {
memory.resize(memory.len() + 512, 0);
} else {
BrainsuckError::throw_error(
"Memory overflow!\nHelp: Give program more memory.".to_owned(),
BrainsuckErrorType::MemoryError,
repl_mode,
);
}
}

match inst {
Instruction::IncrementPointer => match memory.get(*memory_pointer + 1) {
Some(_v) => *memory_pointer += 1,
None => BrainsuckError::throw_error(
"Memory overflow!\nHelp: Give program more memory.".to_owned(),
BrainsuckErrorType::MemoryError,
!repl_mode,
),
},
Instruction::DecrementPointer => match memory.get(*memory_pointer + 1) {
Some(_v) => *memory_pointer -= 1,
None => BrainsuckError::throw_error(
"Memory overflow!\nHelp: Give program more memory.".to_owned(),
BrainsuckErrorType::MemoryError,
!repl_mode,
),
},
Instruction::Increment => match memory.get(*memory_pointer - 1) {
Some(_v) => memory[*memory_pointer] += 1,
None => BrainsuckError::throw_error(
"Memory overflow!\nHelp: Give program more memory.".to_owned(),
BrainsuckErrorType::MemoryError,
!repl_mode,
),
},
Instruction::Decrement => match memory.get(*memory_pointer - 1) {
Some(_v) => memory[*memory_pointer] -= 1,
None => BrainsuckError::throw_error(
"Memory overflow!\nHelp: Give program more memory.".to_owned(),
BrainsuckErrorType::MemoryError,
!repl_mode,
),
},
Instruction::Write => {
if repl_mode {
print!("\n{}\n\n", memory[*memory_pointer] as char)
} else {
print!("{}", memory[*memory_pointer] as char)
}
}
Instruction::Read => {
let mut input_byte: [u8; 1] = [0; 1];
pub fn interpret(instructions: &Vec<I>, memory: &mut Vec<u8>, pointer: &mut usize, repl_mode: bool, auto_allocate: bool) {

for (_idx, instr) in instructions.iter().enumerate() {
match instr {
I::IncrementPointer => if *pointer + 1 > memory.len() - 1 {
if auto_allocate {
alloc(memory, 1);
*pointer += 1;
}
else {
BrainsuckError::throw_error_with_help(
format!("Memory owerflow at {}", pointer),
"Give program more memory or\nenable auto-allocation".to_string(),
BrainsuckErrorType::MemoryError,
!repl_mode,
);
}
} else {
*pointer += 1;
}

match io::stdin().read_exact(&mut input_byte) {
Ok(()) => (),
Err(_e) => BrainsuckError::throw_error(
"Can't read input form stdin".to_owned(),
BrainsuckErrorType::IOError,
repl_mode,
),
}
I::DecrementPointer => if (*pointer as i32) - 1 < 0 {
BrainsuckError::throw_error_with_help(
"Memory pointer can't be negative".to_string(),
format!("Decrementing pointer by 1\nat pointer location {}", pointer),
BrainsuckErrorType::MemoryError,
true,
);
} else {
*pointer -= 1;
}

memory[*memory_pointer] = input_byte[0];
}
Instruction::Loop(loop_instructions) => {
while memory[*memory_pointer] != 0 {
interpret(loop_instructions, memory, memory_pointer, true, false)
}
}
}
}
}
I::Add => if (memory[*pointer] as i32) + 1 > 255 {
memory[*pointer] = 0;
} else {
memory[*pointer] += 1;
},

I::Subtract => if (memory[*pointer] as i32) - 1 < 0 {
memory[*pointer] = 255;
} else {
memory[*pointer] -= 1;
},

I::Write => print!("{}", memory[*pointer] as char),

I::Read => {
let mut input = vec![0; 1];
io::stdin().read(&mut input).unwrap();
memory[*pointer] = input[0];
},

I::Loop(loop_instructions) => {
while memory[*pointer] != 0 {
interpret(&loop_instructions, memory, pointer, repl_mode, auto_allocate);
}
}
}
}
}
4 changes: 2 additions & 2 deletions bs_lib/src/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ pub fn lex(source: &str) -> Vec<OpCode> {
let op = match current_char {
'>' => Some(OpCode::IncrementPointer),
'<' => Some(OpCode::DecrementPointer),
'+' => Some(OpCode::Increment),
'-' => Some(OpCode::Decrement),
'+' => Some(OpCode::Add),
'-' => Some(OpCode::Subtract),
'.' => Some(OpCode::Write),
',' => Some(OpCode::Read),
'[' => Some(OpCode::LoopBegin),
Expand Down
3 changes: 3 additions & 0 deletions bs_lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@ pub mod lexer;
pub mod parser;
pub mod types;
pub mod utils;
pub mod optimizer;
// pub mod compiler;
// pub mod jit;
Loading

0 comments on commit 220b09a

Please sign in to comment.