Improved the test system

This commit is contained in:
0x4261756D 2022-12-18 04:05:50 +01:00
parent 35f65101ad
commit f60441ef9d
13 changed files with 96 additions and 34 deletions

View File

@ -102,24 +102,72 @@ fn main()
{ {
"-t" | "--test" => "-t" | "--test" =>
{ {
let mut count = 0;
for f in fs::read_dir(&args[2]).unwrap() for f in fs::read_dir(&args[2]).unwrap()
{ {
let f = f.unwrap(); let f = f.unwrap();
let file_content = fs::read_to_string(f.path()).unwrap(); let file_content = fs::read_to_string(f.path()).unwrap();
println!("========NOW TESTING '{:?}'========", f.path()); println!("========NOW TESTING '{:?}'========", f.path());
match compile(file_content, &intrinsics, interpret, debug) match compile(&file_content, &intrinsics, interpret, debug)
{ {
Ok(()) => println!("\n\n\n---Successfully parsed '{:?}'---", f.path()), Ok(maybe_msg) =>
Err(msg) => println!("ERROR: {}", msg), {
println!("---Successfully parsed '{:?}'---", f.path());
if let Some(msg) = &maybe_msg
{
print!("---Output---\n'{}'\n", msg);
}
let expected = &format!("//valid,{}:END:", maybe_msg.unwrap_or(String::new()).replace("\n", "\n//"));
if file_content.starts_with(expected)
{
println!("===PASSED===");
count += 1;
}
else if let Some(index) = file_content.find("//:END:")
{
let expected_output = file_content[8..index].replace("\n//", "\n");
println!("\n===FAILED===\nExpected the output to be\n'{}'\n({})", expected_output, expected);
}
else
{
panic!("Could not find an ending marker (:END:) for the expected output in {:?}", f.file_name());
}
}
Err(msg) =>
{
println!("ERROR: {}", msg);
if file_content.starts_with(&format!("//invalid,{}:END:", msg.replace("\n", "\n//")))
{
println!("===PASSED===");
count += 1;
}
else if let Some(index) = file_content.find(":END:")
{
let expected_output = file_content[10..index].replace("\n//", "\n");
println!("\n\n===FAILED===\nExpected the output to be {}", expected_output);
}
else
{
panic!("Could not find an ending marker (//:END:) for the expected output in {:?}", f.file_name());
}
}
} }
} }
println!("\n\n=========RESULT=========\n{}/{}", count, fs::read_dir(&args[2]).unwrap().count());
} }
"-c" | "--compile" => "-c" | "--compile" =>
{ {
let file_content = fs::read_to_string(&args[2]).expect("Could not read the source file"); let file_content = fs::read_to_string(&args[2]).expect("Could not read the source file");
match compile(file_content, &intrinsics, interpret, debug) match compile(&file_content, &intrinsics, interpret, debug)
{ {
Ok(()) => println!("\n\n\n---Successfully parsed '{}'---", args[2]), Ok(maybe_msg) =>
{
println!("---Successfully parsed '{}'---", args[2]);
if let Some(msg) = maybe_msg
{
print!("---Output---\n\n{}", msg);
}
}
Err(msg) => println!("ERROR: {}", msg), Err(msg) => println!("ERROR: {}", msg),
} }
} }
@ -127,7 +175,7 @@ fn main()
} }
} }
fn compile(file_content: String, intrinsics: &HashMap<&str, (Vec<Datatype>, Vec<Datatype>)>, interpret: bool, debug: bool) -> Result<(), String> fn compile(file_content: &String, intrinsics: &HashMap<&str, (Vec<Datatype>, Vec<Datatype>)>, interpret: bool, debug: bool) -> Result<Option<String>, String>
{ {
let mut tokens: Vec<Token> = tokenize(&file_content)?; let mut tokens: Vec<Token> = tokenize(&file_content)?;
println!("---Done tokenizing, got {} tokens---", tokens.len()); println!("---Done tokenizing, got {} tokens---", tokens.len());
@ -139,21 +187,26 @@ fn compile(file_content: String, intrinsics: &HashMap<&str, (Vec<Datatype>, Vec<
println!("---Done validating function calls---"); println!("---Done validating function calls---");
typecheck(&operations, &functions, &intrinsics, debug)?; typecheck(&operations, &functions, &intrinsics, debug)?;
println!("---Done typechecking---"); println!("---Done typechecking---");
if interpret let output = if interpret
{ {
println!("---Starting to interpret the program---\n\n"); println!("---Starting to interpret the program---");
interpret_program(&operations, &mut Vec::new(), &functions, &intrinsics, debug); Some(interpret_program(&operations, &mut Vec::new(), &functions, &intrinsics, debug))
} }
return Ok(()); else
{
None
};
return Ok(output);
} }
fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, functions: &Vec<Function>, intrinsics: &HashMap<&str, (Vec<Datatype>, Vec<Datatype>)>, debug: bool) fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, functions: &Vec<Function>, intrinsics: &HashMap<&str, (Vec<Datatype>, Vec<Datatype>)>, debug: bool) -> String
{ {
let mut output = String::new();
for operation in operations for operation in operations
{ {
if debug if debug
{ {
println!("before: {:?}: {:?}", operation, queue); println!("before: {:?}: {:?}, '{}'", operation, queue, output);
} }
match operation match operation
{ {
@ -191,7 +244,7 @@ fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, funct
let val = queue.remove(0); let val = queue.remove(0);
function_context.push(val); function_context.push(val);
} }
interpret_program(&function.content, function_context, functions, intrinsics, debug); output += interpret_program(&function.content, function_context, functions, intrinsics, debug).as_str();
for val in function_context for val in function_context
{ {
queue.push(val.to_string()); queue.push(val.to_string());
@ -202,11 +255,11 @@ fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, funct
let val = queue.remove(0); let val = queue.remove(0);
if val == "true" if val == "true"
{ {
interpret_program(if_block, queue, functions, intrinsics, debug); output += interpret_program(if_block, queue, functions, intrinsics, debug).as_str();
} }
else if let Some(else_block) = maybe_else_block else if let Some(else_block) = maybe_else_block
{ {
interpret_program(else_block, queue, functions, intrinsics, debug); output += interpret_program(else_block, queue, functions, intrinsics, debug).as_str();
} }
} }
Operation::Intrinsic(intrinsic_name, line, col) => Operation::Intrinsic(intrinsic_name, line, col) =>
@ -215,7 +268,7 @@ fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, funct
{ {
"print" => "print" =>
{ {
print!("{}", queue.remove(0)); output += format!("{}", queue.remove(0)).as_str();
} }
"-" => "-" =>
{ {
@ -260,7 +313,7 @@ fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, funct
} }
"println" => "println" =>
{ {
println!("{}", queue.remove(0)); output += format!("{}\n", queue.remove(0)).as_str();
} }
_ => _ =>
{ {
@ -277,7 +330,7 @@ fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, funct
{ {
break; break;
} }
interpret_program(while_block, queue, functions, intrinsics, debug); output += interpret_program(while_block, queue, functions, intrinsics, debug).as_str();
} }
} }
Operation::Depth(_, _) => Operation::Depth(_, _) =>
@ -292,9 +345,10 @@ fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, funct
} }
if debug if debug
{ {
println!("after: {:?}: {:?}", operation, queue); println!("after: {:?}: {:?}, '{}'", operation, queue, output);
} }
} }
return output;
} }
fn typecheck(operations: &Vec<Operation>, functions: &Vec<Function>, intrinsics: &HashMap<&str, (Vec<Datatype>, Vec<Datatype>)>, debug: bool) -> Result<(), String> fn typecheck(operations: &Vec<Operation>, functions: &Vec<Function>, intrinsics: &HashMap<&str, (Vec<Datatype>, Vec<Datatype>)>, debug: bool) -> Result<(), String>

