2024-07-13 14:47:24 +00:00
|
|
|
use abstract_tree::{Expression, ValueNode, WithPos};
|
2024-05-21 20:29:54 +00:00
|
|
|
use dust_lang::*;
|
2024-07-13 14:47:24 +00:00
|
|
|
use error::{DustError, ValidationError};
|
|
|
|
use identifier::Identifier;
|
2024-03-09 03:34:17 +00:00
|
|
|
|
2024-07-10 03:01:54 +00:00
|
|
|
#[test]
|
|
|
|
fn function_scope() {
|
|
|
|
assert_eq!(
|
|
|
|
interpret(
|
|
|
|
"test",
|
|
|
|
"
|
|
|
|
x = 2
|
2024-07-11 21:22:30 +00:00
|
|
|
|
2024-07-10 03:01:54 +00:00
|
|
|
foo = fn () -> int {
|
|
|
|
x = 42
|
|
|
|
x
|
|
|
|
}
|
2024-07-11 21:22:30 +00:00
|
|
|
|
2024-07-10 03:01:54 +00:00
|
|
|
x = 1
|
|
|
|
|
2024-07-11 21:22:30 +00:00
|
|
|
foo()
|
2024-07-10 03:01:54 +00:00
|
|
|
"
|
|
|
|
),
|
|
|
|
Ok(Some(Value::integer(42)))
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2024-03-29 19:52:02 +00:00
|
|
|
#[test]
|
|
|
|
fn function_call_with_type_argument() {
|
|
|
|
assert_eq!(
|
|
|
|
interpret(
|
|
|
|
"test",
|
|
|
|
"
|
2024-06-24 17:54:37 +00:00
|
|
|
foobar = fn <T> (x: T) -> T { x }
|
2024-06-24 17:48:31 +00:00
|
|
|
foobar::<int>(42)
|
2024-03-29 19:52:02 +00:00
|
|
|
",
|
|
|
|
),
|
|
|
|
Ok(Some(Value::integer(42)))
|
|
|
|
);
|
|
|
|
}
|
2024-03-24 19:35:19 +00:00
|
|
|
|
2024-03-09 03:34:17 +00:00
|
|
|
#[test]
|
|
|
|
fn function_call() {
|
|
|
|
assert_eq!(
|
|
|
|
interpret(
|
2024-03-24 19:35:19 +00:00
|
|
|
"test",
|
2024-03-09 03:34:17 +00:00
|
|
|
"
|
2024-06-19 01:44:22 +00:00
|
|
|
foobar = fn (message: str) -> str { message }
|
2024-03-09 03:34:17 +00:00
|
|
|
foobar('Hiya')
|
|
|
|
",
|
|
|
|
),
|
|
|
|
Ok(Some(Value::string("Hiya".to_string())))
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn callback() {
|
|
|
|
assert_eq!(
|
|
|
|
interpret(
|
2024-03-24 19:35:19 +00:00
|
|
|
"test",
|
2024-03-09 03:34:17 +00:00
|
|
|
"
|
2024-06-18 23:42:04 +00:00
|
|
|
foobar = fn (cb: fn () -> str) -> str {
|
2024-03-09 03:34:17 +00:00
|
|
|
cb()
|
|
|
|
}
|
2024-06-18 23:42:04 +00:00
|
|
|
foobar(fn () -> str { 'Hiya' })
|
2024-03-09 03:34:17 +00:00
|
|
|
",
|
|
|
|
),
|
|
|
|
Ok(Some(Value::string("Hiya".to_string())))
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn built_in_function_call() {
|
2024-07-01 18:23:01 +00:00
|
|
|
assert_eq!(
|
|
|
|
interpret("test", "use std.io io.write_line('Hiya')"),
|
|
|
|
Ok(None)
|
|
|
|
);
|
2024-03-09 03:34:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2024-05-21 20:29:54 +00:00
|
|
|
fn function_context_captures_values() {
|
2024-03-09 03:34:17 +00:00
|
|
|
assert_eq!(
|
|
|
|
interpret(
|
2024-03-24 19:35:19 +00:00
|
|
|
"test",
|
2024-03-09 03:34:17 +00:00
|
|
|
"
|
2024-06-18 23:42:04 +00:00
|
|
|
bar = fn () -> int { 2 }
|
|
|
|
foo = fn () -> int { bar() }
|
2024-03-09 03:34:17 +00:00
|
|
|
foo()
|
|
|
|
"
|
|
|
|
),
|
|
|
|
Ok(Some(Value::integer(2)))
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn recursion() {
|
|
|
|
assert_eq!(
|
|
|
|
interpret(
|
2024-03-24 19:35:19 +00:00
|
|
|
"test",
|
2024-03-09 03:34:17 +00:00
|
|
|
"
|
2024-06-18 23:42:04 +00:00
|
|
|
fib = fn (i: int) -> int {
|
2024-07-11 21:22:30 +00:00
|
|
|
if i <= 1 {
|
|
|
|
i
|
|
|
|
} else {
|
2024-03-09 03:34:17 +00:00
|
|
|
fib(i - 1) + fib(i - 2)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-07-11 21:22:30 +00:00
|
|
|
fib(7)
|
2024-03-09 03:34:17 +00:00
|
|
|
"
|
|
|
|
),
|
2024-06-24 20:48:39 +00:00
|
|
|
Ok(Some(Value::integer(13)))
|
2024-03-09 03:34:17 +00:00
|
|
|
);
|
|
|
|
}
|
2024-07-13 14:47:24 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn value_argument_error() {
|
|
|
|
assert_eq!(
|
|
|
|
interpret(
|
|
|
|
"test",
|
|
|
|
"
|
|
|
|
foobar = fn (a: int, b: int) -> int { a + b }
|
|
|
|
foobar(1)
|
|
|
|
"
|
|
|
|
),
|
|
|
|
Err(InterpreterError::new(
|
|
|
|
"test".into(),
|
|
|
|
vec![DustError::Validation {
|
|
|
|
error: ValidationError::WrongValueArguments {
|
|
|
|
parameters: vec![
|
|
|
|
(Identifier::new("a"), Type::Integer),
|
|
|
|
(Identifier::new("b"), Type::Integer),
|
|
|
|
],
|
|
|
|
arguments: vec![Expression::Value(
|
|
|
|
ValueNode::Integer(1).with_position((78, 79)),
|
|
|
|
)],
|
|
|
|
},
|
|
|
|
position: (71, 80).into()
|
|
|
|
}]
|
|
|
|
))
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn type_argument_error() {
|
|
|
|
assert_eq!(
|
|
|
|
interpret(
|
|
|
|
"test",
|
|
|
|
"
|
|
|
|
foobar = fn <T> (a: T) -> T { a }
|
|
|
|
foobar(1)
|
|
|
|
"
|
|
|
|
),
|
|
|
|
Err(InterpreterError::new(
|
|
|
|
"test".into(),
|
|
|
|
vec![DustError::Validation {
|
|
|
|
error: ValidationError::WrongTypeArguments {
|
|
|
|
parameters: vec![Identifier::new("T")],
|
|
|
|
arguments: vec![]
|
|
|
|
},
|
|
|
|
position: (59, 68).into()
|
|
|
|
}]
|
|
|
|
))
|
|
|
|
);
|
|
|
|
}
|