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/parser | |
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/parser')
-rw-r--r-- | src/parser/expr.rs | 25 | ||||
-rw-r--r-- | src/parser/macros.rs | 1 | ||||
-rw-r--r-- | src/parser/mod.rs | 5 |
3 files changed, 27 insertions, 4 deletions
diff --git a/src/parser/expr.rs b/src/parser/expr.rs index 2fda3e93fa..73c873b5b3 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 )); @@ -400,6 +407,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"); assert_eq!( diff --git a/src/parser/macros.rs b/src/parser/macros.rs index 60db5133dc..406e5c0e69 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 af7dff6ff2..0251d02df4 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -14,7 +14,10 @@ pub use type_::type_; pub type Error = nom::Err<nom::error::Error<String>>; 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> |