From 4a169bc515ef1f99d52b776afc358aa7b367c92f Mon Sep 17 00:00:00 2001 From: Jeff Date: Mon, 17 Feb 2025 10:04:31 -0500 Subject: [PATCH] Fix tests; Rename point to move; Implement lists in the VM --- dust-lang/src/compiler/mod.rs | 23 +- dust-lang/src/instruction/close.rs | 4 +- dust-lang/src/instruction/mod.rs | 23 +- .../src/instruction/{point.rs => move.rs} | 31 +- dust-lang/src/instruction/operation.rs | 4 +- dust-lang/src/lib.rs | 9 +- dust-lang/src/native_function/assert.rs | 6 +- dust-lang/src/native_function/io.rs | 12 +- dust-lang/src/native_function/random.rs | 14 +- dust-lang/src/type.rs | 4 + dust-lang/src/value/abstract_list.rs | 69 ++- dust-lang/src/value/concrete_value.rs | 27 +- dust-lang/src/vm/call_frame.rs | 253 ++++------ dust-lang/src/vm/mod.rs | 5 +- dust-lang/src/vm/thread.rs | 469 ++++++++++++++---- dust-lang/tests/math/divide.rs | 16 +- dust-lang/tests/math/modulo.rs | 12 +- dust-lang/tests/math/multiply.rs | 16 +- dust-lang/tests/math/subtract.rs | 12 +- dust-lang/tests/values.rs | 114 ++--- 20 files changed, 680 insertions(+), 443 deletions(-) rename dust-lang/src/instruction/{point.rs => move.rs} (63%) diff --git a/dust-lang/src/compiler/mod.rs b/dust-lang/src/compiler/mod.rs index 34ef9d3..29558dd 100644 --- a/dust-lang/src/compiler/mod.rs +++ b/dust-lang/src/compiler/mod.rs @@ -30,7 +30,7 @@ use type_checks::{check_math_type, check_math_types}; use std::{mem::replace, sync::Arc}; use crate::{ - instruction::{Jump, Point, Return, TypeCode}, + instruction::{Jump, Move, Return, TypeCode}, Chunk, DustError, DustString, FunctionType, Instruction, Lexer, Local, NativeFunction, Operand, Operation, Scope, Span, Token, TokenKind, Type, }; @@ -876,8 +876,8 @@ impl<'src> Compiler<'src> { position: self.previous_position, })?; let (left, push_back_left) = self.handle_binary_argument(&left_instruction); - let left_is_mutable_local = if left_instruction.operation() == Operation::POINT { - let Point { to, .. } = Point::from(left_instruction); + let left_is_mutable_local = if left_instruction.operation() == Operation::MOVE { + let Move { operand: to, .. } = Move::from(&left_instruction); self.locals .get(to.index() as usize) @@ -1084,8 +1084,8 @@ impl<'src> Compiler<'src> { found: self.previous_token.to_owned(), position: self.previous_position, })?; - let operand_register = if left_instruction.operation() == Operation::POINT { - let Point { to, .. } = Point::from(left_instruction); + let operand_register = if left_instruction.operation() == Operation::MOVE { + let Move { operand: to, .. } = Move::from(&left_instruction); let local = self.get_local(to.index())?; local.register_index @@ -1239,7 +1239,7 @@ impl<'src> Compiler<'src> { Type::String => self.next_string_register(), _ => todo!(), }; - let point = Instruction::point( + let point = Instruction::r#move( destination, Operand::Register(local_register_index, local_type.type_code()), ); @@ -1756,20 +1756,21 @@ impl<'src> Compiler<'src> { } fn parse_implicit_return(&mut self) -> Result<(), CompileError> { - if matches!(self.get_last_operation(), Some(Operation::POINT)) { - let Point { to, .. } = Point::from(self.instructions.last().unwrap().0); + if matches!(self.get_last_operation(), Some(Operation::MOVE)) { + let last_instruction = self.instructions.last().unwrap().0; + let Move { operand, .. } = Move::from(&last_instruction); - let (point, r#type, position) = self.instructions.pop().unwrap(); + let (r#move, r#type, position) = self.instructions.pop().unwrap(); let (should_return, target_register) = if r#type == Type::None { (false, 0) } else { - (true, to.index()) + (true, operand.index()) }; let r#return = Instruction::r#return(should_return, target_register, r#type.type_code()); if !should_return { - self.instructions.push((point, r#type.clone(), position)); + self.instructions.push((r#move, r#type.clone(), position)); } self.emit_instruction(r#return, r#type, self.current_position); diff --git a/dust-lang/src/instruction/close.rs b/dust-lang/src/instruction/close.rs index cc63637..24f80ce 100644 --- a/dust-lang/src/instruction/close.rs +++ b/dust-lang/src/instruction/close.rs @@ -10,8 +10,8 @@ pub struct Close { pub r#type: TypeCode, } -impl From for Close { - fn from(instruction: Instruction) -> Self { +impl From<&Instruction> for Close { + fn from(instruction: &Instruction) -> Self { Close { from: instruction.b_field(), to: instruction.c_field(), diff --git a/dust-lang/src/instruction/mod.rs b/dust-lang/src/instruction/mod.rs index e670a86..373632e 100644 --- a/dust-lang/src/instruction/mod.rs +++ b/dust-lang/src/instruction/mod.rs @@ -93,11 +93,11 @@ mod load_function; mod load_list; mod load_self; mod modulo; +mod r#move; mod multiply; mod negate; mod not; mod operation; -mod point; mod r#return; mod subtract; mod test; @@ -123,7 +123,7 @@ pub use multiply::Multiply; pub use negate::Negate; pub use not::Not; pub use operation::Operation; -pub use point::Point; +pub use r#move::Move; pub use r#return::Return; pub use subtract::Subtract; pub use test::Test; @@ -183,7 +183,7 @@ impl From<&Instruction> for InstructionFields { impl Default for InstructionFields { fn default() -> Self { InstructionFields { - operation: Operation::POINT, + operation: Operation::MOVE, a_field: 0, b_field: 0, c_field: 0, @@ -277,8 +277,8 @@ impl Instruction { pub fn as_operand(&self) -> Operand { match self.operation() { - Operation::POINT => { - let Point { to, .. } = Point::from(*self); + Operation::MOVE => { + let Move { operand: to, .. } = Move::from(self); Operand::Register(to.index(), to.as_type()) } @@ -370,8 +370,11 @@ impl Instruction { Instruction(Operation::NO_OP.0 as u64) } - pub fn point(destination: u16, to: Operand) -> Instruction { - Instruction::from(Point { destination, to }) + pub fn r#move(destination: u16, to: Operand) -> Instruction { + Instruction::from(Move { + destination, + operand: to, + }) } pub fn close(from: u16, to: u16, r#type: TypeCode) -> Instruction { @@ -605,7 +608,7 @@ impl Instruction { pub fn yields_value(&self) -> bool { match self.operation() { - Operation::POINT + Operation::MOVE | Operation::LOAD_ENCODED | Operation::LOAD_CONSTANT | Operation::LOAD_FUNCTION @@ -640,8 +643,8 @@ impl Instruction { let operation = self.operation(); match operation { - Operation::POINT => Point::from(*self).to_string(), - Operation::CLOSE => Close::from(*self).to_string(), + Operation::MOVE => Move::from(self).to_string(), + Operation::CLOSE => Close::from(self).to_string(), Operation::LOAD_ENCODED => LoadEncoded::from(*self).to_string(), Operation::LOAD_CONSTANT => LoadConstant::from(*self).to_string(), Operation::LOAD_FUNCTION => LoadFunction::from(*self).to_string(), diff --git a/dust-lang/src/instruction/point.rs b/dust-lang/src/instruction/move.rs similarity index 63% rename from dust-lang/src/instruction/point.rs rename to dust-lang/src/instruction/move.rs index 68cd9af..d7698a2 100644 --- a/dust-lang/src/instruction/point.rs +++ b/dust-lang/src/instruction/move.rs @@ -4,26 +4,26 @@ use crate::{Instruction, Operation}; use super::{InstructionFields, Operand, TypeCode}; -pub struct Point { +pub struct Move { pub destination: u16, - pub to: Operand, + pub operand: Operand, } -impl From for Point { - fn from(instruction: Instruction) -> Self { - Point { +impl From<&Instruction> for Move { + fn from(instruction: &Instruction) -> Self { + Move { destination: instruction.a_field(), - to: instruction.b_as_operand(), + operand: instruction.b_as_operand(), } } } -impl From for Instruction { - fn from(r#move: Point) -> Self { - let operation = Operation::POINT; +impl From for Instruction { + fn from(r#move: Move) -> Self { + let operation = Operation::MOVE; let a_field = r#move.destination; - let (b_field, b_is_constant) = r#move.to.as_index_and_constant_flag(); - let b_type = r#move.to.as_type(); + let (b_field, b_is_constant) = r#move.operand.as_index_and_constant_flag(); + let b_type = r#move.operand.as_type(); InstructionFields { operation, @@ -37,9 +37,12 @@ impl From for Instruction { } } -impl Display for Point { +impl Display for Move { fn fmt(&self, f: &mut Formatter) -> fmt::Result { - let Point { destination, to } = self; + let Move { + destination, + operand: to, + } = self; match to.as_type() { TypeCode::BOOLEAN => write!(f, "R_BOOL_{destination} -> {to}"), @@ -50,7 +53,7 @@ impl Display for Point { TypeCode::STRING => write!(f, "R_STR_{destination} -> {to}"), unsupported => write!( f, - "Unsupported type code: {unsupported} for Point instruction" + "Unsupported type code: {unsupported} for MOVE instruction" ), } } diff --git a/dust-lang/src/instruction/operation.rs b/dust-lang/src/instruction/operation.rs index 6299971..cfc907a 100644 --- a/dust-lang/src/instruction/operation.rs +++ b/dust-lang/src/instruction/operation.rs @@ -12,7 +12,7 @@ impl Operation { pub const NO_OP: Operation = Operation(0); // Stack manipulation - pub const POINT: Operation = Operation(1); + pub const MOVE: Operation = Operation(1); pub const CLOSE: Operation = Operation(2); // Loaders @@ -55,7 +55,7 @@ impl Operation { pub fn name(&self) -> &'static str { match *self { Self::NO_OP => "NO_OP", - Self::POINT => "POINT", + Self::MOVE => "MOVE", Self::CLOSE => "CLOSE", Self::LOAD_ENCODED => "LOAD_ENCODED", Self::LOAD_CONSTANT => "LOAD_CONSTANT", diff --git a/dust-lang/src/lib.rs b/dust-lang/src/lib.rs index 648893f..0dc2da2 100644 --- a/dust-lang/src/lib.rs +++ b/dust-lang/src/lib.rs @@ -27,6 +27,7 @@ //! //! println!("{}", report); //! ``` +#![feature(get_many_mut)] pub mod chunk; pub mod compiler; @@ -40,17 +41,17 @@ pub mod value; pub mod vm; pub use crate::chunk::{Chunk, Disassembler, Local, Scope}; -pub use crate::compiler::{CompileError, Compiler, compile}; +pub use crate::compiler::{compile, CompileError, Compiler}; pub use crate::dust_error::{AnnotatedError, DustError}; pub use crate::instruction::{Instruction, Operand, Operation}; -pub use crate::lexer::{LexError, Lexer, lex}; +pub use crate::lexer::{lex, LexError, Lexer}; pub use crate::native_function::{NativeFunction, NativeFunctionError}; -pub use crate::token::{Token, TokenKind, TokenOwned}; pub use crate::r#type::{EnumType, FunctionType, StructType, Type, TypeConflict}; +pub use crate::token::{Token, TokenKind, TokenOwned}; pub use crate::value::{ AbstractList, ConcreteValue, DustString, Function, RangeValue, Value, ValueError, }; -pub use crate::vm::{Vm, run}; +pub use crate::vm::{run, Vm}; use std::fmt::Display; diff --git a/dust-lang/src/native_function/assert.rs b/dust-lang/src/native_function/assert.rs index 3925582..b4b6e70 100644 --- a/dust-lang/src/native_function/assert.rs +++ b/dust-lang/src/native_function/assert.rs @@ -8,7 +8,11 @@ pub fn panic(data: &mut Thread, _: usize, argument_range: Range) { let mut message = format!("Dust panic at {position}!"); for register_index in argument_range { - let string = current_frame.get_string_from_register(register_index); + let string = current_frame + .registers + .strings + .get(register_index) + .as_value(); message.push_str(string); message.push('\n'); diff --git a/dust-lang/src/native_function/io.rs b/dust-lang/src/native_function/io.rs index dfa8f1d..7ec44e9 100644 --- a/dust-lang/src/native_function/io.rs +++ b/dust-lang/src/native_function/io.rs @@ -27,7 +27,11 @@ pub fn write(data: &mut Thread, _: usize, argument_range: Range) { let mut stdout = stdout(); for register_index in argument_range { - let string = current_frame.get_string_from_register(register_index); + let string = current_frame + .registers + .strings + .get(register_index) + .as_value(); let _ = stdout.write(string.as_bytes()); } @@ -39,7 +43,11 @@ pub fn write_line(data: &mut Thread, _: usize, argument_range: Range) { let mut stdout = stdout().lock(); for register_index in argument_range { - let string = current_frame.get_string_from_register(register_index); + let string = current_frame + .registers + .strings + .get(register_index) + .as_value(); let _ = stdout.write(string.as_bytes()); } diff --git a/dust-lang/src/native_function/random.rs b/dust-lang/src/native_function/random.rs index cb1d05b..2a44b45 100644 --- a/dust-lang/src/native_function/random.rs +++ b/dust-lang/src/native_function/random.rs @@ -14,17 +14,21 @@ pub fn random_int(data: &mut Thread, destination: usize, argument_range: Range fmt::Result { match self { + Type::Any => write!(f, "any"), Type::Boolean => write!(f, "bool"), Type::Byte => write!(f, "byte"), Type::Character => write!(f, "char"), @@ -231,6 +233,8 @@ impl PartialOrd for Type { impl Ord for Type { fn cmp(&self, other: &Self) -> Ordering { match (self, other) { + (Type::Any, Type::Any) => Ordering::Equal, + (Type::Any, _) => Ordering::Greater, (Type::Boolean, Type::Boolean) => Ordering::Equal, (Type::Boolean, _) => Ordering::Greater, (Type::Byte, Type::Byte) => Ordering::Equal, diff --git a/dust-lang/src/value/abstract_list.rs b/dust-lang/src/value/abstract_list.rs index 7f53050..8e2c085 100644 --- a/dust-lang/src/value/abstract_list.rs +++ b/dust-lang/src/value/abstract_list.rs @@ -5,7 +5,7 @@ use crate::{ vm::{Pointer, Thread}, }; -use super::DustString; +use super::{ConcreteValue, DustString}; #[derive(Clone, Debug, PartialEq, PartialOrd)] pub struct AbstractList { @@ -20,7 +20,7 @@ impl AbstractList { display.push('['); - for (i, pointer) in self.item_pointers.iter().enumerate() { + for (i, pointer) in self.item_pointers.iter().copied().enumerate() { if i > 0 { display.push_str(", "); } @@ -44,6 +44,71 @@ impl AbstractList { display } + + pub fn to_concrete(&self, thread: &Thread) -> ConcreteValue { + let mut concrete_list = Vec::with_capacity(self.item_pointers.len()); + + match self.item_type { + TypeCode::BOOLEAN => { + for pointer in &self.item_pointers { + let boolean = thread.current_frame().get_boolean_from_pointer(*pointer); + + concrete_list.push(ConcreteValue::Boolean(boolean)); + } + } + TypeCode::BYTE => { + for pointer in &self.item_pointers { + let byte = thread.current_frame().get_byte_from_pointer(*pointer); + + concrete_list.push(ConcreteValue::Byte(byte)); + } + } + TypeCode::CHARACTER => { + for pointer in &self.item_pointers { + let character = thread.current_frame().get_character_from_pointer(*pointer); + + concrete_list.push(ConcreteValue::Character(character)); + } + } + TypeCode::FLOAT => { + for pointer in &self.item_pointers { + let float = thread.current_frame().get_float_from_pointer(*pointer); + + concrete_list.push(ConcreteValue::Float(float)); + } + } + TypeCode::INTEGER => { + for pointer in &self.item_pointers { + let integer = thread.current_frame().get_integer_from_pointer(*pointer); + + concrete_list.push(ConcreteValue::Integer(integer)); + } + } + TypeCode::STRING => { + for pointer in &self.item_pointers { + let string = thread + .current_frame() + .get_string_from_pointer(*pointer) + .clone(); + + concrete_list.push(ConcreteValue::String(string)); + } + } + TypeCode::LIST => { + for pointer in &self.item_pointers { + let list = thread + .current_frame() + .get_list_from_pointer(pointer) + .to_concrete(thread); + + concrete_list.push(list); + } + } + _ => todo!(), + } + + ConcreteValue::List(concrete_list) + } } impl Default for AbstractList { diff --git a/dust-lang/src/value/concrete_value.rs b/dust-lang/src/value/concrete_value.rs index efaee74..794ff11 100644 --- a/dust-lang/src/value/concrete_value.rs +++ b/dust-lang/src/value/concrete_value.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use smartstring::{LazyCompact, SmartString}; use tracing::trace; -use crate::{Type, Value, instruction::TypeCode}; +use crate::{Type, Value}; use super::RangeValue; @@ -18,10 +18,7 @@ pub enum ConcreteValue { Character(char), Float(f64), Integer(i64), - List { - items: Vec, - item_type: TypeCode, - }, + List(Vec), Range(RangeValue), String(DustString), } @@ -31,11 +28,8 @@ impl ConcreteValue { Value::Concrete(self) } - pub fn list>>(into_items: T, type_code: TypeCode) -> Self { - ConcreteValue::List { - items: into_items.into(), - item_type: type_code, - } + pub fn list>>(into_items: T) -> Self { + ConcreteValue::List(into_items.into()) } pub fn string>>(to_string: T) -> Self { @@ -91,8 +85,8 @@ impl ConcreteValue { } pub fn as_list(&self) -> Option<&Vec> { - if let ConcreteValue::List { items, .. } = self { - Some(items) + if let ConcreteValue::List(list) = self { + Some(list) } else { None } @@ -117,7 +111,7 @@ impl ConcreteValue { ConcreteValue::Character(_) => Type::Character, ConcreteValue::Float(_) => Type::Float, ConcreteValue::Integer(_) => Type::Integer, - ConcreteValue::List { item_type, .. } => Type::List(*item_type), + ConcreteValue::List(items) => items.first().map_or(Type::Any, |item| item.r#type()), ConcreteValue::Range(range) => range.r#type(), ConcreteValue::String(_) => Type::String, } @@ -134,10 +128,7 @@ impl Clone for ConcreteValue { ConcreteValue::Character(character) => ConcreteValue::Character(*character), ConcreteValue::Float(float) => ConcreteValue::Float(*float), ConcreteValue::Integer(integer) => ConcreteValue::Integer(*integer), - ConcreteValue::List { items, item_type } => ConcreteValue::List { - items: items.clone(), - item_type: *item_type, - }, + ConcreteValue::List(items) => ConcreteValue::List(items.clone()), ConcreteValue::Range(range) => ConcreteValue::Range(*range), ConcreteValue::String(string) => ConcreteValue::String(string.clone()), } @@ -160,7 +151,7 @@ impl Display for ConcreteValue { Ok(()) } ConcreteValue::Integer(integer) => write!(f, "{integer}"), - ConcreteValue::List { items, .. } => { + ConcreteValue::List(items) => { write!(f, "[")?; for (index, item) in items.iter().enumerate() { diff --git a/dust-lang/src/vm/call_frame.rs b/dust-lang/src/vm/call_frame.rs index ef026fc..bd93444 100644 --- a/dust-lang/src/vm/call_frame.rs +++ b/dust-lang/src/vm/call_frame.rs @@ -1,8 +1,7 @@ use std::{ - cell::{RefCell, RefMut}, fmt::{self, Debug, Display, Formatter}, - ops::{Add, Index, IndexMut}, - rc::Rc, + ops::{Index, IndexMut, RangeInclusive}, + sync::Arc, }; use smallvec::SmallVec; @@ -11,14 +10,14 @@ use crate::{AbstractList, Chunk, DustString, Function}; #[derive(Debug)] pub struct CallFrame { - pub chunk: Rc, + pub chunk: Arc, pub ip: usize, pub return_register: u16, pub registers: RegisterTable, } impl CallFrame { - pub fn new(chunk: Rc, return_register: u16) -> Self { + pub fn new(chunk: Arc, return_register: u16) -> Self { let registers = RegisterTable { booleans: RegisterList::new(chunk.boolean_register_count as usize), bytes: RegisterList::new(chunk.byte_register_count as usize), @@ -38,129 +37,81 @@ impl CallFrame { } } - pub fn get_boolean_from_register(&self, register_index: usize) -> bool { - let register = self.registers.booleans.get(register_index); - - match register { - Register::Value { value, .. } => *value, - Register::Pointer { pointer, .. } => self.get_boolean_from_pointer(pointer), - } - } - - pub fn get_boolean_from_pointer(&self, pointer: &Pointer) -> bool { + pub fn get_boolean_from_pointer(&self, pointer: Pointer) -> bool { match pointer { - Pointer::Register(register_index) => self.get_boolean_from_register(*register_index), + Pointer::Register(register_index) => { + *self.registers.booleans.get(register_index).as_value() + } Pointer::Constant(_) => panic!("Attempted to get boolean from constant pointer"), } } - pub fn get_byte_from_register(&self, register_index: usize) -> u8 { - let register = self.registers.bytes.get(register_index); - - match register { - Register::Value { value, .. } => *value, - Register::Pointer { pointer, .. } => self.get_byte_from_pointer(pointer), - } - } - - pub fn get_byte_from_pointer(&self, pointer: &Pointer) -> u8 { + pub fn get_byte_from_pointer(&self, pointer: Pointer) -> u8 { match pointer { - Pointer::Register(register_index) => self.get_byte_from_register(*register_index), + Pointer::Register(register_index) => { + *self.registers.bytes.get(register_index).as_value() + } Pointer::Constant(_) => panic!("Attempted to get byte from constant pointer"), } } - pub fn get_character_from_register(&self, register_index: usize) -> char { - let register = self.registers.characters.get(register_index); - - match register { - Register::Value { value, .. } => *value, - Register::Pointer { pointer, .. } => self.get_character_from_pointer(pointer), - } - } - - pub fn get_character_from_pointer(&self, pointer: &Pointer) -> char { + pub fn get_character_from_pointer(&self, pointer: Pointer) -> char { match pointer { - Pointer::Register(register_index) => self.get_character_from_register(*register_index), - Pointer::Constant(constant_index) => self.get_character_constant(*constant_index), + Pointer::Register(register_index) => { + *self.registers.characters.get(register_index).as_value() + } + Pointer::Constant(constant_index) => self.get_character_constant(constant_index), } } pub fn get_character_constant(&self, constant_index: usize) -> char { - let constant = if cfg!(debug_assertions) { - self.chunk.character_constants.get(constant_index).unwrap() + if cfg!(debug_assertions) { + *self.chunk.character_constants.get(constant_index).unwrap() } else { - unsafe { self.chunk.character_constants.get_unchecked(constant_index) } - }; - - *constant - } - - pub fn get_float_from_register(&self, register_index: usize) -> f64 { - let register = self.registers.floats.get(register_index); - - match register { - Register::Value { value, .. } => *value, - Register::Pointer { pointer, .. } => self.get_float_from_pointer(pointer), + unsafe { *self.chunk.character_constants.get_unchecked(constant_index) } } } - pub fn get_float_from_pointer(&self, pointer: &Pointer) -> f64 { + pub fn get_float_from_pointer(&self, pointer: Pointer) -> f64 { match pointer { - Pointer::Register(register_index) => self.get_float_from_register(*register_index), - Pointer::Constant(constant_index) => self.get_float_constant(*constant_index), + Pointer::Register(register_index) => { + *self.registers.floats.get(register_index).as_value() + } + Pointer::Constant(constant_index) => self.get_float_constant(constant_index), } } pub fn get_float_constant(&self, constant_index: usize) -> f64 { - let constant = if cfg!(debug_assertions) { - self.chunk.float_constants.get(constant_index).unwrap() + if cfg!(debug_assertions) { + *self.chunk.float_constants.get(constant_index).unwrap() } else { - unsafe { self.chunk.float_constants.get_unchecked(constant_index) } - }; - - *constant - } - - pub fn get_integer_from_register(&self, register_index: usize) -> i64 { - let register = self.registers.integers.get(register_index); - - match register { - Register::Value { value, .. } => *value, - Register::Pointer { pointer, .. } => self.get_integer_from_pointer(pointer), + unsafe { *self.chunk.float_constants.get_unchecked(constant_index) } } } - pub fn get_integer_from_pointer(&self, pointer: &Pointer) -> i64 { + pub fn get_integer_from_pointer(&self, pointer: Pointer) -> i64 { match pointer { - Pointer::Register(register_index) => self.get_integer_from_register(*register_index), - Pointer::Constant(constant_index) => self.get_integer_constant(*constant_index), + Pointer::Register(register_index) => { + *self.registers.integers.get(register_index).as_value() + } + Pointer::Constant(constant_index) => self.get_integer_constant(constant_index), } } pub fn get_integer_constant(&self, constant_index: usize) -> i64 { - let constant = if cfg!(debug_assertions) { - self.chunk.integer_constants.get(constant_index).unwrap() + if cfg!(debug_assertions) { + *self.chunk.integer_constants.get(constant_index).unwrap() } else { - unsafe { self.chunk.integer_constants.get_unchecked(constant_index) } - }; - - *constant - } - - pub fn get_string_from_register(&self, register_index: usize) -> &DustString { - let register = self.registers.strings.get(register_index); - - match register { - Register::Value { value, .. } => value, - Register::Pointer { pointer, .. } => self.get_string_from_pointer(pointer), + unsafe { *self.chunk.integer_constants.get_unchecked(constant_index) } } } - pub fn get_string_from_pointer(&self, pointer: &Pointer) -> &DustString { + pub fn get_string_from_pointer(&self, pointer: Pointer) -> &DustString { match pointer { - Pointer::Register(register_index) => self.get_string_from_register(*register_index), - Pointer::Constant(constant_index) => self.get_string_constant(*constant_index), + Pointer::Register(register_index) => { + self.registers.strings.get(register_index).as_value() + } + Pointer::Constant(constant_index) => self.get_string_constant(constant_index), } } @@ -172,52 +123,20 @@ impl CallFrame { } } - pub fn get_list_from_register(&self, register_index: usize) -> &AbstractList { - let register = self.registers.lists.get(register_index); - - match register { - Register::Value { value, .. } => value, - Register::Pointer { pointer, .. } => self.get_list_from_pointer(pointer), - } - } - - pub fn get_list_from_register_mut(&mut self, register_index: usize) -> &mut AbstractList { - let register = self.registers.lists.get_mut(register_index); - - match register { - Register::Value { value, .. } => value, - Register::Pointer { .. } => panic!("Attempted to get mutable list from pointer"), - } - } - pub fn get_list_from_pointer(&self, pointer: &Pointer) -> &AbstractList { match pointer { - Pointer::Register(register_index) => self.get_list_from_register(*register_index), + Pointer::Register(register_index) => { + self.registers.lists.get(*register_index).as_value() + } Pointer::Constant(_) => panic!("Attempted to get list from constant pointer"), } } - pub fn get_function_from_register(&self, register_index: usize) -> &Function { - let register = self.registers.functions.get(register_index); - - match register { - Register::Value { value, .. } => value, - Register::Pointer { pointer, .. } => self.get_function_from_pointer(pointer), - } - } - - pub fn get_function_from_register_mut(&mut self, register_index: usize) -> &mut Function { - let register = self.registers.functions.get_mut(register_index); - - match register { - Register::Value { value, .. } => value, - Register::Pointer { .. } => panic!("Attempted to get mutable function from pointer"), - } - } - pub fn get_function_from_pointer(&self, pointer: &Pointer) -> &Function { match pointer { - Pointer::Register(register_index) => self.get_function_from_register(*register_index), + Pointer::Register(register_index) => { + self.registers.functions.get(*register_index).as_value() + } Pointer::Constant(_) => panic!("Attempted to get function from constant pointer"), } } @@ -276,6 +195,16 @@ where } } + pub fn get_many_mut(&mut self, indices: RangeInclusive) -> &mut [Register] { + let registers = if cfg!(debug_assertions) { + self.registers.get_many_mut([indices]).unwrap() + } else { + unsafe { self.registers.get_many_unchecked_mut([indices]) } + }; + + registers[0] + } + pub fn get_mut(&mut self, index: usize) -> &mut Register { if cfg!(debug_assertions) { let length = self.registers.len(); @@ -302,6 +231,18 @@ where } } + pub fn close_many(&mut self, indices: RangeInclusive) { + let registers = if cfg!(debug_assertions) { + &mut self.registers.get_many_mut([indices]).unwrap()[0] + } else { + unsafe { &mut self.registers.get_many_unchecked_mut([indices])[0] } + }; + + for register in registers.iter_mut() { + register.close(); + } + } + pub fn is_closed(&self, index: usize) -> bool { if cfg!(debug_assertions) { self.registers.get(index).unwrap().is_closed() @@ -325,66 +266,56 @@ impl IndexMut for RegisterList { } } -#[derive(Clone, Debug)] -pub enum Register { - Value { value: T, is_closed: bool }, - Pointer { pointer: Pointer, is_closed: bool }, +#[derive(Clone, Copy, Debug)] +pub struct Register { + value: T, + is_closed: bool, } impl Register { pub fn value(value: T) -> Self { - Self::Value { + Self { value, is_closed: false, } } pub fn is_closed(&self) -> bool { - match self { - Self::Value { is_closed, .. } => *is_closed, - Self::Pointer { is_closed, .. } => *is_closed, - } + self.is_closed } pub fn close(&mut self) { - match self { - Self::Value { is_closed, .. } => *is_closed = true, - Self::Pointer { is_closed, .. } => *is_closed = true, - } + self.is_closed = true; } pub fn set(&mut self, new_value: T) { - match self { - Self::Value { - value: old_value, .. - } => *old_value = new_value, - Self::Pointer { is_closed, .. } => { - *self = Self::Value { - value: new_value, - is_closed: *is_closed, - } - } - } + self.value = new_value; } pub fn as_value(&self) -> &T { - match self { - Self::Value { value, .. } => value, - Self::Pointer { .. } => panic!("Attempted to use pointer as value"), - } + &self.value } pub fn as_value_mut(&mut self) -> &mut T { - match self { - Self::Value { value, .. } => value, - Self::Pointer { .. } => panic!("Attempted to use pointer as value"), - } + &mut self.value + } +} + +impl Register { + pub fn copy_value(&self) -> T { + self.value + } +} + +impl Register { + pub fn clone_value(&self) -> T { + self.value.clone() } } impl Default for Register { fn default() -> Self { - Self::Value { + Self { value: Default::default(), is_closed: false, } diff --git a/dust-lang/src/vm/mod.rs b/dust-lang/src/vm/mod.rs index b330a7a..894d4c9 100644 --- a/dust-lang/src/vm/mod.rs +++ b/dust-lang/src/vm/mod.rs @@ -3,7 +3,7 @@ mod call_frame; mod thread; -use std::{rc::Rc, thread::Builder}; +use std::{sync::Arc, thread::Builder}; pub use call_frame::{CallFrame, Pointer, Register, RegisterTable}; pub use thread::Thread; @@ -32,6 +32,7 @@ impl Vm { pub fn run(self) -> Option { let span = span!(Level::INFO, "Run"); let _enter = span.enter(); + let thread_name = self .main_chunk .name @@ -43,7 +44,7 @@ impl Vm { Builder::new() .name(thread_name) .spawn(move || { - let main_chunk = Rc::new(self.main_chunk); + let main_chunk = Arc::new(self.main_chunk); let main_thread = Thread::new(main_chunk); let return_value = main_thread.run(); let _ = tx.send(return_value); diff --git a/dust-lang/src/vm/thread.rs b/dust-lang/src/vm/thread.rs index 28c4660..d6c9e47 100644 --- a/dust-lang/src/vm/thread.rs +++ b/dust-lang/src/vm/thread.rs @@ -1,21 +1,23 @@ -use std::{rc::Rc, thread::JoinHandle}; +use std::{sync::Arc, thread::JoinHandle}; use tracing::info; use crate::{ - instruction::TypeCode, vm::CallFrame, Chunk, ConcreteValue, DustString, Operation, Span, Value, + instruction::TypeCode, + vm::{CallFrame, Pointer}, + AbstractList, Chunk, DustString, Operation, Span, Value, }; pub struct Thread { - chunk: Rc, + chunk: Arc, call_stack: Vec, _spawned_threads: Vec>, } impl Thread { - pub fn new(chunk: Rc) -> Self { + pub fn new(chunk: Arc) -> Self { let mut call_stack = Vec::with_capacity(chunk.prototypes.len() + 1); - let main_call = CallFrame::new(Rc::clone(&chunk), 0); + let main_call = CallFrame::new(Arc::clone(&chunk), 0); call_stack.push(main_call); @@ -52,6 +54,168 @@ impl Thread { info!("Run instruction {}", instruction.operation()); match instruction.operation() { + Operation::MOVE => { + let source = instruction.b_field() as usize; + let destination = instruction.a_field() as usize; + let source_type = instruction.b_type(); + + match source_type { + TypeCode::BOOLEAN => { + let value = current_frame.registers.booleans.get(source).copy_value(); + + current_frame + .registers + .booleans + .get_mut(destination) + .set(value); + } + TypeCode::BYTE => { + let value = current_frame.registers.bytes.get(source).copy_value(); + + current_frame + .registers + .bytes + .get_mut(destination) + .set(value); + } + TypeCode::CHARACTER => { + let value = current_frame.registers.characters.get(source).copy_value(); + + current_frame + .registers + .characters + .get_mut(destination) + .set(value); + } + TypeCode::FLOAT => { + let value = current_frame.registers.floats.get(source).copy_value(); + + current_frame + .registers + .floats + .get_mut(destination) + .set(value); + } + TypeCode::INTEGER => { + let value = current_frame.registers.integers.get(source).copy_value(); + + current_frame + .registers + .integers + .get_mut(destination) + .set(value); + } + TypeCode::STRING => { + let value = current_frame.registers.strings.get(source).clone_value(); + + current_frame + .registers + .strings + .get_mut(destination) + .set(value); + } + TypeCode::LIST => { + let value = current_frame.registers.lists.get(source).clone_value(); + + current_frame + .registers + .lists + .get_mut(destination) + .set(value); + } + _ => todo!(), + } + } + Operation::CLOSE => { + let from = instruction.b_field() as usize; + let to = instruction.c_field() as usize; + let r#type = instruction.b_type(); + + match r#type { + TypeCode::BOOLEAN => { + let registers = + current_frame.registers.booleans.get_many_mut(from..=to); + + for register in registers { + register.close(); + } + } + TypeCode::BYTE => { + let registers = current_frame.registers.bytes.get_many_mut(from..=to); + + for register in registers { + register.close(); + } + } + TypeCode::CHARACTER => { + let registers = + current_frame.registers.characters.get_many_mut(from..=to); + + for register in registers { + register.close(); + } + } + TypeCode::FLOAT => { + let registers = current_frame.registers.floats.get_many_mut(from..=to); + + for register in registers { + register.close(); + } + } + TypeCode::INTEGER => { + let registers = + current_frame.registers.integers.get_many_mut(from..=to); + + for register in registers { + register.close(); + } + } + TypeCode::STRING => { + let registers = current_frame.registers.strings.get_many_mut(from..=to); + + for register in registers { + register.close(); + } + } + TypeCode::LIST => { + let registers = current_frame.registers.lists.get_many_mut(from..=to); + + for register in registers { + register.close(); + } + } + _ => unreachable!("Invalid CLOSE operation"), + } + } + Operation::LOAD_ENCODED => { + let destination = instruction.a_field() as usize; + let value_type = instruction.b_type(); + let jump_next = instruction.c_field() != 0; + + match value_type { + TypeCode::BOOLEAN => { + let boolean = instruction.b_field() != 0; + + current_frame + .registers + .booleans + .set_to_new_register(destination, boolean); + } + TypeCode::BYTE => { + let byte = instruction.b_field() as u8; + + current_frame + .registers + .bytes + .set_to_new_register(destination, byte); + } + _ => unreachable!(), + } + + if jump_next { + current_frame.ip += 1; + } + } Operation::LOAD_CONSTANT => { let destination = instruction.a_field() as usize; let constant_index = instruction.b_field() as usize; @@ -102,6 +266,139 @@ impl Thread { current_frame.ip += 1; } } + Operation::LOAD_LIST => { + let destination = instruction.a_field() as usize; + let start_register = instruction.b_field() as usize; + let item_type = instruction.b_type(); + let end_register = instruction.c_field() as usize; + let jump_next = instruction.d_field(); + + let mut item_pointers = Vec::with_capacity(end_register - start_register + 1); + + match item_type { + TypeCode::BOOLEAN => { + for register_index in start_register..=end_register { + let register_is_closed = + current_frame.registers.booleans.is_closed(register_index); + + if register_is_closed { + continue; + } + + item_pointers.push(Pointer::Register(register_index)); + } + } + TypeCode::BYTE => { + for register_index in start_register..=end_register { + let register_is_closed = + current_frame.registers.bytes.is_closed(register_index); + + if register_is_closed { + continue; + } + + item_pointers.push(Pointer::Register(register_index)); + } + } + TypeCode::CHARACTER => { + for register_index in start_register..=end_register { + let register_is_closed = + current_frame.registers.characters.is_closed(register_index); + + if register_is_closed { + continue; + } + + item_pointers.push(Pointer::Register(register_index)); + } + } + TypeCode::FLOAT => { + for register_index in start_register..=end_register { + let register_is_closed = + current_frame.registers.floats.is_closed(register_index); + + if register_is_closed { + continue; + } + + item_pointers.push(Pointer::Register(register_index)); + } + } + TypeCode::INTEGER => { + for register_index in start_register..=end_register { + let register_is_closed = + current_frame.registers.integers.is_closed(register_index); + + if register_is_closed { + continue; + } + + item_pointers.push(Pointer::Register(register_index)); + } + } + TypeCode::STRING => { + for register_index in start_register..=end_register { + let register_is_closed = + current_frame.registers.strings.is_closed(register_index); + + if register_is_closed { + continue; + } + + item_pointers.push(Pointer::Register(register_index)); + } + } + TypeCode::LIST => { + for register_index in start_register..=end_register { + let register_is_closed = + current_frame.registers.lists.is_closed(register_index); + + if register_is_closed { + continue; + } + + item_pointers.push(Pointer::Register(register_index)); + } + } + _ => unreachable!("Invalid LOAD_LIST operation"), + } + + let list = AbstractList { + item_type, + item_pointers, + }; + + current_frame.registers.lists.get_mut(destination).set(list); + + if jump_next { + current_frame.ip += 1; + } + } + Operation::LOAD_FUNCTION => { + let destination = instruction.a_field() as usize; + let prototype_index = instruction.b_field() as usize; + let jump_next = instruction.c_field() != 0; + let prototype = if cfg!(debug_assertions) { + current_frame.chunk.prototypes.get(prototype_index).unwrap() + } else { + unsafe { + current_frame + .chunk + .prototypes + .get_unchecked(prototype_index) + } + }; + let function = prototype.as_function(); + + current_frame + .registers + .functions + .set_to_new_register(destination, function); + + if jump_next { + current_frame.ip += 1; + } + } Operation::LESS => match (instruction.b_type(), instruction.c_type()) { (TypeCode::INTEGER, TypeCode::INTEGER) => { let left = instruction.b_field() as usize; @@ -113,12 +410,12 @@ impl Thread { let left_value = if left_is_constant { current_frame.get_integer_constant(left) } else { - current_frame.get_integer_from_register(left) + current_frame.registers.integers.get(left).copy_value() }; let right_value = if right_is_constant { current_frame.get_integer_constant(right) } else { - current_frame.get_integer_from_register(right) + current_frame.registers.integers.get(right).copy_value() }; let is_less_than = left_value < right_value; @@ -134,8 +431,9 @@ impl Thread { let right_index = instruction.c_field() as usize; let destination_index = instruction.a_field() as usize; - let left_value = current_frame.get_byte_from_register(left_index); - let right_value = current_frame.get_byte_from_register(right_index); + let left_value = current_frame.registers.bytes.get(left_index).copy_value(); + let right_value = + current_frame.registers.bytes.get(right_index).copy_value(); let sum = left_value + right_value; current_frame @@ -153,12 +451,20 @@ impl Thread { let left_value = if left_is_constant { current_frame.get_character_constant(left_index) } else { - current_frame.get_character_from_register(left_index) + current_frame + .registers + .characters + .get(left_index) + .copy_value() }; let right_value = if right_is_constant { current_frame.get_character_constant(right_index) } else { - current_frame.get_character_from_register(right_index) + current_frame + .registers + .characters + .get(right_index) + .copy_value() }; let concatenated = { let mut concatenated = DustString::from(String::with_capacity(2)); @@ -184,12 +490,16 @@ impl Thread { let left_value = if left_is_constant { current_frame.get_character_constant(left_index) } else { - current_frame.get_character_from_register(left_index) + current_frame + .registers + .characters + .get(left_index) + .copy_value() }; let right_value = if right_is_constant { current_frame.get_string_constant(right_index) } else { - current_frame.get_string_from_register(right_index) + current_frame.registers.strings.get(right_index).as_value() }; let concatenated = DustString::from(format!("{left_value}{right_value}")); @@ -203,8 +513,10 @@ impl Thread { let right_index = instruction.c_field() as usize; let destination_index = instruction.a_field() as usize; - let left_value = current_frame.get_float_from_register(left_index); - let right_value = current_frame.get_float_from_register(right_index); + let left_value = + current_frame.registers.floats.get(left_index).copy_value(); + let right_value = + current_frame.registers.floats.get(right_index).copy_value(); let sum = left_value + right_value; current_frame @@ -222,12 +534,12 @@ impl Thread { let left_value = if left_is_constant { current_frame.get_integer_constant(left) } else { - current_frame.get_integer_from_register(left) + current_frame.registers.integers.get(left).copy_value() }; let right_value = if right_is_constant { current_frame.get_integer_constant(right) } else { - current_frame.get_integer_from_register(right) + current_frame.registers.integers.get(right).copy_value() }; let sum = left_value + right_value; @@ -246,12 +558,12 @@ impl Thread { let left_value = if left_is_constant { current_frame.get_string_constant(left) } else { - current_frame.get_string_from_register(left) + current_frame.registers.strings.get(left).as_value() }; let right_value = if right_is_constant { current_frame.get_string_constant(right) } else { - current_frame.get_string_from_register(right) + current_frame.registers.strings.get(right).as_value() }; let concatenated = DustString::from(format!("{left_value}{right_value}")); @@ -260,7 +572,7 @@ impl Thread { .strings .set_to_new_register(destination_index, concatenated); } - _ => todo!(), + _ => unreachable!("Invalid ADD operation"), }, Operation::JUMP => { let offset = instruction.b_field() as usize; @@ -280,112 +592,69 @@ impl Thread { if should_return_value { match return_type { TypeCode::BOOLEAN => { - let return_value = - current_frame.get_boolean_from_register(return_register); + let return_value = current_frame + .registers + .booleans + .get(return_register) + .copy_value(); return Some(Value::boolean(return_value)); } TypeCode::BYTE => { - let return_value = - current_frame.get_byte_from_register(return_register); + let return_value = current_frame + .registers + .bytes + .get(return_register) + .copy_value(); return Some(Value::byte(return_value)); } TypeCode::CHARACTER => { - let return_value = - current_frame.get_character_from_register(return_register); + let return_value = current_frame + .registers + .characters + .get(return_register) + .copy_value(); return Some(Value::character(return_value)); } TypeCode::FLOAT => { - let return_value = - current_frame.get_float_from_register(return_register); + let return_value = current_frame + .registers + .floats + .get(return_register) + .copy_value(); return Some(Value::float(return_value)); } TypeCode::INTEGER => { - let return_value = - current_frame.get_integer_from_register(return_register); + let return_value = current_frame + .registers + .integers + .get(return_register) + .copy_value(); return Some(Value::integer(return_value)); } TypeCode::STRING => { let return_value = current_frame - .get_string_from_register(return_register) - .clone(); + .registers + .strings + .get(return_register) + .clone_value(); return Some(Value::string(return_value)); } TypeCode::LIST => { - let abstract_list = - current_frame.get_list_from_register(return_register); + let concrete_list = current_frame + .registers + .lists + .get(return_register) + .as_value() + .clone() + .to_concrete(&self); - let mut concrete_list = - Vec::with_capacity(abstract_list.item_pointers.len()); - - match abstract_list.item_type { - TypeCode::BOOLEAN => { - for pointer in &abstract_list.item_pointers { - let boolean = - current_frame.get_boolean_from_pointer(&pointer); - let value = ConcreteValue::Boolean(boolean); - - concrete_list.push(value); - } - } - TypeCode::BYTE => { - for pointer in &abstract_list.item_pointers { - let byte = - current_frame.get_byte_from_pointer(&pointer); - let value = ConcreteValue::Byte(byte); - - concrete_list.push(value); - } - } - TypeCode::CHARACTER => { - for pointer in &abstract_list.item_pointers { - let character = - current_frame.get_character_from_pointer(&pointer); - let value = ConcreteValue::Character(character); - - concrete_list.push(value); - } - } - TypeCode::FLOAT => { - for pointer in &abstract_list.item_pointers { - let float = - current_frame.get_float_from_pointer(&pointer); - let value = ConcreteValue::Float(float); - - concrete_list.push(value); - } - } - TypeCode::INTEGER => { - for pointer in &abstract_list.item_pointers { - let integer = - current_frame.get_integer_from_pointer(&pointer); - let value = ConcreteValue::Integer(integer); - - concrete_list.push(value); - } - } - TypeCode::STRING => { - for pointer in &abstract_list.item_pointers { - let string = current_frame - .get_string_from_pointer(pointer) - .clone(); - let value = ConcreteValue::String(string); - - concrete_list.push(value); - } - } - _ => todo!(), - } - - return Some(Value::Concrete(ConcreteValue::list( - concrete_list, - abstract_list.item_type, - ))); + return Some(Value::Concrete(concrete_list)); } _ => unreachable!(), } diff --git a/dust-lang/tests/math/divide.rs b/dust-lang/tests/math/divide.rs index 6080ec9..90fc3cd 100644 --- a/dust-lang/tests/math/divide.rs +++ b/dust-lang/tests/math/divide.rs @@ -1,6 +1,6 @@ use dust_lang::{ - Chunk, ConcreteValue, FunctionType, Instruction, Operand, Span, Type, Value, compile, - instruction::TypeCode, run, + compile, instruction::TypeCode, run, Chunk, FunctionType, Instruction, Operand, Span, Type, + Value, }; #[test] @@ -78,7 +78,7 @@ fn divide_floats() { Instruction::r#return(true, 0, TypeCode::FLOAT), ], positions: vec![Span(0, 10), Span(10, 10)], - constants: vec![ConcreteValue::Float(1.0), ConcreteValue::Float(0.25)], + float_constants: vec![1.0, 0.25], ..Chunk::default() }; let return_value = Some(Value::float(4.0)); @@ -106,11 +106,7 @@ fn divide_many_floats() { Instruction::r#return(true, 1, TypeCode::FLOAT), ], positions: vec![Span(0, 10), Span(0, 16), Span(16, 16)], - constants: vec![ - ConcreteValue::Float(1.0), - ConcreteValue::Float(0.25), - ConcreteValue::Float(0.5), - ], + float_constants: vec![1.0, 0.25, 0.5], ..Chunk::default() }; let return_value = Some(Value::float(8.0)); @@ -133,7 +129,7 @@ fn divide_integers() { Instruction::r#return(true, 0, TypeCode::INTEGER), ], positions: vec![Span(0, 6), Span(6, 6)], - constants: vec![ConcreteValue::Integer(10), ConcreteValue::Integer(2)], + integer_constants: vec![10, 2], ..Chunk::default() }; let return_value = Some(Value::integer(5)); @@ -161,7 +157,7 @@ fn divide_many_integers() { Instruction::r#return(true, 1, TypeCode::INTEGER), ], positions: vec![Span(0, 6), Span(0, 10), Span(10, 10)], - constants: vec![ConcreteValue::Integer(10), ConcreteValue::Integer(2)], + integer_constants: vec![10, 2], ..Chunk::default() }; let return_value = Some(Value::integer(2)); diff --git a/dust-lang/tests/math/modulo.rs b/dust-lang/tests/math/modulo.rs index 08e0be2..dec6bc7 100644 --- a/dust-lang/tests/math/modulo.rs +++ b/dust-lang/tests/math/modulo.rs @@ -1,6 +1,6 @@ use dust_lang::{ - Chunk, ConcreteValue, FunctionType, Instruction, Operand, Span, Type, Value, compile, - instruction::TypeCode, run, + compile, instruction::TypeCode, run, Chunk, FunctionType, Instruction, Operand, Span, Type, + Value, }; #[test] @@ -78,7 +78,7 @@ fn modulo_integers() { Instruction::r#return(true, 0, TypeCode::INTEGER), ], positions: vec![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::integer(1)); @@ -106,11 +106,7 @@ fn modulo_many_integers() { Instruction::r#return(true, 1, TypeCode::INTEGER), ], positions: vec![Span(0, 6), Span(0, 10), Span(10, 10)], - constants: vec![ - ConcreteValue::Integer(10), - ConcreteValue::Integer(5), - ConcreteValue::Integer(3), - ], + integer_constants: vec![10, 5, 3], ..Chunk::default() }; let return_value = Some(Value::integer(0)); diff --git a/dust-lang/tests/math/multiply.rs b/dust-lang/tests/math/multiply.rs index 0cb051a..94d76cd 100644 --- a/dust-lang/tests/math/multiply.rs +++ b/dust-lang/tests/math/multiply.rs @@ -1,6 +1,6 @@ use dust_lang::{ - Chunk, ConcreteValue, FunctionType, Instruction, Operand, Span, Type, Value, compile, - instruction::TypeCode, run, + compile, instruction::TypeCode, run, Chunk, FunctionType, Instruction, Operand, Span, Type, + Value, }; #[test] @@ -78,7 +78,7 @@ fn multiply_floats() { Instruction::r#return(true, 0, TypeCode::FLOAT), ], positions: vec![Span(0, 9), Span(9, 9)], - constants: vec![ConcreteValue::Float(0.5), ConcreteValue::Float(2.0)], + float_constants: vec![0.5, 2.0], ..Chunk::default() }; let return_value = Some(Value::float(1.0)); @@ -106,7 +106,7 @@ fn multiply_many_floats() { Instruction::r#return(true, 1, TypeCode::FLOAT), ], positions: vec![Span(0, 9), Span(0, 15), Span(15, 15)], - constants: vec![ConcreteValue::Float(0.5), ConcreteValue::Float(2.0)], + float_constants: vec![0.5, 2.0], ..Chunk::default() }; let return_value = Some(Value::float(0.5)); @@ -129,7 +129,7 @@ fn multiply_integers() { Instruction::r#return(true, 0, TypeCode::INTEGER), ], positions: vec![Span(0, 6), Span(6, 6)], - constants: vec![ConcreteValue::Integer(10), ConcreteValue::Integer(5)], + integer_constants: vec![10, 5], ..Chunk::default() }; let return_value = Some(Value::integer(50)); @@ -157,11 +157,7 @@ fn multiply_many_integers() { Instruction::r#return(true, 1, TypeCode::INTEGER), ], positions: vec![Span(0, 6), Span(0, 10), Span(10, 10)], - constants: vec![ - ConcreteValue::Integer(10), - ConcreteValue::Integer(5), - ConcreteValue::Integer(2), - ], + integer_constants: vec![10, 5, 2], ..Chunk::default() }; let return_value = Some(Value::integer(100)); diff --git a/dust-lang/tests/math/subtract.rs b/dust-lang/tests/math/subtract.rs index 29877a7..eaa6b57 100644 --- a/dust-lang/tests/math/subtract.rs +++ b/dust-lang/tests/math/subtract.rs @@ -1,6 +1,6 @@ use dust_lang::{ - Chunk, ConcreteValue, FunctionType, Instruction, Operand, Span, Type, Value, compile, - instruction::TypeCode, run, + compile, instruction::TypeCode, run, Chunk, FunctionType, Instruction, Operand, Span, Type, + Value, }; #[test] @@ -78,7 +78,7 @@ fn add_floats() { Instruction::r#return(true, 0, TypeCode::FLOAT), ], positions: vec![Span(0, 10), Span(10, 10)], - constants: vec![ConcreteValue::Float(0.5), ConcreteValue::Float(0.25)], + float_constants: vec![0.5, 0.25], ..Chunk::default() }; let return_value = Some(Value::float(0.25)); @@ -106,7 +106,7 @@ fn add_many_floats() { Instruction::r#return(true, 1, TypeCode::FLOAT), ], positions: vec![Span(0, 10), Span(0, 17), Span(17, 17)], - constants: vec![ConcreteValue::Float(0.5), ConcreteValue::Float(0.25)], + float_constants: vec![0.5, 0.25], ..Chunk::default() }; let return_value = Some(Value::float(0.0)); @@ -129,7 +129,7 @@ fn subtract_integers() { Instruction::r#return(true, 0, TypeCode::INTEGER), ], positions: vec![Span(0, 6), Span(6, 6)], - constants: vec![ConcreteValue::Integer(10), ConcreteValue::Integer(5)], + integer_constants: vec![10, 5], ..Chunk::default() }; let return_value = Some(Value::integer(5)); @@ -157,7 +157,7 @@ fn subtract_many_integers() { Instruction::r#return(true, 1, TypeCode::INTEGER), ], positions: vec![Span(0, 6), Span(0, 10), Span(10, 10)], - constants: vec![ConcreteValue::Integer(10), ConcreteValue::Integer(5)], + integer_constants: vec![10, 5], ..Chunk::default() }; let return_value = Some(Value::integer(0)); diff --git a/dust-lang/tests/values.rs b/dust-lang/tests/values.rs index 88e2a3d..4963d4c 100644 --- a/dust-lang/tests/values.rs +++ b/dust-lang/tests/values.rs @@ -147,10 +147,10 @@ fn load_boolean_list() { positions: vec![Span(1, 5), Span(7, 12), Span(0, 13), Span(13, 13)], ..Chunk::default() }; - let return_value = Some(Value::Concrete(ConcreteValue::List { - items: vec![ConcreteValue::Boolean(true), ConcreteValue::Boolean(false)], - item_type: TypeCode::BOOLEAN, - })); + let return_value = Some(Value::Concrete(ConcreteValue::List(vec![ + ConcreteValue::Boolean(true), + ConcreteValue::Boolean(false), + ]))); assert_eq!(chunk, compile(source).unwrap()); assert_eq!(return_value, run(source).unwrap()); @@ -170,10 +170,10 @@ fn load_byte_list() { positions: vec![Span(1, 5), Span(7, 11), Span(0, 12), Span(12, 12)], ..Chunk::default() }; - let return_value = Some(Value::Concrete(ConcreteValue::List { - items: vec![ConcreteValue::Byte(0x2a), ConcreteValue::Byte(0x42)], - item_type: TypeCode::BYTE, - })); + let return_value = Some(Value::Concrete(ConcreteValue::List(vec![ + ConcreteValue::Byte(0x2a), + ConcreteValue::Byte(0x42), + ]))); assert_eq!(chunk, compile(source).unwrap()); assert_eq!(return_value, run(source).unwrap()); @@ -194,10 +194,10 @@ fn load_character_list() { character_constants: vec!['a', 'b'], ..Chunk::default() }; - let return_value = Some(Value::Concrete(ConcreteValue::List { - items: vec![ConcreteValue::Character('a'), ConcreteValue::Character('b')], - item_type: TypeCode::CHARACTER, - })); + let return_value = Some(Value::Concrete(ConcreteValue::List(vec![ + ConcreteValue::Character('a'), + ConcreteValue::Character('b'), + ]))); assert_eq!(chunk, compile(source).unwrap()); assert_eq!(return_value, run(source).unwrap()); @@ -218,10 +218,10 @@ fn load_float_list() { float_constants: vec![42.42, 24.24], ..Chunk::default() }; - let return_value = Some(Value::Concrete(ConcreteValue::List { - items: vec![ConcreteValue::Float(42.42), ConcreteValue::Float(24.24)], - item_type: TypeCode::FLOAT, - })); + let return_value = Some(Value::Concrete(ConcreteValue::List(vec![ + ConcreteValue::Float(42.42), + ConcreteValue::Float(24.24), + ]))); assert_eq!(chunk, compile(source).unwrap()); assert_eq!(return_value, run(source).unwrap()); @@ -243,14 +243,11 @@ fn load_integer_list() { integer_constants: vec![1, 2, 3], ..Chunk::default() }; - let return_value = Some(Value::Concrete(ConcreteValue::List { - items: vec![ - ConcreteValue::Integer(1), - ConcreteValue::Integer(2), - ConcreteValue::Integer(3), - ], - item_type: TypeCode::INTEGER, - })); + let return_value = Some(Value::Concrete(ConcreteValue::List(vec![ + ConcreteValue::Integer(1), + ConcreteValue::Integer(2), + ConcreteValue::Integer(3), + ]))); assert_eq!(chunk, compile(source).unwrap()); assert_eq!(return_value, run(source).unwrap()); @@ -271,13 +268,10 @@ fn load_string_list() { string_constants: vec![DustString::from("Hello"), DustString::from("World")], ..Chunk::default() }; - let return_value = Some(Value::Concrete(ConcreteValue::List { - items: vec![ - ConcreteValue::String(DustString::from("Hello")), - ConcreteValue::String(DustString::from("World")), - ], - item_type: TypeCode::STRING, - })); + let return_value = Some(Value::Concrete(ConcreteValue::List(vec![ + ConcreteValue::String(DustString::from("Hello")), + ConcreteValue::String(DustString::from("World")), + ]))); assert_eq!(chunk, compile(source).unwrap()); assert_eq!(return_value, run(source).unwrap()); @@ -311,19 +305,10 @@ fn load_nested_list() { integer_constants: vec![1, 2, 3, 4], ..Chunk::default() }; - let return_value = Some(Value::Concrete(ConcreteValue::List { - items: vec![ - ConcreteValue::List { - items: vec![ConcreteValue::Integer(1), ConcreteValue::Integer(2)], - item_type: TypeCode::INTEGER, - }, - ConcreteValue::List { - items: vec![ConcreteValue::Integer(3), ConcreteValue::Integer(4)], - item_type: TypeCode::INTEGER, - }, - ], - item_type: TypeCode::LIST, - })); + let return_value = Some(Value::Concrete(ConcreteValue::List(vec![ + ConcreteValue::List(vec![ConcreteValue::Integer(1), ConcreteValue::Integer(2)]), + ConcreteValue::List(vec![ConcreteValue::Integer(3), ConcreteValue::Integer(4)]), + ]))); assert_eq!(chunk, compile(source).unwrap()); assert_eq!(return_value, run(source).unwrap()); @@ -377,37 +362,16 @@ fn load_deeply_nested_list() { integer_constants: vec![1, 2, 3, 4, 5, 6, 7, 8], ..Chunk::default() }; - let return_value = Some(Value::Concrete(ConcreteValue::List { - items: vec![ - ConcreteValue::List { - items: vec![ - ConcreteValue::List { - items: vec![ConcreteValue::Integer(1), ConcreteValue::Integer(2)], - item_type: TypeCode::INTEGER, - }, - ConcreteValue::List { - items: vec![ConcreteValue::Integer(3), ConcreteValue::Integer(4)], - item_type: TypeCode::INTEGER, - }, - ], - item_type: TypeCode::LIST, - }, - ConcreteValue::List { - items: vec![ - ConcreteValue::List { - items: vec![ConcreteValue::Integer(5), ConcreteValue::Integer(6)], - item_type: TypeCode::INTEGER, - }, - ConcreteValue::List { - items: vec![ConcreteValue::Integer(7), ConcreteValue::Integer(8)], - item_type: TypeCode::INTEGER, - }, - ], - item_type: TypeCode::LIST, - }, - ], - item_type: TypeCode::LIST, - })); + let return_value = Some(Value::Concrete(ConcreteValue::List(vec![ + ConcreteValue::List(vec![ + ConcreteValue::List(vec![ConcreteValue::Integer(1), ConcreteValue::Integer(2)]), + ConcreteValue::List(vec![ConcreteValue::Integer(3), ConcreteValue::Integer(4)]), + ]), + ConcreteValue::List(vec![ + ConcreteValue::List(vec![ConcreteValue::Integer(5), ConcreteValue::Integer(6)]), + ConcreteValue::List(vec![ConcreteValue::Integer(7), ConcreteValue::Integer(8)]), + ]), + ]))); assert_eq!(chunk, compile(source).unwrap()); assert_eq!(return_value, run(source).unwrap());