Added Else less if
This commit is contained in:
parent
f2b45e343c
commit
8f91098792
|
@ -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;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(())
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user