added while loops

This commit is contained in:
MCorange 2023-03-14 00:43:16 +02:00
parent f9b1184f18
commit 5ec182ab58
5 changed files with 89 additions and 26 deletions

View File

@ -58,6 +58,7 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
let mut ti = 0; let mut ti = 0;
while ti < tokens.len() { while ti < tokens.len() {
let token = &tokens[ti]; let token = &tokens[ti];
writeln!(writer, "addr_{}:", ti)?; writeln!(writer, "addr_{}:", ti)?;
match token.typ { match token.typ {
OpType::Push => { OpType::Push => {
@ -152,13 +153,25 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
writeln!(writer, " jmp addr_{}", token.value)?; writeln!(writer, " jmp addr_{}", token.value)?;
ti += 1; ti += 1;
}, },
OpType::While => {
writeln!(writer, " ; -- WHILE")?;
ti += 1;
}
OpType::Do => {
writeln!(writer, " ; -- DO")?;
writeln!(writer, " pop rax")?;
writeln!(writer, " test rax, rax")?;
writeln!(writer, " jz addr_{}", token.value)?;
ti += 1;
}
OpType::End => { OpType::End => {
writeln!(writer, " ; -- END")?; writeln!(writer, " ; -- END")?;
writeln!(writer, " jmp addr_{}", token.value)?;
ti += 1; ti += 1;
}, },
} }
} }
writeln!(writer, "addr_{}:", ti)?;
writeln!(writer, " mov rax, 60")?; writeln!(writer, " mov rax, 60")?;
writeln!(writer, " mov rdi, 0")?; writeln!(writer, " mov rdi, 0")?;
writeln!(writer, " syscall")?; writeln!(writer, " syscall")?;

View File

@ -12,7 +12,9 @@ pub enum OpType {
End, End,
Dup, Dup,
Gt, Gt,
Lt Lt,
While,
Do
} }

View File

@ -14,6 +14,7 @@ pub fn run(tokens: Vec<crate::constants::Operator>) -> Result<(), &'static str>{
let mut ti = 0; let mut ti = 0;
while ti < tokens.len() { while ti < tokens.len() {
let token = &tokens[ti]; let token = &tokens[ti];
match token.typ { match token.typ {
OpType::Push => { OpType::Push => {
stack.push(token.value); stack.push(token.value);
@ -65,6 +66,7 @@ pub fn run(tokens: Vec<crate::constants::Operator>) -> Result<(), &'static str>{
let a = stack_pop(&mut stack)?; let a = stack_pop(&mut stack)?;
stack.push(a); stack.push(a);
stack.push(a); stack.push(a);
ti += 1;
}, },
OpType::If => { OpType::If => {
let a = stack_pop(&mut stack)?; let a = stack_pop(&mut stack)?;
@ -78,7 +80,21 @@ pub fn run(tokens: Vec<crate::constants::Operator>) -> Result<(), &'static str>{
ti = token.value as usize; ti = token.value as usize;
}, },
OpType::End => ti += 1
OpType::While => {
ti += 1;
}
OpType::Do => {
let a = stack.pop().unwrap();
if a == 0 {
ti = token.value as usize;
} else {
ti += 1;
}
}
OpType::End => {
ti = token.value as usize;
}
} }
} }
Ok(()) Ok(())

View File

