1
0

Fix some bugs to get language working with new 64-bit instructions

This commit is contained in:
Jeff 2025-01-13 10:37:54 -05:00
parent ac1ee793ab
commit 1409698fdd
6 changed files with 156 additions and 37 deletions

View File

@ -46,11 +46,11 @@ use colored::{ColoredString, Colorize};
use crate::{Chunk, Local};
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 LOCAL_COLUMNS: [(&str, usize); 5] = [
@ -286,7 +286,7 @@ impl<'a, W: Write> Disassembler<'a, W> {
.unwrap_or("stripped".to_string());
let operation = instruction.operation().to_string();
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)?;
}

View File

@ -220,7 +220,7 @@ impl Instruction {
}
pub fn d_field(&self) -> bool {
(self.0 >> 54) & 1 == 0
(self.0 >> 54) & 1 != 0
}
pub fn b_type(&self) -> TypeCode {

View File

@ -26,31 +26,31 @@ impl Operation {
// Arithmetic
pub const ADD: Operation = Operation(9);
pub const SUBTRACT: Operation = Operation(16);
pub const MULTIPLY: Operation = Operation(19);
pub const DIVIDE: Operation = Operation(22);
pub const MODULO: Operation = Operation(25);
pub const SUBTRACT: Operation = Operation(10);
pub const MULTIPLY: Operation = Operation(11);
pub const DIVIDE: Operation = Operation(12);
pub const MODULO: Operation = Operation(13);
// Comparison
pub const EQUAL: Operation = Operation(28);
pub const LESS: Operation = Operation(36);
pub const LESS_EQUAL: Operation = Operation(41);
pub const EQUAL: Operation = Operation(14);
pub const LESS: Operation = Operation(15);
pub const LESS_EQUAL: Operation = Operation(16);
// Unary operations
pub const NEGATE: Operation = Operation(46);
pub const NOT: Operation = Operation(48);
pub const NEGATE: Operation = Operation(17);
pub const NOT: Operation = Operation(18);
// Logical operations
pub const TEST: Operation = Operation(49);
pub const TEST_SET: Operation = Operation(50);
pub const TEST: Operation = Operation(19);
pub const TEST_SET: Operation = Operation(20);
// Function calls
pub const CALL: Operation = Operation(51);
pub const CALL_NATIVE: Operation = Operation(52);
pub const CALL: Operation = Operation(21);
pub const CALL_NATIVE: Operation = Operation(22);
// Control flow
pub const JUMP: Operation = Operation(53);
pub const RETURN: Operation = Operation(54);
pub const JUMP: Operation = Operation(23);
pub const RETURN: Operation = Operation(24);
}
impl Operation {

View File

@ -48,10 +48,16 @@ impl Vm {
.unwrap_or_else(|| "anonymous".to_string());
let mut main_thread = Thread::new(Arc::new(self.main_chunk));
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 _ = tx.send(value_option);
});
})
.unwrap()
.join()
.unwrap();
rx.recv().unwrap_or(None)
}

View File

@ -44,13 +44,13 @@ pub const RUNNER_LOGIC_TABLE: [RunnerLogic; 25] = [
multiply,
divide,
modulo,
test,
test_set,
equal,
less,
less_equal,
negate,
not,
test,
test_set,
call,
call_native,
jump,
@ -535,9 +535,65 @@ pub fn equal(instruction: Instruction, data: &mut ThreadData) -> bool {
right,
right_type,
} = instruction.into();
let left = data.get_argument_unchecked(left);
let right = data.get_argument_unchecked(right);
let is_equal = left.equals(right);
let is_equal = match (left_type, right_type) {
(TypeCode::INTEGER, TypeCode::INTEGER) => {
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 {
let current_call = data.call_stack.last_mut_unchecked();
@ -558,9 +614,37 @@ pub fn less(instruction: Instruction, data: &mut ThreadData) -> bool {
right,
right_type,
} = instruction.into();
let left = data.get_argument_unchecked(left);
let right = data.get_argument_unchecked(right);
let is_less = left < right;
let is_less = match (left_type, right_type) {
(TypeCode::INTEGER, TypeCode::INTEGER) => {
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 {
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_type,
} = instruction.into();
let left = data.get_argument_unchecked(left);
let right = data.get_argument_unchecked(right);
let is_less_or_equal = left <= right;
let is_less_or_equal = match (left_type, right_type) {
(TypeCode::INTEGER, TypeCode::INTEGER) => {
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 {
let current_call = data.call_stack.last_mut_unchecked();

View File

@ -25,7 +25,8 @@ impl Thread {
);
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);