Fix comparison tests; Implement less_equal and equal actions
This commit is contained in:
parent
07f8b36c99
commit
7f939b693e
@ -1,7 +1,7 @@
|
||||
use std::io::{stdin, stdout, Write};
|
||||
use std::ops::Range;
|
||||
|
||||
use crate::vm::{Register, RuntimeValue, Thread};
|
||||
use crate::vm::{RuntimeValue, Thread};
|
||||
use crate::DustString;
|
||||
|
||||
pub fn read_line(data: &mut Thread, destination: usize, _argument_range: Range<usize>) {
|
||||
|
@ -2,7 +2,7 @@ use std::ops::Range;
|
||||
|
||||
use rand::Rng;
|
||||
|
||||
use crate::vm::{Register, RuntimeValue, Thread};
|
||||
use crate::vm::{RuntimeValue, Thread};
|
||||
|
||||
pub fn random_int(data: &mut Thread, destination: usize, argument_range: Range<usize>) {
|
||||
let current_frame = data.current_frame_mut();
|
||||
|
198
dust-lang/src/vm/action/equal.rs
Normal file
198
dust-lang/src/vm/action/equal.rs
Normal file
@ -0,0 +1,198 @@
|
||||
use tracing::trace;
|
||||
|
||||
use crate::{
|
||||
instruction::InstructionFields,
|
||||
vm::{RuntimeValue, Thread},
|
||||
};
|
||||
|
||||
pub fn equal_booleans(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let left_index = instruction.b_field as usize;
|
||||
let right_index = instruction.c_field as usize;
|
||||
let comparator = instruction.d_field;
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = current_frame.get_boolean_from_register(left_index);
|
||||
let right_value = current_frame.get_boolean_from_register(right_index);
|
||||
let is_equal = left_value == right_value;
|
||||
|
||||
if is_equal == comparator {
|
||||
*ip += 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn equal_bytes(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let left = instruction.b_field as usize;
|
||||
let right = instruction.c_field as usize;
|
||||
let comparator = instruction.d_field;
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = current_frame.get_byte_from_register(left);
|
||||
let right_value = current_frame.get_byte_from_register(right);
|
||||
let is_equal = left_value == right_value;
|
||||
|
||||
if is_equal == comparator {
|
||||
*ip += 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn equal_characters(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let left_index = instruction.b_field as usize;
|
||||
let left_is_constant = instruction.b_is_constant;
|
||||
let right_index = instruction.c_field as usize;
|
||||
let right_is_constant = instruction.c_is_constant;
|
||||
let comparator = instruction.d_field;
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = if left_is_constant {
|
||||
current_frame.get_character_constant(left_index)
|
||||
} else {
|
||||
current_frame.get_character_from_register(left_index)
|
||||
};
|
||||
let right_value = if right_is_constant {
|
||||
current_frame.get_character_constant(right_index)
|
||||
} else {
|
||||
current_frame.get_character_from_register(right_index)
|
||||
};
|
||||
let is_equal = left_value == right_value;
|
||||
|
||||
if is_equal == comparator {
|
||||
*ip += 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn equal_floats(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let left = instruction.b_field as usize;
|
||||
let left_is_constant = instruction.b_is_constant;
|
||||
let right = instruction.c_field as usize;
|
||||
let right_is_constant = instruction.c_is_constant;
|
||||
let comparator = instruction.d_field;
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = if left_is_constant {
|
||||
current_frame.get_float_constant(left)
|
||||
} else {
|
||||
current_frame.get_float_from_register(left)
|
||||
};
|
||||
let right_value = if right_is_constant {
|
||||
current_frame.get_float_constant(right)
|
||||
} else {
|
||||
current_frame.get_float_from_register(right)
|
||||
};
|
||||
let is_equal = left_value == right_value;
|
||||
|
||||
if is_equal == comparator {
|
||||
*ip += 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn equal_integers(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let left = instruction.b_field as usize;
|
||||
let left_is_constant = instruction.b_is_constant;
|
||||
let right = instruction.c_field as usize;
|
||||
let right_is_constant = instruction.c_is_constant;
|
||||
let comparator = instruction.d_field;
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = if left_is_constant {
|
||||
current_frame.get_integer_constant(left)
|
||||
} else {
|
||||
current_frame.get_integer_from_register(left)
|
||||
};
|
||||
let right_value = if right_is_constant {
|
||||
current_frame.get_integer_constant(right)
|
||||
} else {
|
||||
current_frame.get_integer_from_register(right)
|
||||
};
|
||||
let is_equal = left_value == right_value;
|
||||
|
||||
if is_equal == comparator {
|
||||
*ip += 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn equal_strings(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let left = instruction.b_field as usize;
|
||||
let left_is_constant = instruction.b_is_constant;
|
||||
let right = instruction.c_field as usize;
|
||||
let right_is_constant = instruction.c_is_constant;
|
||||
let comparator = instruction.d_field;
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = if left_is_constant {
|
||||
current_frame.get_string_constant(left)
|
||||
} else {
|
||||
current_frame.get_string_from_register(left)
|
||||
};
|
||||
let right_value = if right_is_constant {
|
||||
current_frame.get_string_constant(right)
|
||||
} else {
|
||||
current_frame.get_string_from_register(right)
|
||||
};
|
||||
let is_equal = left_value == right_value;
|
||||
|
||||
if is_equal == comparator {
|
||||
*ip += 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn optimized_equal_integers(
|
||||
ip: &mut usize,
|
||||
instruction: &InstructionFields,
|
||||
thread: &mut Thread,
|
||||
cache: &mut Option<[RuntimeValue<i64>; 2]>,
|
||||
) {
|
||||
if let Some([left, right]) = cache {
|
||||
trace!("equal_INTEGERS_OPTIMIZED using cache");
|
||||
|
||||
let is_equal = left == right;
|
||||
|
||||
if is_equal {
|
||||
*ip += 1;
|
||||
}
|
||||
} else {
|
||||
let left_index = instruction.b_field as usize;
|
||||
let left_is_constant = instruction.b_is_constant;
|
||||
let right_index = instruction.c_field as usize;
|
||||
let right_is_constant = instruction.c_is_constant;
|
||||
let comparator = instruction.d_field;
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = if left_is_constant {
|
||||
let value = current_frame.get_integer_constant_mut(left_index).to_rc();
|
||||
|
||||
current_frame.constants.integers[left_index] = value.clone();
|
||||
|
||||
value
|
||||
} else {
|
||||
let value = current_frame
|
||||
.get_integer_from_register_mut(left_index)
|
||||
.to_ref_cell();
|
||||
|
||||
current_frame.registers.integers[left_index].set(value.clone());
|
||||
|
||||
value
|
||||
};
|
||||
let right_value = if right_is_constant {
|
||||
let value = current_frame.get_integer_constant_mut(right_index).to_rc();
|
||||
|
||||
current_frame.constants.integers[right_index] = value.clone();
|
||||
|
||||
value
|
||||
} else {
|
||||
let value = current_frame
|
||||
.get_integer_from_register_mut(right_index)
|
||||
.to_ref_cell();
|
||||
|
||||
current_frame.registers.integers[right_index].set(value.clone());
|
||||
|
||||
value
|
||||
};
|
||||
let is_equal = left_value == right_value;
|
||||
|
||||
if is_equal == comparator {
|
||||
*ip += 1;
|
||||
}
|
||||
|
||||
*cache = Some([left_value, right_value]);
|
||||
}
|
||||
}
|
198
dust-lang/src/vm/action/less_equal.rs
Normal file
198
dust-lang/src/vm/action/less_equal.rs
Normal file
@ -0,0 +1,198 @@
|
||||
use tracing::trace;
|
||||
|
||||
use crate::{
|
||||
instruction::InstructionFields,
|
||||
vm::{RuntimeValue, Thread},
|
||||
};
|
||||
|
||||
pub fn less_equal_booleans(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let left_index = instruction.b_field as usize;
|
||||
let right_index = instruction.c_field as usize;
|
||||
let comparator = instruction.d_field;
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = current_frame.get_boolean_from_register(left_index);
|
||||
let right_value = current_frame.get_boolean_from_register(right_index);
|
||||
let is_less_than_or_equal = left_value <= right_value;
|
||||
|
||||
if is_less_than_or_equal == comparator {
|
||||
*ip += 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn less_equal_bytes(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let left = instruction.b_field as usize;
|
||||
let right = instruction.c_field as usize;
|
||||
let comparator = instruction.d_field;
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = current_frame.get_byte_from_register(left);
|
||||
let right_value = current_frame.get_byte_from_register(right);
|
||||
let is_less_than_or_equal = left_value <= right_value;
|
||||
|
||||
if is_less_than_or_equal == comparator {
|
||||
*ip += 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn less_equal_characters(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let left_index = instruction.b_field as usize;
|
||||
let left_is_constant = instruction.b_is_constant;
|
||||
let right_index = instruction.c_field as usize;
|
||||
let right_is_constant = instruction.c_is_constant;
|
||||
let comparator = instruction.d_field;
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = if left_is_constant {
|
||||
current_frame.get_character_constant(left_index)
|
||||
} else {
|
||||
current_frame.get_character_from_register(left_index)
|
||||
};
|
||||
let right_value = if right_is_constant {
|
||||
current_frame.get_character_constant(right_index)
|
||||
} else {
|
||||
current_frame.get_character_from_register(right_index)
|
||||
};
|
||||
let is_less_than_or_equal = left_value <= right_value;
|
||||
|
||||
if is_less_than_or_equal == comparator {
|
||||
*ip += 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn less_equal_floats(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let left = instruction.b_field as usize;
|
||||
let left_is_constant = instruction.b_is_constant;
|
||||
let right = instruction.c_field as usize;
|
||||
let right_is_constant = instruction.c_is_constant;
|
||||
let comparator = instruction.d_field;
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = if left_is_constant {
|
||||
current_frame.get_float_constant(left)
|
||||
} else {
|
||||
current_frame.get_float_from_register(left)
|
||||
};
|
||||
let right_value = if right_is_constant {
|
||||
current_frame.get_float_constant(right)
|
||||
} else {
|
||||
current_frame.get_float_from_register(right)
|
||||
};
|
||||
let is_less_than_or_equal = left_value <= right_value;
|
||||
|
||||
if is_less_than_or_equal == comparator {
|
||||
*ip += 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn less_equal_integers(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let left = instruction.b_field as usize;
|
||||
let left_is_constant = instruction.b_is_constant;
|
||||
let right = instruction.c_field as usize;
|
||||
let right_is_constant = instruction.c_is_constant;
|
||||
let comparator = instruction.d_field;
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = if left_is_constant {
|
||||
current_frame.get_integer_constant(left)
|
||||
} else {
|
||||
current_frame.get_integer_from_register(left)
|
||||
};
|
||||
let right_value = if right_is_constant {
|
||||
current_frame.get_integer_constant(right)
|
||||
} else {
|
||||
current_frame.get_integer_from_register(right)
|
||||
};
|
||||
let is_less_than_or_equal = left_value <= right_value;
|
||||
|
||||
if is_less_than_or_equal == comparator {
|
||||
*ip += 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn less_equal_strings(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
let left = instruction.b_field as usize;
|
||||
let left_is_constant = instruction.b_is_constant;
|
||||
let right = instruction.c_field as usize;
|
||||
let right_is_constant = instruction.c_is_constant;
|
||||
let comparator = instruction.d_field;
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = if left_is_constant {
|
||||
current_frame.get_string_constant(left)
|
||||
} else {
|
||||
current_frame.get_string_from_register(left)
|
||||
};
|
||||
let right_value = if right_is_constant {
|
||||
current_frame.get_string_constant(right)
|
||||
} else {
|
||||
current_frame.get_string_from_register(right)
|
||||
};
|
||||
let is_less_than_or_equal = left_value <= right_value;
|
||||
|
||||
if is_less_than_or_equal == comparator {
|
||||
*ip += 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn optimized_less_equal_integers(
|
||||
ip: &mut usize,
|
||||
instruction: &InstructionFields,
|
||||
thread: &mut Thread,
|
||||
cache: &mut Option<[RuntimeValue<i64>; 2]>,
|
||||
) {
|
||||
if let Some([left, right]) = cache {
|
||||
trace!("LESS_INTEGERS_OPTIMIZED using cache");
|
||||
|
||||
let is_less_than_or_equal = left <= right;
|
||||
|
||||
if is_less_than_or_equal {
|
||||
*ip += 1;
|
||||
}
|
||||
} else {
|
||||
let left_index = instruction.b_field as usize;
|
||||
let left_is_constant = instruction.b_is_constant;
|
||||
let right_index = instruction.c_field as usize;
|
||||
let right_is_constant = instruction.c_is_constant;
|
||||
let comparator = instruction.d_field;
|
||||
|
||||
let current_frame = thread.current_frame_mut();
|
||||
let left_value = if left_is_constant {
|
||||
let value = current_frame.get_integer_constant_mut(left_index).to_rc();
|
||||
|
||||
current_frame.constants.integers[left_index] = value.clone();
|
||||
|
||||
value
|
||||
} else {
|
||||
let value = current_frame
|
||||
.get_integer_from_register_mut(left_index)
|
||||
.to_ref_cell();
|
||||
|
||||
current_frame.registers.integers[left_index].set(value.clone());
|
||||
|
||||
value
|
||||
};
|
||||
let right_value = if right_is_constant {
|
||||
let value = current_frame.get_integer_constant_mut(right_index).to_rc();
|
||||
|
||||
current_frame.constants.integers[right_index] = value.clone();
|
||||
|
||||
value
|
||||
} else {
|
||||
let value = current_frame
|
||||
.get_integer_from_register_mut(right_index)
|
||||
.to_ref_cell();
|
||||
|
||||
current_frame.registers.integers[right_index].set(value.clone());
|
||||
|
||||
value
|
||||
};
|
||||
let is_less_than_or_equal = left_value <= right_value;
|
||||
|
||||
if is_less_than_or_equal == comparator {
|
||||
*ip += 1;
|
||||
}
|
||||
|
||||
*cache = Some([left_value, right_value]);
|
||||
}
|
||||
}
|
@ -1,17 +1,24 @@
|
||||
mod add;
|
||||
mod equal;
|
||||
mod jump;
|
||||
mod less;
|
||||
mod less_equal;
|
||||
|
||||
use add::{
|
||||
add_bytes, add_character_string, add_characters, add_floats, add_integers,
|
||||
add_string_character, add_strings, optimized_add_integer,
|
||||
};
|
||||
use equal::optimized_equal_integers;
|
||||
use jump::jump;
|
||||
use less::{
|
||||
less_booleans, less_bytes, less_characters, less_floats, less_integers, less_strings,
|
||||
optimized_less_integers,
|
||||
};
|
||||
|
||||
use less_equal::{
|
||||
less_equal_booleans, less_equal_bytes, less_equal_characters, less_equal_floats,
|
||||
less_equal_integers, less_equal_strings, optimized_less_equal_integers,
|
||||
};
|
||||
use tracing::info;
|
||||
|
||||
use std::fmt::{self, Display, Formatter};
|
||||
@ -29,7 +36,6 @@ pub struct ActionSequence {
|
||||
}
|
||||
|
||||
impl ActionSequence {
|
||||
#[allow(clippy::while_let_on_iterator)]
|
||||
pub fn new(instructions: Vec<InstructionFields>) -> Self {
|
||||
let mut actions = Vec::with_capacity(instructions.len());
|
||||
let mut instructions_reversed = instructions.into_iter().rev();
|
||||
@ -93,9 +99,15 @@ impl ActionSequence {
|
||||
Action::OptimizedAddIntegers(cache) => {
|
||||
optimized_add_integer(instruction, thread, cache);
|
||||
}
|
||||
Action::OptimizedEqualIntegers(cache) => {
|
||||
optimized_equal_integers(&mut local_ip, instruction, thread, cache);
|
||||
}
|
||||
Action::OptimizedLessIntegers(cache) => {
|
||||
optimized_less_integers(&mut local_ip, instruction, thread, cache);
|
||||
}
|
||||
Action::OptimizedLessEqualIntegers(cache) => {
|
||||
optimized_less_equal_integers(&mut local_ip, instruction, thread, cache);
|
||||
}
|
||||
Action::OptimizedJumpForward { offset } => {
|
||||
local_ip += *offset;
|
||||
}
|
||||
@ -133,7 +145,9 @@ enum Action {
|
||||
actions: ActionSequence,
|
||||
},
|
||||
OptimizedAddIntegers(Option<[RuntimeValue<i64>; 3]>),
|
||||
OptimizedEqualIntegers(Option<[RuntimeValue<i64>; 2]>),
|
||||
OptimizedLessIntegers(Option<[RuntimeValue<i64>; 2]>),
|
||||
OptimizedLessEqualIntegers(Option<[RuntimeValue<i64>; 2]>),
|
||||
OptimizedJumpForward {
|
||||
offset: usize,
|
||||
},
|
||||
@ -168,7 +182,15 @@ impl Action {
|
||||
Operation::MODULO => modulo,
|
||||
Operation::NEGATE => negate,
|
||||
Operation::NOT => not,
|
||||
Operation::EQUAL => equal,
|
||||
Operation::EQUAL => match (instruction.b_type, instruction.c_type) {
|
||||
(TypeCode::BOOLEAN, TypeCode::BOOLEAN) => equal::equal_booleans,
|
||||
(TypeCode::BYTE, TypeCode::BYTE) => equal::equal_bytes,
|
||||
(TypeCode::CHARACTER, TypeCode::CHARACTER) => equal::equal_characters,
|
||||
(TypeCode::FLOAT, TypeCode::FLOAT) => equal::equal_floats,
|
||||
(TypeCode::INTEGER, TypeCode::INTEGER) => equal::equal_integers,
|
||||
(TypeCode::STRING, TypeCode::STRING) => equal::equal_strings,
|
||||
_ => todo!(),
|
||||
},
|
||||
Operation::LESS => match (instruction.b_type, instruction.c_type) {
|
||||
(TypeCode::BOOLEAN, TypeCode::BOOLEAN) => less_booleans,
|
||||
(TypeCode::BYTE, TypeCode::BYTE) => less_bytes,
|
||||
@ -178,7 +200,15 @@ impl Action {
|
||||
(TypeCode::STRING, TypeCode::STRING) => less_strings,
|
||||
_ => todo!(),
|
||||
},
|
||||
Operation::LESS_EQUAL => less_equal,
|
||||
Operation::LESS_EQUAL => match (instruction.b_type, instruction.c_type) {
|
||||
(TypeCode::BOOLEAN, TypeCode::BOOLEAN) => less_equal_booleans,
|
||||
(TypeCode::BYTE, TypeCode::BYTE) => less_equal_bytes,
|
||||
(TypeCode::CHARACTER, TypeCode::CHARACTER) => less_equal_characters,
|
||||
(TypeCode::FLOAT, TypeCode::FLOAT) => less_equal_floats,
|
||||
(TypeCode::INTEGER, TypeCode::INTEGER) => less_equal_integers,
|
||||
(TypeCode::STRING, TypeCode::STRING) => less_equal_strings,
|
||||
_ => todo!(),
|
||||
},
|
||||
Operation::TEST => test,
|
||||
Operation::TEST_SET => test_set,
|
||||
Operation::CALL => call,
|
||||
@ -197,10 +227,18 @@ impl Action {
|
||||
(TypeCode::INTEGER, TypeCode::INTEGER) => Action::OptimizedAddIntegers(None),
|
||||
_ => todo!(),
|
||||
},
|
||||
Operation::EQUAL => match (instruction.b_type, instruction.c_type) {
|
||||
(TypeCode::INTEGER, TypeCode::INTEGER) => Action::OptimizedEqualIntegers(None),
|
||||
_ => todo!(),
|
||||
},
|
||||
Operation::LESS => match (instruction.b_type, instruction.c_type) {
|
||||
(TypeCode::INTEGER, TypeCode::INTEGER) => Action::OptimizedLessIntegers(None),
|
||||
_ => todo!(),
|
||||
},
|
||||
Operation::LESS_EQUAL => match (instruction.b_type, instruction.c_type) {
|
||||
(TypeCode::INTEGER, TypeCode::INTEGER) => Action::OptimizedLessEqualIntegers(None),
|
||||
_ => todo!(),
|
||||
},
|
||||
Operation::JUMP => {
|
||||
let offset = instruction.b_field as usize;
|
||||
let is_positive = instruction.c_field != 0;
|
||||
@ -232,9 +270,15 @@ impl Display for Action {
|
||||
Action::OptimizedAddIntegers { .. } => {
|
||||
write!(f, "ADD_INTEGERS_OPTIMIZED")
|
||||
}
|
||||
Action::OptimizedEqualIntegers { .. } => {
|
||||
write!(f, "EQUAL_INTEGERS_OPTIMIZED")
|
||||
}
|
||||
Action::OptimizedLessIntegers { .. } => {
|
||||
write!(f, "LESS_INTEGERS_OPTIMIZED")
|
||||
}
|
||||
Action::OptimizedLessEqualIntegers { .. } => {
|
||||
write!(f, "LESS_EQUAL_INTEGERS_OPTIMIZED")
|
||||
}
|
||||
Action::OptimizedJumpForward { offset } => {
|
||||
write!(f, "JUMP +{offset}")
|
||||
}
|
||||
@ -256,7 +300,39 @@ fn close(_: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
}
|
||||
|
||||
fn load_encoded(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
todo!()
|
||||
let destination = instruction.a_field;
|
||||
let value_type = instruction.b_type;
|
||||
let jump_next = instruction.c_field != 0;
|
||||
|
||||
match value_type {
|
||||
TypeCode::BOOLEAN => {
|
||||
let value = instruction.b_field != 0;
|
||||
|
||||
thread
|
||||
.current_frame_mut()
|
||||
.registers
|
||||
.booleans
|
||||
.get_mut(destination as usize)
|
||||
.as_value_mut()
|
||||
.set_inner(value);
|
||||
}
|
||||
TypeCode::BYTE => {
|
||||
let value = instruction.b_field as u8;
|
||||
|
||||
thread
|
||||
.current_frame_mut()
|
||||
.registers
|
||||
.bytes
|
||||
.get_mut(destination as usize)
|
||||
.as_value_mut()
|
||||
.set_inner(value);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
||||
if jump_next {
|
||||
*ip += 1;
|
||||
}
|
||||
}
|
||||
|
||||
fn load_constant(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
@ -347,10 +423,6 @@ fn test_set(_: &mut usize, _: &InstructionFields, _: &mut Thread) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn equal(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn less_equal(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
|
||||
todo!()
|
||||
}
|
||||
|
@ -437,14 +437,10 @@ impl<T: Clone> RuntimeValue<T> {
|
||||
pub fn set_inner(&mut self, new_value: T) {
|
||||
match self {
|
||||
Self::Raw(value) => *value = new_value,
|
||||
Self::Rc(value) => {
|
||||
if let Some(mutable) = Rc::get_mut(value) {
|
||||
*mutable = new_value;
|
||||
}
|
||||
}
|
||||
Self::RefCell(value) => {
|
||||
let _ = value.replace(new_value);
|
||||
}
|
||||
Self::Rc(_) => panic!("Attempted to modify immutable runtime value"),
|
||||
}
|
||||
}
|
||||
|
||||
@ -459,7 +455,7 @@ impl<T: Clone> RuntimeValue<T> {
|
||||
pub fn borrow_mut(&self) -> RefMut<T> {
|
||||
match self {
|
||||
Self::RefCell(value) => value.borrow_mut(),
|
||||
_ => panic!("Attempted to borrow mutable reference from immutable register value"),
|
||||
_ => panic!("Attempted to borrow mutable reference from immutable runtime value"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use dust_lang::{
|
||||
Chunk, ConcreteValue, DustString, FunctionType, Instruction, Operand, Span, Type, Value,
|
||||
compile, instruction::TypeCode, run,
|
||||
compile, instruction::TypeCode, run, Chunk, DustString, FunctionType, Instruction, Operand,
|
||||
Span, Type, Value,
|
||||
};
|
||||
|
||||
#[test]
|
||||
@ -61,7 +61,7 @@ fn equal_characters() {
|
||||
Span(0, 10),
|
||||
Span(10, 10),
|
||||
],
|
||||
constants: vec![ConcreteValue::Character('a'), ConcreteValue::Character('b')],
|
||||
character_constants: vec!['a', 'b'],
|
||||
..Chunk::default()
|
||||
};
|
||||
let return_value = Some(Value::boolean(false));
|
||||
@ -93,7 +93,7 @@ fn equal_floats() {
|
||||
Span(0, 11),
|
||||
Span(11, 11),
|
||||
],
|
||||
constants: vec![ConcreteValue::Float(10.0), ConcreteValue::Float(3.0)],
|
||||
float_constants: vec![10.0, 3.0],
|
||||
..Chunk::default()
|
||||
};
|
||||
let return_value = Some(Value::boolean(false));
|
||||
@ -119,7 +119,7 @@ fn equal_integers() {
|
||||
Instruction::r#return(true, 0, TypeCode::BOOLEAN),
|
||||
],
|
||||
positions: vec![Span(0, 7), Span(0, 7), Span(0, 7), Span(0, 7), Span(7, 7)],
|
||||
constants: vec![ConcreteValue::Integer(10), ConcreteValue::Integer(3)],
|
||||
integer_constants: vec![10, 3],
|
||||
..Chunk::default()
|
||||
};
|
||||
let return_value = Some(Value::boolean(false));
|
||||
@ -151,10 +151,7 @@ fn equal_strings() {
|
||||
Span(0, 14),
|
||||
Span(14, 14),
|
||||
],
|
||||
constants: vec![
|
||||
ConcreteValue::String(DustString::from("abc")),
|
||||
ConcreteValue::String(DustString::from("def")),
|
||||
],
|
||||
string_constants: vec![DustString::from("abc"), DustString::from("def")],
|
||||
..Chunk::default()
|
||||
};
|
||||
let return_value = Some(Value::boolean(false));
|
||||
|
@ -1,6 +1,6 @@
|
||||
use dust_lang::{
|
||||
Chunk, ConcreteValue, DustString, FunctionType, Instruction, Operand, Span, Type, Value,
|
||||
compile, instruction::TypeCode, run,
|
||||
compile, instruction::TypeCode, run, Chunk, DustString, FunctionType, Instruction, Operand,
|
||||
Span, Type, Value,
|
||||
};
|
||||
|
||||
#[test]
|
||||
@ -55,7 +55,7 @@ fn greater_characters() {
|
||||
Instruction::r#return(true, 0, TypeCode::BOOLEAN),
|
||||
],
|
||||
positions: vec![Span(0, 9), Span(0, 9), Span(0, 9), Span(0, 9), Span(9, 9)],
|
||||
constants: vec![ConcreteValue::Character('a'), ConcreteValue::Character('b')],
|
||||
character_constants: vec!['a', 'b'],
|
||||
..Chunk::default()
|
||||
};
|
||||
let return_value = Some(Value::boolean(false));
|
||||
@ -87,7 +87,7 @@ fn greater_floats() {
|
||||
Span(0, 10),
|
||||
Span(10, 10),
|
||||
],
|
||||
constants: vec![ConcreteValue::Float(10.0), ConcreteValue::Float(3.0)],
|
||||
float_constants: vec![10.0, 3.0],
|
||||
..Chunk::default()
|
||||
};
|
||||
let return_value = Some(Value::boolean(true));
|
||||
@ -113,7 +113,7 @@ fn greater_integers() {
|
||||
Instruction::r#return(true, 0, TypeCode::BOOLEAN),
|
||||
],
|
||||
positions: vec![Span(0, 6), Span(0, 6), Span(0, 6), Span(0, 6), Span(6, 6)],
|
||||
constants: vec![ConcreteValue::Integer(10), ConcreteValue::Integer(3)],
|
||||
integer_constants: vec![10, 3],
|
||||
..Chunk::default()
|
||||
};
|
||||
let return_value = Some(Value::boolean(true));
|
||||
@ -145,10 +145,7 @@ fn greater_strings() {
|
||||
Span(0, 13),
|
||||
Span(13, 13),
|
||||
],
|
||||
constants: vec![
|
||||
ConcreteValue::String(DustString::from("abc")),
|
||||
ConcreteValue::String(DustString::from("def")),
|
||||
],
|
||||
string_constants: vec![DustString::from("abc"), DustString::from("def")],
|
||||
..Chunk::default()
|
||||
};
|
||||
let return_value = Some(Value::boolean(false));
|
||||
|
@ -1,6 +1,6 @@
|
||||
use dust_lang::{
|
||||
Chunk, ConcreteValue, DustString, FunctionType, Instruction, Operand, Span, Type, Value,
|
||||
compile, instruction::TypeCode, run,
|
||||
compile, instruction::TypeCode, run, Chunk, DustString, FunctionType, Instruction, Operand,
|
||||
Span, Type, Value,
|
||||
};
|
||||
|
||||
#[test]
|
||||
@ -96,7 +96,7 @@ fn greater_equal_characters() {
|
||||
Span(0, 10),
|
||||
Span(10, 10),
|
||||
],
|
||||
constants: vec![ConcreteValue::Character('a'), ConcreteValue::Character('b')],
|
||||
character_constants: vec!['a', 'b'],
|
||||
..Chunk::default()
|
||||
};
|
||||
let return_value = Some(Value::boolean(false));
|
||||
@ -128,7 +128,7 @@ fn greater_equal_floats() {
|
||||
Span(0, 11),
|
||||
Span(11, 11),
|
||||
],
|
||||
constants: vec![ConcreteValue::Float(10.0), ConcreteValue::Float(3.0)],
|
||||
float_constants: vec![10.0, 3.0],
|
||||
..Chunk::default()
|
||||
};
|
||||
let return_value = Some(Value::boolean(true));
|
||||
@ -154,7 +154,7 @@ fn greater_equal_integers() {
|
||||
Instruction::r#return(true, 0, TypeCode::BOOLEAN),
|
||||
],
|
||||
positions: vec![Span(0, 7), Span(0, 7), Span(0, 7), Span(0, 7), Span(7, 7)],
|
||||
constants: vec![ConcreteValue::Integer(10), ConcreteValue::Integer(3)],
|
||||
integer_constants: vec![10, 3],
|
||||
..Chunk::default()
|
||||
};
|
||||
let return_value = Some(Value::boolean(true));
|
||||
@ -186,10 +186,7 @@ fn greater_equal_strings() {
|
||||
Span(0, 14),
|
||||
Span(14, 14),
|
||||
],
|
||||
constants: vec![
|
||||
ConcreteValue::String(DustString::from("abc")),
|
||||
ConcreteValue::String(DustString::from("def")),
|
||||
],
|
||||
string_constants: vec![DustString::from("abc"), DustString::from("def")],
|
||||
..Chunk::default()
|
||||
};
|
||||
let return_value = Some(Value::boolean(false));
|
||||
|
@ -1,6 +1,6 @@
|
||||
use dust_lang::{
|
||||
Chunk, ConcreteValue, DustString, FunctionType, Instruction, Operand, Span, Type, Value,
|
||||
compile, instruction::TypeCode, run,
|
||||
compile, instruction::TypeCode, run, Chunk, DustString, FunctionType, Instruction, Operand,
|
||||
Span, Type, Value,
|
||||
};
|
||||
|
||||
#[test]
|
||||
@ -90,7 +90,7 @@ fn less_characters() {
|
||||
Instruction::r#return(true, 0, TypeCode::BOOLEAN),
|
||||
],
|
||||
positions: vec![Span(0, 9), Span(0, 9), Span(0, 9), Span(0, 9), Span(9, 9)],
|
||||
constants: vec![ConcreteValue::Character('a'), ConcreteValue::Character('b')],
|
||||
character_constants: vec!['a', 'b'],
|
||||
..Chunk::default()
|
||||
};
|
||||
let return_value = Some(Value::boolean(true));
|
||||
@ -122,7 +122,7 @@ fn less_floats() {
|
||||
Span(0, 10),
|
||||
Span(10, 10),
|
||||
],
|
||||
constants: vec![ConcreteValue::Float(10.0), ConcreteValue::Float(3.0)],
|
||||
float_constants: vec![10.0, 3.0],
|
||||
..Chunk::default()
|
||||
};
|
||||
let return_value = Some(Value::boolean(false));
|
||||
@ -148,7 +148,7 @@ fn less_integers() {
|
||||
Instruction::r#return(true, 0, TypeCode::BOOLEAN),
|
||||
],
|
||||
positions: vec![Span(0, 6), Span(0, 6), Span(0, 6), Span(0, 6), Span(6, 6)],
|
||||
constants: vec![ConcreteValue::Integer(10), ConcreteValue::Integer(3)],
|
||||
integer_constants: vec![10, 3],
|
||||
..Chunk::default()
|
||||
};
|
||||
let return_value = Some(Value::boolean(false));
|
||||
@ -180,10 +180,7 @@ fn less_strings() {
|
||||
Span(0, 13),
|
||||
Span(13, 13),
|
||||
],
|
||||
constants: vec![
|
||||
ConcreteValue::String(DustString::from("abc")),
|
||||
ConcreteValue::String(DustString::from("def")),
|
||||
],
|
||||
string_constants: vec![DustString::from("abc"), DustString::from("def")],
|
||||
..Chunk::default()
|
||||
};
|
||||
let return_value = Some(Value::boolean(true));
|
||||
|
@ -1,6 +1,6 @@
|
||||
use dust_lang::{
|
||||
Chunk, ConcreteValue, DustString, FunctionType, Instruction, Operand, Span, Type, Value,
|
||||
compile, instruction::TypeCode, run,
|
||||
compile, instruction::TypeCode, run, Chunk, DustString, FunctionType, Instruction, Operand,
|
||||
Span, Type, Value,
|
||||
};
|
||||
|
||||
#[test]
|
||||
@ -96,7 +96,7 @@ fn less_equal_characters() {
|
||||
Span(0, 10),
|
||||
Span(10, 10),
|
||||
],
|
||||
constants: vec![ConcreteValue::Character('a'), ConcreteValue::Character('b')],
|
||||
character_constants: vec!['a', 'b'],
|
||||
..Chunk::default()
|
||||
};
|
||||
let return_value = Some(Value::boolean(true));
|
||||
@ -128,7 +128,7 @@ fn less_equal_floats() {
|
||||
Span(0, 11),
|
||||
Span(11, 11),
|
||||
],
|
||||
constants: vec![ConcreteValue::Float(10.0), ConcreteValue::Float(3.0)],
|
||||
float_constants: vec![10.0, 3.0],
|
||||
..Chunk::default()
|
||||
};
|
||||
let return_value = Some(Value::boolean(false));
|
||||
@ -154,7 +154,7 @@ fn less_equal_integers() {
|
||||
Instruction::r#return(true, 0, TypeCode::BOOLEAN),
|
||||
],
|
||||
positions: vec![Span(0, 7), Span(0, 7), Span(0, 7), Span(0, 7), Span(7, 7)],
|
||||
constants: vec![ConcreteValue::Integer(10), ConcreteValue::Integer(3)],
|
||||
integer_constants: vec![10, 3],
|
||||
..Chunk::default()
|
||||
};
|
||||
let return_value = Some(Value::boolean(false));
|
||||
@ -186,10 +186,7 @@ fn less_equal_strings() {
|
||||
Span(0, 14),
|
||||
Span(14, 14),
|
||||
],
|
||||
constants: vec![
|
||||
ConcreteValue::String(DustString::from("abc")),
|
||||
ConcreteValue::String(DustString::from("def")),
|
||||
],
|
||||
string_constants: vec![DustString::from("abc"), DustString::from("def")],
|
||||
..Chunk::default()
|
||||
};
|
||||
let return_value = Some(Value::boolean(true));
|
||||
|
@ -1,6 +1,6 @@
|
||||
use dust_lang::{
|
||||
Chunk, ConcreteValue, DustString, FunctionType, Instruction, Operand, Span, Type, Value,
|
||||
compile, instruction::TypeCode, run,
|
||||
compile, instruction::TypeCode, run, Chunk, DustString, FunctionType, Instruction, Operand,
|
||||
Span, Type, Value,
|
||||
};
|
||||
|
||||
#[test]
|
||||
@ -96,7 +96,7 @@ fn not_equal_characters() {
|
||||
Span(0, 10),
|
||||
Span(10, 10),
|
||||
],
|
||||
constants: vec![ConcreteValue::Character('a'), ConcreteValue::Character('b')],
|
||||
character_constants: vec!['a', 'b'],
|
||||
..Chunk::default()
|
||||
};
|
||||
let return_value = Some(Value::boolean(true));
|
||||
@ -128,7 +128,7 @@ fn not_equal_floats() {
|
||||
Span(0, 11),
|
||||
Span(11, 11),
|
||||
],
|
||||
constants: vec![ConcreteValue::Float(10.0), ConcreteValue::Float(3.0)],
|
||||
float_constants: vec![10.0, 3.0],
|
||||
..Chunk::default()
|
||||
};
|
||||
let return_value = Some(Value::boolean(true));
|
||||
@ -154,7 +154,7 @@ fn not_equal_integers() {
|
||||
Instruction::r#return(true, 0, TypeCode::BOOLEAN),
|
||||
],
|
||||
positions: vec![Span(0, 7), Span(0, 7), Span(0, 7), Span(0, 7), Span(7, 7)],
|
||||
constants: vec![ConcreteValue::Integer(10), ConcreteValue::Integer(3)],
|
||||
integer_constants: vec![10, 3],
|
||||
..Chunk::default()
|
||||
};
|
||||
let return_value = Some(Value::boolean(true));
|
||||
@ -186,10 +186,7 @@ fn not_equal_strings() {
|
||||
Span(0, 14),
|
||||
Span(14, 14),
|
||||
],
|
||||
constants: vec![
|
||||
ConcreteValue::String(DustString::from("abc")),
|
||||
ConcreteValue::String(DustString::from("def")),
|
||||
],
|
||||
string_constants: vec![DustString::from("abc"), DustString::from("def")],
|
||||
..Chunk::default()
|
||||
};
|
||||
let return_value = Some(Value::boolean(true));
|
||||
|
Loading…
x
Reference in New Issue
Block a user