feat(tazjin/rlox): Implement else clauses
Change-Id: I0bc2333c0b4dd3e2e584a90d0d15b28c48130f03 Reviewed-on: https://cl.tvl.fyi/c/depot/+/3740 Tested-by: BuildkiteCI Reviewed-by: tazjin <mail@tazj.in>
This commit is contained in:
parent
670662a360
commit
33e71ba97f
4 changed files with 22 additions and 1 deletions
|
@ -1,5 +1,7 @@
|
|||
if (true) {
|
||||
if (false) {
|
||||
print "yes";
|
||||
} else {
|
||||
print "no";
|
||||
}
|
||||
|
||||
print "afterwards";
|
||||
|
|
|
@ -343,8 +343,17 @@ impl<T: Iterator<Item = Token>> Compiler<T> {
|
|||
);
|
||||
|
||||
let then_jump = self.emit_op(OpCode::OpJumpPlaceholder(false));
|
||||
self.emit_op(OpCode::OpPop);
|
||||
self.statement()?;
|
||||
let else_jump = self.emit_op(OpCode::OpJumpPlaceholder(true));
|
||||
self.patch_jump(then_jump);
|
||||
self.emit_op(OpCode::OpPop);
|
||||
|
||||
if self.match_token(&TokenKind::Else) {
|
||||
self.statement()?;
|
||||
}
|
||||
|
||||
self.patch_jump(else_jump);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -620,6 +629,11 @@ impl<T: Iterator<Item = Token>> Compiler<T> {
|
|||
fn patch_jump(&mut self, idx: CodeIdx) {
|
||||
let offset = CodeOffset(self.chunk.code.len() - idx.0 - 1);
|
||||
|
||||
if let OpCode::OpJumpPlaceholder(true) = self.chunk.code[idx.0] {
|
||||
self.chunk.code[idx.0] = OpCode::OpJump(offset);
|
||||
return;
|
||||
}
|
||||
|
||||
if let OpCode::OpJumpPlaceholder(false) = self.chunk.code[idx.0] {
|
||||
self.chunk.code[idx.0] = OpCode::OpJumpIfFalse(offset);
|
||||
return;
|
||||
|
|
|
@ -51,5 +51,6 @@ pub enum OpCode {
|
|||
|
||||
// Control flow
|
||||
OpJumpPlaceholder(bool),
|
||||
OpJump(CodeOffset),
|
||||
OpJumpIfFalse(CodeOffset),
|
||||
}
|
||||
|
|
|
@ -213,6 +213,10 @@ impl VM {
|
|||
panic!("unpatched jump detected - this is a fatal compiler error!");
|
||||
}
|
||||
|
||||
OpCode::OpJump(offset) => {
|
||||
self.ip += offset.0;
|
||||
}
|
||||
|
||||
OpCode::OpJumpIfFalse(offset) => {
|
||||
if self
|
||||
.stack
|
||||
|
|
Loading…
Reference in a new issue