Merge pull request #434 from Kindelia/experimental

Dependencies between record fields
This commit is contained in:
Felipe G 2022-12-02 18:29:06 -03:00 committed by GitHub
commit ec94c208d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 109 additions and 81 deletions

View File

@ -258,8 +258,10 @@ impl Visitor for UnboundCollector {
TopLevel::RecordType(entr) => {
let inside_vars = self.context_vars.clone();
visit_vec!(entr.parameters.iter_mut(), arg => self.visit_argument(arg));
visit_vec!(entr.fields.iter_mut(), (_, _, typ) => {
visit_vec!(entr.fields.iter_mut(), (name, _, typ) => {
self.visit_expr(typ);
self.context_vars.push((name.range, name.to_string()))
});
self.context_vars = inside_vars;

View File

@ -0,0 +1,4 @@
record FieldDependency {
ty : Type
snd : ty
}

View File

@ -0,0 +1,2 @@
Main = 3

View File

@ -0,0 +1,5 @@
Kek <a: U60> : U60
Kek a = a
Main : U60
Main = 3

View File

@ -0,0 +1,6 @@
Main = (Kuk)
Kuk = (Kek 3)
Kek a = a

View File

@ -0,0 +1,8 @@
Kek (a: U60) : U60
Kek a = a
Main : U60
Main = (Kuk) ~(20)
Kuk : ~(a : U60) -> U60
Kuk = ~x => Kek 3

View File

@ -0,0 +1,10 @@
ERROR This irrelevant parameter should not be used in a relevant position.
/--[suite/erasure/fail/ErrInType.kind2:2:8]
|
1 | Main : Type
2 | Main = Type
| v---
| \It's in relevant position!

View File

@ -0,0 +1,2 @@
Main : Type
Main = Type

View File

@ -0,0 +1,11 @@
ERROR This irrelevant parameter should not be used in a relevant position.
/--[suite/erasure/fail/ShouldErr.kind2:2:9]
|
1 | Kek <a: U60> : U60
2 | Kek a = a
| v
| \It's in relevant position!
3 |

View File

@ -0,0 +1,8 @@
Kek <a: U60> : U60
Kek a = a
Main : U60
Main = (Kuk) ~(20)
Kuk : ~(a : U60) -> U60
Kuk = ~x => Kek 3

View File

@ -13,7 +13,7 @@ use walkdir::{Error, WalkDir};
use kind_driver as driver;
fn golden_test(path: &Path, run: fn(&Path) -> String) {
fn golden_test(path: &Path, run: &dyn Fn(&Path) -> String) {
let result = run(path);
let golden_path = path.with_extension("golden");
@ -25,12 +25,36 @@ fn golden_test(path: &Path, run: fn(&Path) -> String) {
}
}
fn test_kind2(path: &Path, run: fn(&Path) -> String) -> Result<(), Error> {
fn test_kind2(path: &Path, run: fn(&PathBuf, &mut Session) -> Option<String>) -> Result<(), Error> {
for entry in WalkDir::new(path).follow_links(true) {
let entry = entry?;
let path = entry.path();
if path.is_file() && path.extension().map(|x| x == "kind2").unwrap_or(false) {
golden_test(path, run);
golden_test(path, &|path| {
let (rx, tx) = std::sync::mpsc::channel();
let root = PathBuf::from("./suite/lib").canonicalize().unwrap();
let mut session = Session::new(root, rx);
let res = run(&PathBuf::from(path), &mut session);
let diagnostics = tx.try_iter().collect::<Vec<Box<dyn Diagnostic>>>();
let render = RenderConfig::ascii(2);
kind_report::check_if_colors_are_supported(true);
match res {
Some(res) if diagnostics.is_empty() => res,
_ => {
let mut res_string = String::new();
for diag in diagnostics {
diag.render(&session, &render, &mut res_string).unwrap();
}
res_string
}
}
});
}
}
Ok(())
@ -39,31 +63,10 @@ fn test_kind2(path: &Path, run: fn(&Path) -> String) -> Result<(), Error> {
#[test]
#[timeout(30000)]
fn test_checker() -> Result<(), Error> {
test_kind2(Path::new("./suite/checker"), |path| {
let (rx, tx) = std::sync::mpsc::channel();
let root = PathBuf::from("./suite/lib").canonicalize().unwrap();
let mut session = Session::new(root, rx);
test_kind2(Path::new("./suite/checker"), |path, session| {
let entrypoints = vec!["Main".to_string()];
let check = driver::type_check_book(&mut session, &PathBuf::from(path), entrypoints, Some(1));
let diagnostics = tx.try_iter().collect::<Vec<Box<dyn Diagnostic>>>();
let render = RenderConfig::ascii(2);
kind_report::check_if_colors_are_supported(true);
match check {
Ok(_) if diagnostics.is_empty() => "Ok!".to_string(),
_ => {
let mut res_string = String::new();
for diag in diagnostics {
diag.render(&mut session, &render, &mut res_string).unwrap();
}
res_string
}
}
let check = driver::type_check_book(session, path, entrypoints, Some(1));
check.map(|_| "Ok!".to_string()).ok()
})?;
Ok(())
}
@ -71,69 +74,35 @@ fn test_checker() -> Result<(), Error> {
#[test]
#[timeout(15000)]
fn test_eval() -> Result<(), Error> {
test_kind2(Path::new("./suite/eval"), |path| {
let (rx, tx) = std::sync::mpsc::channel();
let root = PathBuf::from("./suite/lib").canonicalize().unwrap();
let mut session = Session::new(root, rx);
test_kind2(Path::new("./suite/eval"), |path, session| {
let entrypoints = vec!["Main".to_string()];
let check = driver::erase_book(&mut session, &PathBuf::from(path), entrypoints)
.map(|x| driver::compile_book_to_hvm(x, false));
let check = driver::erase_book(session, path, entrypoints)
.map(|file| driver::compile_book_to_hvm(file, false))
.map(|file| driver::execute_file(&file.to_string(), Some(1)).map_or_else(|e| e, |f| f));
let diagnostics = tx.try_iter().collect::<Vec<_>>();
let render = RenderConfig::ascii(2);
kind_report::check_if_colors_are_supported(true);
match check {
Ok(file) if diagnostics.is_empty() => {
driver::execute_file(&file.to_string(), Some(1)).map_or_else(|e| e, |f| f)
}
_ => {
let mut res_string = String::new();
for diag in diagnostics {
diag.render(&mut session, &render, &mut res_string).unwrap();
}
res_string
}
}
check.ok()
})?;
Ok(())
}
#[test]
#[timeout(15000)]
fn test_kdl() -> Result<(), Error> {
test_kind2(Path::new("./suite/kdl"), |path| {
let (rx, tx) = std::sync::mpsc::channel();
let root = PathBuf::from("./suite/lib").canonicalize().unwrap();
let mut session = Session::new(root, rx);
test_kind2(Path::new("./suite/kdl"), |path, session| {
let entrypoints = vec!["Main".to_string()];
let check = driver::compile_book_to_kdl(&PathBuf::from(path), &mut session, "", entrypoints);
let diagnostics = tx.try_iter().collect::<Vec<_>>();
let render = RenderConfig::ascii(2);
kind_report::check_if_colors_are_supported(true);
match check {
Ok(file) if diagnostics.is_empty() => {
file.to_string()
},
_ => {
let mut res_string = String::new();
for diag in diagnostics {
diag.render(&mut session, &render, &mut res_string).unwrap();
}
res_string
}
}
let check = driver::compile_book_to_kdl(path, session, "", entrypoints);
check.ok().map(|x| x.to_string())
})?;
Ok(())
}
#[test]
#[timeout(15000)]
fn test_erasure() -> Result<(), Error> {
test_kind2(Path::new("./suite/erasure"), |path, session| {
let entrypoints = vec!["Main".to_string()];
let check = driver::erase_book(session, path, entrypoints).map(|file| file.to_string());
check.ok()
})?;
Ok(())
}