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.
This commit is contained in:
Griffin Smith 2021-03-13 21:57:27 -05:00
parent f8beda81fb
commit 32a5c0ff0f
20 changed files with 980 additions and 78 deletions

View file

@ -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");