|
|
@ -104,96 +104,96 @@ end function |
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn recursion_stack_overflow() {
|
|
|
|
let mut tio = common::TestIO::new("");
|
|
|
|
{
|
|
|
|
let mut xb = XBasic::new(&mut tio);
|
|
|
|
assert!(xb
|
|
|
|
.run(
|
|
|
|
"
|
|
|
|
let tio = common::TestIO::new("");
|
|
|
|
|
|
|
|
let mut xb = XBasic::new(tio);
|
|
|
|
assert!(xb
|
|
|
|
.run(
|
|
|
|
"
|
|
|
|
function a()
|
|
|
|
a()
|
|
|
|
end function
|
|
|
|
|
|
|
|
a()
|
|
|
|
"
|
|
|
|
)
|
|
|
|
.is_err());
|
|
|
|
assert!(xb.error_handler.had_errors);
|
|
|
|
assert_eq!(
|
|
|
|
xb.error_handler.errors,
|
|
|
|
["[line 3] Error : Stack overflow."]
|
|
|
|
);
|
|
|
|
}
|
|
|
|
tio.check();
|
|
|
|
)
|
|
|
|
.is_err());
|
|
|
|
assert!(xb.error_handler.had_errors);
|
|
|
|
assert_eq!(
|
|
|
|
xb.error_handler.errors,
|
|
|
|
["[line 3] Error : Stack overflow."]
|
|
|
|
);
|
|
|
|
|
|
|
|
xb.get_io().check();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn function_does_not_exist() {
|
|
|
|
let mut tio = common::TestIO::new("");
|
|
|
|
{
|
|
|
|
let mut xb = XBasic::new(&mut tio);
|
|
|
|
assert!(xb
|
|
|
|
.run(
|
|
|
|
"
|
|
|
|
let tio = common::TestIO::new("");
|
|
|
|
|
|
|
|
let mut xb = XBasic::new(tio);
|
|
|
|
assert!(xb
|
|
|
|
.run(
|
|
|
|
"
|
|
|
|
a()
|
|
|
|
"
|
|
|
|
)
|
|
|
|
.is_err());
|
|
|
|
assert!(xb.error_handler.had_errors);
|
|
|
|
assert_eq!(
|
|
|
|
xb.error_handler.errors,
|
|
|
|
["[line 2] Error at 'a': Not a function."]
|
|
|
|
);
|
|
|
|
}
|
|
|
|
tio.check();
|
|
|
|
)
|
|
|
|
.is_err());
|
|
|
|
assert!(xb.error_handler.had_errors);
|
|
|
|
assert_eq!(
|
|
|
|
xb.error_handler.errors,
|
|
|
|
["[line 2] Error at 'a': Not a function."]
|
|
|
|
);
|
|
|
|
|
|
|
|
xb.get_io().check();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn function_already_defined() {
|
|
|
|
let mut tio = common::TestIO::new("");
|
|
|
|
{
|
|
|
|
let mut xb = XBasic::new(&mut tio);
|
|
|
|
assert!(xb
|
|
|
|
.run(
|
|
|
|
"
|
|
|
|
let tio = common::TestIO::new("");
|
|
|
|
|
|
|
|
let mut xb = XBasic::new(tio);
|
|
|
|
assert!(xb
|
|
|
|
.run(
|
|
|
|
"
|
|
|
|
function a()
|
|
|
|
end function
|
|
|
|
|
|
|
|
function a()
|
|
|
|
end function
|
|
|
|
"
|
|
|
|
)
|
|
|
|
.is_err());
|
|
|
|
assert!(xb.error_handler.had_errors);
|
|
|
|
assert_eq!(
|
|
|
|
xb.error_handler.errors,
|
|
|
|
["[line 5] Error at 'a': Function is already defined on line 2."]
|
|
|
|
);
|
|
|
|
}
|
|
|
|
tio.check();
|
|
|
|
)
|
|
|
|
.is_err());
|
|
|
|
assert!(xb.error_handler.had_errors);
|
|
|
|
assert_eq!(
|
|
|
|
xb.error_handler.errors,
|
|
|
|
["[line 5] Error at 'a': Function is already defined on line 2."]
|
|
|
|
);
|
|
|
|
|
|
|
|
xb.get_io().check();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn function_mismatched_arity() {
|
|
|
|
let mut tio = common::TestIO::new("");
|
|
|
|
{
|
|
|
|
let mut xb = XBasic::new(&mut tio);
|
|
|
|
assert!(xb
|
|
|
|
.run(
|
|
|
|
"
|
|
|
|
let tio = common::TestIO::new("");
|
|
|
|
|
|
|
|
let mut xb = XBasic::new(tio);
|
|
|
|
assert!(xb
|
|
|
|
.run(
|
|
|
|
"
|
|
|
|
a(1, 2, 3, 4)
|
|
|
|
function a(b, c, d)
|
|
|
|
end function
|
|
|
|
"
|
|
|
|
)
|
|
|
|
.is_err());
|
|
|
|
assert!(xb.error_handler.had_errors);
|
|
|
|
assert_eq!(
|
|
|
|
xb.error_handler.errors,
|
|
|
|
["[line 2] Error at 'a': Expected 3 arguments, got 4."]
|
|
|
|
);
|
|
|
|
}
|
|
|
|
tio.check();
|
|
|
|
)
|
|
|
|
.is_err());
|
|
|
|
assert!(xb.error_handler.had_errors);
|
|
|
|
assert_eq!(
|
|
|
|
xb.error_handler.errors,
|
|
|
|
["[line 2] Error at 'a': Expected 3 arguments, got 4."]
|
|
|
|
);
|
|
|
|
|
|
|
|
xb.get_io().check();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
@ -264,62 +264,62 @@ return |
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn function_across_multiple_calls() {
|
|
|
|
let mut tio = common::TestIO::new("5\n");
|
|
|
|
{
|
|
|
|
let mut xb = XBasic::new(&mut tio);
|
|
|
|
assert!(xb
|
|
|
|
.run(
|
|
|
|
"
|
|
|
|
let tio = common::TestIO::new("5\n");
|
|
|
|
|
|
|
|
let mut xb = XBasic::new(tio);
|
|
|
|
assert!(xb
|
|
|
|
.run(
|
|
|
|
"
|
|
|
|
function a(b)
|
|
|
|
return b
|
|
|
|
end function
|
|
|
|
"
|
|
|
|
)
|
|
|
|
.is_ok());
|
|
|
|
assert!(xb.run("print a(5)\n").is_ok());
|
|
|
|
assert!(!xb.error_handler.had_errors);
|
|
|
|
}
|
|
|
|
tio.check();
|
|
|
|
)
|
|
|
|
.is_ok());
|
|
|
|
assert!(xb.run("print a(5)\n").is_ok());
|
|
|
|
assert!(!xb.error_handler.had_errors);
|
|
|
|
|
|
|
|
xb.get_io().check();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn function_overwrite_across_runs() {
|
|
|
|
let mut tio = common::TestIO::new("5\n");
|
|
|
|
{
|
|
|
|
let mut xb = XBasic::new(&mut tio);
|
|
|
|
assert!(xb
|
|
|
|
.run(
|
|
|
|
"
|
|
|
|
let tio = common::TestIO::new("5\n");
|
|
|
|
|
|
|
|
let mut xb = XBasic::new(tio);
|
|
|
|
assert!(xb
|
|
|
|
.run(
|
|
|
|
"
|
|
|
|
function a(b)
|
|
|
|
return b
|
|
|
|
end function
|
|
|
|
"
|
|
|
|
)
|
|
|
|
.is_ok());
|
|
|
|
assert!(xb
|
|
|
|
.run(
|
|
|
|
"
|
|
|
|
)
|
|
|
|
.is_ok());
|
|
|
|
assert!(xb
|
|
|
|
.run(
|
|
|
|
"
|
|
|
|
function a(b)
|
|
|
|
return b * 2
|
|
|
|
end function
|
|
|
|
"
|
|
|
|
)
|
|
|
|
.is_err());
|
|
|
|
xb.clear_errors();
|
|
|
|
assert!(xb.run("print a(5)\n").is_ok());
|
|
|
|
assert!(!xb.error_handler.had_errors);
|
|
|
|
}
|
|
|
|
tio.check();
|
|
|
|
)
|
|
|
|
.is_err());
|
|
|
|
xb.clear_errors();
|
|
|
|
assert!(xb.run("print a(5)\n").is_ok());
|
|
|
|
assert!(!xb.error_handler.had_errors);
|
|
|
|
|
|
|
|
xb.get_io().check();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn function_variable_edge_case() {
|
|
|
|
let mut tio = common::TestIO::new("done\n");
|
|
|
|
{
|
|
|
|
let mut xb = XBasic::new(&mut tio);
|
|
|
|
assert!(xb
|
|
|
|
.run(
|
|
|
|
"
|
|
|
|
let tio = common::TestIO::new("done\n");
|
|
|
|
|
|
|
|
let mut xb = XBasic::new(tio);
|
|
|
|
assert!(xb
|
|
|
|
.run(
|
|
|
|
"
|
|
|
|
function func(b)
|
|
|
|
a = 0
|
|
|
|
end function
|
|
|
@ -329,21 +329,21 @@ z = 0 |
|
|
|
b = 0
|
|
|
|
print \"done\"
|
|
|
|
",
|
|
|
|
)
|
|
|
|
.is_ok());
|
|
|
|
assert!(!xb.error_handler.had_errors);
|
|
|
|
}
|
|
|
|
tio.check();
|
|
|
|
)
|
|
|
|
.is_ok());
|
|
|
|
assert!(!xb.error_handler.had_errors);
|
|
|
|
|
|
|
|
xb.get_io().check();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn function_argument_edge_case() {
|
|
|
|
let mut tio = common::TestIO::new("3\ndone\n");
|
|
|
|
{
|
|
|
|
let mut xb = XBasic::new(&mut tio);
|
|
|
|
assert!(xb
|
|
|
|
.run(
|
|
|
|
"
|
|
|
|
let tio = common::TestIO::new("3\ndone\n");
|
|
|
|
|
|
|
|
let mut xb = XBasic::new(tio);
|
|
|
|
assert!(xb
|
|
|
|
.run(
|
|
|
|
"
|
|
|
|
a = test
|
|
|
|
function func(b)
|
|
|
|
c = 0
|
|
|
@ -354,21 +354,21 @@ end function |
|
|
|
z = 0
|
|
|
|
print \"done\"
|
|
|
|
",
|
|
|
|
)
|
|
|
|
.is_ok());
|
|
|
|
assert!(!xb.error_handler.had_errors);
|
|
|
|
}
|
|
|
|
tio.check();
|
|
|
|
)
|
|
|
|
.is_ok());
|
|
|
|
assert!(!xb.error_handler.had_errors);
|
|
|
|
|
|
|
|
xb.get_io().check();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn function_doesnt_corrupt_stack() {
|
|
|
|
let mut tio = common::TestIO::new("3\n0\n1\n2\n3\n4\n5\n");
|
|
|
|
{
|
|
|
|
let mut xb = XBasic::new(&mut tio);
|
|
|
|
assert!(xb
|
|
|
|
.run(
|
|
|
|
"
|
|
|
|
let tio = common::TestIO::new("3\n0\n1\n2\n3\n4\n5\n");
|
|
|
|
|
|
|
|
let mut xb = XBasic::new(tio);
|
|
|
|
assert!(xb
|
|
|
|
.run(
|
|
|
|
"
|
|
|
|
function func(b)
|
|
|
|
print b
|
|
|
|
end function
|
|
|
@ -378,9 +378,9 @@ for x = 0 to 5 |
|
|
|
print x
|
|
|
|
next x
|
|
|
|
",
|
|
|
|
)
|
|
|
|
.is_ok());
|
|
|
|
assert!(!xb.error_handler.had_errors);
|
|
|
|
}
|
|
|
|
tio.check();
|
|
|
|
)
|
|
|
|
.is_ok());
|
|
|
|
assert!(!xb.error_handler.had_errors);
|
|
|
|
|
|
|
|
xb.get_io().check();
|
|
|
|
}
|