Fix some bugs to get language working with new 64-bit instructions
This commit is contained in:
parent
ac1ee793ab
commit
1409698fdd
@ -46,11 +46,11 @@ use colored::{ColoredString, Colorize};
|
|||||||
use crate::{Chunk, Local};
|
use crate::{Chunk, Local};
|
||||||
|
|
||||||
const INSTRUCTION_COLUMNS: [(&str, usize); 4] =
|
const INSTRUCTION_COLUMNS: [(&str, usize); 4] =
|
||||||
[("i", 5), ("POSITION", 12), ("OPERATION", 17), ("INFO", 36)];
|
[("i", 5), ("POSITION", 12), ("OPERATION", 17), ("INFO", 41)];
|
||||||
const INSTRUCTION_BORDERS: [&str; 3] = [
|
const INSTRUCTION_BORDERS: [&str; 3] = [
|
||||||
"╭─────┬────────────┬─────────────────┬────────────────────────────────────╮",
|
"╭─────┬────────────┬─────────────────┬─────────────────────────────────────────╮",
|
||||||
"├─────┼────────────┼─────────────────┼────────────────────────────────────┤",
|
"├─────┼────────────┼─────────────────┼─────────────────────────────────────────┤",
|
||||||
"╰─────┴────────────┴─────────────────┴────────────────────────────────────╯",
|
"╰─────┴────────────┴─────────────────┴─────────────────────────────────────────╯",
|
||||||
];
|
];
|
||||||
|
|
||||||
const LOCAL_COLUMNS: [(&str, usize); 5] = [
|
const LOCAL_COLUMNS: [(&str, usize); 5] = [
|
||||||
@ -286,7 +286,7 @@ impl<'a, W: Write> Disassembler<'a, W> {
|
|||||||
.unwrap_or("stripped".to_string());
|
.unwrap_or("stripped".to_string());
|
||||||
let operation = instruction.operation().to_string();
|
let operation = instruction.operation().to_string();
|
||||||
let info = instruction.disassembly_info();
|
let info = instruction.disassembly_info();
|
||||||
let row = format!("│{index:^5}│{position:^12}│{operation:^17}│{info:^36}│");
|
let row = format!("│{index:^5}│{position:^12}│{operation:^17}│{info:^41}│");
|
||||||
|
|
||||||
self.write_center_border(&row)?;
|
self.write_center_border(&row)?;
|
||||||
}
|
}
|
||||||
|
@ -220,7 +220,7 @@ impl Instruction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn d_field(&self) -> bool {
|
pub fn d_field(&self) -> bool {
|
||||||
(self.0 >> 54) & 1 == 0
|
(self.0 >> 54) & 1 != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn b_type(&self) -> TypeCode {
|
pub fn b_type(&self) -> TypeCode {
|
||||||
|
@ -26,31 +26,31 @@ impl Operation {
|
|||||||
|
|
||||||
// Arithmetic
|
// Arithmetic
|
||||||
pub const ADD: Operation = Operation(9);
|
pub const ADD: Operation = Operation(9);
|
||||||
pub const SUBTRACT: Operation = Operation(16);
|
pub const SUBTRACT: Operation = Operation(10);
|
||||||
pub const MULTIPLY: Operation = Operation(19);
|
pub const MULTIPLY: Operation = Operation(11);
|
||||||
pub const DIVIDE: Operation = Operation(22);
|
pub const DIVIDE: Operation = Operation(12);
|
||||||
pub const MODULO: Operation = Operation(25);
|
pub const MODULO: Operation = Operation(13);
|
||||||
|
|
||||||
// Comparison
|
// Comparison
|
||||||
pub const EQUAL: Operation = Operation(28);
|
pub const EQUAL: Operation = Operation(14);
|
||||||
pub const LESS: Operation = Operation(36);
|
pub const LESS: Operation = Operation(15);
|
||||||
pub const LESS_EQUAL: Operation = Operation(41);
|
pub const LESS_EQUAL: Operation = Operation(16);
|
||||||
|
|
||||||
// Unary operations
|
// Unary operations
|
||||||
pub const NEGATE: Operation = Operation(46);
|
pub const NEGATE: Operation = Operation(17);
|
||||||
pub const NOT: Operation = Operation(48);
|
pub const NOT: Operation = Operation(18);
|
||||||
|
|
||||||
// Logical operations
|
// Logical operations
|
||||||
pub const TEST: Operation = Operation(49);
|
pub const TEST: Operation = Operation(19);
|
||||||
pub const TEST_SET: Operation = Operation(50);
|
pub const TEST_SET: Operation = Operation(20);
|
||||||
|
|
||||||
// Function calls
|
// Function calls
|
||||||
pub const CALL: Operation = Operation(51);
|
pub const CALL: Operation = Operation(21);
|
||||||
pub const CALL_NATIVE: Operation = Operation(52);
|
pub const CALL_NATIVE: Operation = Operation(22);
|
||||||
|
|
||||||
// Control flow
|
// Control flow
|
||||||
pub const JUMP: Operation = Operation(53);
|
pub const JUMP: Operation = Operation(23);
|
||||||
pub const RETURN: Operation = Operation(54);
|
pub const RETURN: Operation = Operation(24);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Operation {
|
impl Operation {
|
||||||
|
@ -48,10 +48,16 @@ impl Vm {
|
|||||||
.unwrap_or_else(|| "anonymous".to_string());
|
.unwrap_or_else(|| "anonymous".to_string());
|
||||||
let mut main_thread = Thread::new(Arc::new(self.main_chunk));
|
let mut main_thread = Thread::new(Arc::new(self.main_chunk));
|
||||||
let (tx, rx) = bounded(1);
|
let (tx, rx) = bounded(1);
|
||||||
let _ = Builder::new().name(thread_name).spawn(move || {
|
|
||||||
|
Builder::new()
|
||||||
|
.name(thread_name)
|
||||||
|
.spawn(move || {
|
||||||
let value_option = main_thread.run();
|
let value_option = main_thread.run();
|
||||||
let _ = tx.send(value_option);
|
let _ = tx.send(value_option);
|
||||||
});
|
})
|
||||||
|
.unwrap()
|
||||||
|
.join()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
rx.recv().unwrap_or(None)
|
rx.recv().unwrap_or(None)
|
||||||
}
|
}
|
||||||
|
@ -44,13 +44,13 @@ pub const RUNNER_LOGIC_TABLE: [RunnerLogic; 25] = [
|
|||||||
multiply,
|
multiply,
|
||||||
divide,
|
divide,
|
||||||
modulo,
|
modulo,
|
||||||
test,
|
|
||||||
test_set,
|
|
||||||
equal,
|
equal,
|
||||||
less,
|
less,
|
||||||
less_equal,
|
less_equal,
|
||||||
negate,
|
negate,
|
||||||
not,
|
not,
|
||||||
|
test,
|
||||||
|
test_set,
|
||||||
call,
|
call,
|
||||||
call_native,
|
call_native,
|
||||||
jump,
|
jump,
|
||||||
@ -535,9 +535,65 @@ pub fn equal(instruction: Instruction, data: &mut ThreadData) -> bool {
|
|||||||
right,
|
right,
|
||||||
right_type,
|
right_type,
|
||||||
} = instruction.into();
|
} = instruction.into();
|
||||||
let left = data.get_argument_unchecked(left);
|
let is_equal = match (left_type, right_type) {
|
||||||
let right = data.get_argument_unchecked(right);
|
(TypeCode::INTEGER, TypeCode::INTEGER) => {
|
||||||
let is_equal = left.equals(right);
|
let left = unsafe {
|
||||||
|
data.get_argument_unchecked(left)
|
||||||
|
.as_integer()
|
||||||
|
.unwrap_unchecked()
|
||||||
|
};
|
||||||
|
let right = unsafe {
|
||||||
|
data.get_argument_unchecked(right)
|
||||||
|
.as_integer()
|
||||||
|
.unwrap_unchecked()
|
||||||
|
};
|
||||||
|
|
||||||
|
left == right
|
||||||
|
}
|
||||||
|
(TypeCode::FLOAT, TypeCode::FLOAT) => {
|
||||||
|
let left = unsafe {
|
||||||
|
data.get_argument_unchecked(left)
|
||||||
|
.as_float()
|
||||||
|
.unwrap_unchecked()
|
||||||
|
};
|
||||||
|
let right = unsafe {
|
||||||
|
data.get_argument_unchecked(right)
|
||||||
|
.as_float()
|
||||||
|
.unwrap_unchecked()
|
||||||
|
};
|
||||||
|
|
||||||
|
left == right
|
||||||
|
}
|
||||||
|
(TypeCode::BOOLEAN, TypeCode::BOOLEAN) => {
|
||||||
|
let left = unsafe {
|
||||||
|
data.get_argument_unchecked(left)
|
||||||
|
.as_boolean()
|
||||||
|
.unwrap_unchecked()
|
||||||
|
};
|
||||||
|
let right = unsafe {
|
||||||
|
data.get_argument_unchecked(right)
|
||||||
|
.as_boolean()
|
||||||
|
.unwrap_unchecked()
|
||||||
|
};
|
||||||
|
|
||||||
|
left == right
|
||||||
|
}
|
||||||
|
(TypeCode::STRING, TypeCode::STRING) => {
|
||||||
|
let left = unsafe {
|
||||||
|
data.get_argument_unchecked(left)
|
||||||
|
.as_string()
|
||||||
|
.unwrap_unchecked()
|
||||||
|
};
|
||||||
|
let right = unsafe {
|
||||||
|
data.get_argument_unchecked(right)
|
||||||
|
.as_string()
|
||||||
|
.unwrap_unchecked()
|
||||||
|
};
|
||||||
|
|
||||||
|
left == right
|
||||||
|
}
|
||||||
|
_ => panic!("VM Error: Cannot compare values"),
|
||||||
|
};
|
||||||
|
|
||||||
if is_equal == comparator {
|
if is_equal == comparator {
|
||||||
let current_call = data.call_stack.last_mut_unchecked();
|
let current_call = data.call_stack.last_mut_unchecked();
|
||||||
@ -558,9 +614,37 @@ pub fn less(instruction: Instruction, data: &mut ThreadData) -> bool {
|
|||||||
right,
|
right,
|
||||||
right_type,
|
right_type,
|
||||||
} = instruction.into();
|
} = instruction.into();
|
||||||
let left = data.get_argument_unchecked(left);
|
let is_less = match (left_type, right_type) {
|
||||||
let right = data.get_argument_unchecked(right);
|
(TypeCode::INTEGER, TypeCode::INTEGER) => {
|
||||||
let is_less = left < right;
|
let left = unsafe {
|
||||||
|
data.get_argument_unchecked(left)
|
||||||
|
.as_integer()
|
||||||
|
.unwrap_unchecked()
|
||||||
|
};
|
||||||
|
let right = unsafe {
|
||||||
|
data.get_argument_unchecked(right)
|
||||||
|
.as_integer()
|
||||||
|
.unwrap_unchecked()
|
||||||
|
};
|
||||||
|
|
||||||
|
left < right
|
||||||
|
}
|
||||||
|
(TypeCode::FLOAT, TypeCode::FLOAT) => {
|
||||||
|
let left = unsafe {
|
||||||
|
data.get_argument_unchecked(left)
|
||||||
|
.as_float()
|
||||||
|
.unwrap_unchecked()
|
||||||
|
};
|
||||||
|
let right = unsafe {
|
||||||
|
data.get_argument_unchecked(right)
|
||||||
|
.as_float()
|
||||||
|
.unwrap_unchecked()
|
||||||
|
};
|
||||||
|
|
||||||
|
left < right
|
||||||
|
}
|
||||||
|
_ => panic!("VM Error: Cannot compare values"),
|
||||||
|
};
|
||||||
|
|
||||||
if is_less == comparator {
|
if is_less == comparator {
|
||||||
let current_call = data.call_stack.last_mut_unchecked();
|
let current_call = data.call_stack.last_mut_unchecked();
|
||||||
@ -581,9 +665,37 @@ pub fn less_equal(instruction: Instruction, data: &mut ThreadData) -> bool {
|
|||||||
right,
|
right,
|
||||||
right_type,
|
right_type,
|
||||||
} = instruction.into();
|
} = instruction.into();
|
||||||
let left = data.get_argument_unchecked(left);
|
let is_less_or_equal = match (left_type, right_type) {
|
||||||
let right = data.get_argument_unchecked(right);
|
(TypeCode::INTEGER, TypeCode::INTEGER) => {
|
||||||
let is_less_or_equal = left <= right;
|
let left = unsafe {
|
||||||
|
data.get_argument_unchecked(left)
|
||||||
|
.as_integer()
|
||||||
|
.unwrap_unchecked()
|
||||||
|
};
|
||||||
|
let right = unsafe {
|
||||||
|
data.get_argument_unchecked(right)
|
||||||
|
.as_integer()
|
||||||
|
.unwrap_unchecked()
|
||||||
|
};
|
||||||
|
|
||||||
|
left <= right
|
||||||
|
}
|
||||||
|
(TypeCode::FLOAT, TypeCode::FLOAT) => {
|
||||||
|
let left = unsafe {
|
||||||
|
data.get_argument_unchecked(left)
|
||||||
|
.as_float()
|
||||||
|
.unwrap_unchecked()
|
||||||
|
};
|
||||||
|
let right = unsafe {
|
||||||
|
data.get_argument_unchecked(right)
|
||||||
|
.as_float()
|
||||||
|
.unwrap_unchecked()
|
||||||
|
};
|
||||||
|
|
||||||
|
left <= right
|
||||||
|
}
|
||||||
|
_ => panic!("VM Error: Cannot compare values"),
|
||||||
|
};
|
||||||
|
|
||||||
if is_less_or_equal == comparator {
|
if is_less_or_equal == comparator {
|
||||||
let current_call = data.call_stack.last_mut_unchecked();
|
let current_call = data.call_stack.last_mut_unchecked();
|
||||||
|
@ -25,7 +25,8 @@ impl Thread {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let mut call_stack = Stack::with_capacity(self.chunk.prototypes.len() + 1);
|
let mut call_stack = Stack::with_capacity(self.chunk.prototypes.len() + 1);
|
||||||
let main_call = FunctionCall::new(self.chunk.clone(), 0);
|
let mut main_call = FunctionCall::new(self.chunk.clone(), 0);
|
||||||
|
main_call.ip = 1; // The first action is already known
|
||||||
|
|
||||||
call_stack.push(main_call);
|
call_stack.push(main_call);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user