From 32a5c0ff0fc58aa6721c1e0ad41950bde2d66744 Mon Sep 17 00:00:00 2001 From: Griffin Smith Date: Sat, 13 Mar 2021 21:57:27 -0500 Subject: 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. --- src/parser/expr.rs | 25 ++++++++++++++++++++++--- src/parser/macros.rs | 1 + src/parser/mod.rs | 5 ++++- 3 files changed, 27 insertions(+), 4 deletions(-) (limited to 'src/parser') diff --git a/src/parser/expr.rs b/src/parser/expr.rs index 2fda3e93fae9..73c873b5b304 100644 --- a/src/parser/expr.rs +++ b/src/parser/expr.rs @@ -156,7 +156,14 @@ where named!(int(&str) -> Literal, map!(flat_map!(digit1, parse_to!(u64)), Literal::Int)); -named!(literal(&str) -> Expr, map!(alt!(int), Expr::Literal)); +named!(bool_(&str) -> Literal, alt!( + tag!("true") => { |_| Literal::Bool(true) } | + tag!("false") => { |_| Literal::Bool(false) } +)); + +named!(literal(&str) -> Literal, alt!(int | bool_)); + +named!(literal_expr(&str) -> Expr, map!(literal, Expr::Literal)); named!(binding(&str) -> Binding, do_parse!( multispace0 @@ -262,7 +269,7 @@ named!(fun_expr(&str) -> Expr, do_parse!( named!(arg(&str) -> Expr, alt!( ident_expr | - literal | + literal_expr | paren_expr )); @@ -280,7 +287,7 @@ named!(simple_expr_unascripted(&str) -> Expr, alt!( let_ | if_ | fun_expr | - literal | + literal_expr | ident_expr )); @@ -399,6 +406,18 @@ pub(crate) mod tests { } } + #[test] + fn bools() { + assert_eq!( + test_parse!(expr, "true"), + Expr::Literal(Literal::Bool(true)) + ); + assert_eq!( + test_parse!(expr, "false"), + Expr::Literal(Literal::Bool(false)) + ); + } + #[test] fn let_complex() { let res = test_parse!(expr, "let x = 1; y = x * 7 in (x + y) * 4"); diff --git a/src/parser/macros.rs b/src/parser/macros.rs index 60db5133dc0f..406e5c0e699e 100644 --- a/src/parser/macros.rs +++ b/src/parser/macros.rs @@ -1,3 +1,4 @@ +#[cfg(test)] #[macro_use] macro_rules! test_parse { ($parser: ident, $src: expr) => {{ diff --git a/src/parser/mod.rs b/src/parser/mod.rs index af7dff6ff213..0251d02df464 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -14,7 +14,10 @@ pub use type_::type_; pub type Error = nom::Err>; pub(crate) fn is_reserved(s: &str) -> bool { - matches!(s, "if" | "then" | "else" | "let" | "in" | "fn") + matches!( + s, + "if" | "then" | "else" | "let" | "in" | "fn" | "int" | "float" | "bool" | "true" | "false" + ) } pub(crate) fn ident<'a, E>(i: &'a str) -> nom::IResult<&'a str, Ident, E> -- cgit 1.4.1