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;
|
||||
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")?;
|
||||
|
|
|
@ -12,7 +12,9 @@ pub enum OpType {
|
|||
End,
|
||||
Dup,
|
||||
Gt,
|
||||
Lt
|
||||
Lt,
|
||||
While,
|
||||
Do
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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(())
|
||||
|
|
|
@ -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,18 +87,27 @@ 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 => {
|
||||
util::logger::pos_error(pos, format!("Unknown token '{}'", t).as_str());
|
||||
|
|
Loading…
Reference in New Issue
Block a user