diff options
author | Griffin Smith <root@gws.fyi> | 2021-03-14T02·57-0500 |
---|---|---|
committer | Griffin Smith <root@gws.fyi> | 2021-03-14T03·07-0500 |
commit | 32a5c0ff0fc58aa6721c1e0ad41950bde2d66744 (patch) | |
tree | ef5dcf5234c2a86607ee2f8f30db73bad016e075 /src/commands | |
parent | f8beda81fbe8d04883aee71ff4ea078f897c6de4 (diff) |
Add the start of a hindley-milner typechecker
The beginning of a parse-don't-validate-based hindley-milner typechecker, which returns on success an IR where every AST node trivially knows its own type, and using those types to determine LLVM types in codegen.
Diffstat (limited to 'src/commands')
-rw-r--r-- | src/commands/check.rs | 39 | ||||
-rw-r--r-- | src/commands/eval.rs | 6 | ||||
-rw-r--r-- | src/commands/mod.rs | 2 |
3 files changed, 45 insertions, 2 deletions
diff --git a/src/commands/check.rs b/src/commands/check.rs new file mode 100644 index 000000000000..40de288a282c --- /dev/null +++ b/src/commands/check.rs @@ -0,0 +1,39 @@ +use clap::Clap; +use std::path::PathBuf; + +use crate::ast::Type; +use crate::{parser, tc, Result}; + +/// Typecheck a file or expression +#[derive(Clap)] +pub struct Check { + /// File to check + path: Option<PathBuf>, + + /// Expression to check + #[clap(long, short = 'e')] + expr: Option<String>, +} + +fn run_expr(expr: String) -> Result<Type> { + let (_, parsed) = parser::expr(&expr)?; + let hir_expr = tc::typecheck_expr(parsed)?; + Ok(hir_expr.type_().clone()) +} + +fn run_path(path: PathBuf) -> Result<Type> { + todo!() +} + +impl Check { + pub fn run(self) -> Result<()> { + let type_ = match (self.path, self.expr) { + (None, None) => Err("Must specify either a file or expression to check".into()), + (Some(_), Some(_)) => Err("Cannot specify both a file and expression to check".into()), + (None, Some(expr)) => run_expr(expr), + (Some(path), None) => run_path(path), + }?; + println!("type: {}", type_); + Ok(()) + } +} diff --git a/src/commands/eval.rs b/src/commands/eval.rs index 112bee64625b..61a712c08a8e 100644 --- a/src/commands/eval.rs +++ b/src/commands/eval.rs @@ -3,6 +3,7 @@ use clap::Clap; use crate::codegen; use crate::interpreter; use crate::parser; +use crate::tc; use crate::Result; /// Evaluate an expression and print its result @@ -19,10 +20,11 @@ pub struct Eval { impl Eval { pub fn run(self) -> Result<()> { let (_, parsed) = parser::expr(&self.expr)?; + let hir = tc::typecheck_expr(parsed)?; let result = if self.jit { - codegen::jit_eval::<i64>(&parsed)?.into() + codegen::jit_eval::<i64>(&hir)?.into() } else { - interpreter::eval(&parsed)? + interpreter::eval(&hir)? }; println!("{}", result); Ok(()) diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 9c0038dabfb1..fd0a822708c2 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -1,5 +1,7 @@ +pub mod check; pub mod compile; pub mod eval; +pub use check::Check; pub use compile::Compile; pub use eval::Eval; |