added while loops
This commit is contained in:
parent
f9b1184f18
commit
5ec182ab58
|
@ -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")?;
|
||||||
|
|
|
@ -12,7 +12,9 @@ pub enum OpType {
|
||||||
End,
|
End,
|
||||||
Dup,
|
Dup,
|
||||||
Gt,
|
Gt,
|
||||||
Lt
|
Lt,
|
||||||
|
While,
|
||||||
|
Do
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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(())
|
||||||
|
|
|
@ -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 => {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user