Removed makefile for a simpler sh script and finalized the compiler with loops

master
Wynd 2024-10-22 16:10:04 +03:00
parent 31d7cb27c6
commit 659f9fbe65
5 changed files with 53 additions and 46 deletions

View File

@ -1,34 +0,0 @@
[tasks.compile-bf]
clear = true
private = true
command = "cargo"
args = ["run", "--release", "--", "${@}"]
[tasks.move]
clear = true
private = true
command = "mv"
args = ["./program.asm", "./asm/program.asm"]
dependencies = ["compile-bf"]
[tasks.assemble]
private = true
command = "nasm"
args = ["-felf64", "./asm/program.asm"]
dependencies = ["move"]
[tasks.link]
clear = true
private = true
command = "ld.lld"
args = ["./asm/program.o", "-o", "./asm/program"]
dependencies = ["assemble"]
[tasks.compile]
clear = true
dependencies = ["link"]
[tasks.test]
clear = true
command = "./asm/program"
dependencies = ["link"]

View File

@ -1,8 +1,11 @@
use std::collections::VecDeque;
use crate::tokenizer::{Token, TokenType};
pub fn generate(tokens: Vec<Token>) -> String {
let mut output = String::new();
// reserving mem
output.push_str(
"section .bss\n\
data: resb 65536\n",
@ -15,12 +18,11 @@ pub fn generate(tokens: Vec<Token>) -> String {
_start:\n",
);
// create the pointer for var
// create the pointer for our data
output.push_str("mov rdx, data\n");
// NOTE: For debugging only
// output.push_str("mov byte[rdx], 48\n");
let mut loops = 0;
let mut stack: VecDeque<usize> = VecDeque::new();
for token in tokens {
match token.r#type {
TokenType::Plus(x) => {
@ -57,8 +59,23 @@ pub fn generate(tokens: Vec<Token>) -> String {
pop rdx\n",
);
}
TokenType::BracketOpen => todo!(),
TokenType::BracketClose => todo!(),
TokenType::BracketOpen => {
output.push_str(&format!(
".loop_{loops}_start:\n\
cmp byte[rdx], 0\n\
je .loop_{loops}_end\n"
));
stack.push_back(loops);
loops += 1;
}
TokenType::BracketClose => {
let current_loop = stack.pop_back().unwrap();
output.push_str(&format!(
"cmp byte[rdx], 0\n\
jne .loop_{current_loop}_start\n\
.loop_{current_loop}_end:\n",
));
}
}
}

View File

@ -9,15 +9,23 @@ mod tokenizer;
fn main() {
let args: Vec<String> = env::args().collect();
let input = args.get(1).expect("malformed arguments");
let mode = args.get(1).expect("mode expected");
let input = args.get(2).expect("malformed arguments");
let program: Vec<u8> = load_program(input);
let name = args
.get(2)
.get(3)
.map(|s| s.to_string())
.unwrap_or_else(|| "program".to_string());
match mode {
x if x == "c" => {
compiler::compile(program, name);
// interpreter::run(program);
}
x if x == "i" => {
interpreter::run(program);
}
_ => {}
}
}
fn load_program(input: &str) -> Vec<u8> {

View File

@ -55,8 +55,12 @@ pub fn tokenize(program: Vec<u8>) -> Vec<Token> {
b',' => {
tokens.push(Token::new(TokenType::Input));
}
b'[' => {}
b']' => {}
b'[' => {
tokens.push(Token::new(TokenType::BracketOpen));
}
b']' => {
tokens.push(Token::new(TokenType::BracketClose));
}
_ => {}
}
}

12
test.sh 100755
View File

@ -0,0 +1,12 @@
#!/bin/bash
(
mode=$1
program=$2
cargo run --release -- $mode $program
if [ "$mode" == "c" ]; then
mv ./program.asm ./asm/program.asm \
&& nasm -felf64 ./asm/program.asm \
&& ld.lld ./asm/program.o -o ./asm/program \
&& ./asm/program
fi
)