View File

@ -1,4 +1,4 @@
//invalid,Function name print at 3:22 is already an intrinsic //invalid,Function name print at 3:22 is already an intrinsic:END:
function int => print function int => print
{ {

View File

@ -1,4 +1,4 @@
//invalid,Expected function name but got deq at 3:20 //invalid,Expected function name but got deq at 3:20:END:
function int => deq function int => deq
{ {

View File

@ -1,4 +1,4 @@
//invalid,Expected function name but got { at 4:2 //invalid,Expected function name but got { at 4:2:END:
function int => function int =>
{ {

View File

@ -1,3 +1,6 @@
//valid,10946
//:END:
function int int int int => int fibonacci function int int int int => int fibonacci
{ {
dup 0 == req req req req dup 0 == req req req req
@ -11,4 +14,4 @@ function int int int int => int fibonacci
} }
} }
20 0 1 0 fibonacci print 20 0 1 0 fibonacci println

View File

@ -1,3 +1,7 @@
//valid,231
//231
//:END:
function int => int req_impl { } function int => int req_impl { }
1 2 3 req_impl print print println 1 2 3 req_impl print print println

View File

@ -1,4 +1,4 @@
//valid,:END:
function bool bool bool => bool rule110 function bool bool bool => bool rule110
{ {
if if

View File

@ -1,6 +1,5 @@
//valid //valid,Hello, World!
//output: Hello, World! //4242test2Falsetesttesttest:END:
//4242test2Falsetesttesttest
"Hello, World!\n" print 43 foo foo deq "Hello, World!\n" print 43 foo foo deq

View File

@ -1,8 +1,9 @@
//valid,output:42footesttest2stuff //valid,42footesttest2stuff
//:END:
function int str any => str str str foo function int str any => str str str foo
{ {
print req deq "test" "test2" "stuff" print print req deq "test" "test2" "stuff" print
} }
42 "foo" "bar" foo print print print 42 "foo" "bar" foo print print println

View File

@ -1,2 +1,2 @@
//invalid,Call to unknown function foo at 2:4 //invalid,Call to unknown function 'foo' at 2:4:END:
foo foo

View File

@ -1,4 +1,4 @@
//invalid,Call to unknown function bar at 9:7 //invalid,Call to unknown function 'bar' at 9:7:END:
function int => foo function int => foo
{ {

View File

@ -1,4 +1,4 @@
//invalid,Call to unknown function bar at 5:5 //invalid,Call to unknown function 'bar' at 5:5:END:
function => foo function => foo
{ {

View File

@ -1,4 +1,5 @@
//valid,output:10987654321falsefalse //valid,10987654321falsefalse
//:END:
true while true while
{ {
@ -18,4 +19,4 @@ true true true while
{ {
false false
} }
print print print println