diff --git a/dust-lang/src/parser.rs b/dust-lang/src/parser.rs index 6bf7aab..7aa2f09 100644 --- a/dust-lang/src/parser.rs +++ b/dust-lang/src/parser.rs @@ -1401,7 +1401,7 @@ impl<'src> Parser<'src> { let register = value_parameters .as_ref() - .map(|values| values.len() as u8 - 1) + .map(|values| values.len() as u8) .unwrap_or(0); let (_, identifier_index) = function_parser.declare_local( parameter, @@ -1449,7 +1449,7 @@ impl<'src> Parser<'src> { value_parameters, return_type, }; - let function = Value::function(function_parser.chunk, function_type.clone()); + let function = Value::function(function_parser.finish(), function_type.clone()); let function_end = self.current_position.1; self.lexer.skip_to(function_end); diff --git a/dust-lang/tests/control_flow.rs b/dust-lang/tests/control_flow.rs index 130bd69..c4769f0 100644 --- a/dust-lang/tests/control_flow.rs +++ b/dust-lang/tests/control_flow.rs @@ -22,8 +22,8 @@ fn equality_assignment_long() { (Instruction::get_local(1, 0), Span(43, 44)), (Instruction::r#return(true), Span(44, 44)), ], - vec![Value::integer(4)], - vec![Local::new(0, None, false, 0, 0)] + vec![Value::integer(4), Value::string("a")], + vec![Local::new(1, None, false, 0, 0)] )), ); @@ -52,8 +52,8 @@ fn equality_assignment_short() { (Instruction::get_local(1, 0), Span(15, 16)), (Instruction::r#return(true), Span(16, 16)), ], - vec![Value::integer(4)], - vec![Local::new(0, None, false, 0, 0)] + vec![Value::integer(4), Value::string("a")], + vec![Local::new(1, None, false, 0, 0)] )), ); @@ -110,8 +110,9 @@ fn if_else_assigment() { Value::integer(2), Value::integer(3), Value::integer(42), + Value::string("a") ], - vec![Local::new(0, None, false, 0, 0)] + vec![Local::new(5, None, false, 0, 0)] )), ); diff --git a/dust-lang/tests/expressions.rs b/dust-lang/tests/expressions.rs index 4609c98..fda1e82 100644 --- a/dust-lang/tests/expressions.rs +++ b/dust-lang/tests/expressions.rs @@ -36,12 +36,12 @@ fn add_assign() { vec![ (Instruction::load_constant(0, 0, false), Span(12, 13)), (Instruction::define_local(0, 0, true), Span(8, 9)), - (*Instruction::add(0, 0, 1).set_c_is_constant(), Span(17, 19)), + (*Instruction::add(0, 0, 2).set_c_is_constant(), Span(17, 19)), (Instruction::get_local(1, 0), Span(23, 24)), (Instruction::r#return(true), Span(24, 24)) ], - vec![Value::integer(1), Value::integer(2)], - vec![Local::new(0, None, true, 0, 0)] + vec![Value::integer(1), Value::string("a"), Value::integer(2)], + vec![Local::new(1, None, true, 0, 0)] )) ); @@ -81,8 +81,8 @@ fn define_local() { (Instruction::define_local(0, 0, false), Span(4, 5)), (Instruction::r#return(false), Span(11, 11)) ], - vec![Value::integer(42)], - vec![Local::new(0, None, false, 0, 0)] + vec![Value::integer(42), Value::string("x")], + vec![Local::new(1, None, false, 0, 0)] )), ); @@ -132,8 +132,8 @@ fn divide_assign() { (Instruction::get_local(1, 0), Span(23, 24)), (Instruction::r#return(true), Span(24, 24)) ], - vec![Value::integer(2)], - vec![Local::new(0, None, true, 0, 0)] + vec![Value::integer(2), Value::string("a")], + vec![Local::new(1, None, true, 0, 0)] )) ); @@ -352,14 +352,14 @@ fn multiply_assign() { (Instruction::load_constant(0, 0, false), Span(12, 13)), (Instruction::define_local(0, 0, true), Span(8, 9)), ( - *Instruction::multiply(0, 0, 1).set_c_is_constant(), + *Instruction::multiply(0, 0, 2).set_c_is_constant(), Span(17, 19) ), (Instruction::get_local(1, 0), Span(22, 23)), (Instruction::r#return(true), Span(23, 23)) ], - vec![Value::integer(2), Value::integer(3)], - vec![Local::new(0, None, true, 0, 0),] + vec![Value::integer(2), Value::string("a"), Value::integer(3)], + vec![Local::new(1, None, true, 0, 0),] )) ); @@ -447,13 +447,13 @@ fn set_local() { vec![ (Instruction::load_constant(0, 0, false), Span(12, 14)), (Instruction::define_local(0, 0, true), Span(8, 9)), - (Instruction::load_constant(1, 1, false), Span(20, 22)), + (Instruction::load_constant(1, 2, false), Span(20, 22)), (Instruction::set_local(1, 0), Span(16, 17)), (Instruction::get_local(2, 0), Span(24, 25)), (Instruction::r#return(true), Span(25, 25)), ], - vec![Value::integer(41), Value::integer(42)], - vec![Local::new(0, None, true, 0, 0)] + vec![Value::integer(41), Value::string("x"), Value::integer(42)], + vec![Local::new(1, None, true, 0, 0)] )), ); @@ -497,14 +497,14 @@ fn subtract_assign() { (Instruction::load_constant(0, 0, false), Span(12, 14)), (Instruction::define_local(0, 0, true), Span(8, 9)), ( - *Instruction::subtract(0, 0, 1).set_c_is_constant(), + *Instruction::subtract(0, 0, 2).set_c_is_constant(), Span(18, 20) ), (Instruction::get_local(1, 0), Span(24, 25)), (Instruction::r#return(true), Span(25, 25)), ], - vec![Value::integer(42), Value::integer(2)], - vec![Local::new(0, None, true, 0, 0)] + vec![Value::integer(42), Value::string("x"), Value::integer(2)], + vec![Local::new(1, None, true, 0, 0)] )), ); @@ -530,10 +530,10 @@ fn variable_and() { (Instruction::get_local(3, 1), Span(34, 35)), (Instruction::r#return(true), Span(35, 35)), ], - vec![], + vec![Value::string("a"), Value::string("b"),], vec![ Local::new(0, None, false, 0, 0), - Local::new(0, None, false, 0, 1), + Local::new(1, None, false, 0, 1), ] )) ); @@ -553,17 +553,22 @@ fn r#while() { (Instruction::load_constant(0, 0, false), Span(12, 13)), (Instruction::define_local(0, 0, true), Span(8, 9)), ( - *Instruction::less(true, 0, 1).set_c_is_constant(), + *Instruction::less(true, 0, 2).set_c_is_constant(), Span(23, 24) ), (Instruction::jump(2, true), Span(41, 42)), - (*Instruction::add(0, 0, 2).set_c_is_constant(), Span(39, 40)), + (*Instruction::add(0, 0, 3).set_c_is_constant(), Span(39, 40)), (Instruction::jump(3, false), Span(41, 42)), (Instruction::get_local(1, 0), Span(41, 42)), (Instruction::r#return(true), Span(42, 42)), ], - vec![Value::integer(0), Value::integer(5), Value::integer(1),], - vec![Local::new(0, None, true, 0, 0),] + vec![ + Value::integer(0), + Value::string("x"), + Value::integer(5), + Value::integer(1), + ], + vec![Local::new(1, None, true, 0, 0),] )), ); diff --git a/dust-lang/tests/functions.rs b/dust-lang/tests/functions.rs index 36044e7..0717f4e 100644 --- a/dust-lang/tests/functions.rs +++ b/dust-lang/tests/functions.rs @@ -13,70 +13,21 @@ fn function() { (Instruction::add(2, 0, 1), Span(30, 31)), (Instruction::r#return(true), Span(35, 35)), ], - vec![], + vec![Value::string("a"), Value::string("b"),], vec![ Local::new(0, Some(Type::Integer), false, 0, 0), - Local::new(0, Some(Type::Integer), false, 0, 1) + Local::new(1, Some(Type::Integer), false, 0, 1) ] ), FunctionType { type_parameters: None, - value_parameters: Some(vec![(0, Type::Integer), (0, Type::Integer)]), + value_parameters: Some(vec![(0, Type::Integer), (1, Type::Integer)]), return_type: Some(Box::new(Type::Integer)), } ))) ); } -#[test] -fn function_declaration() { - let source = "fn add (a: int, b: int) -> int { a + b }"; - - assert_eq!( - parse(source), - Ok(Chunk::with_data( - None, - vec![ - (Instruction::load_constant(0, 0, false), Span(0, 40)), - (Instruction::define_local(0, 0, false), Span(3, 6)), - (Instruction::r#return(false), Span(40, 40)) - ], - vec![Value::function( - Chunk::with_data( - None, - vec![ - (Instruction::add(2, 0, 1), Span(35, 36)), - (Instruction::r#return(true), Span(40, 40)), - ], - vec![], - vec![ - Local::new(0, Some(Type::Integer), false, 0, 0), - Local::new(0, Some(Type::Integer), false, 0, 1) - ] - ), - FunctionType { - type_parameters: None, - value_parameters: Some(vec![(0, Type::Integer), (0, Type::Integer)]), - return_type: Some(Box::new(Type::Integer)), - }, - )], - vec![Local::new( - 0, - Some(Type::Function(FunctionType { - type_parameters: None, - value_parameters: Some(vec![(0, Type::Integer), (0, Type::Integer)]), - return_type: Some(Box::new(Type::Integer)), - })), - false, - 0, - 0 - ),], - )), - ); - - assert_eq!(run(source), Ok(None)); -} - #[test] fn function_call() { let source = "fn(a: int, b: int) -> int { a + b }(1, 2)"; @@ -100,15 +51,15 @@ fn function_call() { (Instruction::add(2, 0, 1), Span(30, 31)), (Instruction::r#return(true), Span(35, 36)), ], - vec![], + vec![Value::string("a"), Value::string("b"),], vec![ Local::new(0, Some(Type::Integer), false, 0, 0), - Local::new(0, Some(Type::Integer), false, 0, 1) + Local::new(1, Some(Type::Integer), false, 0, 1) ] ), FunctionType { type_parameters: None, - value_parameters: Some(vec![(0, Type::Integer), (0, Type::Integer)]), + value_parameters: Some(vec![(0, Type::Integer), (1, Type::Integer)]), return_type: Some(Box::new(Type::Integer)), } ), @@ -121,3 +72,55 @@ fn function_call() { assert_eq!(run(source), Ok(Some(Value::integer(3)))); } + +#[test] +fn function_declaration() { + let source = "fn add (a: int, b: int) -> int { a + b }"; + + assert_eq!( + parse(source), + Ok(Chunk::with_data( + None, + vec![ + (Instruction::load_constant(0, 1, false), Span(0, 40)), + (Instruction::define_local(0, 0, false), Span(3, 6)), + (Instruction::r#return(false), Span(40, 40)) + ], + vec![ + Value::string("add"), + Value::function( + Chunk::with_data( + None, + vec![ + (Instruction::add(2, 0, 1), Span(35, 36)), + (Instruction::r#return(true), Span(40, 40)), + ], + vec![Value::string("a"), Value::string("b")], + vec![ + Local::new(0, Some(Type::Integer), false, 0, 0), + Local::new(1, Some(Type::Integer), false, 0, 1) + ] + ), + FunctionType { + type_parameters: None, + value_parameters: Some(vec![(0, Type::Integer), (1, Type::Integer)]), + return_type: Some(Box::new(Type::Integer)), + }, + ) + ], + vec![Local::new( + 0, + Some(Type::Function(FunctionType { + type_parameters: None, + value_parameters: Some(vec![(0, Type::Integer), (1, Type::Integer)]), + return_type: Some(Box::new(Type::Integer)), + })), + false, + 0, + 0 + ),], + )), + ); + + assert_eq!(run(source), Ok(None)); +} diff --git a/dust-lang/tests/scopes.rs b/dust-lang/tests/scopes.rs index 7ce4486..fdc73c2 100644 --- a/dust-lang/tests/scopes.rs +++ b/dust-lang/tests/scopes.rs @@ -33,28 +33,33 @@ fn block_scope() { vec![ (Instruction::load_constant(0, 0, false), Span(17, 18)), (Instruction::define_local(0, 0, false), Span(13, 14)), - (Instruction::load_constant(1, 1, false), Span(50, 52)), + (Instruction::load_constant(1, 2, false), Span(50, 52)), (Instruction::define_local(1, 1, false), Span(46, 47)), - (Instruction::load_constant(2, 2, false), Span(92, 93)), + (Instruction::load_constant(2, 4, false), Span(92, 93)), (Instruction::define_local(2, 2, false), Span(88, 89)), - (Instruction::load_constant(3, 3, false), Span(129, 130)), + (Instruction::load_constant(3, 6, false), Span(129, 130)), (Instruction::define_local(3, 3, false), Span(125, 126)), - (Instruction::load_constant(4, 2, false), Span(158, 159)), + (Instruction::load_constant(4, 4, false), Span(158, 159)), (Instruction::define_local(4, 4, false), Span(154, 155)), (Instruction::r#return(false), Span(165, 165)) ], vec![ Value::integer(0), + Value::string("a"), Value::integer(42), + Value::string("b"), Value::integer(1), + Value::string("c"), Value::integer(2), + Value::string("d"), + Value::string("e"), ], vec![ - Local::new(0, None, false, 0, 0), - Local::new(0, None, false, 1, 1), - Local::new(0, None, false, 2, 2), - Local::new(0, None, false, 1, 3), - Local::new(0, None, false, 0, 4), + Local::new(1, None, false, 0, 0), + Local::new(3, None, false, 1, 1), + Local::new(5, None, false, 2, 2), + Local::new(7, None, false, 1, 3), + Local::new(8, None, false, 0, 4), ] )), );