Added Else less if

This commit is contained in:
MCorange 2023-03-13 17:38:05 +02:00
parent f2b45e343c
commit 8f91098792
6 changed files with 97 additions and 21 deletions

View File

@ -55,17 +55,22 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
writeln!(writer, "_start:")?; writeln!(writer, "_start:")?;
let mut ti = 0;
for token in tokens { while ti < tokens.len() {
let token = &tokens[ti];
writeln!(writer, "addr_{}:", ti)?;
match token.typ { match token.typ {
OpType::Push => { OpType::Push => {
writeln!(writer, " ; -- PUSH {}", token.value)?; writeln!(writer, " ; -- PUSH {}", token.value)?;
writeln!(writer, " mov rax, {}", token.value)?; writeln!(writer, " mov rax, {}", token.value)?;
writeln!(writer, " push rax")?; writeln!(writer, " push rax")?;
ti += 1;
}, },
OpType::Pop => { OpType::Pop => {
writeln!(writer, " ; -- POP")?; writeln!(writer, " ; -- POP")?;
writeln!(writer, " pop")?; writeln!(writer, " pop")?;
ti += 1;
}, },
OpType::Plus => { OpType::Plus => {
writeln!(writer, " ; -- PLUS")?; writeln!(writer, " ; -- PLUS")?;
@ -73,6 +78,7 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
writeln!(writer, " pop rbx")?; writeln!(writer, " pop rbx")?;
writeln!(writer, " add rax, rbx")?; writeln!(writer, " add rax, rbx")?;
writeln!(writer, " push rax")?; writeln!(writer, " push rax")?;
ti += 1;
}, },
OpType::Minus => { OpType::Minus => {
writeln!(writer, " ; -- MINUS")?; writeln!(writer, " ; -- MINUS")?;
@ -80,6 +86,7 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
writeln!(writer, " pop rbx")?; writeln!(writer, " pop rbx")?;
writeln!(writer, " sub rbx, rax")?; writeln!(writer, " sub rbx, rax")?;
writeln!(writer, " push rbx")?; writeln!(writer, " push rbx")?;
ti += 1;
}, },
OpType::Equals => { OpType::Equals => {
writeln!(writer, " ; -- EQUALS")?; writeln!(writer, " ; -- EQUALS")?;
@ -90,12 +97,27 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
writeln!(writer, " cmp rax, rbx")?; writeln!(writer, " cmp rax, rbx")?;
writeln!(writer, " cmove rcx, rdx")?; writeln!(writer, " cmove rcx, rdx")?;
writeln!(writer, " push rcx")?; writeln!(writer, " push rcx")?;
ti += 1;
}, },
OpType::Print => { OpType::Print => {
writeln!(writer, " ; -- PRINT")?; writeln!(writer, " ; -- PRINT")?;
writeln!(writer, " pop rdi")?; writeln!(writer, " pop rdi")?;
writeln!(writer, " call print")?; writeln!(writer, " call print")?;
ti += 1;
},
OpType::If => {
writeln!(writer, " ; -- IF")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " test rax, rax")?;
writeln!(writer, " jz addr_{}", token.value)?;
ti += 1;
},
OpType::Else => {
ti += 1;
},
OpType::End => {
ti += 1;
}, },
} }
} }

View File

