Fix register closing
This commit is contained in:
parent
833ee30930
commit
59f64c9afd
@ -1,18 +1,15 @@
|
|||||||
//! Representation of a Dust program or function.
|
//! Representation of a Dust program or function.
|
||||||
//!
|
//!
|
||||||
|
//! **Except for testing purposes, a chunk should not be created directly. Instead, use the compiler
|
||||||
|
//! to generate a chunk from Dust source code.**
|
||||||
|
//!
|
||||||
//! A chunk is output by the compiler to represent all the information needed to execute a Dust
|
//! A chunk is output by the compiler to represent all the information needed to execute a Dust
|
||||||
//! program. In addition to the program itself, each function in the source is compiled into its own
|
//! program. In addition to the program itself, each function in the source is compiled into its own
|
||||||
//! chunk and stored in the `prototypes` field of its parent. Thus, a chunk can also represent a
|
//! chunk and stored in the `prototypes` field of its parent. Thus, a chunk can also represent a
|
||||||
//! function prototype.
|
//! function prototype.
|
||||||
//!
|
//!
|
||||||
//! Chunks have a name when they belong to a named function. They also have a type, so the input
|
//! Chunks have a name when they belong to a named function. They also have a type, so the input
|
||||||
//! parameters and the type of the return value are statically known. The [`Chunk::stack_size`]
|
//! parameters and the type of the return value are statically known.
|
||||||
//! field can provide the necessary stack size that will be needed by the virtual machine. Chunks
|
|
||||||
//! cannot be instantiated directly and must be created by the compiler. However, when the Rust
|
|
||||||
//! compiler is in the "test" or "debug_assertions" configuration (used for all types of test),
|
|
||||||
//! [`Chunk::with_data`] can be used to create a chunk for comparison to the compiler output. Do not
|
|
||||||
//! try to run these chunks in a virtual machine. Due to their missing stack size and record index,
|
|
||||||
//! they will cause a panic or undefined behavior.
|
|
||||||
mod disassembler;
|
mod disassembler;
|
||||||
mod local;
|
mod local;
|
||||||
mod scope;
|
mod scope;
|
||||||
|
@ -11,8 +11,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
/// The `block index` is a unique identifier for a block within a chunk. It is used to differentiate
|
/// The `block index` is a unique identifier for a block within a chunk. It is used to differentiate
|
||||||
/// between blocks that are not nested together but have the same depth, i.e. sibling scopes. If the
|
/// between blocks that are not nested together but have the same depth, i.e. sibling scopes. If the
|
||||||
/// `block_index` is 0, then the scope is the root scope of the chunk. The `block_index` is always 0
|
/// `block_index` is 0, then the scope is the root scope of the chunk. The `block_index` is always 0
|
||||||
/// when the `depth` is 0. See [Chunk::begin_scope][] and [Chunk::end_scope][] to see how scopes are
|
/// when the `depth` is 0.
|
||||||
/// incremented and decremented.
|
|
||||||
#[derive(Debug, Clone, Copy, Default, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Copy, Default, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
pub struct Scope {
|
pub struct Scope {
|
||||||
/// Level of block nesting.
|
/// Level of block nesting.
|
||||||
|
@ -16,10 +16,6 @@
|
|||||||
//! 32-47 | B field (unsigned 16-bit integer)
|
//! 32-47 | B field (unsigned 16-bit integer)
|
||||||
//! 48-63 | C field (unsigned 16-bit integer)
|
//! 48-63 | C field (unsigned 16-bit integer)
|
||||||
//!
|
//!
|
||||||
//! **Be careful when working with instructions directly**. When modifying an instruction's fields,
|
|
||||||
//! you may also need to modify its flags. It is usually best to remove instructions and insert new
|
|
||||||
//! ones in their place instead of mutating them.
|
|
||||||
//!
|
|
||||||
//! # Creating Instructions
|
//! # Creating Instructions
|
||||||
//!
|
//!
|
||||||
//! For each operation, there are two ways to create an instruction:
|
//! For each operation, there are two ways to create an instruction:
|
||||||
@ -68,7 +64,6 @@
|
|||||||
//! // - `a += 2`
|
//! // - `a += 2`
|
||||||
//! // - `a = a + 2`
|
//! // - `a = a + 2`
|
||||||
//! // - `a = 2 + a`
|
//! // - `a = 2 + a`
|
||||||
//!
|
|
||||||
//! let operation = mystery_instruction.operation();
|
//! let operation = mystery_instruction.operation();
|
||||||
//! let is_add_assign = match operation {
|
//! let is_add_assign = match operation {
|
||||||
//! Operation::ADD => {
|
//! Operation::ADD => {
|
||||||
|
@ -88,15 +88,6 @@ pub enum Register<T> {
|
|||||||
Pointer(Pointer),
|
Pointer(Pointer),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Register<T> {
|
|
||||||
#[allow(unused_assignments)]
|
|
||||||
pub fn close(mut self) {
|
|
||||||
if let Self::Value(value) = self {
|
|
||||||
self = Self::Closed(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Display> Display for Register<T> {
|
impl<T: Display> Display for Register<T> {
|
||||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
|
@ -242,12 +242,17 @@ impl Thread {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn close_boolean_register(&mut self, register_index: usize) {
|
pub fn close_boolean_register(&mut self, register_index: usize) {
|
||||||
self.current_frame_mut()
|
let register = self
|
||||||
|
.current_frame_mut()
|
||||||
.registers
|
.registers
|
||||||
.booleans
|
.booleans
|
||||||
.get_mut(register_index)
|
.get_mut(register_index)
|
||||||
.unwrap()
|
.unwrap();
|
||||||
.close();
|
|
||||||
|
*register = match register {
|
||||||
|
Register::Value(value) => Register::Closed(*value),
|
||||||
|
_ => panic!("Attempted to close non-value register"),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_byte_register(&self, register_index: usize) -> &u8 {
|
pub fn get_byte_register(&self, register_index: usize) -> &u8 {
|
||||||
@ -332,12 +337,17 @@ impl Thread {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn close_byte_register(&mut self, register_index: usize) {
|
pub fn close_byte_register(&mut self, register_index: usize) {
|
||||||
self.current_frame_mut()
|
let register = self
|
||||||
|
.current_frame_mut()
|
||||||
.registers
|
.registers
|
||||||
.bytes
|
.bytes
|
||||||
.get_mut(register_index)
|
.get_mut(register_index)
|
||||||
.unwrap()
|
.unwrap();
|
||||||
.close();
|
|
||||||
|
*register = match register {
|
||||||
|
Register::Value(value) => Register::Closed(*value),
|
||||||
|
_ => panic!("Attempted to close non-value register"),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_character_register(&self, register_index: usize) -> &char {
|
pub fn get_character_register(&self, register_index: usize) -> &char {
|
||||||
@ -427,12 +437,17 @@ impl Thread {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn close_character_register(&mut self, register_index: usize) {
|
pub fn close_character_register(&mut self, register_index: usize) {
|
||||||
self.current_frame_mut()
|
let register = self
|
||||||
|
.current_frame_mut()
|
||||||
.registers
|
.registers
|
||||||
.characters
|
.characters
|
||||||
.get_mut(register_index)
|
.get_mut(register_index)
|
||||||
.unwrap()
|
.unwrap();
|
||||||
.close();
|
|
||||||
|
*register = match register {
|
||||||
|
Register::Value(value) => Register::Closed(*value),
|
||||||
|
_ => panic!("Attempted to close non-value register"),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_float_register(&self, register_index: usize) -> &f64 {
|
pub fn get_float_register(&self, register_index: usize) -> &f64 {
|
||||||
@ -520,12 +535,17 @@ impl Thread {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn close_float_register(&mut self, register_index: usize) {
|
pub fn close_float_register(&mut self, register_index: usize) {
|
||||||
self.current_frame_mut()
|
let register = self
|
||||||
|
.current_frame_mut()
|
||||||
.registers
|
.registers
|
||||||
.floats
|
.floats
|
||||||
.get_mut(register_index)
|
.get_mut(register_index)
|
||||||
.unwrap()
|
.unwrap();
|
||||||
.close();
|
|
||||||
|
*register = match register {
|
||||||
|
Register::Value(value) => Register::Closed(*value),
|
||||||
|
_ => panic!("Attempted to close non-value register"),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_integer_register(&self, register_index: usize) -> &i64 {
|
pub fn get_integer_register(&self, register_index: usize) -> &i64 {
|
||||||
@ -613,12 +633,17 @@ impl Thread {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn close_integer_register(&mut self, register_index: usize) {
|
pub fn close_integer_register(&mut self, register_index: usize) {
|
||||||
self.current_frame_mut()
|
let register = self
|
||||||
|
.current_frame_mut()
|
||||||
.registers
|
.registers
|
||||||
.integers
|
.integers
|
||||||
.get_mut(register_index)
|
.get_mut(register_index)
|
||||||
.unwrap()
|
.unwrap();
|
||||||
.close();
|
|
||||||
|
*register = match register {
|
||||||
|
Register::Value(value) => Register::Closed(*value),
|
||||||
|
_ => panic!("Attempted to close non-value register"),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_string_register(&self, register_index: usize) -> &DustString {
|
pub fn get_string_register(&self, register_index: usize) -> &DustString {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user