Add a verifier

The current implementation only performs a few basic checks.
This commit is contained in:
Morgan Phillips
2016-09-06 14:05:44 -07:00
parent 78a9e67a09
commit d8712b2ce6
10 changed files with 287 additions and 3 deletions

View File

@@ -21,6 +21,9 @@ dependencies = [
[[package]]
name = "cretonne"
version = "0.0.0"
dependencies = [
"regex 0.1.71 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cretonne-reader"

View File

@@ -0,0 +1,66 @@
extern crate cretonne;
extern crate cton_reader;
extern crate glob;
extern crate regex;
use std::env;
use glob::glob;
use regex::Regex;
use std::fs::File;
use std::io::Read;
use self::cton_reader::parser::Parser;
use self::cretonne::verifier::Verifier;
/// Compile a function and run verifier tests based on specially formatted
/// comments in the [function's] source.
fn verifier_tests_from_source(function_source: &str) {
let func_re = Regex::new("^[ \t]*function.*").unwrap();
let err_re = Regex::new(";[ \t]*Err\\((.*)+\\)").unwrap();
// Each entry corresponds to an optional regular expression, where
// the index corresponds to the function offset in our source code.
// If no error is expected for a given function its entry will be
// set to None.
let mut verifier_results = Vec::new();
for line in function_source.lines() {
if func_re.is_match(line) {
match err_re.captures(line) {
Some(caps) => {
verifier_results.push(Some(Regex::new(caps.at(1).unwrap()).unwrap()));
},
None => {
verifier_results.push(None);
},
};
}
}
// Run the verifier against each function and compare the output
// with the expected result (as determined above).
for (i, func) in Parser::parse(function_source).unwrap().into_iter().enumerate() {
let result = Verifier::new(&func).run();
match verifier_results[i] {
Some(ref re) => {
assert_eq!(re.is_match(&result.err().unwrap()), true);
},
None => {
assert_eq!(result, Ok(()));
}
}
}
}
#[test]
fn test_all() {
let testdir = format!("{}/tests/verifier_testdata/*.cton",
env::current_dir().unwrap().display());
for entry in glob(&testdir).unwrap() {
let path = entry.unwrap();
println!("Testing {:?}", path);
let mut file = File::open(&path).unwrap();
let mut buffer = String::new();
file.read_to_string(&mut buffer).unwrap();
verifier_tests_from_source(&buffer);
}
}

View File

@@ -0,0 +1,17 @@
function test(i32) { ; Err(terminating)
ebb0(v0: i32):
jump ebb1
return
ebb1:
jump ebb2
brz v0, ebb3
ebb2:
jump ebb3
ebb3:
return
}
function test(i32) { ; Ok
ebb0(v0: i32):
return
}