1
Fork 0

Handle Goto, Panic, and If terminators properly.

This commit is contained in:
Scott Olson 2015-11-19 03:23:50 -06:00
parent c37b2bba05
commit 7112fc8cd1
2 changed files with 55 additions and 17 deletions

View file

@ -34,7 +34,7 @@ impl Interpreter {
}
}
fn call(&mut self, mir: &Mir, _args: &[Value]) -> Value {
fn push_stack_frame(&mut self, mir: &Mir, _args: &[Value]) {
self.call_stack.push(Frame {
offset: self.value_stack.len(),
num_args: mir.arg_decls.len(),
@ -42,27 +42,55 @@ impl Interpreter {
num_temps: mir.temp_decls.len(),
});
{
let frame = self.call_stack.last().unwrap();
let frame_size = 1 + frame.num_args + frame.num_vars + frame.num_temps;
self.value_stack.extend(iter::repeat(Value::Uninit).take(frame_size));
}
let frame = self.call_stack.last().unwrap();
let frame_size = 1 + frame.num_args + frame.num_vars + frame.num_temps;
self.value_stack.extend(iter::repeat(Value::Uninit).take(frame_size));
let start_block = mir.basic_block_data(mir::START_BLOCK);
// TODO(tsion): Write args into value_stack.
}
for stmt in &start_block.statements {
use rustc_mir::repr::StatementKind::*;
fn call(&mut self, mir: &Mir, args: &[Value]) -> Value {
self.push_stack_frame(mir, args);
let mut block = mir::START_BLOCK;
match stmt.kind {
Assign(ref lvalue, ref rvalue) => {
let index = self.eval_lvalue(lvalue);
let value = self.eval_rvalue(rvalue);
self.value_stack[index] = value;
loop {
use rustc_mir::repr::Terminator::*;
let block_data = mir.basic_block_data(block);
for stmt in &block_data.statements {
use rustc_mir::repr::StatementKind::*;
match stmt.kind {
Assign(ref lvalue, ref rvalue) => {
let index = self.eval_lvalue(lvalue);
let value = self.eval_rvalue(rvalue);
self.value_stack[index] = value;
}
Drop(_kind, ref _lv) => {
// TODO
},
}
}
println!("{:?}", block_data.terminator);
match block_data.terminator {
Goto { target } => block = target,
Panic { target: _target } => unimplemented!(),
If { ref cond, targets } => {
match self.eval_operand(&cond) {
Value::Bool(true) => block = targets[0],
Value::Bool(false) => block = targets[1],
cond_val => panic!("Non-boolean `if` condition value: {:?}", cond_val),
}
}
Drop(_kind, ref _lv) => {
// TODO
},
Return => break,
_ => unimplemented!(),
}
}