@ -1,12 +1,15 @@
#[derive(Debug)] #[derive(Debug, Clone, PartialEq)]
pub enum OpType { pub enum OpType {
Push, Push,
Pop, Pop,
Minus, Minus,
Plus, Plus,
Equals, Equals,
Print Print,
If,
Else,
End,
} }
@ -15,17 +18,19 @@ pub enum OpType {
// } // }
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct Operator { pub struct Operator {
pub typ: OpType, pub typ: OpType,
pub value: i32, pub value: i32,
pub pos: (String, u32, u32)
} }
impl Operator { impl Operator {
pub fn new(typ: OpType, value: i32) -> Self { pub fn new(typ: OpType, value: i32, file: String, row: u32, col: u32) -> Self {
Self { Self {
typ, typ,
value value,
pos: (file, row, col)
} }
} }
} }

View File

@ -11,37 +11,55 @@ fn stack_pop(stack: &mut Vec<i32>) -> Result<i32, &'static str> {
pub fn run(tokens: Vec<crate::constants::Operator>) -> Result<(), &'static str>{ pub fn run(tokens: Vec<crate::constants::Operator>) -> Result<(), &'static str>{
let mut stack: Vec<i32> = Vec::new(); let mut stack: Vec<i32> = Vec::new();
let mut ti = 0;
for token in tokens { while ti < tokens.len() {
let token = &tokens[ti];
match token.typ { match token.typ {
OpType::Push => { OpType::Push => {
stack.push(token.value); stack.push(token.value);
ti += 1;
}, },
OpType::Pop => { OpType::Pop => {
stack.pop(); stack.pop();
ti += 1;
}, },
OpType::Plus => { OpType::Plus => {
let a = stack_pop(&mut stack)?; let a = stack_pop(&mut stack)?;
let b = stack_pop(&mut stack)?; let b = stack_pop(&mut stack)?;
stack.push(b + a); stack.push(b + a);
ti += 1;
}, },
OpType::Minus => { OpType::Minus => {
let a = stack_pop(&mut stack)?; let a = stack_pop(&mut stack)?;
let b = stack_pop(&mut stack)?; let b = stack_pop(&mut stack)?;
stack.push(b - a); stack.push(b - a);
ti += 1;
}, },
OpType::Equals => { OpType::Equals => {
let a = stack_pop(&mut stack)?; let a = stack_pop(&mut stack)?;
let b = stack_pop(&mut stack)?; let b = stack_pop(&mut stack)?;
stack.push((a == b) as i32); stack.push((a == b) as i32);
ti += 1;
}, },
OpType::Print => { OpType::Print => {
let a = stack_pop(&mut stack)?; let a = stack_pop(&mut stack)?;
println!("{a}"); println!("{a}");
// let _ = io::stdout().flush(); // let _ = io::stdout().flush();
ti += 1;
}, },
OpType::If => {
let a = stack_pop(&mut stack)?;
if a == 0 {
ti = token.value as usize;
}
ti += 1;
},
OpType::Else => {
ti += 1;
},
OpType::End => ti += 1
} }
} }
Ok(()) Ok(())

View File

@ -2,6 +2,8 @@
use crate::constants::Token; use crate::constants::Token;
use color_eyre::Result; use color_eyre::Result;
pub fn find_col<F>(text: String, mut col: u32, predicate: F) -> Result<u32> where F: Fn(char) -> bool { pub fn find_col<F>(text: String, mut col: u32, predicate: F) -> Result<u32> where F: Fn(char) -> bool {
while (col as usize) < text.len() && !predicate(text.chars().nth(col as usize).unwrap()) { while (col as usize) < text.len() && !predicate(text.chars().nth(col as usize).unwrap()) {
col += 1; col += 1;

View File

@ -1,6 +1,32 @@
use crate::{constants::{Operator, OpType, Token}, util}; use crate::{constants::{Operator, OpType, Token}, util};
use color_eyre::Result; use color_eyre::Result;
pub fn cross_ref(mut tokens: Vec<Operator>) -> Vec<Operator> {
let mut stack: Vec<u32> = Vec::new();
for ip in 0..tokens.len() {
let op = &tokens.clone()[ip];
match op.typ {
OpType::If => {
stack.push(ip as u32)
}
OpType::End => {
let if_ip = stack.pop().unwrap();
let mut if_og = &mut tokens[if_ip as usize];
if !vec![OpType::If].contains(&(*if_og).typ) {
util::logger::pos_error(op.clone().pos,"'end' can only close 'if' blocks");
std::process::exit(1); // idc
}
(*if_og).value = ip as i32;
}
_ => ()
}
}
tokens.clone()
}
pub struct Parser { pub struct Parser {
tokens: Vec<Token> tokens: Vec<Token>
@ -21,14 +47,17 @@ impl Parser {
match token.text.as_str() { match token.text.as_str() {
t if t.parse::<i32>().is_ok() => { t if t.parse::<i32>().is_ok() => {
let num = t.parse::<i32>().unwrap(); let num = t.parse::<i32>().unwrap();
tokens.push(Operator::new(OpType::Push, num)); tokens.push(Operator::new(OpType::Push, num, token.file.clone(), token.line, token.col));
}, },
"pop" => tokens.push(Operator::new(OpType::Pop, 0)), "pop" => tokens.push(Operator::new(OpType::Pop, 0, token.file.clone(), token.line, token.col)),
"+" => tokens.push(Operator::new(OpType::Plus, 0)), "+" => tokens.push(Operator::new(OpType::Plus, 0, token.file.clone(), token.line, token.col)),
"-" => tokens.push(Operator::new(OpType::Minus, 0)), "-" => tokens.push(Operator::new(OpType::Minus, 0, token.file.clone(), token.line, token.col)),
"print" => tokens.push(Operator::new(OpType::Print, 0)), "print" => tokens.push(Operator::new(OpType::Print, 0, token.file.clone(), token.line, token.col)),
"=" => tokens.push(Operator::new(OpType::Equals, 0)), "=" => tokens.push(Operator::new(OpType::Equals, 0, token.file.clone(), token.line, token.col)),
"if" => tokens.push(Operator::new(OpType::If, 0, token.file.clone(), token.line, token.col)),
"else" => tokens.push(Operator::new(OpType::Else, 0, token.file.clone(), token.line, token.col)),
"end" => tokens.push(Operator::new(OpType::End, 0, token.file.clone(), token.line, token.col)),
t => { t => {
@ -38,6 +67,6 @@ impl Parser {
} }
} }
Ok(tokens) Ok(cross_ref(tokens))
} }
} }

View File

@ -1,3 +1,3 @@
35 34 + 69 = print 35 34 + 692 = if
21 print
500 80 - print end