use dust_lang::*; #[test] fn function() { let source = "fn(a: int, b: int) -> int { a + b }"; assert_eq!( run(source), Ok(Some(ConcreteValue::function(Chunk::with_data( None, FunctionType { type_parameters: None, value_parameters: None, return_type: Box::new(Type::Function(FunctionType { type_parameters: None, value_parameters: Some(vec![(0, Type::Integer), (1, Type::Integer)]), return_type: Box::new(Type::Integer), })) }, vec![ ( Instruction::add( Destination::Register(2), Argument::Local(0), Argument::Local(1) ), Span(30, 31) ), (Instruction::r#return(true), Span(34, 35)), ], vec![ConcreteValue::string("a"), ConcreteValue::string("b"),], vec![ Local::new(0, Type::Integer, false, Scope::default()), Local::new(1, Type::Integer, false, Scope::default()) ] )))) ); } #[test] fn function_call() { let source = "fn(a: int, b: int) -> int { a + b }(1, 2)"; assert_eq!( compile(source), Ok(Chunk::with_data( None, FunctionType { type_parameters: None, value_parameters: None, return_type: Box::new(Type::Integer) }, vec![ ( Instruction::load_constant(Destination::Register(0), 0, false), Span(0, 35) ), ( Instruction::load_constant(Destination::Register(1), 1, false), Span(36, 37) ), ( Instruction::load_constant(Destination::Register(2), 2, false), Span(39, 40) ), ( Instruction::call(Destination::Register(3), Argument::Constant(0), 2), Span(35, 41) ), (Instruction::r#return(true), Span(41, 41)), ], vec![ ConcreteValue::function(Chunk::with_data( None, FunctionType { type_parameters: None, value_parameters: Some(vec![(0, Type::Integer), (1, Type::Integer)]), return_type: Box::new(Type::Integer) }, vec![ ( Instruction::add( Destination::Register(2), Argument::Local(0), Argument::Local(1) ), Span(30, 31) ), (Instruction::r#return(true), Span(34, 35)), ], vec![ConcreteValue::string("a"), ConcreteValue::string("b"),], vec![ Local::new(0, Type::Integer, false, Scope::default()), Local::new(1, Type::Integer, false, Scope::default()) ] )), ConcreteValue::Integer(1), ConcreteValue::Integer(2) ], vec![] )), ); assert_eq!(run(source), Ok(Some(ConcreteValue::Integer(3)))); } #[test] fn function_declaration() { let source = "fn add (a: int, b: int) -> int { a + b }"; assert_eq!( compile(source), Ok(Chunk::with_data( None, FunctionType { type_parameters: None, value_parameters: None, return_type: Box::new(Type::None) }, vec![ ( Instruction::load_constant(Destination::Register(0), 0, false), Span(0, 40) ), (Instruction::define_local(0, 0, false), Span(3, 6)), (Instruction::r#return(false), Span(40, 40)) ], vec![ ConcreteValue::function(Chunk::with_data( Some("add".to_string()), FunctionType { type_parameters: None, value_parameters: Some(vec![(0, Type::Integer), (1, Type::Integer)]), return_type: Box::new(Type::Integer) }, vec![ ( Instruction::add( Destination::Register(2), Argument::Local(0), Argument::Local(1) ), Span(35, 36) ), (Instruction::r#return(true), Span(39, 40)), ], vec![ConcreteValue::string("a"), ConcreteValue::string("b")], vec![ Local::new(0, Type::Integer, false, Scope::default()), Local::new(1, Type::Integer, false, Scope::default()) ] )), ConcreteValue::string("add"), ], vec![Local::new( 1, Type::Function(FunctionType { type_parameters: None, value_parameters: Some(vec![(0, Type::Integer), (1, Type::Integer)]), return_type: Box::new(Type::Integer), }), false, Scope::default(), ),], )), ); assert_eq!(run(source), Ok(None)); }