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;
while ti < tokens.len() {
let token = &tokens[ti];
writeln!(writer, "addr_{}:", ti)?;
match token.typ {
OpType::Push => {
@ -152,13 +153,25 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
writeln!(writer, " jmp addr_{}", token.value)?;
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 => {
writeln!(writer, " ; -- END")?;
writeln!(writer, " jmp addr_{}", token.value)?;
ti += 1;
},
}
}
writeln!(writer, "addr_{}:", ti)?;
writeln!(writer, " mov rax, 60")?;
writeln!(writer, " mov rdi, 0")?;
writeln!(writer, " syscall")?;

View File

@ -12,7 +12,9 @@ pub enum OpType {
End,
Dup,
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;
while ti < tokens.len() {
let token = &tokens[ti];
match token.typ {
OpType::Push => {
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)?;
stack.push(a);
stack.push(a);
ti += 1;
},
OpType::If => {
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;
},
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(())

View File

@ -9,19 +9,6 @@ pub fn cross_ref(mut tokens: Vec<Operator>) -> Vec<Operator> {
OpType::If => {
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 => {
let if_ip = stack.pop().unwrap();
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
}
(*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);
}
_ => ()
@ -65,17 +87,26 @@ impl Parser {
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)),
// comp and math
"+" => 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)),
"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)),
"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)),
"dup" => tokens.push(Operator::new(OpType::Dup, 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)),
"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)),
"while" => tokens.push(Operator::new(OpType::While, 0, token.file.clone(), token.line, token.col)),
"do" => tokens.push(Operator::new(OpType::Do, 0, token.file.clone(), token.line, token.col)),
t => {

View File

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