Consolidate point instructions into return instructions
This commit is contained in:
parent
bd273035aa
commit
75d6948e82
@ -1287,7 +1287,11 @@ impl<'src> Compiler<'src> {
|
|||||||
Type::String => self.next_string_register(),
|
Type::String => self.next_string_register(),
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
};
|
};
|
||||||
let point = Instruction::point(local_register_index, Operand::Register(register));
|
let point = Instruction::point(
|
||||||
|
local_register_index,
|
||||||
|
Operand::Register(register),
|
||||||
|
r#type.type_code(),
|
||||||
|
);
|
||||||
|
|
||||||
self.emit_instruction(point, r#type, start_position);
|
self.emit_instruction(point, r#type, start_position);
|
||||||
}
|
}
|
||||||
@ -1304,7 +1308,11 @@ impl<'src> Compiler<'src> {
|
|||||||
Type::String => self.next_string_register(),
|
Type::String => self.next_string_register(),
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
};
|
};
|
||||||
let point = Instruction::point(destination, Operand::Register(local_register_index));
|
let point = Instruction::point(
|
||||||
|
destination,
|
||||||
|
Operand::Register(local_register_index),
|
||||||
|
r#type.type_code(),
|
||||||
|
);
|
||||||
|
|
||||||
self.emit_instruction(point, r#type, self.previous_position);
|
self.emit_instruction(point, r#type, self.previous_position);
|
||||||
|
|
||||||
@ -1695,7 +1703,18 @@ impl<'src> Compiler<'src> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn parse_implicit_return(&mut self) -> Result<(), CompileError> {
|
fn parse_implicit_return(&mut self) -> Result<(), CompileError> {
|
||||||
if matches!(self.get_last_operation(), Some(Operation::RETURN))
|
if matches!(self.get_last_operation(), Some(Operation::POINT)) {
|
||||||
|
let Point {
|
||||||
|
destination,
|
||||||
|
r#type: type_code,
|
||||||
|
..
|
||||||
|
} = Point::from(self.instructions.last().unwrap().0);
|
||||||
|
|
||||||
|
let (_, r#type, _) = self.instructions.pop().unwrap();
|
||||||
|
let r#return = Instruction::r#return(true, destination, type_code);
|
||||||
|
|
||||||
|
self.emit_instruction(r#return, r#type, self.current_position);
|
||||||
|
} else if matches!(self.get_last_operation(), Some(Operation::RETURN))
|
||||||
|| matches!(
|
|| matches!(
|
||||||
self.get_last_operations(),
|
self.get_last_operations(),
|
||||||
Some([Operation::RETURN, Operation::JUMP])
|
Some([Operation::RETURN, Operation::JUMP])
|
||||||
|
@ -278,8 +278,12 @@ impl Instruction {
|
|||||||
*self = fields.build();
|
*self = fields.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn point(destination: u16, to: Operand) -> Instruction {
|
pub fn point(destination: u16, to: Operand, r#type: TypeCode) -> Instruction {
|
||||||
Instruction::from(Point { destination, to })
|
Instruction::from(Point {
|
||||||
|
destination,
|
||||||
|
to,
|
||||||
|
r#type,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn close(from: u16, to: u16) -> Instruction {
|
pub fn close(from: u16, to: u16) -> Instruction {
|
||||||
@ -711,8 +715,8 @@ impl Operand {
|
|||||||
impl Display for Operand {
|
impl Display for Operand {
|
||||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Operand::Constant(index) => write!(f, "C{index}"),
|
Operand::Constant(index) => write!(f, "{index}"),
|
||||||
Operand::Register(index) => write!(f, "R{index}"),
|
Operand::Register(index) => write!(f, "{index}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,12 @@ use std::fmt::{self, Display, Formatter};
|
|||||||
|
|
||||||
use crate::{Instruction, Operation};
|
use crate::{Instruction, Operation};
|
||||||
|
|
||||||
use super::{InstructionFields, Operand};
|
use super::{InstructionFields, Operand, TypeCode};
|
||||||
|
|
||||||
pub struct Point {
|
pub struct Point {
|
||||||
pub destination: u16,
|
pub destination: u16,
|
||||||
pub to: Operand,
|
pub to: Operand,
|
||||||
|
pub r#type: TypeCode,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Instruction> for Point {
|
impl From<Instruction> for Point {
|
||||||
@ -14,6 +15,7 @@ impl From<Instruction> for Point {
|
|||||||
Point {
|
Point {
|
||||||
destination: instruction.a_field(),
|
destination: instruction.a_field(),
|
||||||
to: instruction.b_as_operand(),
|
to: instruction.b_as_operand(),
|
||||||
|
r#type: instruction.b_type(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -23,11 +25,13 @@ impl From<Point> for Instruction {
|
|||||||
let operation = Operation::POINT;
|
let operation = Operation::POINT;
|
||||||
let a_field = r#move.destination;
|
let a_field = r#move.destination;
|
||||||
let (b_field, b_is_constant) = r#move.to.as_index_and_constant_flag();
|
let (b_field, b_is_constant) = r#move.to.as_index_and_constant_flag();
|
||||||
|
let b_type = r#move.r#type;
|
||||||
|
|
||||||
InstructionFields {
|
InstructionFields {
|
||||||
operation,
|
operation,
|
||||||
a_field,
|
a_field,
|
||||||
b_field,
|
b_field,
|
||||||
|
b_type,
|
||||||
b_is_constant,
|
b_is_constant,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
@ -37,8 +41,23 @@ impl From<Point> for Instruction {
|
|||||||
|
|
||||||
impl Display for Point {
|
impl Display for Point {
|
||||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
let Point { destination, to } = self;
|
let Point {
|
||||||
|
destination,
|
||||||
|
to,
|
||||||
|
r#type,
|
||||||
|
} = self;
|
||||||
|
|
||||||
write!(f, "R{destination} -> {to}")
|
match *r#type {
|
||||||
|
TypeCode::BOOLEAN => write!(f, "R_BOOL_{destination} -> R_BOOL_{to}"),
|
||||||
|
TypeCode::BYTE => write!(f, "R_BYTE_{destination} -> R_BYTE_{to}"),
|
||||||
|
TypeCode::CHARACTER => write!(f, "R_CHAR_{destination} -> R_CHAR_{to}"),
|
||||||
|
TypeCode::FLOAT => write!(f, "R_FLOAT_{destination} -> R_FLOAT_{to}"),
|
||||||
|
TypeCode::INTEGER => write!(f, "R_INT_{destination} -> R_INT_{to}"),
|
||||||
|
TypeCode::STRING => write!(f, "R_STR_{destination} -> R_STR_{to}"),
|
||||||
|
unsupported => write!(
|
||||||
|
f,
|
||||||
|
"Unsupported type code: {unsupported} for Point instruction"
|
||||||
|
),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ use std::io::{Write, stdin, stdout};
|
|||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
|
||||||
use crate::DustString;
|
use crate::DustString;
|
||||||
use crate::vm::Thread;
|
use crate::vm::{Register, Thread};
|
||||||
|
|
||||||
pub fn read_line(data: &mut Thread, destination: usize, _argument_range: Range<usize>) {
|
pub fn read_line(data: &mut Thread, destination: usize, _argument_range: Range<usize>) {
|
||||||
let mut buffer = String::new();
|
let mut buffer = String::new();
|
||||||
@ -13,8 +13,9 @@ pub fn read_line(data: &mut Thread, destination: usize, _argument_range: Range<u
|
|||||||
buffer.truncate(length.saturating_sub(1));
|
buffer.truncate(length.saturating_sub(1));
|
||||||
|
|
||||||
let string = DustString::from(buffer);
|
let string = DustString::from(buffer);
|
||||||
|
let register = Register::Value(string);
|
||||||
|
|
||||||
data.set_string_register(destination, string);
|
data.set_string_register(destination, register);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ use std::ops::Range;
|
|||||||
|
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
|
|
||||||
use crate::vm::Thread;
|
use crate::vm::{Register, Thread};
|
||||||
|
|
||||||
pub fn random_int(data: &mut Thread, destination: usize, argument_range: Range<usize>) {
|
pub fn random_int(data: &mut Thread, destination: usize, argument_range: Range<usize>) {
|
||||||
let mut argument_range_iter = argument_range.into_iter();
|
let mut argument_range_iter = argument_range.into_iter();
|
||||||
@ -16,14 +16,15 @@ pub fn random_int(data: &mut Thread, destination: usize, argument_range: Range<u
|
|||||||
let integer = data.get_integer_register(register_index);
|
let integer = data.get_integer_register(register_index);
|
||||||
|
|
||||||
if min.is_none() {
|
if min.is_none() {
|
||||||
min = Some(integer);
|
min = Some(*integer);
|
||||||
} else {
|
} else {
|
||||||
break (min, integer);
|
break (min, *integer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let random_integer = rand::thread_rng().gen_range(min.unwrap()..max);
|
let random_integer = rand::thread_rng().gen_range(min.unwrap()..max);
|
||||||
|
let register = Register::Value(random_integer);
|
||||||
|
|
||||||
data.set_integer_register(destination, random_integer);
|
data.set_integer_register(destination, register);
|
||||||
}
|
}
|
||||||
|
@ -35,41 +35,41 @@ impl ConcreteValue {
|
|||||||
ConcreteValue::String(to_string.into())
|
ConcreteValue::String(to_string.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_boolean(&self) -> Option<bool> {
|
pub fn as_boolean(&self) -> Option<&bool> {
|
||||||
if let ConcreteValue::Boolean(boolean) = self {
|
if let ConcreteValue::Boolean(boolean) = self {
|
||||||
Some(*boolean)
|
Some(boolean)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_byte(&self) -> Option<u8> {
|
pub fn as_byte(&self) -> Option<&u8> {
|
||||||
if let ConcreteValue::Byte(byte) = self {
|
if let ConcreteValue::Byte(byte) = self {
|
||||||
Some(*byte)
|
Some(byte)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_character(&self) -> Option<char> {
|
pub fn as_character(&self) -> Option<&char> {
|
||||||
if let ConcreteValue::Character(character) = self {
|
if let ConcreteValue::Character(character) = self {
|
||||||
Some(*character)
|
Some(character)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_float(&self) -> Option<f64> {
|
pub fn as_float(&self) -> Option<&f64> {
|
||||||
if let ConcreteValue::Float(float) = self {
|
if let ConcreteValue::Float(float) = self {
|
||||||
Some(*float)
|
Some(float)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_integer(&self) -> Option<i64> {
|
pub fn as_integer(&self) -> Option<&i64> {
|
||||||
if let ConcreteValue::Integer(integer) = self {
|
if let ConcreteValue::Integer(integer) = self {
|
||||||
Some(*integer)
|
Some(integer)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ use crate::{
|
|||||||
instruction::{InstructionFields, TypeCode},
|
instruction::{InstructionFields, TypeCode},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::thread::Thread;
|
use super::{Pointer, Register, thread::Thread};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ActionSequence {
|
pub struct ActionSequence {
|
||||||
@ -74,7 +74,39 @@ pub fn close(instruction: InstructionFields, thread: &mut Thread) {}
|
|||||||
|
|
||||||
pub fn load_boolean(instruction: InstructionFields, thread: &mut Thread) {}
|
pub fn load_boolean(instruction: InstructionFields, thread: &mut Thread) {}
|
||||||
|
|
||||||
pub fn load_constant(instruction: InstructionFields, thread: &mut Thread) {}
|
pub fn load_constant(instruction: InstructionFields, thread: &mut Thread) {
|
||||||
|
let destination = instruction.a_field as usize;
|
||||||
|
let constant_index = instruction.b_field as usize;
|
||||||
|
let constant_type = instruction.b_type;
|
||||||
|
let jump_next = instruction.c_field != 0;
|
||||||
|
|
||||||
|
match constant_type {
|
||||||
|
TypeCode::CHARACTER => {
|
||||||
|
let constant = *thread.get_constant(constant_index).as_character().unwrap();
|
||||||
|
let register = Register::Value(constant);
|
||||||
|
|
||||||
|
thread.set_character_register(destination, register);
|
||||||
|
}
|
||||||
|
TypeCode::FLOAT => {
|
||||||
|
let constant = *thread.get_constant(constant_index).as_float().unwrap();
|
||||||
|
let register = Register::Value(constant);
|
||||||
|
|
||||||
|
thread.set_float_register(destination, register);
|
||||||
|
}
|
||||||
|
TypeCode::INTEGER => {
|
||||||
|
let constant = *thread.get_constant(constant_index).as_integer().unwrap();
|
||||||
|
let register = Register::Value(constant);
|
||||||
|
|
||||||
|
thread.set_integer_register(destination as usize, register);
|
||||||
|
}
|
||||||
|
TypeCode::STRING => {
|
||||||
|
let register = Register::Pointer(Pointer::Constant(constant_index));
|
||||||
|
|
||||||
|
thread.set_string_register(destination as usize, register);
|
||||||
|
}
|
||||||
|
_ => unimplemented!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn load_list(instruction: InstructionFields, thread: &mut Thread) {}
|
pub fn load_list(instruction: InstructionFields, thread: &mut Thread) {}
|
||||||
|
|
||||||
@ -111,9 +143,10 @@ pub fn add(instruction: InstructionFields, thread: &mut Thread) {
|
|||||||
} else {
|
} else {
|
||||||
thread.get_integer_register(right)
|
thread.get_integer_register(right)
|
||||||
};
|
};
|
||||||
let result = left_value + right_value;
|
let sum = left_value + right_value;
|
||||||
|
let register = Register::Value(sum);
|
||||||
|
|
||||||
thread.set_integer_register(destination, result);
|
thread.set_integer_register(destination, register);
|
||||||
}
|
}
|
||||||
(TypeCode::STRING, TypeCode::STRING) => {
|
(TypeCode::STRING, TypeCode::STRING) => {
|
||||||
let left_value = if left_is_constant {
|
let left_value = if left_is_constant {
|
||||||
@ -146,9 +179,10 @@ pub fn add(instruction: InstructionFields, thread: &mut Thread) {
|
|||||||
} else {
|
} else {
|
||||||
thread.get_string_register(right).clone()
|
thread.get_string_register(right).clone()
|
||||||
};
|
};
|
||||||
let result = left_value + &right_value;
|
let concatenated = left_value + &right_value;
|
||||||
|
let register = Register::Value(concatenated);
|
||||||
|
|
||||||
thread.set_string_register(destination, result);
|
thread.set_string_register(destination, register);
|
||||||
}
|
}
|
||||||
_ => unimplemented!(),
|
_ => unimplemented!(),
|
||||||
}
|
}
|
||||||
@ -220,7 +254,7 @@ pub fn jump(instruction: InstructionFields, thread: &mut Thread) {
|
|||||||
if is_positive {
|
if is_positive {
|
||||||
thread.current_frame_mut().ip += offset;
|
thread.current_frame_mut().ip += offset;
|
||||||
} else {
|
} else {
|
||||||
thread.current_frame_mut().ip -= offset;
|
thread.current_frame_mut().ip -= offset + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,23 +270,23 @@ pub fn r#return(instruction: InstructionFields, thread: &mut Thread) {
|
|||||||
if should_return_value {
|
if should_return_value {
|
||||||
match return_type {
|
match return_type {
|
||||||
TypeCode::BOOLEAN => {
|
TypeCode::BOOLEAN => {
|
||||||
let return_value = thread.get_boolean_register(return_register);
|
let return_value = *thread.get_boolean_register(return_register);
|
||||||
thread.return_value = Some(Some(Value::boolean(return_value)));
|
thread.return_value = Some(Some(Value::boolean(return_value)));
|
||||||
}
|
}
|
||||||
TypeCode::BYTE => {
|
TypeCode::BYTE => {
|
||||||
let return_value = thread.get_byte_register(return_register);
|
let return_value = *thread.get_byte_register(return_register);
|
||||||
thread.return_value = Some(Some(Value::byte(return_value)));
|
thread.return_value = Some(Some(Value::byte(return_value)));
|
||||||
}
|
}
|
||||||
TypeCode::CHARACTER => {
|
TypeCode::CHARACTER => {
|
||||||
let return_value = thread.get_character_register(return_register);
|
let return_value = *thread.get_character_register(return_register);
|
||||||
thread.return_value = Some(Some(Value::character(return_value)));
|
thread.return_value = Some(Some(Value::character(return_value)));
|
||||||
}
|
}
|
||||||
TypeCode::FLOAT => {
|
TypeCode::FLOAT => {
|
||||||
let return_value = thread.get_float_register(return_register);
|
let return_value = *thread.get_float_register(return_register);
|
||||||
thread.return_value = Some(Some(Value::float(return_value)));
|
thread.return_value = Some(Some(Value::float(return_value)));
|
||||||
}
|
}
|
||||||
TypeCode::INTEGER => {
|
TypeCode::INTEGER => {
|
||||||
let return_value = thread.get_integer_register(return_register);
|
let return_value = *thread.get_integer_register(return_register);
|
||||||
thread.return_value = Some(Some(Value::integer(return_value)));
|
thread.return_value = Some(Some(Value::integer(return_value)));
|
||||||
}
|
}
|
||||||
TypeCode::STRING => {
|
TypeCode::STRING => {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::{sync::Arc, thread::JoinHandle};
|
use std::{collections::HashMap, sync::Arc, thread::JoinHandle};
|
||||||
|
|
||||||
use tracing::{info, trace};
|
use tracing::{info, trace};
|
||||||
|
|
||||||
@ -10,6 +10,7 @@ pub struct Thread {
|
|||||||
chunk: Arc<Chunk>,
|
chunk: Arc<Chunk>,
|
||||||
call_stack: Vec<CallFrame>,
|
call_stack: Vec<CallFrame>,
|
||||||
pub return_value: Option<Option<Value>>,
|
pub return_value: Option<Option<Value>>,
|
||||||
|
pub integer_cache: HashMap<usize, *const i64>,
|
||||||
_spawned_threads: Vec<JoinHandle<()>>,
|
_spawned_threads: Vec<JoinHandle<()>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,6 +25,7 @@ impl Thread {
|
|||||||
chunk,
|
chunk,
|
||||||
call_stack,
|
call_stack,
|
||||||
return_value: None,
|
return_value: None,
|
||||||
|
integer_cache: HashMap::new(),
|
||||||
_spawned_threads: Vec::new(),
|
_spawned_threads: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -46,9 +48,9 @@ impl Thread {
|
|||||||
ip
|
ip
|
||||||
};
|
};
|
||||||
let current_action = if cfg!(debug_assertions) {
|
let current_action = if cfg!(debug_assertions) {
|
||||||
current_frame.action_sequence.actions.get(ip).unwrap()
|
current_frame.action_sequence.actions.get_mut(ip).unwrap()
|
||||||
} else {
|
} else {
|
||||||
unsafe { current_frame.action_sequence.actions.get_unchecked(ip) }
|
unsafe { current_frame.action_sequence.actions.get_unchecked_mut(ip) }
|
||||||
};
|
};
|
||||||
|
|
||||||
trace!(
|
trace!(
|
||||||
@ -86,7 +88,7 @@ impl Thread {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_boolean_register(&self, register_index: usize) -> bool {
|
pub fn get_boolean_register(&self, register_index: usize) -> &bool {
|
||||||
let register = if cfg!(debug_assertions) {
|
let register = if cfg!(debug_assertions) {
|
||||||
self.call_stack
|
self.call_stack
|
||||||
.last()
|
.last()
|
||||||
@ -107,13 +109,13 @@ impl Thread {
|
|||||||
};
|
};
|
||||||
|
|
||||||
match register {
|
match register {
|
||||||
Register::Value(value) => *value,
|
Register::Value(value) => value,
|
||||||
Register::Pointer(pointer) => self.get_pointer_to_boolean(pointer),
|
Register::Pointer(pointer) => self.get_pointer_to_boolean(pointer),
|
||||||
Register::Empty => panic!("Attempted to get value from empty register"),
|
Register::Empty => panic!("Attempted to get value from empty register"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_pointer_to_boolean(&self, pointer: &Pointer) -> bool {
|
pub fn get_pointer_to_boolean(&self, pointer: &Pointer) -> &bool {
|
||||||
match pointer {
|
match pointer {
|
||||||
Pointer::Register(register_index) => self.get_boolean_register(*register_index),
|
Pointer::Register(register_index) => self.get_boolean_register(*register_index),
|
||||||
Pointer::Constant(constant_index) => {
|
Pointer::Constant(constant_index) => {
|
||||||
@ -132,7 +134,7 @@ impl Thread {
|
|||||||
};
|
};
|
||||||
|
|
||||||
match register {
|
match register {
|
||||||
Register::Value(value) => *value,
|
Register::Value(value) => value,
|
||||||
Register::Pointer(pointer) => self.get_pointer_to_boolean(pointer),
|
Register::Pointer(pointer) => self.get_pointer_to_boolean(pointer),
|
||||||
Register::Empty => panic!("Attempted to get value from empty register"),
|
Register::Empty => panic!("Attempted to get value from empty register"),
|
||||||
}
|
}
|
||||||
@ -140,8 +142,8 @@ impl Thread {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_boolean_register(&mut self, register_index: usize, value: bool) {
|
pub fn set_boolean_register(&mut self, register_index: usize, new_register: Register<bool>) {
|
||||||
let register = if cfg!(debug_assertions) {
|
let old_register = if cfg!(debug_assertions) {
|
||||||
self.call_stack
|
self.call_stack
|
||||||
.last_mut()
|
.last_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -160,10 +162,10 @@ impl Thread {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
*register = Register::Value(value);
|
*old_register = new_register;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_byte_register(&self, register_index: usize) -> u8 {
|
pub fn get_byte_register(&self, register_index: usize) -> &u8 {
|
||||||
let register = if cfg!(debug_assertions) {
|
let register = if cfg!(debug_assertions) {
|
||||||
self.call_stack
|
self.call_stack
|
||||||
.last()
|
.last()
|
||||||
@ -184,13 +186,13 @@ impl Thread {
|
|||||||
};
|
};
|
||||||
|
|
||||||
match register {
|
match register {
|
||||||
Register::Value(value) => *value,
|
Register::Value(value) => value,
|
||||||
Register::Pointer(pointer) => self.get_pointer_to_byte(pointer),
|
Register::Pointer(pointer) => self.get_pointer_to_byte(pointer),
|
||||||
Register::Empty => panic!("Attempted to get value from empty register"),
|
Register::Empty => panic!("Attempted to get value from empty register"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_pointer_to_byte(&self, pointer: &Pointer) -> u8 {
|
pub fn get_pointer_to_byte(&self, pointer: &Pointer) -> &u8 {
|
||||||
match pointer {
|
match pointer {
|
||||||
Pointer::Register(register_index) => self.get_byte_register(*register_index),
|
Pointer::Register(register_index) => self.get_byte_register(*register_index),
|
||||||
Pointer::Constant(constant_index) => {
|
Pointer::Constant(constant_index) => {
|
||||||
@ -209,7 +211,7 @@ impl Thread {
|
|||||||
};
|
};
|
||||||
|
|
||||||
match register {
|
match register {
|
||||||
Register::Value(value) => *value,
|
Register::Value(value) => value,
|
||||||
Register::Pointer(pointer) => self.get_pointer_to_byte(pointer),
|
Register::Pointer(pointer) => self.get_pointer_to_byte(pointer),
|
||||||
Register::Empty => panic!("Attempted to get value from empty register"),
|
Register::Empty => panic!("Attempted to get value from empty register"),
|
||||||
}
|
}
|
||||||
@ -217,8 +219,8 @@ impl Thread {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_byte_register(&mut self, register_index: usize, value: u8) {
|
pub fn set_byte_register(&mut self, register_index: usize, new_register: Register<u8>) {
|
||||||
let register = if cfg!(debug_assertions) {
|
let old_register = if cfg!(debug_assertions) {
|
||||||
self.call_stack
|
self.call_stack
|
||||||
.last_mut()
|
.last_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -237,10 +239,10 @@ impl Thread {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
*register = Register::Value(value);
|
*old_register = new_register;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_character_register(&self, register_index: usize) -> char {
|
pub fn get_character_register(&self, register_index: usize) -> &char {
|
||||||
let register = if cfg!(debug_assertions) {
|
let register = if cfg!(debug_assertions) {
|
||||||
self.call_stack
|
self.call_stack
|
||||||
.last()
|
.last()
|
||||||
@ -261,13 +263,13 @@ impl Thread {
|
|||||||
};
|
};
|
||||||
|
|
||||||
match register {
|
match register {
|
||||||
Register::Value(value) => *value,
|
Register::Value(value) => value,
|
||||||
Register::Pointer(pointer) => self.get_pointer_to_character(pointer),
|
Register::Pointer(pointer) => self.get_pointer_to_character(pointer),
|
||||||
Register::Empty => panic!("Attempted to get value from empty register"),
|
Register::Empty => panic!("Attempted to get value from empty register"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_pointer_to_character(&self, pointer: &Pointer) -> char {
|
pub fn get_pointer_to_character(&self, pointer: &Pointer) -> &char {
|
||||||
match pointer {
|
match pointer {
|
||||||
Pointer::Register(register_index) => self.get_character_register(*register_index),
|
Pointer::Register(register_index) => self.get_character_register(*register_index),
|
||||||
Pointer::Constant(constant_index) => {
|
Pointer::Constant(constant_index) => {
|
||||||
@ -295,7 +297,7 @@ impl Thread {
|
|||||||
};
|
};
|
||||||
|
|
||||||
match register {
|
match register {
|
||||||
Register::Value(value) => *value,
|
Register::Value(value) => value,
|
||||||
Register::Pointer(pointer) => self.get_pointer_to_character(pointer),
|
Register::Pointer(pointer) => self.get_pointer_to_character(pointer),
|
||||||
Register::Empty => panic!("Attempted to get value from empty register"),
|
Register::Empty => panic!("Attempted to get value from empty register"),
|
||||||
}
|
}
|
||||||
@ -303,8 +305,8 @@ impl Thread {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_character_register(&mut self, register_index: usize, value: char) {
|
pub fn set_character_register(&mut self, register_index: usize, new_register: Register<char>) {
|
||||||
let register = if cfg!(debug_assertions) {
|
let old_register = if cfg!(debug_assertions) {
|
||||||
self.call_stack
|
self.call_stack
|
||||||
.last_mut()
|
.last_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -323,10 +325,10 @@ impl Thread {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
*register = Register::Value(value);
|
*old_register = new_register;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_float_register(&self, register_index: usize) -> f64 {
|
pub fn get_float_register(&self, register_index: usize) -> &f64 {
|
||||||
let register = if cfg!(debug_assertions) {
|
let register = if cfg!(debug_assertions) {
|
||||||
self.call_stack
|
self.call_stack
|
||||||
.last()
|
.last()
|
||||||
@ -347,13 +349,13 @@ impl Thread {
|
|||||||
};
|
};
|
||||||
|
|
||||||
match register {
|
match register {
|
||||||
Register::Value(value) => *value,
|
Register::Value(value) => value,
|
||||||
Register::Pointer(pointer) => self.get_pointer_to_float(pointer),
|
Register::Pointer(pointer) => self.get_pointer_to_float(pointer),
|
||||||
Register::Empty => panic!("Attempted to get value from empty register"),
|
Register::Empty => panic!("Attempted to get value from empty register"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_pointer_to_float(&self, pointer: &Pointer) -> f64 {
|
pub fn get_pointer_to_float(&self, pointer: &Pointer) -> &f64 {
|
||||||
match pointer {
|
match pointer {
|
||||||
Pointer::Register(register_index) => self.get_float_register(*register_index),
|
Pointer::Register(register_index) => self.get_float_register(*register_index),
|
||||||
Pointer::Constant(constant_index) => {
|
Pointer::Constant(constant_index) => {
|
||||||
@ -372,7 +374,7 @@ impl Thread {
|
|||||||
};
|
};
|
||||||
|
|
||||||
match register {
|
match register {
|
||||||
Register::Value(value) => *value,
|
Register::Value(value) => value,
|
||||||
Register::Pointer(pointer) => self.get_pointer_to_float(pointer),
|
Register::Pointer(pointer) => self.get_pointer_to_float(pointer),
|
||||||
Register::Empty => panic!("Attempted to get value from empty register"),
|
Register::Empty => panic!("Attempted to get value from empty register"),
|
||||||
}
|
}
|
||||||
@ -380,8 +382,8 @@ impl Thread {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_float_register(&mut self, register_index: usize, value: f64) {
|
pub fn set_float_register(&mut self, register_index: usize, new_register: Register<f64>) {
|
||||||
let register = if cfg!(debug_assertions) {
|
let old_register = if cfg!(debug_assertions) {
|
||||||
self.call_stack
|
self.call_stack
|
||||||
.last_mut()
|
.last_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -400,10 +402,10 @@ impl Thread {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
*register = Register::Value(value);
|
*old_register = new_register;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_integer_register(&self, register_index: usize) -> i64 {
|
pub fn get_integer_register(&self, register_index: usize) -> &i64 {
|
||||||
let register = if cfg!(debug_assertions) {
|
let register = if cfg!(debug_assertions) {
|
||||||
self.call_stack
|
self.call_stack
|
||||||
.last()
|
.last()
|
||||||
@ -424,13 +426,13 @@ impl Thread {
|
|||||||
};
|
};
|
||||||
|
|
||||||
match register {
|
match register {
|
||||||
Register::Value(value) => *value,
|
Register::Value(value) => value,
|
||||||
Register::Pointer(pointer) => self.get_pointer_to_integer(pointer),
|
Register::Pointer(pointer) => self.get_pointer_to_integer(pointer),
|
||||||
Register::Empty => panic!("Attempted to get value from empty register"),
|
Register::Empty => panic!("Attempted to get value from empty register"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_pointer_to_integer(&self, pointer: &Pointer) -> i64 {
|
pub fn get_pointer_to_integer(&self, pointer: &Pointer) -> &i64 {
|
||||||
match pointer {
|
match pointer {
|
||||||
Pointer::Register(register_index) => self.get_integer_register(*register_index),
|
Pointer::Register(register_index) => self.get_integer_register(*register_index),
|
||||||
Pointer::Constant(constant_index) => {
|
Pointer::Constant(constant_index) => {
|
||||||
@ -449,7 +451,7 @@ impl Thread {
|
|||||||
};
|
};
|
||||||
|
|
||||||
match register {
|
match register {
|
||||||
Register::Value(value) => *value,
|
Register::Value(value) => value,
|
||||||
Register::Pointer(pointer) => self.get_pointer_to_integer(pointer),
|
Register::Pointer(pointer) => self.get_pointer_to_integer(pointer),
|
||||||
Register::Empty => panic!("Attempted to get value from empty register"),
|
Register::Empty => panic!("Attempted to get value from empty register"),
|
||||||
}
|
}
|
||||||
@ -457,8 +459,8 @@ impl Thread {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_integer_register(&mut self, register_index: usize, value: i64) {
|
pub fn set_integer_register(&mut self, register_index: usize, new_register: Register<i64>) {
|
||||||
let register = if cfg!(debug_assertions) {
|
let old_register = if cfg!(debug_assertions) {
|
||||||
self.call_stack
|
self.call_stack
|
||||||
.last_mut()
|
.last_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -477,7 +479,7 @@ impl Thread {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
*register = Register::Value(value);
|
*old_register = new_register;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_string_register(&self, register_index: usize) -> &DustString {
|
pub fn get_string_register(&self, register_index: usize) -> &DustString {
|
||||||
@ -534,8 +536,12 @@ impl Thread {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_string_register(&mut self, register_index: usize, value: DustString) {
|
pub fn set_string_register(
|
||||||
let register = if cfg!(debug_assertions) {
|
&mut self,
|
||||||
|
register_index: usize,
|
||||||
|
new_register: Register<DustString>,
|
||||||
|
) {
|
||||||
|
let old_register = if cfg!(debug_assertions) {
|
||||||
self.call_stack
|
self.call_stack
|
||||||
.last_mut()
|
.last_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -554,7 +560,7 @@ impl Thread {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
*register = Register::Value(value);
|
*old_register = new_register;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_constant(&self, constant_index: usize) -> &ConcreteValue {
|
pub fn get_constant(&self, constant_index: usize) -> &ConcreteValue {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user