Improved the test system
This commit is contained in:
parent
35f65101ad
commit
f60441ef9d
92
src/main.rs
92
src/main.rs
@ -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>
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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 =>
|
||||||
{
|
{
|
||||||
|
@ -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
|
@ -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
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
|
//valid,:END:
|
||||||
function bool bool bool => bool rule110
|
function bool bool bool => bool rule110
|
||||||
{
|
{
|
||||||
if
|
if
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
@ -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
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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
|
Loading…
x
Reference in New Issue
Block a user