@ -9,19 +9,6 @@ pub fn cross_ref(mut tokens: Vec<Operator>) -> Vec<Operator> {
OpType::If => { OpType::If => {
stack.push(ip as u32) stack.push(ip as u32)
} }
OpType::End => {
let block_ip = stack.pop().unwrap();
let mut block_og = &mut tokens[block_ip as usize];
if vec![OpType::If, OpType::Else].contains(&(*block_og).typ) {
(*block_og).value = ip as i32;
tokens[block_ip as usize] = block_og.clone();
} else {
util::logger::pos_error(op.clone().pos,"'end' can only close 'if' blocks");
std::process::exit(1); // idc
}
}
OpType::Else => { OpType::Else => {
let if_ip = stack.pop().unwrap(); let if_ip = stack.pop().unwrap();
let mut if_og = &mut tokens[if_ip as usize]; let mut if_og = &mut tokens[if_ip as usize];
@ -30,7 +17,42 @@ pub fn cross_ref(mut tokens: Vec<Operator>) -> Vec<Operator> {
std::process::exit(1); // idc std::process::exit(1); // idc
} }
(*if_og).value = ip as i32; (*if_og).value = (ip + 1) as i32;
stack.push(ip as u32);
},
OpType::End => {
let block_ip = stack.pop().unwrap();
let mut block_og = &mut tokens[block_ip as usize].clone();
if vec![OpType::If, OpType::Else].contains(&(*block_og).typ) {
(*block_og).value = ip as i32;
tokens[block_ip as usize] = block_og.clone();
let do_og = &mut tokens[ip as usize].clone();
do_og.value = (ip + 1) as i32;
tokens[ip as usize] = (*do_og).clone();
} else if (*block_og).typ == OpType::Do {
let do_og = &mut tokens[ip as usize];
do_og.value = block_og.value;
tokens[ip as usize] = (*do_og).clone();
let mut block_og = block_og.clone();
block_og.value = (ip + 1) as i32;
tokens[block_ip as usize] = block_og.clone();
} else {
util::logger::pos_error(op.clone().pos,"'end' can only close 'if' blocks");
std::process::exit(1); // idc
}
}
OpType::While => {
stack.push(ip as u32);
}
OpType::Do => {
let while_ip = stack.pop().unwrap();
(&mut tokens[ip as usize]).value = while_ip as i32;
stack.push(ip as u32); stack.push(ip as u32);
} }
_ => () _ => ()
@ -65,17 +87,26 @@ impl Parser {
tokens.push(Operator::new(OpType::Push, num, token.file.clone(), token.line, token.col)); tokens.push(Operator::new(OpType::Push, num, token.file.clone(), token.line, token.col));
}, },
"print" => tokens.push(Operator::new(OpType::Print, 0, token.file.clone(), token.line, token.col)),
// stack
"dup" => tokens.push(Operator::new(OpType::Dup, 0, token.file.clone(), token.line, token.col)),
"pop" => tokens.push(Operator::new(OpType::Pop, 0, token.file.clone(), token.line, token.col)), "pop" => tokens.push(Operator::new(OpType::Pop, 0, token.file.clone(), token.line, token.col)),
// comp and math
"+" => tokens.push(Operator::new(OpType::Plus, 0, token.file.clone(), token.line, token.col)), "+" => tokens.push(Operator::new(OpType::Plus, 0, token.file.clone(), token.line, token.col)),
"-" => tokens.push(Operator::new(OpType::Minus, 0, token.file.clone(), token.line, token.col)), "-" => tokens.push(Operator::new(OpType::Minus, 0, token.file.clone(), token.line, token.col)),
"print" => tokens.push(Operator::new(OpType::Print, 0, token.file.clone(), token.line, token.col)),
"=" => tokens.push(Operator::new(OpType::Equals, 0, token.file.clone(), token.line, token.col)), "=" => tokens.push(Operator::new(OpType::Equals, 0, token.file.clone(), token.line, token.col)),
">" => tokens.push(Operator::new(OpType::Gt, 0, token.file.clone(), token.line, token.col)),
"<" => tokens.push(Operator::new(OpType::Lt, 0, token.file.clone(), token.line, token.col)),
// block
"if" => tokens.push(Operator::new(OpType::If, 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)), "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)), "end" => tokens.push(Operator::new(OpType::End, 0, token.file.clone(), token.line, token.col)),
"dup" => tokens.push(Operator::new(OpType::Dup, 0, token.file.clone(), token.line, token.col)), "while" => tokens.push(Operator::new(OpType::While, 0, token.file.clone(), token.line, token.col)),
">" => tokens.push(Operator::new(OpType::Gt, 0, token.file.clone(), token.line, token.col)), "do" => tokens.push(Operator::new(OpType::Do, 0, token.file.clone(), token.line, token.col)),
"<" => tokens.push(Operator::new(OpType::Lt, 0, token.file.clone(), token.line, token.col)),
t => { t => {

View File

@ -1,5 +1,6 @@
2 1 < if 10 while dup 0 > do
1 print dup print
else 1 -
0 print
end end
696969 print