diff --git a/dust-lang/src/chunk.rs b/dust-lang/src/chunk.rs index 2b643d1..13d5b3a 100644 --- a/dust-lang/src/chunk.rs +++ b/dust-lang/src/chunk.rs @@ -18,7 +18,7 @@ pub struct Chunk { name: Option, r#type: FunctionType, - instructions: Vec<(Instruction, Type, Span)>, + instructions: Vec<(Instruction, Span)>, constants: Vec, locals: Vec, } @@ -41,7 +41,7 @@ impl Chunk { pub fn with_data( name: Option, r#type: FunctionType, - instructions: Vec<(Instruction, Type, Span)>, + instructions: Vec<(Instruction, Span)>, constants: Vec, locals: Vec, ) -> Self { @@ -74,7 +74,7 @@ impl Chunk { &self.constants } - pub fn instructions(&self) -> &Vec<(Instruction, Type, Span)> { + pub fn instructions(&self) -> &Vec<(Instruction, Span)> { &self.instructions } diff --git a/dust-lang/src/compiler.rs b/dust-lang/src/compiler.rs index 58f16eb..22e60a8 100644 --- a/dust-lang/src/compiler.rs +++ b/dust-lang/src/compiler.rs @@ -112,11 +112,16 @@ impl<'src> Compiler<'src> { value_parameters, return_type: Box::new(self.return_type.unwrap_or(Type::None)), }; + let instructions = self + .instructions + .into_iter() + .map(|(i, _, s)| (i, s)) + .collect(); Chunk::with_data( self.self_name, r#type, - self.instructions, + instructions, self.constants, self.locals, ) diff --git a/dust-lang/src/disassembler.rs b/dust-lang/src/disassembler.rs index 664bf86..02105a3 100644 --- a/dust-lang/src/disassembler.rs +++ b/dust-lang/src/disassembler.rs @@ -47,8 +47,8 @@ use crate::{value::ConcreteValue, Chunk, Local}; const INSTRUCTION_HEADER: [&str; 4] = [ "Instructions", "------------", - " i POSITION OPERATION TYPE INFO ", - "--- ---------- ------------- -------------- --------------------------------", + " i POSITION OPERATION INFO ", + "--- ---------- ------------- --------------------------------", ]; const CONSTANT_HEADER: [&str; 4] = [ @@ -61,8 +61,8 @@ const CONSTANT_HEADER: [&str; 4] = [ const LOCAL_HEADER: [&str; 4] = [ "Locals", "------", - " i SCOPE MUTABLE TYPE IDENTIFIER ", - "--- ------- ------- -------------------------------- ----------------", + " i SCOPE MUTABLE TYPE IDENTIFIER ", + "--- ------- ------- ---------------- ----------------", ]; /// Builder that constructs a human-readable representation of a chunk. @@ -89,11 +89,11 @@ impl<'a> Disassembler<'a> { } } - /// The default width of the disassembly output, including borders. + /// The default width of the disassembly output, including borders and padding. pub fn default_width() -> usize { let longest_line = INSTRUCTION_HEADER[3]; - (longest_line.chars().count() + 2).max(80) + longest_line.chars().count() + 4 // Allow for one border and one padding space on each side. } pub fn source(mut self, source: &'a str) -> Self { @@ -209,22 +209,12 @@ impl<'a> Disassembler<'a> { self.push_header(line); } - for (index, (instruction, r#type, position)) in self.chunk.instructions().iter().enumerate() - { + for (index, (instruction, position)) in self.chunk.instructions().iter().enumerate() { let position = position.to_string(); let operation = instruction.operation().to_string(); - let type_display = { - let mut type_string = r#type.to_string(); - - if type_string.len() > 14 { - type_string = format!("{type_string:.11}..."); - } - - type_string - }; let info = instruction.disassembly_info(); let instruction_display = - format!("{index:^3} {position:^10} {operation:13} {type_display:^14} {info:^32}"); + format!("{index:^3} {position:^10} {operation:13} {info:^32}"); self.push_details(&instruction_display); } @@ -254,7 +244,7 @@ impl<'a> Disassembler<'a> { let type_display = r#type.to_string(); let scope = scope.to_string(); let local_display = format!( - "{index:^3} {scope:^7} {is_mutable:^7} {type_display:^32} {identifier_display:^16}" + "{index:^3} {scope:^7} {is_mutable:^7} {type_display:^16} {identifier_display:^16}" ); self.push_details(&local_display); diff --git a/dust-lang/src/vm.rs b/dust-lang/src/vm.rs index 934f1b6..e713479 100644 --- a/dust-lang/src/vm.rs +++ b/dust-lang/src/vm.rs @@ -715,13 +715,12 @@ impl<'a> Vm<'a> { } fn read(&mut self) -> Result { - let (instruction, _type, position) = - self.chunk.instructions().get(self.ip).ok_or_else(|| { - VmError::InstructionIndexOutOfBounds { - index: self.ip, - position: self.current_position, - } - })?; + let (instruction, position) = self.chunk.instructions().get(self.ip).ok_or_else(|| { + VmError::InstructionIndexOutOfBounds { + index: self.ip, + position: self.current_position, + } + })?; self.ip += 1; self.current_position = *position; diff --git a/dust-lang/tests/basic.rs b/dust-lang/tests/basic.rs index f6be57e..c6378bb 100644 --- a/dust-lang/tests/basic.rs +++ b/dust-lang/tests/basic.rs @@ -16,10 +16,9 @@ fn constant() { vec![ ( Instruction::load_constant(Destination::Register(0), 0, false), - Type::Integer, Span(0, 2) ), - (Instruction::r#return(true), Type::None, Span(2, 2)) + (Instruction::r#return(true), Span(2, 2)) ], vec![ConcreteValue::Integer(42)], vec![] @@ -42,7 +41,7 @@ fn empty() { value_parameters: None, return_type: Box::new(Type::None) }, - vec![(Instruction::r#return(false), Type::None, Span(0, 0))], + vec![(Instruction::r#return(false), Span(0, 0))], vec![], vec![] )) @@ -70,7 +69,6 @@ fn parentheses_precedence() { Argument::Constant(0), Argument::Constant(1) ), - Type::Integer, Span(3, 4) ), ( @@ -79,10 +77,9 @@ fn parentheses_precedence() { Argument::Register(0), Argument::Constant(2) ), - Type::Integer, Span(8, 9) ), - (Instruction::r#return(true), Type::None, Span(11, 11)), + (Instruction::r#return(true), Span(11, 11)), ], vec![ ConcreteValue::Integer(1), diff --git a/dust-lang/tests/comparison.rs b/dust-lang/tests/comparison.rs index 1b19be9..095a184 100644 --- a/dust-lang/tests/comparison.rs +++ b/dust-lang/tests/comparison.rs @@ -16,21 +16,18 @@ fn equal() { vec![ ( Instruction::equal(true, Argument::Constant(0), Argument::Constant(1)), - Type::None, Span(2, 4) ), - (Instruction::jump(1, true), Type::None, Span(2, 4)), + (Instruction::jump(1, true), Span(2, 4)), ( Instruction::load_boolean(Destination::Register(0), true, true), - Type::Boolean, Span(2, 4) ), ( Instruction::load_boolean(Destination::Register(0), false, false), - Type::Boolean, Span(2, 4) ), - (Instruction::r#return(true), Type::None, Span(6, 6)), + (Instruction::r#return(true), Span(6, 6)), ], vec![ConcreteValue::Integer(1), ConcreteValue::Integer(2)], vec![] @@ -56,21 +53,18 @@ fn greater() { vec![ ( Instruction::less_equal(false, Argument::Constant(0), Argument::Constant(1)), - Type::None, Span(2, 3) ), - (Instruction::jump(1, true), Type::None, Span(2, 3)), + (Instruction::jump(1, true), Span(2, 3)), ( Instruction::load_boolean(Destination::Register(0), true, true), - Type::Boolean, Span(2, 3) ), ( Instruction::load_boolean(Destination::Register(0), false, false), - Type::Boolean, Span(2, 3) ), - (Instruction::r#return(true), Type::None, Span(5, 5)), + (Instruction::r#return(true), Span(5, 5)), ], vec![ConcreteValue::Integer(1), ConcreteValue::Integer(2)], vec![] @@ -96,21 +90,18 @@ fn greater_than_or_equal() { vec![ ( Instruction::less(false, Argument::Constant(0), Argument::Constant(1)), - Type::None, Span(2, 4) ), - (Instruction::jump(1, true), Type::None, Span(2, 4)), + (Instruction::jump(1, true), Span(2, 4)), ( Instruction::load_boolean(Destination::Register(0), true, true), - Type::Boolean, Span(2, 4) ), ( Instruction::load_boolean(Destination::Register(0), false, false), - Type::Boolean, Span(2, 4) ), - (Instruction::r#return(true), Type::None, Span(6, 6)), + (Instruction::r#return(true), Span(6, 6)), ], vec![ConcreteValue::Integer(1), ConcreteValue::Integer(2)], vec![] @@ -136,21 +127,18 @@ fn less_than() { vec![ ( Instruction::less(true, Argument::Constant(0), Argument::Constant(1)), - Type::None, Span(2, 3) ), - (Instruction::jump(1, true), Type::None, Span(2, 3)), + (Instruction::jump(1, true), Span(2, 3)), ( Instruction::load_boolean(Destination::Register(0), true, true), - Type::Boolean, Span(2, 3) ), ( Instruction::load_boolean(Destination::Register(0), false, false), - Type::Boolean, Span(2, 3) ), - (Instruction::r#return(true), Type::None, Span(5, 5)), + (Instruction::r#return(true), Span(5, 5)), ], vec![ConcreteValue::Integer(1), ConcreteValue::Integer(2)], vec![] @@ -176,21 +164,18 @@ fn less_than_or_equal() { vec![ ( Instruction::less_equal(true, Argument::Constant(0), Argument::Constant(1)), - Type::None, Span(2, 4) ), - (Instruction::jump(1, true), Type::None, Span(2, 4)), + (Instruction::jump(1, true), Span(2, 4)), ( Instruction::load_boolean(Destination::Register(0), true, true), - Type::Boolean, Span(2, 4) ), ( Instruction::load_boolean(Destination::Register(0), false, false), - Type::Boolean, Span(2, 4) ), - (Instruction::r#return(true), Type::None, Span(6, 6)), + (Instruction::r#return(true), Span(6, 6)), ], vec![ConcreteValue::Integer(1), ConcreteValue::Integer(2)], vec![] @@ -216,21 +201,18 @@ fn not_equal() { vec![ ( Instruction::equal(false, Argument::Constant(0), Argument::Constant(1)), - Type::None, Span(2, 4) ), - (Instruction::jump(1, true), Type::None, Span(2, 4)), + (Instruction::jump(1, true), Span(2, 4)), ( Instruction::load_boolean(Destination::Register(0), true, true), - Type::Boolean, Span(2, 4) ), ( Instruction::load_boolean(Destination::Register(0), false, false), - Type::Boolean, Span(2, 4) ), - (Instruction::r#return(true), Type::None, Span(6, 6)), + (Instruction::r#return(true), Span(6, 6)), ], vec![ConcreteValue::Integer(1), ConcreteValue::Integer(2)], vec![] diff --git a/dust-lang/tests/functions.rs b/dust-lang/tests/functions.rs index 6eab230..de353d2 100644 --- a/dust-lang/tests/functions.rs +++ b/dust-lang/tests/functions.rs @@ -24,10 +24,9 @@ fn function() { Argument::Local(0), Argument::Local(1) ), - Type::Integer, Span(30, 31) ), - (Instruction::r#return(true), Type::None, Span(35, 35)), + (Instruction::r#return(true), Span(35, 35)), ], vec![ConcreteValue::string("a"), ConcreteValue::string("b"),], vec![ @@ -54,29 +53,21 @@ fn function_call() { vec![ ( Instruction::load_constant(Destination::Register(0), 0, false), - Type::Function(FunctionType { - type_parameters: None, - value_parameters: Some(vec![(0, Type::Integer), (1, Type::Integer)]), - return_type: Box::new(Type::Integer), - }), Span(0, 36) ), ( Instruction::load_constant(Destination::Register(1), 1, false), - Type::Integer, Span(36, 37) ), ( Instruction::load_constant(Destination::Register(2), 2, false), - Type::Integer, Span(39, 40) ), ( Instruction::call(Destination::Register(3), Argument::Constant(0), 2), - Type::Integer, Span(35, 41) ), - (Instruction::r#return(true), Type::None, Span(41, 41)), + (Instruction::r#return(true), Span(41, 41)), ], vec![ ConcreteValue::Function(Chunk::with_data( @@ -93,10 +84,9 @@ fn function_call() { Argument::Local(0), Argument::Local(1) ), - Type::Integer, Span(30, 31) ), - (Instruction::r#return(true), Type::None, Span(35, 36)), + (Instruction::r#return(true), Span(35, 36)), ], vec![ConcreteValue::string("a"), ConcreteValue::string("b"),], vec![ @@ -130,19 +120,10 @@ fn function_declaration() { vec![ ( Instruction::load_constant(Destination::Register(0), 0, false), - Type::Function(FunctionType { - type_parameters: None, - value_parameters: Some(vec![(0, Type::Integer), (1, Type::Integer)]), - return_type: Box::new(Type::Integer), - }), Span(0, 40) ), - ( - Instruction::define_local(0, 0, false), - Type::None, - Span(3, 6) - ), - (Instruction::r#return(false), Type::None, Span(40, 40)) + (Instruction::define_local(0, 0, false), Span(3, 6)), + (Instruction::r#return(false), Span(40, 40)) ], vec![ ConcreteValue::Function(Chunk::with_data( @@ -159,10 +140,9 @@ fn function_declaration() { Argument::Local(0), Argument::Local(1) ), - Type::Integer, Span(35, 36) ), - (Instruction::r#return(true), Type::None, Span(40, 40)), + (Instruction::r#return(true), Span(40, 40)), ], vec![ConcreteValue::string("a"), ConcreteValue::string("b")], vec![ diff --git a/dust-lang/tests/lists.rs b/dust-lang/tests/lists.rs index c8fcd5e..aa6eaac 100644 --- a/dust-lang/tests/lists.rs +++ b/dust-lang/tests/lists.rs @@ -16,10 +16,9 @@ fn empty_list() { vec![ ( Instruction::load_list(Destination::Register(0), 0), - Type::List(Box::new(Type::Any)), Span(0, 2) ), - (Instruction::r#return(true), Type::None, Span(2, 2)), + (Instruction::r#return(true), Span(2, 2)), ], vec![], vec![] @@ -45,25 +44,21 @@ fn list() { vec![ ( Instruction::load_constant(Destination::Register(0), 0, false), - Type::Integer, Span(1, 2) ), ( Instruction::load_constant(Destination::Register(1), 1, false), - Type::Integer, Span(4, 5) ), ( Instruction::load_constant(Destination::Register(2), 2, false), - Type::Integer, Span(7, 8) ), ( Instruction::load_list(Destination::Register(3), 0), - Type::List(Box::new(Type::Integer)), Span(0, 9) ), - (Instruction::r#return(true), Type::None, Span(9, 9)), + (Instruction::r#return(true), Span(9, 9)), ], vec![ ConcreteValue::Integer(1), @@ -100,7 +95,6 @@ fn list_with_complex_expression() { vec![ ( Instruction::load_constant(Destination::Register(0), 0, false), - Type::Integer, Span(1, 2) ), ( @@ -109,7 +103,6 @@ fn list_with_complex_expression() { Argument::Constant(1), Argument::Constant(2) ), - Type::Integer, Span(6, 7) ), ( @@ -118,7 +111,6 @@ fn list_with_complex_expression() { Argument::Constant(3), Argument::Constant(4) ), - Type::Integer, Span(14, 15) ), ( @@ -127,16 +119,14 @@ fn list_with_complex_expression() { Argument::Register(1), Argument::Register(2) ), - Type::Integer, Span(10, 11) ), - (Instruction::close(1, 3), Type::None, Span(17, 18)), + (Instruction::close(1, 3), Span(17, 18)), ( Instruction::load_list(Destination::Register(4), 0), - Type::List(Box::new(Type::Integer)), Span(0, 18) ), - (Instruction::r#return(true), Type::None, Span(18, 18)), + (Instruction::r#return(true), Span(18, 18)), ], vec![ ConcreteValue::Integer(1), @@ -174,7 +164,6 @@ fn list_with_simple_expression() { vec![ ( Instruction::load_constant(Destination::Register(0), 0, false), - Type::Integer, Span(1, 2) ), ( @@ -183,20 +172,17 @@ fn list_with_simple_expression() { Argument::Constant(1), Argument::Constant(2) ), - Type::Integer, Span(6, 7) ), ( Instruction::load_constant(Destination::Register(2), 3, false), - Type::Integer, Span(11, 12) ), ( Instruction::load_list(Destination::Register(3), 0), - Type::List(Box::new(Type::Integer)), Span(0, 13) ), - (Instruction::r#return(true), Type::None, Span(13, 13)), + (Instruction::r#return(true), Span(13, 13)), ], vec![ ConcreteValue::Integer(1), diff --git a/dust-lang/tests/logic.rs b/dust-lang/tests/logic.rs deleted file mode 100644 index 5b1784c..0000000 --- a/dust-lang/tests/logic.rs +++ /dev/null @@ -1,160 +0,0 @@ -use dust_lang::*; - -#[test] -fn and() { - let source = "true && false"; - - assert_eq!( - compile(source), - Ok(Chunk::with_data( - None, - FunctionType { - type_parameters: None, - value_parameters: None, - return_type: Box::new(Type::Boolean), - }, - vec![ - ( - Instruction::load_boolean(Destination::Register(0), true, false), - Type::Boolean, - Span(0, 4) - ), - ( - Instruction::test(Argument::Register(0), true), - Type::None, - Span(5, 7) - ), - (Instruction::jump(1, true), Type::None, Span(5, 7)), - ( - Instruction::load_boolean(Destination::Register(1), false, false), - Type::Boolean, - Span(8, 13) - ), - (Instruction::r#return(true), Type::None, Span(13, 13)), - ], - vec![], - vec![] - )) - ); - - assert_eq!(run(source), Ok(Some(ConcreteValue::Boolean(false)))); -} - -#[test] -fn or() { - let source = "true || false"; - - assert_eq!( - compile(source), - Ok(Chunk::with_data( - None, - FunctionType { - type_parameters: None, - value_parameters: None, - return_type: Box::new(Type::Boolean), - }, - vec![ - ( - Instruction::load_boolean(Destination::Register(0), true, false), - Type::Boolean, - Span(0, 4) - ), - ( - Instruction::test(Argument::Register(0), false), - Type::None, - Span(5, 7) - ), - (Instruction::jump(1, true), Type::None, Span(5, 7)), - ( - Instruction::load_boolean(Destination::Register(1), false, false), - Type::Boolean, - Span(8, 13) - ), - (Instruction::r#return(true), Type::None, Span(13, 13)), - ], - vec![], - vec![] - )) - ); - - assert_eq!(run(source), Ok(Some(ConcreteValue::Boolean(true)))); -} - -#[test] -fn and_and_or() { - let source = "let a = true; let b = true; let c = false; a && b || c"; - - assert_eq!( - compile(source), - Ok(Chunk::with_data( - None, - FunctionType { - type_parameters: None, - value_parameters: None, - return_type: Box::new(Type::Boolean), - }, - vec![ - ( - Instruction::load_boolean(Destination::Register(0), true, false), - Type::Boolean, - Span(8, 12) - ), - ( - Instruction::define_local(0, 0, false), - Type::None, - Span(4, 5) - ), - ( - Instruction::load_boolean(Destination::Register(1), true, false), - Type::Boolean, - Span(22, 26) - ), - ( - Instruction::define_local(1, 1, false), - Type::None, - Span(18, 19) - ), - ( - Instruction::load_boolean(Destination::Register(2), false, false), - Type::Boolean, - Span(36, 41) - ), - ( - Instruction::define_local(2, 2, false), - Type::None, - Span(32, 33) - ), - ( - Instruction::test(Argument::Local(0), true), - Type::None, - Span(45, 47) - ), - (Instruction::jump(1, true), Type::None, Span(45, 47)), - ( - Instruction::test(Argument::Local(1), false), - Type::None, - Span(50, 52) - ), - (Instruction::jump(1, true), Type::None, Span(50, 52)), - ( - Instruction::get_local(Destination::Register(3), 2), - Type::Boolean, - Span(53, 54) - ), - (Instruction::r#return(true), Type::None, Span(54, 54)), - ], - vec![ - ConcreteValue::string("a"), - ConcreteValue::string("b"), - ConcreteValue::string("c") - ], - vec![ - Local::new(0, Type::Boolean, false, Scope::default()), - Local::new(1, Type::Boolean, false, Scope::default()), - Local::new(2, Type::Boolean, false, Scope::default()) - ] - )) - ); - - assert_eq!(run(source), Ok(Some(ConcreteValue::Boolean(true)))); -} diff --git a/dust-lang/tests/logic_booleans.rs b/dust-lang/tests/logic_booleans.rs new file mode 100644 index 0000000..ca5b635 --- /dev/null +++ b/dust-lang/tests/logic_booleans.rs @@ -0,0 +1,69 @@ +use dust_lang::*; + +#[test] +fn and() { + let source = "true && false"; + + assert_eq!( + compile(source), + Ok(Chunk::with_data( + None, + FunctionType { + type_parameters: None, + value_parameters: None, + return_type: Box::new(Type::Boolean), + }, + vec![ + ( + Instruction::load_boolean(Destination::Register(0), true, false), + Span(0, 4) + ), + (Instruction::test(Argument::Register(0), true), Span(5, 7)), + (Instruction::jump(1, true), Span(5, 7)), + ( + Instruction::load_boolean(Destination::Register(1), false, false), + Span(8, 13) + ), + (Instruction::r#return(true), Span(13, 13)), + ], + vec![], + vec![] + )) + ); + + assert_eq!(run(source), Ok(Some(ConcreteValue::Boolean(false)))); +} + +#[test] +fn or() { + let source = "true || false"; + + assert_eq!( + compile(source), + Ok(Chunk::with_data( + None, + FunctionType { + type_parameters: None, + value_parameters: None, + return_type: Box::new(Type::Boolean), + }, + vec![ + ( + Instruction::load_boolean(Destination::Register(0), true, false), + Span(0, 4) + ), + (Instruction::test(Argument::Register(0), false), Span(5, 7)), + (Instruction::jump(1, true), Span(5, 7)), + ( + Instruction::load_boolean(Destination::Register(1), false, false), + Span(8, 13) + ), + (Instruction::r#return(true), Span(13, 13)), + ], + vec![], + vec![] + )) + ); + + assert_eq!(run(source), Ok(Some(ConcreteValue::Boolean(true)))); +} diff --git a/dust-lang/tests/logic_variables.rs b/dust-lang/tests/logic_variables.rs new file mode 100644 index 0000000..e2519c8 --- /dev/null +++ b/dust-lang/tests/logic_variables.rs @@ -0,0 +1,378 @@ +use dust_lang::*; + +#[test] +fn true_and_true() { + let source = "let a = true; let b = true; a && b"; + + assert_eq!( + compile(source), + Ok(Chunk::with_data( + None, + FunctionType { + type_parameters: None, + value_parameters: None, + return_type: Box::new(Type::Boolean), + }, + vec![ + ( + Instruction::load_boolean(Destination::Register(0), true, false), + Span(8, 12) + ), + (Instruction::define_local(0, 0, false), Span(4, 5)), + ( + Instruction::load_boolean(Destination::Register(1), true, false), + Span(22, 26) + ), + (Instruction::define_local(1, 1, false), Span(18, 19)), + ( + Instruction::get_local(Destination::Register(2), 0), + Span(28, 29) + ), + (Instruction::test(Argument::Local(0), true), Span(30, 32)), + (Instruction::jump(1, true), Span(30, 32)), + ( + Instruction::get_local(Destination::Register(3), 1), + Span(33, 34) + ), + (Instruction::r#return(true), Span(34, 34)), + ], + vec![ConcreteValue::string("a"), ConcreteValue::string("b")], + vec![ + Local::new(0, Type::Boolean, false, Scope::default()), + Local::new(1, Type::Boolean, false, Scope::default()) + ] + )) + ); + + assert_eq!(run(source), Ok(Some(ConcreteValue::Boolean(true)))); +} + +#[test] +fn false_and_false() { + let source = "let a = false; let b = false; a && b"; + + assert_eq!( + compile(source), + Ok(Chunk::with_data( + None, + FunctionType { + type_parameters: None, + value_parameters: None, + return_type: Box::new(Type::Boolean), + }, + vec![ + ( + Instruction::load_boolean(Destination::Register(0), false, false), + Span(8, 13) + ), + (Instruction::define_local(0, 0, false), Span(4, 5)), + ( + Instruction::load_boolean(Destination::Register(1), false, false), + Span(23, 28) + ), + (Instruction::define_local(1, 1, false), Span(19, 20)), + ( + Instruction::get_local(Destination::Register(2), 0), + Span(30, 31) + ), + (Instruction::test(Argument::Local(0), true), Span(32, 34)), + (Instruction::jump(1, true), Span(32, 34)), + ( + Instruction::get_local(Destination::Register(3), 1), + Span(35, 36) + ), + (Instruction::r#return(true), Span(36, 36)), + ], + vec![ConcreteValue::string("a"), ConcreteValue::string("b")], + vec![ + Local::new(0, Type::Boolean, false, Scope::default()), + Local::new(1, Type::Boolean, false, Scope::default()) + ] + )) + ); + + assert_eq!(run(source), Ok(Some(ConcreteValue::Boolean(false)))); +} + +#[test] +fn true_and_false() { + let source = "let a = true; let b = false; a && b"; + + assert_eq!( + compile(source), + Ok(Chunk::with_data( + None, + FunctionType { + type_parameters: None, + value_parameters: None, + return_type: Box::new(Type::Boolean), + }, + vec![ + ( + Instruction::load_boolean(Destination::Register(0), true, false), + Span(8, 12) + ), + (Instruction::define_local(0, 0, false), Span(4, 5)), + ( + Instruction::load_boolean(Destination::Register(1), false, false), + Span(22, 27) + ), + (Instruction::define_local(1, 1, false), Span(18, 19)), + ( + Instruction::get_local(Destination::Register(2), 0), + Span(29, 30) + ), + (Instruction::test(Argument::Local(0), true), Span(31, 33)), + (Instruction::jump(1, true), Span(31, 33)), + ( + Instruction::get_local(Destination::Register(3), 1), + Span(34, 35) + ), + (Instruction::r#return(true), Span(35, 35)), + ], + vec![ConcreteValue::string("a"), ConcreteValue::string("b")], + vec![ + Local::new(0, Type::Boolean, false, Scope::default()), + Local::new(1, Type::Boolean, false, Scope::default()) + ] + )) + ); + + assert_eq!(run(source), Ok(Some(ConcreteValue::Boolean(false)))); +} + +#[test] +fn false_and_true() { + let source = "let a = false; let b = true; a && b"; + + assert_eq!( + compile(source), + Ok(Chunk::with_data( + None, + FunctionType { + type_parameters: None, + value_parameters: None, + return_type: Box::new(Type::Boolean), + }, + vec![ + ( + Instruction::load_boolean(Destination::Register(0), false, false), + Span(8, 13) + ), + (Instruction::define_local(0, 0, false), Span(4, 5)), + ( + Instruction::load_boolean(Destination::Register(1), true, false), + Span(23, 27) + ), + (Instruction::define_local(1, 1, false), Span(19, 20)), + ( + Instruction::get_local(Destination::Register(2), 0), + Span(29, 30) + ), + (Instruction::test(Argument::Local(0), true), Span(31, 33)), + (Instruction::jump(1, true), Span(31, 33)), + ( + Instruction::get_local(Destination::Register(3), 1), + Span(34, 35) + ), + (Instruction::r#return(true), Span(35, 35)), + ], + vec![ConcreteValue::string("a"), ConcreteValue::string("b")], + vec![ + Local::new(0, Type::Boolean, false, Scope::default()), + Local::new(1, Type::Boolean, false, Scope::default()) + ] + )) + ); + + assert_eq!(run(source), Ok(Some(ConcreteValue::Boolean(false)))); +} + +#[test] +fn true_and_true_and_true() { + let source = "let a = true; let b = true; let c = true; a && b && c"; + + assert_eq!( + compile(source), + Ok(Chunk::with_data( + None, + FunctionType { + type_parameters: None, + value_parameters: None, + return_type: Box::new(Type::Boolean), + }, + vec![ + ( + Instruction::load_boolean(Destination::Register(0), true, false), + Span(8, 12) + ), + (Instruction::define_local(0, 0, false), Span(4, 5)), + ( + Instruction::load_boolean(Destination::Register(1), true, false), + Span(22, 26) + ), + (Instruction::define_local(1, 1, false), Span(18, 19)), + ( + Instruction::load_boolean(Destination::Register(2), true, false), + Span(36, 40) + ), + (Instruction::define_local(2, 2, false), Span(32, 33)), + ( + Instruction::get_local(Destination::Register(3), 0), + Span(42, 43) + ), + (Instruction::test(Argument::Local(0), true), Span(44, 46)), + (Instruction::jump(1, true), Span(44, 46)), + ( + Instruction::get_local(Destination::Register(4), 1), + Span(47, 48) + ), + (Instruction::test(Argument::Local(1), true), Span(49, 51)), + (Instruction::jump(1, true), Span(49, 51)), + ( + Instruction::get_local(Destination::Register(5), 2), + Span(52, 53) + ), + (Instruction::r#return(true), Span(53, 53)), + ], + vec![ + ConcreteValue::string("a"), + ConcreteValue::string("b"), + ConcreteValue::string("c") + ], + vec![ + Local::new(0, Type::Boolean, false, Scope::default()), + Local::new(1, Type::Boolean, false, Scope::default()), + Local::new(2, Type::Boolean, false, Scope::default()) + ] + )) + ); + + assert_eq!(run(source), Ok(Some(ConcreteValue::Boolean(true)))); +} + +#[test] +fn false_and_false_and_false() { + let source = "let a = false; let b = false; let c = false; a && b && c"; + + assert_eq!( + compile(source), + Ok(Chunk::with_data( + None, + FunctionType { + type_parameters: None, + value_parameters: None, + return_type: Box::new(Type::Boolean), + }, + vec![ + ( + Instruction::load_boolean(Destination::Register(0), false, false), + Span(8, 13) + ), + (Instruction::define_local(0, 0, false), Span(4, 5)), + ( + Instruction::load_boolean(Destination::Register(1), false, false), + Span(23, 28) + ), + (Instruction::define_local(1, 1, false), Span(19, 20)), + ( + Instruction::load_boolean(Destination::Register(2), false, false), + Span(38, 43) + ), + (Instruction::define_local(2, 2, false), Span(34, 35)), + ( + Instruction::get_local(Destination::Register(3), 0), + Span(45, 46) + ), + (Instruction::test(Argument::Local(0), true), Span(47, 49)), + (Instruction::jump(1, true), Span(47, 49)), + ( + Instruction::get_local(Destination::Register(4), 1), + Span(50, 51) + ), + (Instruction::test(Argument::Local(1), true), Span(52, 54)), + (Instruction::jump(1, true), Span(52, 54)), + ( + Instruction::get_local(Destination::Register(5), 2), + Span(55, 56) + ), + (Instruction::r#return(true), Span(56, 56)), + ], + vec![ + ConcreteValue::string("a"), + ConcreteValue::string("b"), + ConcreteValue::string("c") + ], + vec![ + Local::new(0, Type::Boolean, false, Scope::default()), + Local::new(1, Type::Boolean, false, Scope::default()), + Local::new(2, Type::Boolean, false, Scope::default()) + ] + )) + ); + + assert_eq!(run(source), Ok(Some(ConcreteValue::Boolean(false)))); +} + +#[test] +fn true_and_true_or_false() { + let source = "let a = true; let b = true; let c = false; a && b || c"; + + assert_eq!( + compile(source), + Ok(Chunk::with_data( + None, + FunctionType { + type_parameters: None, + value_parameters: None, + return_type: Box::new(Type::Boolean), + }, + vec![ + ( + Instruction::load_boolean(Destination::Register(0), true, false), + Span(8, 12) + ), + (Instruction::define_local(0, 0, false), Span(4, 5)), + ( + Instruction::load_boolean(Destination::Register(1), true, false), + Span(22, 26) + ), + (Instruction::define_local(1, 1, false), Span(18, 19)), + ( + Instruction::load_boolean(Destination::Register(2), false, false), + Span(36, 41) + ), + (Instruction::define_local(2, 2, false), Span(32, 33)), + ( + Instruction::get_local(Destination::Register(3), 0), + Span(43, 44) + ), + (Instruction::test(Argument::Local(0), true), Span(45, 47)), + (Instruction::jump(1, true), Span(45, 47)), + ( + Instruction::get_local(Destination::Register(4), 1), + Span(48, 49) + ), + (Instruction::test(Argument::Local(1), false), Span(50, 52)), + (Instruction::jump(1, true), Span(50, 52)), + ( + Instruction::get_local(Destination::Register(5), 2), + Span(53, 54) + ), + (Instruction::r#return(true), Span(54, 54)), + ], + vec![ + ConcreteValue::string("a"), + ConcreteValue::string("b"), + ConcreteValue::string("c") + ], + vec![ + Local::new(0, Type::Boolean, false, Scope::default()), + Local::new(1, Type::Boolean, false, Scope::default()), + Local::new(2, Type::Boolean, false, Scope::default()) + ] + )) + ); + + assert_eq!(run(source), Ok(Some(ConcreteValue::Boolean(true)))); +} diff --git a/dust-lang/tests/loops.rs b/dust-lang/tests/loops.rs index 2ca09aa..c8bbbf4 100644 --- a/dust-lang/tests/loops.rs +++ b/dust-lang/tests/loops.rs @@ -16,36 +16,28 @@ fn r#while() { vec![ ( Instruction::load_constant(Destination::Register(0), 0, false), - Type::Integer, Span(12, 13) ), - ( - Instruction::define_local(0, 0, true), - Type::None, - Span(8, 9) - ), + (Instruction::define_local(0, 0, true), Span(8, 9)), ( Instruction::less(true, Argument::Local(0), Argument::Constant(2)), - Type::None, Span(23, 24) ), - (Instruction::jump(2, true), Type::None, Span(41, 42)), + (Instruction::jump(2, true), Span(41, 42)), ( Instruction::add( Destination::Local(0), Argument::Local(0), Argument::Constant(3) ), - Type::Integer, Span(35, 36) ), - (Instruction::jump(3, false), Type::None, Span(41, 42)), + (Instruction::jump(3, false), Span(41, 42)), ( Instruction::get_local(Destination::Register(1), 0), - Type::Integer, Span(41, 42) ), - (Instruction::r#return(true), Type::None, Span(42, 42)), + (Instruction::r#return(true), Span(42, 42)), ], vec![ ConcreteValue::Integer(0), diff --git a/dust-lang/tests/math.rs b/dust-lang/tests/math.rs index f17fe8c..34b8256 100644 --- a/dust-lang/tests/math.rs +++ b/dust-lang/tests/math.rs @@ -20,10 +20,9 @@ fn add() { Argument::Constant(0), Argument::Constant(1) ), - Type::Integer, Span(2, 3) ), - (Instruction::r#return(true), Type::None, Span(5, 5)) + (Instruction::r#return(true), Span(5, 5)) ], vec![ConcreteValue::Integer(1), ConcreteValue::Integer(2)], vec![] @@ -49,29 +48,22 @@ fn add_assign() { vec![ ( Instruction::load_constant(Destination::Register(0), 0, false), - Type::Integer, Span(12, 13) ), - ( - Instruction::define_local(0, 0, true), - Type::None, - Span(8, 9) - ), + (Instruction::define_local(0, 0, true), Span(8, 9)), ( Instruction::add( Destination::Local(0), Argument::Local(0), Argument::Constant(2) ), - Type::None, Span(17, 19) ), ( Instruction::get_local(Destination::Register(1), 0), - Type::Integer, Span(23, 24) ), - (Instruction::r#return(true), Type::None, Span(24, 24)) + (Instruction::r#return(true), Span(24, 24)) ], vec![ ConcreteValue::Integer(1), @@ -137,10 +129,9 @@ fn divide() { Argument::Constant(0), Argument::Constant(0) ), - Type::Integer, Span(2, 3) ), - (Instruction::r#return(true), Type::None, Span(5, 5)) + (Instruction::r#return(true), Span(5, 5)) ], vec![ConcreteValue::Integer(2)], vec![] @@ -166,29 +157,22 @@ fn divide_assign() { vec![ ( Instruction::load_constant(Destination::Register(0), 0, false), - Type::Integer, Span(12, 13) ), - ( - Instruction::define_local(0, 0, true), - Type::None, - Span(8, 9) - ), + (Instruction::define_local(0, 0, true), Span(8, 9)), ( Instruction::divide( Destination::Local(0), Argument::Local(0), Argument::Constant(0) ), - Type::None, Span(17, 19) ), ( Instruction::get_local(Destination::Register(1), 0), - Type::Integer, Span(23, 24) ), - (Instruction::r#return(true), Type::None, Span(24, 24)) + (Instruction::r#return(true), Span(24, 24)) ], vec![ConcreteValue::Integer(2), ConcreteValue::string("a")], vec![Local::new(1, Type::Integer, true, Scope::default())] @@ -234,7 +218,6 @@ fn math_operator_precedence() { Argument::Constant(0), Argument::Constant(1) ), - Type::Integer, Span(2, 3) ), ( @@ -243,7 +226,6 @@ fn math_operator_precedence() { Argument::Constant(2), Argument::Constant(3) ), - Type::Integer, Span(10, 11) ), ( @@ -252,7 +234,6 @@ fn math_operator_precedence() { Argument::Register(1), Argument::Constant(4) ), - Type::Integer, Span(14, 15) ), ( @@ -261,10 +242,9 @@ fn math_operator_precedence() { Argument::Register(0), Argument::Register(2) ), - Type::Integer, Span(6, 7) ), - (Instruction::r#return(true), Type::None, Span(17, 17)), + (Instruction::r#return(true), Span(17, 17)), ], vec![ ConcreteValue::Integer(1), @@ -300,10 +280,9 @@ fn multiply() { Argument::Constant(0), Argument::Constant(1) ), - Type::Integer, Span(2, 3) ), - (Instruction::r#return(true), Type::None, Span(5, 5)), + (Instruction::r#return(true), Span(5, 5)), ], vec![ConcreteValue::Integer(1), ConcreteValue::Integer(2)], vec![] @@ -329,29 +308,22 @@ fn multiply_assign() { vec![ ( Instruction::load_constant(Destination::Register(0), 0, false), - Type::Integer, Span(12, 13) ), - ( - Instruction::define_local(0, 0, true), - Type::None, - Span(8, 9) - ), + (Instruction::define_local(0, 0, true), Span(8, 9)), ( Instruction::multiply( Destination::Local(0), Argument::Local(0), Argument::Constant(2) ), - Type::None, Span(17, 19) ), ( Instruction::get_local(Destination::Register(1), 0), - Type::Integer, Span(22, 23) ), - (Instruction::r#return(true), Type::None, Span(23, 23)) + (Instruction::r#return(true), Span(23, 23)) ], vec![ ConcreteValue::Integer(2), @@ -401,10 +373,9 @@ fn subtract() { Argument::Constant(0), Argument::Constant(1) ), - Type::Integer, Span(2, 3) ), - (Instruction::r#return(true), Type::None, Span(5, 5)), + (Instruction::r#return(true), Span(5, 5)), ], vec![ConcreteValue::Integer(1), ConcreteValue::Integer(2)], vec![] @@ -430,29 +401,22 @@ fn subtract_assign() { vec![ ( Instruction::load_constant(Destination::Register(0), 0, false), - Type::Integer, Span(12, 14) ), - ( - Instruction::define_local(0, 0, true), - Type::None, - Span(8, 9) - ), + (Instruction::define_local(0, 0, true), Span(8, 9)), ( Instruction::subtract( Destination::Local(0), Argument::Local(0), Argument::Constant(2) ), - Type::None, Span(18, 20) ), ( Instruction::get_local(Destination::Register(1), 0), - Type::Integer, Span(24, 25) ), - (Instruction::r#return(true), Type::None, Span(25, 25)), + (Instruction::r#return(true), Span(25, 25)), ], vec![ ConcreteValue::Integer(42), diff --git a/dust-lang/tests/native_functions.rs b/dust-lang/tests/native_functions.rs index 4b83b21..abdc8b5 100644 --- a/dust-lang/tests/native_functions.rs +++ b/dust-lang/tests/native_functions.rs @@ -16,20 +16,17 @@ fn panic() { vec![ ( Instruction::load_constant(Destination::Register(0), 0, false), - Type::String, Span(6, 22) ), ( Instruction::load_constant(Destination::Register(1), 1, false), - Type::Integer, Span(24, 26) ), ( Instruction::call_native(Destination::Register(2), NativeFunction::Panic, 2), - Type::None, Span(0, 27) ), - (Instruction::r#return(false), Type::None, Span(27, 27)) + (Instruction::r#return(false), Span(27, 27)) ], vec![ ConcreteValue::string("Goodbye world!"), @@ -67,15 +64,13 @@ fn to_string() { vec![ ( Instruction::load_constant(Destination::Register(0), 0, false), - Type::Integer, Span(10, 12) ), ( Instruction::call_native(Destination::Register(1), NativeFunction::ToString, 1), - Type::String, Span(0, 13) ), - (Instruction::r#return(true), Type::None, Span(13, 13)) + (Instruction::r#return(true), Span(13, 13)) ], vec![ConcreteValue::Integer(42)], vec![] diff --git a/dust-lang/tests/scopes.rs b/dust-lang/tests/scopes.rs index c34d33b..4bdc46b 100644 --- a/dust-lang/tests/scopes.rs +++ b/dust-lang/tests/scopes.rs @@ -38,55 +38,30 @@ fn block_scope() { vec![ ( Instruction::load_constant(Destination::Register(0), 0, false), - Type::Integer, Span(17, 18) ), - ( - Instruction::define_local(0, 0, false), - Type::None, - Span(13, 14) - ), + (Instruction::define_local(0, 0, false), Span(13, 14)), ( Instruction::load_constant(Destination::Register(1), 2, false), - Type::Integer, Span(50, 52) ), - ( - Instruction::define_local(1, 1, false), - Type::None, - Span(46, 47) - ), + (Instruction::define_local(1, 1, false), Span(46, 47)), ( Instruction::load_constant(Destination::Register(2), 4, false), - Type::Integer, Span(92, 93) ), - ( - Instruction::define_local(2, 2, false), - Type::None, - Span(88, 89) - ), + (Instruction::define_local(2, 2, false), Span(88, 89)), ( Instruction::load_constant(Destination::Register(3), 6, false), - Type::Integer, Span(129, 130) ), - ( - Instruction::define_local(3, 3, false), - Type::None, - Span(125, 126) - ), + (Instruction::define_local(3, 3, false), Span(125, 126)), ( Instruction::load_constant(Destination::Register(4), 4, false), - Type::Integer, Span(158, 159) ), - ( - Instruction::define_local(4, 4, false), - Type::None, - Span(154, 155) - ), - (Instruction::r#return(false), Type::None, Span(165, 165)) + (Instruction::define_local(4, 4, false), Span(154, 155)), + (Instruction::r#return(false), Span(165, 165)) ], vec![ ConcreteValue::Integer(0), @@ -146,95 +121,50 @@ fn multiple_block_scopes() { vec![ ( Instruction::load_constant(Destination::Register(0), 0, false), - Type::Integer, Span(17, 18) ), - ( - Instruction::define_local(0, 0, false), - Type::None, - Span(13, 14) - ), + (Instruction::define_local(0, 0, false), Span(13, 14)), ( Instruction::load_constant(Destination::Register(1), 2, false), - Type::Integer, Span(50, 52) ), - ( - Instruction::define_local(1, 1, false), - Type::None, - Span(46, 47) - ), + (Instruction::define_local(1, 1, false), Span(46, 47)), ( Instruction::load_constant(Destination::Register(2), 4, false), - Type::Integer, Span(92, 93) ), - ( - Instruction::define_local(2, 2, false), - Type::None, - Span(88, 89) - ), + (Instruction::define_local(2, 2, false), Span(88, 89)), ( Instruction::get_local(Destination::Register(3), 1), - Type::Integer, Span(129, 130) ), - ( - Instruction::define_local(3, 3, false), - Type::None, - Span(125, 126) - ), + (Instruction::define_local(3, 3, false), Span(125, 126)), ( Instruction::get_local(Destination::Register(4), 0), - Type::Integer, Span(158, 159) ), - ( - Instruction::define_local(4, 4, false), - Type::None, - Span(154, 155) - ), + (Instruction::define_local(4, 4, false), Span(154, 155)), ( Instruction::load_constant(Destination::Register(5), 2, false), - Type::Integer, Span(191, 193) ), - ( - Instruction::define_local(5, 5, false), - Type::None, - Span(187, 188) - ), + (Instruction::define_local(5, 5, false), Span(187, 188)), ( Instruction::load_constant(Destination::Register(6), 4, false), - Type::Integer, Span(233, 234) ), - ( - Instruction::define_local(6, 6, false), - Type::None, - Span(229, 230) - ), + (Instruction::define_local(6, 6, false), Span(229, 230)), ( Instruction::get_local(Destination::Register(7), 5), - Type::Integer, Span(270, 271) ), - ( - Instruction::define_local(7, 7, false), - Type::None, - Span(266, 267) - ), + (Instruction::define_local(7, 7, false), Span(266, 267)), ( Instruction::get_local(Destination::Register(8), 0), - Type::Integer, Span(299, 300) ), - ( - Instruction::define_local(8, 8, false), - Type::None, - Span(295, 296) - ), - (Instruction::r#return(false), Type::None, Span(306, 306)) + (Instruction::define_local(8, 8, false), Span(295, 296)), + (Instruction::r#return(false), Span(306, 306)) ], vec![ ConcreteValue::Integer(0), diff --git a/dust-lang/tests/unary_operations.rs b/dust-lang/tests/unary_operations.rs index 8e289c5..f60f7d0 100644 --- a/dust-lang/tests/unary_operations.rs +++ b/dust-lang/tests/unary_operations.rs @@ -16,10 +16,9 @@ fn negate() { vec![ ( Instruction::negate(Destination::Register(0), Argument::Constant(0)), - Type::Integer, Span(0, 1) ), - (Instruction::r#return(true), Type::None, Span(5, 5)), + (Instruction::r#return(true), Span(5, 5)), ], vec![ConcreteValue::Integer(42)], vec![] @@ -45,15 +44,13 @@ fn not() { vec![ ( Instruction::load_boolean(Destination::Register(0), true, false), - Type::Boolean, Span(1, 5) ), ( Instruction::not(Destination::Register(1), Argument::Register(0)), - Type::Boolean, Span(0, 1) ), - (Instruction::r#return(true), Type::None, Span(5, 5)), + (Instruction::r#return(true), Span(5, 5)), ], vec![], vec![] diff --git a/dust-lang/tests/variables.rs b/dust-lang/tests/variables.rs index bdd7254..ab83450 100644 --- a/dust-lang/tests/variables.rs +++ b/dust-lang/tests/variables.rs @@ -16,15 +16,10 @@ fn define_local() { vec![ ( Instruction::load_constant(Destination::Register(0), 0, false), - Type::Integer, Span(8, 10) ), - ( - Instruction::define_local(0, 0, false), - Type::None, - Span(4, 5) - ), - (Instruction::r#return(false), Type::None, Span(11, 11)) + (Instruction::define_local(0, 0, false), Span(4, 5)), + (Instruction::r#return(false), Span(11, 11)) ], vec![ConcreteValue::Integer(42), ConcreteValue::string("x")], vec![Local::new(1, Type::Integer, false, Scope::default())] @@ -67,26 +62,19 @@ fn set_local() { vec![ ( Instruction::load_constant(Destination::Register(0), 0, false), - Type::Integer, Span(12, 14) ), - ( - Instruction::define_local(0, 0, true), - Type::None, - Span(8, 9) - ), + (Instruction::define_local(0, 0, true), Span(8, 9)), ( Instruction::load_constant(Destination::Register(1), 2, false), - Type::Integer, Span(20, 22) ), - (Instruction::set_local(1, 0), Type::None, Span(16, 17)), + (Instruction::set_local(1, 0), Span(16, 17)), ( Instruction::get_local(Destination::Register(2), 0), - Type::Integer, Span(24, 25) ), - (Instruction::r#return(true), Type::None, Span(25, 25)), + (Instruction::r#return(true), Span(25, 25)), ], vec![ ConcreteValue::Integer(41),