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" =>
{
let mut count = 0;
for f in fs::read_dir(&args[2]).unwrap()
{
let f = f.unwrap();
let file_content = fs::read_to_string(f.path()).unwrap();
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()),
Err(msg) => println!("ERROR: {}", msg),
Ok(maybe_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" =>
{
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),
}
}
@ -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)?;
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---");
typecheck(&operations, &functions, &intrinsics, debug)?;
println!("---Done typechecking---");
if interpret
let output = if interpret
{
println!("---Starting to interpret the program---\n\n");
interpret_program(&operations, &mut Vec::new(), &functions, &intrinsics, debug);
println!("---Starting to interpret the program---");
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
{
if debug
{
println!("before: {:?}: {:?}", operation, queue);
println!("before: {:?}: {:?}, '{}'", operation, queue, output);
}
match operation
{
@ -191,7 +244,7 @@ fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, funct
let val = queue.remove(0);
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
{
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);
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
{
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) =>
@ -215,7 +268,7 @@ fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, funct
{
"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!("{}", 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;
}
interpret_program(while_block, queue, functions, intrinsics, debug);
output += interpret_program(while_block, queue, functions, intrinsics, debug).as_str();
}
}
Operation::Depth(_, _) =>
@ -292,9 +345,10 @@ fn interpret_program(operations: &Vec<Operation>, queue: &mut Vec<String>, funct
}
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>

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
{

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
{

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 =>
{

View File

@ -1,3 +1,6 @@
//valid,10946
//:END:
function int int int int => int fibonacci
{
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 { }
1 2 3 req_impl print print println

View File

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

View File

@ -1,6 +1,5 @@
//valid
//output: Hello, World!
//4242test2Falsetesttesttest
//valid,Hello, World!
//4242test2Falsetesttesttest:END:
"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
{
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

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
{

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
{

View File

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