diff --git a/dust-lang/src/compiler/mod.rs b/dust-lang/src/compiler/mod.rs index 8df9d3a..81a7c6c 100644 --- a/dust-lang/src/compiler/mod.rs +++ b/dust-lang/src/compiler/mod.rs @@ -703,7 +703,7 @@ impl<'src> Compiler<'src> { (Operand::Register(local.register_index), false) } - Operation::LOAD_BOOLEAN + Operation::LOAD_ENCODED | Operation::LOAD_LIST | Operation::LOAD_SELF | Operation::ADD @@ -1245,8 +1245,8 @@ impl<'src> Compiler<'src> { Some([ Operation::EQUAL | Operation::LESS | Operation::LESS_EQUAL, Operation::JUMP, - Operation::LOAD_BOOLEAN, - Operation::LOAD_BOOLEAN + Operation::LOAD_ENCODED, + Operation::LOAD_ENCODED ]), ) { self.instructions.pop(); @@ -1308,7 +1308,7 @@ impl<'src> Compiler<'src> { match else_block_distance { 0 => {} 1 => { - if let Some(Operation::LOAD_BOOLEAN | Operation::LOAD_CONSTANT) = + if let Some(Operation::LOAD_ENCODED | Operation::LOAD_CONSTANT) = self.get_last_operation() { let (loader, _, _) = self.instructions.last_mut().unwrap(); @@ -1358,8 +1358,8 @@ impl<'src> Compiler<'src> { Some([ Operation::EQUAL | Operation::LESS | Operation::LESS_EQUAL, Operation::JUMP, - Operation::LOAD_BOOLEAN, - Operation::LOAD_BOOLEAN + Operation::LOAD_ENCODED, + Operation::LOAD_ENCODED ]), ) { self.instructions.pop(); diff --git a/dust-lang/src/compiler/optimize.rs b/dust-lang/src/compiler/optimize.rs index bf22d34..f60ad82 100644 --- a/dust-lang/src/compiler/optimize.rs +++ b/dust-lang/src/compiler/optimize.rs @@ -39,8 +39,8 @@ pub fn control_flow_register_consolidation(compiler: &mut Compiler) { Some([ Operation::TEST | Operation::EQUAL | Operation::LESS | Operation::LESS_EQUAL, Operation::JUMP, - Operation::LOAD_BOOLEAN | Operation::LOAD_CONSTANT, - Operation::LOAD_BOOLEAN | Operation::LOAD_CONSTANT, + Operation::LOAD_ENCODED | Operation::LOAD_CONSTANT, + Operation::LOAD_ENCODED | Operation::LOAD_CONSTANT, ]) ) { return; diff --git a/dust-lang/src/instruction/load_boolean.rs b/dust-lang/src/instruction/load_boolean.rs deleted file mode 100644 index f14ff3c..0000000 --- a/dust-lang/src/instruction/load_boolean.rs +++ /dev/null @@ -1,57 +0,0 @@ -use std::fmt::{self, Display, Formatter}; - -use crate::{Instruction, Operation}; - -use super::InstructionBuilder; - -pub struct LoadBoolean { - pub destination: u16, - pub value: bool, - pub jump_next: bool, -} - -impl From for LoadBoolean { - fn from(instruction: Instruction) -> Self { - LoadBoolean { - destination: instruction.a_field(), - value: instruction.b_field() != 0, - jump_next: instruction.c_field() != 0, - } - } -} - -impl From for Instruction { - fn from(load_boolean: LoadBoolean) -> Self { - let operation = Operation::LOAD_BOOLEAN; - let a_field = load_boolean.destination; - let b_field = load_boolean.value as u16; - let c_field = load_boolean.jump_next as u16; - - InstructionBuilder { - operation, - a_field, - b_field, - c_field, - ..Default::default() - } - .build() - } -} - -impl Display for LoadBoolean { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - let LoadBoolean { - destination, - value, - jump_next, - } = self; - - write!(f, "R{destination} = {value}")?; - - if *jump_next { - write!(f, " JUMP +1")?; - } - - Ok(()) - } -} diff --git a/dust-lang/src/instruction/load_encoded.rs b/dust-lang/src/instruction/load_encoded.rs new file mode 100644 index 0000000..ac8e5b5 --- /dev/null +++ b/dust-lang/src/instruction/load_encoded.rs @@ -0,0 +1,66 @@ +use std::fmt::{self, Display, Formatter}; + +use crate::{Instruction, Operation}; + +use super::{InstructionBuilder, TypeCode}; + +pub struct LoadEncoded { + pub destination: u16, + pub value: u16, + pub r#type: TypeCode, + pub jump_next: bool, +} + +impl From for LoadEncoded { + fn from(instruction: Instruction) -> Self { + LoadEncoded { + destination: instruction.a_field(), + value: instruction.b_field(), + r#type: instruction.b_type(), + jump_next: instruction.c_field() != 0, + } + } +} + +impl From for Instruction { + fn from(load_encoded: LoadEncoded) -> Self { + let operation = Operation::LOAD_ENCODED; + let a_field = load_encoded.destination; + let b_field = load_encoded.value as u16; + let b_type = load_encoded.r#type; + let c_field = load_encoded.jump_next as u16; + + InstructionBuilder { + operation, + a_field, + b_field, + b_type, + c_field, + ..Default::default() + } + .build() + } +} + +impl Display for LoadEncoded { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + let LoadEncoded { + destination, + value, + r#type, + jump_next, + } = self; + + match *r#type { + TypeCode::BOOLEAN => write!(f, "R{destination} = {}", *value != 0)?, + TypeCode::BYTE => write!(f, "R{destination} = {value}")?, + unsupported => unsupported.panic_from_unsupported_code(), + }; + + if *jump_next { + write!(f, " JUMP +1")?; + } + + Ok(()) + } +} diff --git a/dust-lang/src/instruction/mod.rs b/dust-lang/src/instruction/mod.rs index 424819c..b846010 100644 --- a/dust-lang/src/instruction/mod.rs +++ b/dust-lang/src/instruction/mod.rs @@ -103,8 +103,8 @@ mod get_local; mod jump; mod less; mod less_equal; -mod load_boolean; mod load_constant; +mod load_encoded; mod load_function; mod load_list; mod load_self; @@ -131,8 +131,8 @@ pub use get_local::GetLocal; pub use jump::Jump; pub use less::Less; pub use less_equal::LessEqual; -pub use load_boolean::LoadBoolean; pub use load_constant::LoadConstant; +pub use load_encoded::LoadEncoded; pub use load_function::LoadFunction; pub use load_list::LoadList; pub use load_self::LoadSelf; @@ -529,7 +529,7 @@ impl Instruction { pub fn as_argument(&self) -> Option { match self.operation() { Operation::LOAD_CONSTANT => Some(Operand::Constant(self.b_field())), - Operation::LOAD_BOOLEAN + Operation::LOAD_ENCODED | Operation::LOAD_LIST | Operation::LOAD_SELF | Operation::GET_LOCAL @@ -583,7 +583,7 @@ impl Instruction { pub fn yields_value(&self) -> bool { match self.operation() { Operation::POINT - | Operation::LOAD_BOOLEAN + | Operation::LOAD_ENCODED | Operation::LOAD_CONSTANT | Operation::LOAD_FUNCTION | Operation::LOAD_LIST @@ -621,7 +621,7 @@ impl Instruction { match operation { Operation::POINT => Point::from(*self).to_string(), Operation::CLOSE => Close::from(*self).to_string(), - Operation::LOAD_BOOLEAN => LoadBoolean::from(*self).to_string(), + Operation::LOAD_ENCODED => LoadBoolean::from(*self).to_string(), Operation::LOAD_CONSTANT => LoadConstant::from(*self).to_string(), Operation::LOAD_FUNCTION => LoadFunction::from(*self).to_string(), Operation::LOAD_LIST => LoadList::from(*self).to_string(), diff --git a/dust-lang/src/instruction/operation.rs b/dust-lang/src/instruction/operation.rs index 5617f9c..78d88d8 100644 --- a/dust-lang/src/instruction/operation.rs +++ b/dust-lang/src/instruction/operation.rs @@ -14,7 +14,7 @@ impl Operation { pub const CLOSE: Operation = Operation(1); // Loaders - pub const LOAD_BOOLEAN: Operation = Operation(2); + pub const LOAD_ENCODED: Operation = Operation(2); pub const LOAD_CONSTANT: Operation = Operation(3); pub const LOAD_FUNCTION: Operation = Operation(4); pub const LOAD_LIST: Operation = Operation(5); @@ -58,7 +58,7 @@ impl Operation { match *self { Self::POINT => "POINT", Self::CLOSE => "CLOSE", - Self::LOAD_BOOLEAN => "LOAD_BOOLEAN", + Self::LOAD_ENCODED => "LOAD_ENCODED", Self::LOAD_CONSTANT => "LOAD_CONSTANT", Self::LOAD_FUNCTION => "LOAD_FUNCTION", Self::LOAD_LIST => "LOAD_LIST", diff --git a/dust-lang/src/instruction/type_code.rs b/dust-lang/src/instruction/type_code.rs index daf6e82..4420e3f 100644 --- a/dust-lang/src/instruction/type_code.rs +++ b/dust-lang/src/instruction/type_code.rs @@ -14,6 +14,10 @@ impl TypeCode { pub fn panic_from_unknown_code(self) -> ! { panic!("Unknown type code: {}", self.0); } + + pub fn panic_from_unsupported_code(self) -> ! { + panic!("Type code {} is not supported in the context", self.0,); + } } impl Display for TypeCode { diff --git a/dust-lang/src/vm/action.rs b/dust-lang/src/vm/action.rs index 0a99caf..009b6f0 100644 --- a/dust-lang/src/vm/action.rs +++ b/dust-lang/src/vm/action.rs @@ -3,8 +3,8 @@ use tracing::trace; use crate::{ AbstractList, ConcreteValue, Instruction, Operand, Type, Value, instruction::{ - Add, Call, CallNative, Close, Divide, Equal, GetLocal, Jump, Less, LessEqual, LoadBoolean, - LoadConstant, LoadFunction, LoadList, LoadSelf, Modulo, Multiply, Negate, Not, Point, + Add, Call, CallNative, Close, Divide, Equal, GetLocal, Jump, Less, LessEqual, LoadConstant, + LoadEncoded, LoadFunction, LoadList, LoadSelf, Modulo, Multiply, Negate, Not, Point, Return, SetLocal, Subtract, Test, TestSet, TypeCode, }, vm::CallFrame, @@ -97,7 +97,7 @@ pub fn close(instruction: Instruction, data: &mut ThreadData) -> bool { } pub fn load_boolean(instruction: Instruction, data: &mut ThreadData) -> bool { - let LoadBoolean { + let LoadEncoded { destination, value, jump_next, @@ -855,7 +855,7 @@ mod tests { const ALL_OPERATIONS: [(Operation, RunnerLogic); 24] = [ (Operation::POINT, point), (Operation::CLOSE, close), - (Operation::LOAD_BOOLEAN, load_boolean), + (Operation::LOAD_ENCODED, load_boolean), (Operation::LOAD_CONSTANT, load_constant), (Operation::LOAD_LIST, load_list), (Operation::LOAD_SELF, load_self),