From 83165376bc6bd1f18062eca126aa7197e9d19aee Mon Sep 17 00:00:00 2001 From: felipegchi Date: Wed, 30 Nov 2022 12:12:01 -0300 Subject: [PATCH] style: changed code style --- crates/kind-checker/src/lib.rs | 9 +- crates/kind-cli/src/lib.rs | 271 ---------------------- crates/kind-cli/src/main.rs | 267 ++++++++++++++++++++- crates/kind-derive/src/subst.rs | 1 + crates/kind-driver/src/lib.rs | 45 ++-- crates/kind-driver/src/resolution.rs | 6 +- crates/kind-pass/src/desugar/mod.rs | 6 +- crates/kind-pass/src/desugar/top_level.rs | 1 + crates/kind-pass/src/erasure/mod.rs | 8 +- crates/kind-pass/src/unbound/mod.rs | 1 + crates/kind-target-kdl/src/compile.rs | 6 +- crates/kind-target-kdl/src/lib.rs | 4 +- crates/kind-tests/benches/pure.rs | 37 +-- crates/kind-tests/tests/mod.rs | 10 +- crates/kind-tree/src/concrete/expr.rs | 17 +- crates/kind-tree/src/concrete/pat.rs | 3 + crates/kind-tree/src/concrete/visitor.rs | 1 + 17 files changed, 328 insertions(+), 365 deletions(-) delete mode 100644 crates/kind-cli/src/lib.rs diff --git a/crates/kind-checker/src/lib.rs b/crates/kind-checker/src/lib.rs index aec57cc6..38d80b5a 100644 --- a/crates/kind-checker/src/lib.rs +++ b/crates/kind-checker/src/lib.rs @@ -17,13 +17,15 @@ use report::parse_report; pub const CHECKER: &str = include_str!("checker.hvm"); -pub fn eval(file: &str, term: &str, dbug: bool) -> Result, String> { +pub fn eval(file: &str, term: &str, dbug: bool, tids: Option) -> Result, String> { let file = language::syntax::read_file(&format!("{}\nHVM_MAIN_CALL = {}", file, term))?; let book = language::rulebook::gen_rulebook(&file); let mut prog = runtime::Program::new(); prog.add_book(&book); let size = runtime::default_heap_size(); - let tids = runtime::default_heap_tids(); + + let tids = tids.unwrap_or_else(runtime::default_heap_tids); + let heap = runtime::new_heap(size, tids); let tids = runtime::new_tids(tids); runtime::link( @@ -53,10 +55,11 @@ pub fn type_check( book: &Book, tx: Sender>, functions_to_check: Vec, + tids: Option ) -> bool { let file = gen_checker(book, functions_to_check); - match eval(&file, "Main", false) { + match eval(&file, "Main", false, tids) { Ok(term) => { let errs = parse_report(&term).unwrap_or_else(|_| { panic!( diff --git a/crates/kind-cli/src/lib.rs b/crates/kind-cli/src/lib.rs deleted file mode 100644 index 9508a51b..00000000 --- a/crates/kind-cli/src/lib.rs +++ /dev/null @@ -1,271 +0,0 @@ -use std::path::PathBuf; -use std::time::Instant; -use std::{fmt, io}; - -use clap::{Parser, Subcommand}; -use kind_driver::session::Session; -use kind_report::data::{Diagnostic, Log}; -use kind_report::report::{FileCache, Report}; -use kind_report::RenderConfig; - -use kind_driver as driver; - -#[derive(Parser, Debug)] -#[command(author, version, about, long_about = None)] -#[clap(propagate_version = true)] -pub struct Cli { - /// Configuration file to change information about - /// pretty printing or project root. - #[arg(short, long, value_name = "FILE")] - pub config: Option, - - /// Turn on the debugging information generated - /// by the compiler. - #[arg(short, long)] - pub debug: bool, - - /// Show warning messages - #[arg(short, long)] - pub warning: bool, - - /// Disable colors in error messages - #[arg(short, long)] - pub no_color: bool, - - /// Prints all of the functions and their evaluation - #[arg(short, long)] - pub trace: bool, - - /// Only ascii characters in error messages - #[arg(short, long)] - pub ascii: bool, - - #[arg(short, long)] - entrypoint: Option, - - #[arg(short, long, value_name = "FILE")] - pub root: Option, - - #[command(subcommand)] - pub command: Command, -} - -#[derive(Subcommand, Debug)] -pub enum Command { - /// Check a file - #[clap(aliases = &["c"])] - Check { file: String }, - - /// Evaluates Main on Kind2 - #[clap(aliases = &["er"])] - Eval { file: String }, - - #[clap(aliases = &["k"])] - ToKindCore { file: String }, - - #[clap(aliases = &["e"])] - Erase { file: String }, - - /// Runs Main on the HVM - #[clap(aliases = &["r"])] - Run { file: String }, - - /// Generates a checker (.hvm) for a file - #[clap(aliases = &["gc"])] - GenChecker { file: String }, - - /// Stringifies a file - #[clap(aliases = &["s"])] - Show { file: String }, - - /// Compiles a file to Kindelia (.kdl) - #[clap(aliases = &["kdl"])] - ToKDL { - file: String, - /// If given, a namespace that goes before each compiled name. Can be at most 10 charaters long. - #[clap(long, aliases = &["ns"])] - namespace: Option, - }, - - /// Compiles a file to HVM (.hvm) - #[clap(aliases = &["hvm"])] - ToHVM { file: String }, -} - -/// Helper structure to use stderr as fmt::Write -struct ToWriteFmt(pub T); - -impl fmt::Write for ToWriteFmt -where - T: io::Write, -{ - fn write_str(&mut self, s: &str) -> fmt::Result { - self.0.write_all(s.as_bytes()).map_err(|_| fmt::Error) - } -} - -pub fn render_to_stderr(render_config: &RenderConfig, session: &T, err: &E) -where - T: FileCache, - E: Report, -{ - Report::render( - err, - session, - render_config, - &mut ToWriteFmt(std::io::stderr()), - ) - .unwrap(); -} - -pub fn compile_in_session( - render_config: RenderConfig, - root: PathBuf, - file: String, - compiled: bool, - fun: &mut dyn FnMut(&mut Session) -> Option, -) -> Option { - let (rx, tx) = std::sync::mpsc::channel(); - - let mut session = Session::new(root, rx); - - eprintln!(); - - render_to_stderr( - &render_config, - &session, - &Log::Checking(format!("the file '{}'", file)), - ); - - let start = Instant::now(); - - let res = fun(&mut session); - - let diagnostics = tx.try_iter().collect::>>(); - - if diagnostics.is_empty() && res.is_some() { - render_to_stderr( - &render_config, - &session, - &if compiled { - Log::Compiled(start.elapsed()) - } else { - Log::Checked(start.elapsed()) - }, - ); - eprintln!(); - res - } else { - render_to_stderr(&render_config, &session, &Log::Failed(start.elapsed())); - eprintln!(); - for diagnostic in diagnostics { - render_to_stderr(&render_config, &session, &diagnostic) - } - None - } -} - -pub fn run_cli(config: Cli) { - kind_report::check_if_colors_are_supported(config.no_color); - - let render_config = kind_report::check_if_utf8_is_supported(config.ascii, 2); - let root = config.root.unwrap_or_else(|| PathBuf::from(".")); - - let mut entrypoints = vec!["Main".to_string()]; - - if let Some(res) = &config.entrypoint { - entrypoints.push(res.clone()) - } - - match config.command { - Command::Check { file } => { - compile_in_session(render_config, root, file.clone(), false, &mut |session| { - driver::type_check_book(session, &PathBuf::from(file.clone()), entrypoints.clone()) - }); - } - Command::ToHVM { file } => { - compile_in_session(render_config, root, file.clone(), true, &mut |session| { - let book = - driver::erase_book(session, &PathBuf::from(file.clone()), entrypoints.clone())?; - Some(driver::compile_book_to_hvm(book, config.trace)) - }) - .map(|res| { - println!("{}", res); - res - }); - } - Command::Run { file } => { - let res = compile_in_session(render_config, root, file.clone(), true, &mut |session| { - let book = - driver::erase_book(session, &PathBuf::from(file.clone()), entrypoints.clone())?; - driver::check_main_entry(session, &book)?; - Some(driver::compile_book_to_hvm(book, config.trace)) - }); - - if let Some(res) = res { - match driver::execute_file(&res.to_string()) { - Ok(res) => println!("{}", res), - Err(err) => println!("{}", err), - } - } - } - Command::Show { file } => { - compile_in_session(render_config, root, file.clone(), true, &mut |session| { - driver::to_book(session, &PathBuf::from(file.clone())) - }) - .map(|res| { - print!("{}", res); - res - }); - } - Command::ToKindCore { file } => { - compile_in_session(render_config, root, file.clone(), true, &mut |session| { - driver::desugar_book(session, &PathBuf::from(file.clone())) - }) - .map(|res| { - print!("{}", res); - res - }); - } - Command::Erase { file } => { - compile_in_session(render_config, root, file.clone(), true, &mut |session| { - driver::erase_book(session, &PathBuf::from(file.clone()), entrypoints.clone()) - }) - .map(|res| { - print!("{}", res); - res - }); - } - Command::GenChecker { file } => { - compile_in_session(render_config, root, file.clone(), true, &mut |session| { - driver::check_erasure_book(session, &PathBuf::from(file.clone())) - }) - .map(|res| { - print!("{}", driver::generate_checker(&res)); - res - }); - } - Command::Eval { file } => { - compile_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)?; - Some(book) - }) - .map(|res| println!("{}", driver::eval_in_checker(&res))); - } - Command::ToKDL { file, namespace } => { - compile_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(), - ) - }) - .map(|res| { - println!("{}", res); - res - }); - } - } -} diff --git a/crates/kind-cli/src/main.rs b/crates/kind-cli/src/main.rs index 0ca31a19..1a01a809 100644 --- a/crates/kind-cli/src/main.rs +++ b/crates/kind-cli/src/main.rs @@ -1,6 +1,267 @@ -use clap::Parser; -use kind_cli::{run_cli, Cli}; +use std::path::PathBuf; +use std::time::Instant; +use std::{fmt, io}; -pub fn main() { +use clap::{Parser, Subcommand}; +use kind_driver::session::Session; +use kind_report::data::{Diagnostic, Log}; +use kind_report::report::{FileCache, Report}; +use kind_report::RenderConfig; + +use kind_driver as driver; + +#[derive(Parser, Debug)] +#[command(author, version, about, long_about = None)] +#[clap(propagate_version = true)] +pub struct Cli { + /// Configuration file to change information about + /// pretty printing or project root. + #[arg(short, long, value_name = "FILE")] + pub config: Option, + + /// Turn on the debugging information generated + /// by the compiler. + #[arg(short, long)] + pub debug: bool, + + /// Show warning messages + #[arg(short, long)] + pub warning: bool, + + /// Disable colors in error messages + #[arg(short, long)] + pub no_color: bool, + + /// How much concurrency in HVM + #[arg(short, long)] + pub tids: Option, + + /// Prints all of the functions and their evaluation + #[arg(short, long)] + pub trace: bool, + + /// Only ascii characters in error messages + #[arg(short, long)] + pub ascii: bool, + + /// Entrypoint of the file that makes the erasure checker + /// not remove the entry. + #[arg(short, long)] + entrypoint: Option, + + #[arg(short, long, value_name = "FILE")] + pub root: Option, + + #[command(subcommand)] + pub command: Command, +} + +#[derive(Subcommand, Debug)] +pub enum Command { + /// Check a file + #[clap(aliases = &["c"])] + Check { file: String }, + + /// Evaluates Main on Kind2 + #[clap(aliases = &["er"])] + Eval { file: String }, + + #[clap(aliases = &["k"])] + ToKindCore { file: String }, + + #[clap(aliases = &["e"])] + Erase { file: String }, + + /// Runs Main on the HVM + #[clap(aliases = &["r"])] + Run { file: String }, + + /// Generates a checker (.hvm) for a file + #[clap(aliases = &["gc"])] + GenChecker { file: String }, + + /// Stringifies a file + #[clap(aliases = &["s"])] + Show { file: String }, + + /// Compiles a file to Kindelia (.kdl) + #[clap(aliases = &["kdl"])] + ToKDL { + file: String, + /// If given, a namespace that goes before each compiled name. Can be at most 10 charaters long. + #[clap(long, aliases = &["ns"])] + namespace: Option, + }, + + /// Compiles a file to HVM (.hvm) + #[clap(aliases = &["hvm"])] + ToHVM { file: String }, +} + +/// Helper structure to use stderr as fmt::Write +struct ToWriteFmt(pub T); + +impl fmt::Write for ToWriteFmt +where + T: io::Write, +{ + fn write_str(&mut self, s: &str) -> fmt::Result { + self.0.write_all(s.as_bytes()).map_err(|_| fmt::Error) + } +} + +pub fn render_to_stderr(render_config: &RenderConfig, session: &T, err: &E) +where + T: FileCache, + E: Report, +{ + Report::render( + err, + session, + render_config, + &mut ToWriteFmt(std::io::stderr()), + ) + .unwrap(); +} + +pub fn compile_in_session( + render_config: RenderConfig, + root: PathBuf, + file: String, + compiled: bool, + fun: &mut dyn FnMut(&mut Session) -> Result, +) -> Result { + let (rx, tx) = std::sync::mpsc::channel(); + + let mut session = Session::new(root, rx); + + eprintln!(); + + render_to_stderr( + &render_config, + &session, + &Log::Checking(format!("the file '{}'", file)), + ); + + let start = Instant::now(); + + let res = fun(&mut session); + + let diagnostics = tx.try_iter().collect::>>(); + + if diagnostics.is_empty() && res.is_ok() { + render_to_stderr( + &render_config, + &session, + &if compiled { + Log::Compiled(start.elapsed()) + } else { + Log::Checked(start.elapsed()) + }, + ); + eprintln!(); + Ok(res.unwrap()) + } else { + render_to_stderr(&render_config, &session, &Log::Failed(start.elapsed())); + eprintln!(); + for diagnostic in diagnostics { + render_to_stderr(&render_config, &session, &diagnostic) + } + Err(()) + } +} + +pub fn run_cli(config: Cli) -> Result<(), ()> { + kind_report::check_if_colors_are_supported(config.no_color); + + let render_config = kind_report::check_if_utf8_is_supported(config.ascii, 2); + let root = config.root.unwrap_or_else(|| PathBuf::from(".")); + + let mut entrypoints = vec!["Main".to_string()]; + + if let Some(res) = &config.entrypoint { + entrypoints.push(res.clone()) + } + + match config.command { + Command::Check { file } => { + compile_in_session(render_config, root, file.clone(), false, &mut |session| { + driver::type_check_book(session, &PathBuf::from(file.clone()), entrypoints.clone(), config.tids) + })?; + } + Command::ToHVM { file } => { + let result = compile_in_session(render_config, root, file.clone(), true, &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 = compile_in_session(render_config, root, file.clone(), true, &mut |session| { + let book = + driver::erase_book(session, &PathBuf::from(file.clone()), entrypoints.clone())?; + driver::check_main_entry(session, &book)?; + Ok(driver::compile_book_to_hvm(book, config.trace)) + })?; + + match driver::execute_file(&res.to_string(), config.tids) { + Ok(res) => println!("{}", res), + Err(err) => println!("{}", err), + } + } + Command::Show { file } => { + compile_in_session(render_config, root, file.clone(), true, &mut |session| { + driver::to_book(session, &PathBuf::from(file.clone())) + }) + .map(|res| { + print!("{}", res); + res + })?; + } + Command::ToKindCore { file } => { + let res = compile_in_session(render_config, root, file.clone(), true, &mut |session| { + driver::desugar_book(session, &PathBuf::from(file.clone())) + })?; + print!("{}", res); + } + Command::Erase { file } => { + let res = compile_in_session(render_config, root, file.clone(), true, &mut |session| { + driver::erase_book(session, &PathBuf::from(file.clone()), entrypoints.clone()) + })?; + print!("{}", res); + } + Command::GenChecker { file } => { + let res = compile_in_session(render_config, root, file.clone(), true, &mut |session| { + driver::check_erasure_book(session, &PathBuf::from(file.clone())) + })?; + print!("{}", driver::generate_checker(&res)); + } + Command::Eval { file } => { + let res = compile_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)?; + Ok(book) + })?; + println!("{}", driver::eval_in_checker(&res)); + } + Command::ToKDL { file, namespace } => { + let res = compile_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(), + ) + })?; + println!("{}", res); + } + } + + Ok(()) +} + +pub fn main() -> Result<(), ()> { run_cli(Cli::parse()) } diff --git a/crates/kind-derive/src/subst.rs b/crates/kind-derive/src/subst.rs index 62093be4..de1f2d35 100644 --- a/crates/kind-derive/src/subst.rs +++ b/crates/kind-derive/src/subst.rs @@ -79,6 +79,7 @@ impl<'a> Visitor for Subst<'a> { PatKind::Var(ident) => self.visit_pat_ident(ident), PatKind::Str(_) => (), PatKind::Num(_) => (), + PatKind::Char(_) => (), PatKind::Hole => (), PatKind::List(ls) => { for pat in ls { diff --git a/crates/kind-driver/src/lib.rs b/crates/kind-driver/src/lib.rs index 1f2fbb37..9179c4d1 100644 --- a/crates/kind-driver/src/lib.rs +++ b/crates/kind-driver/src/lib.rs @@ -25,16 +25,17 @@ pub fn type_check_book( session: &mut Session, path: &PathBuf, entrypoints: Vec, -) -> Option { + tids: Option +) -> Result { let concrete_book = to_book(session, path)?; let desugared_book = desugar::desugar_book(session.diagnostic_sender.clone(), &concrete_book)?; let all = desugared_book.entrs.iter().map(|x| x.0).cloned().collect(); - let succeeded = checker::type_check(&desugared_book, session.diagnostic_sender.clone(), all); + let succeeded = checker::type_check(&desugared_book, session.diagnostic_sender.clone(), all, tids); if !succeeded { - return None; + return Err(()); } let mut book = erasure::erase_book( @@ -44,26 +45,26 @@ pub fn type_check_book( )?; inline_book(&mut book); - Some(book) + Ok(book) } -pub fn to_book(session: &mut Session, path: &PathBuf) -> Option { +pub fn to_book(session: &mut Session, path: &PathBuf) -> Result { let mut concrete_book = resolution::parse_and_store_book(session, path)?; let failed = resolution::check_unbound_top_level(session, &mut concrete_book); if failed { - return None; + return Err(()); } - Some(concrete_book) + Ok(concrete_book) } pub fn erase_book( session: &mut Session, path: &PathBuf, entrypoints: Vec, -) -> Option { +) -> Result { let concrete_book = to_book(session, path)?; let desugared_book = desugar::desugar_book(session.diagnostic_sender.clone(), &concrete_book)?; let mut book = erasure::erase_book( @@ -72,19 +73,17 @@ pub fn erase_book( entrypoints, )?; inline_book(&mut book); - Some(book) + Ok(book) } -pub fn desugar_book(session: &mut Session, path: &PathBuf) -> Option { +pub fn desugar_book(session: &mut Session, path: &PathBuf) -> Result { let concrete_book = to_book(session, path)?; desugar::desugar_book(session.diagnostic_sender.clone(), &concrete_book) } -pub fn check_erasure_book(session: &mut Session, path: &PathBuf) -> Option { +pub fn check_erasure_book(session: &mut Session, path: &PathBuf) -> Result { let concrete_book = to_book(session, path)?; - let desugared_book = desugar::desugar_book(session.diagnostic_sender.clone(), &concrete_book)?; - - Some(desugared_book) + desugar::desugar_book(session.diagnostic_sender.clone(), &concrete_book) } pub fn compile_book_to_hvm(book: untyped::Book, trace: bool) -> backend::File { @@ -96,7 +95,7 @@ pub fn compile_book_to_kdl( session: &mut Session, namespace: &str, entrypoints: Vec, -) -> Option { +) -> Result { let concrete_book = to_book(session, path)?; let desugared_book = desugar::desugar_book(session.diagnostic_sender.clone(), &concrete_book)?; let mut book = erasure::erase_book( @@ -110,32 +109,32 @@ pub fn compile_book_to_kdl( kind_target_kdl::compile_book(book, session.diagnostic_sender.clone(), namespace) } -pub fn check_main_entry(session: &mut Session, book: &untyped::Book) -> Option<()> { +pub fn check_main_entry(session: &mut Session, book: &untyped::Book) -> Result<(), ()> { if !book.entrs.contains_key("Main") { session .diagnostic_sender .send(Box::new(DriverError::ThereIsntAMain)) .unwrap(); - None + Err(()) } else { - Some(()) + Ok(()) } } -pub fn check_main_desugared_entry(session: &mut Session, book: &desugared::Book) -> Option<()> { +pub fn check_main_desugared_entry(session: &mut Session, book: &desugared::Book) -> Result<(), ()> { if !book.entrs.contains_key("Main") { session .diagnostic_sender .send(Box::new(DriverError::ThereIsntAMain)) .unwrap(); - None + Err(()) } else { - Some(()) + Ok(()) } } -pub fn execute_file(file: &str) -> Result { - let res = eval(file, "Main", false)?; +pub fn execute_file(file: &str, tids: Option) -> Result { + let res = eval(file, "Main", false, tids)?; Ok(res.to_string()) } diff --git a/crates/kind-driver/src/resolution.rs b/crates/kind-driver/src/resolution.rs index 775d74ea..45a81c00 100644 --- a/crates/kind-driver/src/resolution.rs +++ b/crates/kind-driver/src/resolution.rs @@ -260,12 +260,12 @@ fn unbound_variable(session: &mut Session, book: &Book, idents: &[Ident]) { .unwrap(); } -pub fn parse_and_store_book(session: &mut Session, path: &PathBuf) -> Option { +pub fn parse_and_store_book(session: &mut Session, path: &PathBuf) -> Result { let mut book = Book::default(); if parse_and_store_book_by_path(session, path, &mut book) { - None + Err(()) } else { - Some(book) + Ok(book) } } diff --git a/crates/kind-pass/src/desugar/mod.rs b/crates/kind-pass/src/desugar/mod.rs index dd58f696..e73391d7 100644 --- a/crates/kind-pass/src/desugar/mod.rs +++ b/crates/kind-pass/src/desugar/mod.rs @@ -35,7 +35,7 @@ pub struct DesugarState<'a> { pub fn desugar_book( errors: Sender>, book: &concrete::Book, -) -> Option { +) -> Result { let mut state = DesugarState { errors, old_book: book, @@ -45,9 +45,9 @@ pub fn desugar_book( }; state.desugar_book(book); if state.failed { - None + Err(()) } else { - Some(state.new_book) + Ok(state.new_book) } } diff --git a/crates/kind-pass/src/desugar/top_level.rs b/crates/kind-pass/src/desugar/top_level.rs index e6d528f9..3ff6cc3b 100644 --- a/crates/kind-pass/src/desugar/top_level.rs +++ b/crates/kind-pass/src/desugar/top_level.rs @@ -293,6 +293,7 @@ impl<'a> DesugarState<'a> { } PatKind::Var(ident) => desugared::Expr::var(ident.0.clone()), PatKind::Num(kind_tree::Number::U60(n)) => desugared::Expr::num60(pat.range, *n), + PatKind::Char(n) => desugared::Expr::num60(pat.range, *n as u64), PatKind::Num(kind_tree::Number::U120(n)) => desugared::Expr::num120(pat.range, *n), PatKind::Pair(fst, snd) => self.desugar_pair_pat(pat.range, fst, snd), PatKind::List(ls) => self.desugar_list_pat(pat.range, ls), diff --git a/crates/kind-pass/src/erasure/mod.rs b/crates/kind-pass/src/erasure/mod.rs index 9f5e3e38..86034c61 100644 --- a/crates/kind-pass/src/erasure/mod.rs +++ b/crates/kind-pass/src/erasure/mod.rs @@ -55,7 +55,7 @@ pub fn erase_book( book: &desugared::Book, errs: Sender>, entrypoints: Vec, -) -> Option { +) -> Result { let mut state = ErasureState { errs, book, @@ -100,7 +100,7 @@ impl<'a> ErasureState<'a> { &mut self, book: &'a desugared::Book, named_entrypoints: Vec, - ) -> Option { + ) -> Result { let mut vals = FxHashMap::default(); let mut entrypoints = Vec::new(); @@ -190,9 +190,9 @@ impl<'a> ErasureState<'a> { } if self.failed { - None + Err(()) } else { - Some(new_book) + Ok(new_book) } } diff --git a/crates/kind-pass/src/unbound/mod.rs b/crates/kind-pass/src/unbound/mod.rs index afc5605d..d1113df6 100644 --- a/crates/kind-pass/src/unbound/mod.rs +++ b/crates/kind-pass/src/unbound/mod.rs @@ -335,6 +335,7 @@ impl Visitor for UnboundCollector { match &mut pat.data { PatKind::Var(ident) => self.visit_pat_ident(ident), PatKind::Str(_) => (), + PatKind::Char(_) => (), PatKind::Num(_) => (), PatKind::Hole => (), PatKind::List(ls) => { diff --git a/crates/kind-target-kdl/src/compile.rs b/crates/kind-target-kdl/src/compile.rs index 06a560db..d005912f 100644 --- a/crates/kind-target-kdl/src/compile.rs +++ b/crates/kind-target-kdl/src/compile.rs @@ -97,7 +97,7 @@ pub fn compile_book( book: &untyped::Book, sender: Sender>, namespace: &str, -) -> Option { +) -> Result { let mut ctx = CompileCtx::new(book, sender); for (name, entry) in &book.entrs { @@ -120,10 +120,10 @@ pub fn compile_book( } if ctx.failed { - return None; + return Err(()); } - Some(ctx.file) + Ok(ctx.file) } pub fn compile_rule(ctx: &mut CompileCtx, rule: &untyped::Rule) -> kindelia_lang::ast::Rule { diff --git a/crates/kind-target-kdl/src/lib.rs b/crates/kind-target-kdl/src/lib.rs index 7575c760..6bdaba39 100644 --- a/crates/kind-target-kdl/src/lib.rs +++ b/crates/kind-target-kdl/src/lib.rs @@ -16,7 +16,7 @@ pub fn compile_book( book: untyped::Book, sender: Sender>, namespace: &str, -) -> Option { +) -> Result { // TODO: Remove kdl_states (maybe check if they're ever called?) // TODO: Convert to some sort of Kindelia.Contract let flattened = flatten(book); @@ -26,5 +26,5 @@ pub fn compile_book( println!("{}", file); let file = linearize::linearize_file(file); - Some(file) + Ok(file) } diff --git a/crates/kind-tests/benches/pure.rs b/crates/kind-tests/benches/pure.rs index 96104365..632a2238 100644 --- a/crates/kind-tests/benches/pure.rs +++ b/crates/kind-tests/benches/pure.rs @@ -1,15 +1,13 @@ #![feature(test)] extern crate test; -use std::{fs, path::{PathBuf, Path}}; +use std::{fs, path::{PathBuf}}; use driver::{resolution}; use kind_driver::session::Session; use kind_pass::{expand::{self, uses::expand_uses}, desugar, erasure}; -use kind_tree::concrete; use test::Bencher; -use kind_checker as checker; use kind_driver as driver; fn new_session() -> Session { @@ -20,15 +18,6 @@ fn new_session() -> Session { Session::new(root, rx) } -fn get_book(session: &mut Session, path: &str) -> Result { - let path = PathBuf::from(path); - - match resolution::parse_and_store_book(session, &path) { - Some(res) => Ok(res), - None => Err("Cannot parse".to_string()) - } -} - fn exp_paths() -> Vec<&'static str> { vec![ "./suite/eval/Getters.kind2", @@ -186,27 +175,3 @@ fn bench_exp_pure_to_hvm(b: &mut Bencher) { }).fold(0, |n, _| n + 1) }) } - - -#[bench] -fn bench_exp_pure_check_without_the_checker(b: &mut Bencher) { - let mut paths = exp_paths(); - - let books: Vec<_> = paths.iter().map(|x| { - let mut session = new_session(); - let mut book = resolution::parse_and_store_book(&mut session, &PathBuf::from(x)).unwrap(); - let failed = resolution::check_unbound_top_level(&mut session, &mut book); - let book = desugar::desugar_book(session.diagnostic_sender.clone(), &book).unwrap(); - assert!(!failed); - - (session, book) - }).collect(); - - b.iter(move || { - books.iter().map(move |(session, book)| { - let all = book.entrs.iter().map(|x| x.0).cloned().collect(); - let succeeded = checker::type_check(book, session.diagnostic_sender.clone(), all); - assert!(succeeded) - }).fold(0, |n, _| n + 1) - }) -} \ No newline at end of file diff --git a/crates/kind-tests/tests/mod.rs b/crates/kind-tests/tests/mod.rs index 6867e0e1..2a7b9faf 100644 --- a/crates/kind-tests/tests/mod.rs +++ b/crates/kind-tests/tests/mod.rs @@ -45,7 +45,7 @@ fn test_checker() -> Result<(), Error> { let mut session = Session::new(root, rx); let entrypoints = vec!["Main".to_string()]; - let check = driver::type_check_book(&mut session, &PathBuf::from(path), entrypoints); + let check = driver::type_check_book(&mut session, &PathBuf::from(path), entrypoints, Some(1)); let diagnostics = tx.try_iter().collect::>>(); let render = RenderConfig::ascii(2); @@ -53,7 +53,7 @@ fn test_checker() -> Result<(), Error> { kind_report::check_if_colors_are_supported(true); match check { - Some(_) if diagnostics.is_empty() => "Ok!".to_string(), + Ok(_) if diagnostics.is_empty() => "Ok!".to_string(), _ => { let mut res_string = String::new(); @@ -86,8 +86,8 @@ fn test_eval() -> Result<(), Error> { kind_report::check_if_colors_are_supported(true); match check { - Some(file) if diagnostics.is_empty() => { - driver::execute_file(&file.to_string()).map_or_else(|e| e, |f| f) + 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(); @@ -121,7 +121,7 @@ fn test_kdl() -> Result<(), Error> { kind_report::check_if_colors_are_supported(true); match check { - Some(file) if diagnostics.is_empty() => { + Ok(file) if diagnostics.is_empty() => { file.to_string() }, _ => { diff --git a/crates/kind-tree/src/concrete/expr.rs b/crates/kind-tree/src/concrete/expr.rs index 53c5eef2..2362b877 100644 --- a/crates/kind-tree/src/concrete/expr.rs +++ b/crates/kind-tree/src/concrete/expr.rs @@ -1,16 +1,15 @@ //! This module describes a abstract syntax tree //! that is almost like a concrete tree. It helps when it -//! we have to statically analyse the tree with better -//! error messages. +//! we have to statically analyse the tree in order to generate +//! better error messages. use super::pat::PatIdent; use crate::symbol::{Ident, QualifiedIdent}; use crate::Operator; + use kind_span::{Locatable, Range}; use std::fmt::{Display, Error, Formatter}; -pub struct ConsIdent(pub Ident); - /// A binding express the positional or named argument of /// a constructor or function. #[derive(Clone, Debug, Hash, PartialEq, Eq)] @@ -22,6 +21,7 @@ pub enum Binding { /// Vector of bindings pub type Spine = Vec; +/// A binding that is used inside applications. #[derive(Clone, Debug, Hash, PartialEq, Eq)] pub struct AppBinding { pub data: Box, @@ -45,11 +45,10 @@ pub enum CaseBinding { Renamed(Ident, Ident), } -/// A match case with a constructor that will matches the -/// strutinizer, bindings to the names of each of arguments -/// of the telescope of the constructor and a right-hand side -/// value. The ignore_rest flag useful to just fill all of the -/// case bindings that are not used with a default name. +/// A match case with a constructor that will match the +/// strutinizer, bindings to the names of each arguments and +/// a right-hand side value. The ignore_rest flag useful to just +/// fill all of the case bindings that are not used with a default name. #[derive(Clone, Debug, Hash, PartialEq, Eq)] pub struct Case { pub constructor: Ident, diff --git a/crates/kind-tree/src/concrete/pat.rs b/crates/kind-tree/src/concrete/pat.rs index 4b12644d..750c0a67 100644 --- a/crates/kind-tree/src/concrete/pat.rs +++ b/crates/kind-tree/src/concrete/pat.rs @@ -27,6 +27,8 @@ pub enum PatKind { List(Vec), /// Str Str(String), + /// + Char(char), /// Wildcard Hole, } @@ -58,6 +60,7 @@ impl Display for Pat { .join(" ") ), Str(str) => write!(f, "\"{}\"", str), + Char(chr) => write!(f, "\'{}\'", chr), Num(crate::Number::U60(num)) => write!(f, "{}", num), Num(crate::Number::U120(num)) => write!(f, "{}u120", num), Pair(fst, snd) => write!(f, "({}, {})", fst, snd), diff --git a/crates/kind-tree/src/concrete/visitor.rs b/crates/kind-tree/src/concrete/visitor.rs index 5fddc18f..29947e81 100644 --- a/crates/kind-tree/src/concrete/visitor.rs +++ b/crates/kind-tree/src/concrete/visitor.rs @@ -280,6 +280,7 @@ pub fn walk_pat(ctx: &mut T, pat: &mut Pat) { match &mut pat.data { PatKind::Var(ident) => ctx.visit_pat_ident(ident), PatKind::Str(_) => (), + PatKind::Char(_) => (), PatKind::Num(_) => (), PatKind::Hole => (), PatKind::List(ls) => {