mirror of
https://github.com/Kindelia/Kind2.git
synced 2024-07-14 18:40:27 +03:00
feat: transformed into a comment
This commit is contained in:
parent
f1979a2021
commit
5105ebf09c
@ -115,6 +115,10 @@ pub enum Command {
|
||||
#[clap(aliases = &["s"])]
|
||||
Show { file: String },
|
||||
|
||||
/// Gets direct dependencies of a file
|
||||
#[clap(aliases = &["gd"])]
|
||||
GetDeps { file: String },
|
||||
|
||||
/// Compiles a file to Kindelia (.kdl)
|
||||
#[clap(aliases = &["kdl"])]
|
||||
ToKDL {
|
||||
@ -160,11 +164,21 @@ pub fn run_in_session<T>(
|
||||
root: PathBuf,
|
||||
file: String,
|
||||
compiled: bool,
|
||||
silent: bool,
|
||||
action: &mut dyn FnMut(&mut Session) -> anyhow::Result<T>,
|
||||
) -> anyhow::Result<T> {
|
||||
let log =
|
||||
|session: &Session, report: &dyn Report| render_to_stderr(render_config, session, report);
|
||||
driver::run_in_session(render_config, root, file, compiled, action, &log)
|
||||
let sil = |_: &Session, _: &dyn Report| ();
|
||||
|
||||
driver::run_in_session(
|
||||
render_config,
|
||||
root,
|
||||
file,
|
||||
compiled,
|
||||
action,
|
||||
if silent { &sil } else { &log },
|
||||
)
|
||||
}
|
||||
|
||||
pub fn run_cli(config: Cli) -> anyhow::Result<()> {
|
||||
@ -182,7 +196,7 @@ pub fn run_cli(config: Cli) -> anyhow::Result<()> {
|
||||
config.hide_vals,
|
||||
mode,
|
||||
config.hide_deps,
|
||||
config.get_deps
|
||||
config.get_deps,
|
||||
);
|
||||
|
||||
let root = config.root.unwrap_or_else(|| PathBuf::from("."));
|
||||
@ -195,97 +209,172 @@ pub fn run_cli(config: Cli) -> anyhow::Result<()> {
|
||||
|
||||
match config.command {
|
||||
Command::Check { file, coverage } => {
|
||||
run_in_session(&render_config, root, file.clone(), false, &mut |session| {
|
||||
let (_, rewrites) = driver::type_check_book(
|
||||
session,
|
||||
&PathBuf::from(file.clone()),
|
||||
entrypoints.clone(),
|
||||
config.tids,
|
||||
coverage,
|
||||
)?;
|
||||
run_in_session(
|
||||
&render_config,
|
||||
root,
|
||||
file.clone(),
|
||||
false,
|
||||
false,
|
||||
&mut |session| {
|
||||
let (_, rewrites) = driver::type_check_book(
|
||||
session,
|
||||
&PathBuf::from(file.clone()),
|
||||
entrypoints.clone(),
|
||||
config.tids,
|
||||
coverage,
|
||||
)?;
|
||||
|
||||
render_to_stderr(&render_config, session, &Log::Rewrites(rewrites));
|
||||
render_to_stderr(&render_config, session, &Log::Rewrites(rewrites));
|
||||
|
||||
Ok(())
|
||||
})?;
|
||||
Ok(())
|
||||
},
|
||||
)?;
|
||||
}
|
||||
Command::ToHVM { file } => {
|
||||
let result =
|
||||
run_in_session(&render_config, root, file.clone(), true, &mut |session| {
|
||||
let result = run_in_session(
|
||||
&render_config,
|
||||
root,
|
||||
file.clone(),
|
||||
true,
|
||||
false,
|
||||
&mut |session| {
|
||||
let book = driver::erase_book(
|
||||
session,
|
||||
&PathBuf::from(file.clone()),
|
||||
entrypoints.clone(),
|
||||
)?;
|
||||
Ok(driver::compile_book_to_hvm(book, config.trace))
|
||||
})?;
|
||||
},
|
||||
)?;
|
||||
|
||||
println!("{}", result);
|
||||
}
|
||||
Command::Run { file } => {
|
||||
let res = run_in_session(&render_config, root, file.clone(), true, &mut |session| {
|
||||
let path = PathBuf::from(file.clone());
|
||||
let book = driver::erase_book(session, &path, entrypoints.clone())?;
|
||||
driver::check_main_entry(session, &book)?;
|
||||
let book = driver::compile_book_to_hvm(book, config.trace);
|
||||
let (result, rewrites) = driver::execute_file(&book.to_string(), config.tids)?;
|
||||
let res = run_in_session(
|
||||
&render_config,
|
||||
root,
|
||||
file.clone(),
|
||||
true,
|
||||
false,
|
||||
&mut |session| {
|
||||
let path = PathBuf::from(file.clone());
|
||||
let book = driver::erase_book(session, &path, entrypoints.clone())?;
|
||||
driver::check_main_entry(session, &book)?;
|
||||
let book = driver::compile_book_to_hvm(book, config.trace);
|
||||
let (result, rewrites) = driver::execute_file(&book.to_string(), config.tids)?;
|
||||
|
||||
render_to_stderr(&render_config, session, &Log::Rewrites(rewrites));
|
||||
render_to_stderr(&render_config, session, &Log::Rewrites(rewrites));
|
||||
|
||||
Ok(result)
|
||||
})?;
|
||||
Ok(result)
|
||||
},
|
||||
)?;
|
||||
println!("{}", res);
|
||||
}
|
||||
Command::Show { file } => {
|
||||
run_in_session(&render_config, root, file.clone(), true, &mut |session| {
|
||||
driver::to_book(session, &PathBuf::from(file.clone()))
|
||||
})
|
||||
run_in_session(
|
||||
&render_config,
|
||||
root,
|
||||
file.clone(),
|
||||
true,
|
||||
false,
|
||||
&mut |session| driver::to_book(session, &PathBuf::from(file.clone())),
|
||||
)
|
||||
.map(|res| {
|
||||
print!("{}", res);
|
||||
res
|
||||
})?;
|
||||
}
|
||||
Command::ToKindCore { file } => {
|
||||
let res = run_in_session(&render_config, root, file.clone(), true, &mut |session| {
|
||||
driver::desugar_book(session, &PathBuf::from(file.clone()))
|
||||
})?;
|
||||
let res = run_in_session(
|
||||
&render_config,
|
||||
root,
|
||||
file.clone(),
|
||||
true,
|
||||
false,
|
||||
&mut |session| driver::desugar_book(session, &PathBuf::from(file.clone())),
|
||||
)?;
|
||||
print!("{}", res);
|
||||
}
|
||||
Command::Erase { file } => {
|
||||
let res = run_in_session(&render_config, root, file.clone(), true, &mut |session| {
|
||||
driver::erase_book(session, &PathBuf::from(file.clone()), entrypoints.clone())
|
||||
})?;
|
||||
let res = run_in_session(
|
||||
&render_config,
|
||||
root,
|
||||
file.clone(),
|
||||
true,
|
||||
false,
|
||||
&mut |session| {
|
||||
driver::erase_book(session, &PathBuf::from(file.clone()), entrypoints.clone())
|
||||
},
|
||||
)?;
|
||||
print!("{}", res);
|
||||
}
|
||||
Command::GenChecker { file, coverage } => {
|
||||
let res = run_in_session(&render_config, root, file.clone(), true, &mut |session| {
|
||||
driver::check_erasure_book(session, &PathBuf::from(file.clone()))
|
||||
})?;
|
||||
let res = run_in_session(
|
||||
&render_config,
|
||||
root,
|
||||
file.clone(),
|
||||
true,
|
||||
false,
|
||||
&mut |session| driver::check_erasure_book(session, &PathBuf::from(file.clone())),
|
||||
)?;
|
||||
print!("{}", driver::generate_checker(&res, coverage));
|
||||
}
|
||||
Command::Eval { file } => {
|
||||
let res = run_in_session(&render_config, root, file.clone(), true, &mut |session| {
|
||||
let book = driver::desugar_book(session, &PathBuf::from(file.clone()))?;
|
||||
driver::check_main_desugared_entry(session, &book)?;
|
||||
let (res, rewrites) = driver::eval_in_checker(&book);
|
||||
let res = run_in_session(
|
||||
&render_config,
|
||||
root,
|
||||
file.clone(),
|
||||
true,
|
||||
false,
|
||||
&mut |session| {
|
||||
let book = driver::desugar_book(session, &PathBuf::from(file.clone()))?;
|
||||
driver::check_main_desugared_entry(session, &book)?;
|
||||
let (res, rewrites) = driver::eval_in_checker(&book);
|
||||
|
||||
render_to_stderr(&render_config, session, &Log::Rewrites(rewrites));
|
||||
render_to_stderr(&render_config, session, &Log::Rewrites(rewrites));
|
||||
|
||||
Ok(res)
|
||||
})?;
|
||||
Ok(res)
|
||||
},
|
||||
)?;
|
||||
println!("{}", res);
|
||||
}
|
||||
Command::ToKDL { file, namespace } => {
|
||||
let res = run_in_session(&render_config, root, file.clone(), true, &mut |session| {
|
||||
driver::compile_book_to_kdl(
|
||||
&PathBuf::from(file.clone()),
|
||||
session,
|
||||
&namespace.clone().unwrap_or("".to_string()),
|
||||
entrypoints.clone(),
|
||||
)
|
||||
})?;
|
||||
let res = run_in_session(
|
||||
&render_config,
|
||||
root,
|
||||
file.clone(),
|
||||
true,
|
||||
false,
|
||||
&mut |session| {
|
||||
driver::compile_book_to_kdl(
|
||||
&PathBuf::from(file.clone()),
|
||||
session,
|
||||
&namespace.clone().unwrap_or("".to_string()),
|
||||
entrypoints.clone(),
|
||||
)
|
||||
},
|
||||
)?;
|
||||
println!("{}", res);
|
||||
}
|
||||
Command::GetDeps { file } => {
|
||||
let res = run_in_session(
|
||||
&render_config,
|
||||
root,
|
||||
file.clone(),
|
||||
true,
|
||||
true,
|
||||
&mut |session| {
|
||||
Ok(driver::get_unbound_variables(
|
||||
session,
|
||||
&PathBuf::from(file.clone()),
|
||||
))
|
||||
},
|
||||
)?;
|
||||
|
||||
if let Some(res) = res {
|
||||
println!("{}", res.join(" "));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -20,6 +20,8 @@ pub mod diagnostic;
|
||||
pub mod resolution;
|
||||
pub mod session;
|
||||
|
||||
pub use resolution::get_unbound_variables;
|
||||
|
||||
impl FileCache for Session {
|
||||
fn fetch(&self, ctx: SyntaxCtxIndex) -> Option<(PathBuf, &String)> {
|
||||
let path = self.loaded_paths[ctx.0].as_ref().to_owned();
|
||||
|
@ -191,6 +191,21 @@ fn parse_and_store_book_by_identifier(
|
||||
}
|
||||
}
|
||||
|
||||
fn read_file(session: &mut Session, path: &Path) -> Option<String> {
|
||||
match fs::read_to_string(path) {
|
||||
Ok(res) => Some(res),
|
||||
Err(_) => {
|
||||
session
|
||||
.diagnostic_sender
|
||||
.send(Box::new(DriverDiagnostic::CannotFindFile(
|
||||
path.to_str().unwrap().to_string(),
|
||||
)))
|
||||
.unwrap();
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_and_store_book_by_path(session: &mut Session, path: &PathBuf, book: &mut Book, immediate: bool) -> bool {
|
||||
if !path.exists() {
|
||||
let err = Box::new(DriverDiagnostic::CannotFindFile(
|
||||
@ -207,18 +222,7 @@ fn parse_and_store_book_by_path(session: &mut Session, path: &PathBuf, book: &mu
|
||||
return false;
|
||||
}
|
||||
|
||||
let input = match fs::read_to_string(path) {
|
||||
Ok(res) => res,
|
||||
Err(_) => {
|
||||
session
|
||||
.diagnostic_sender
|
||||
.send(Box::new(DriverDiagnostic::CannotFindFile(
|
||||
path.to_str().unwrap().to_string(),
|
||||
)))
|
||||
.unwrap();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
let Some(input) = read_file(session, path) else { return true };
|
||||
|
||||
let ctx_id = session.book_counter;
|
||||
session.add_path(Rc::new(fs::canonicalize(path).unwrap()), input.clone());
|
||||
@ -250,6 +254,23 @@ fn parse_and_store_book_by_path(session: &mut Session, path: &PathBuf, book: &mu
|
||||
failed
|
||||
}
|
||||
|
||||
pub fn get_unbound_variables(session: &mut Session, path: &Path) -> Option<Vec<String>> {
|
||||
let tx = session.diagnostic_sender.clone();
|
||||
|
||||
let Some(input) = read_file(session, path) else { return None };
|
||||
|
||||
let (mut module, _) = kind_parser::parse_book(tx.clone(), 0, &input);
|
||||
|
||||
expand_uses(&mut module, tx.clone());
|
||||
expand_module(tx.clone(), &mut module);
|
||||
|
||||
let mut state = UnboundCollector::new(tx.clone(), false);
|
||||
state.visit_module(&mut module);
|
||||
|
||||
Some(state.unbound_top_level.keys().cloned().collect())
|
||||
}
|
||||
|
||||
|
||||
fn unbound_variable(session: &mut Session, book: &Book, idents: &[Ident]) {
|
||||
let mut similar_names = book
|
||||
.names
|
||||
|
@ -322,20 +322,20 @@ impl Diagnostic for PassDiagnostic {
|
||||
DiagnosticFrame {
|
||||
code: 210,
|
||||
severity: Severity::Error,
|
||||
title: "Incorrect arity.".to_string(),
|
||||
subtitles: vec![],
|
||||
hints: vec![if *expected == 0 {
|
||||
title: if *expected == 0 {
|
||||
format!("This function expects no arguments but got {}", got.len())
|
||||
} else if *hidden == 0 {
|
||||
format!("This function expects {} arguments but got {}", expected, got.len())
|
||||
format!("This function expects exactly {} arguments but got {}", expected, got.len())
|
||||
} else {
|
||||
format!(
|
||||
"This function expects {} arguments or {} (without hidden ones) but got {}.",
|
||||
"This function expects exactly {} arguments or {} (without hidden ones) but got {}.",
|
||||
expected,
|
||||
expected - hidden,
|
||||
got.len()
|
||||
)
|
||||
}],
|
||||
},
|
||||
subtitles: vec![],
|
||||
hints: vec![],
|
||||
positions,
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
ERROR Incorrect arity.
|
||||
ERROR This function expects exactly 1 arguments but got 0
|
||||
|
||||
/--[suite/issues/checker/ArityOnLet.kind2:6:13]
|
||||
|
|
||||
@ -8,5 +8,4 @@
|
||||
| \This function requires a fixed number of arguments
|
||||
7 | 2
|
||||
|
||||
Hint: This function expects 1 arguments but got 0
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user