Add Test and JMP
This commit is contained in:
parent
0a6d13c5f6
commit
1f14f2b9f9
@ -5,5 +5,14 @@ function add(x)
|
||||
end
|
||||
end
|
||||
|
||||
function min(x, y)
|
||||
local m = x
|
||||
if y < x then
|
||||
m = y
|
||||
end
|
||||
return m
|
||||
end
|
||||
|
||||
print(max(11, 9))
|
||||
print(add(10)(15))
|
||||
print(add(10)(15))
|
||||
print(min(11, 9))
|
||||
21
src/vm.rs
21
src/vm.rs
@ -42,6 +42,10 @@ pub enum Instruction {
|
||||
Add(u16, u16, u16),
|
||||
/// R(A) := R(B) < R(C)
|
||||
LessThan(u16, u16, u16),
|
||||
/// PC += sAx
|
||||
Jmp(i32),
|
||||
/// if (R(B) <=> C) then R(A) := R(B) else PC++
|
||||
Test(u16, u16, u16),
|
||||
/// [func] [params.len()] [ret_regs.len()]
|
||||
/// R(A), ... R(A+C-2) := R(A)(R(A+1), ... R(A+B-1))
|
||||
Call(u16, u16, u16),
|
||||
@ -62,6 +66,8 @@ impl Debug for Instruction {
|
||||
Instruction::GetGlobal(arg0, arg1) => write!(f, "GETGLOBAL {} {}", arg0, arg1),
|
||||
Instruction::GetUpVal(arg0, arg1) => write!(f, "GETUPVAL {} {}", arg0, arg1),
|
||||
Instruction::SetUpVal(arg0, arg1) => write!(f, "SETUPVAL {} {}", arg0, arg1),
|
||||
Instruction::Jmp(arg0) => write!(f, "JMP {}", arg0),
|
||||
Instruction::Test(arg0, arg1, arg2) => write!(f, "TEST {} {} {}", arg0, arg1, arg2),
|
||||
Instruction::Call(arg0, arg1, arg2) => write!(f, "CALL {} {} {}", arg0, arg1, arg2),
|
||||
Instruction::Close(arg0) => write!(f, "CLOSE {}", arg0),
|
||||
Instruction::Closure(arg0, arg1) => write!(f, "CLOSURE {} {}", arg0, arg1),
|
||||
@ -263,6 +269,21 @@ impl ClosureRunner {
|
||||
*self.closure.upvalues.get(upvalreg).unwrap().borrow_mut() =
|
||||
self.stack.get(reg).cloned().unwrap_or(Value::Nil);
|
||||
}
|
||||
Instruction::Jmp(b) => {
|
||||
self.program_counter = (self.program_counter as i32 + *b) as usize
|
||||
}
|
||||
Instruction::Test(a, b, c) => {
|
||||
let is_true = match self.stack.get(b).unwrap_or(&Value::Nil) {
|
||||
Value::Number(val) => (*val as u16) == *c,
|
||||
_ => false,
|
||||
};
|
||||
if is_true {
|
||||
self.stack
|
||||
.insert(*a, self.stack.get(b).cloned().unwrap_or(Value::Nil));
|
||||
} else {
|
||||
self.program_counter += 1;
|
||||
}
|
||||
}
|
||||
Instruction::Call(func_reg, param_len, ret_len) => {
|
||||
let param_start_func_reg = if *param_len == 0 {
|
||||
self.function_register
|
||||
|
||||
Loading…
Reference in New Issue
Block a user