diff options
author | Griffin Smith <grfn@gws.fyi> | 2021-03-28T17·28-0400 |
---|---|---|
committer | glittershark <grfn@gws.fyi> | 2021-03-28T17·33+0000 |
commit | 8e13b1303a0d152c2f3b68f2421163e94fdf226c (patch) | |
tree | 0cac0fee2cd52f912bb118cff78fdca9d28ac895 /users/glittershark/achilles/src/parser/expr.rs | |
parent | db62866d820cf524b67cebe34033d3928804cf3c (diff) |
feat(achilles): Implement a Unit type r/2356
Add support for a zero-sized Unit type. This requires some special at the codegen level because LLVM (unsurprisingly) only allows Void types in function return position - to make that a little easier to handle there's a new pass that strips any unit-only expressions and pulls unit-only function arguments up to new `let` bindings, so we never have to actually pass around unit values. Change-Id: I0fc18a516821f2d69172c42a6a5d246b23471e38 Reviewed-on: https://cl.tvl.fyi/c/depot/+/2695 Reviewed-by: glittershark <grfn@gws.fyi> Tested-by: BuildkiteCI
Diffstat (limited to 'users/glittershark/achilles/src/parser/expr.rs')
-rw-r--r-- | users/glittershark/achilles/src/parser/expr.rs | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/users/glittershark/achilles/src/parser/expr.rs b/users/glittershark/achilles/src/parser/expr.rs index 99c8018fd00c..8a28d00984c9 100644 --- a/users/glittershark/achilles/src/parser/expr.rs +++ b/users/glittershark/achilles/src/parser/expr.rs @@ -186,7 +186,9 @@ named!(string(&str) -> Literal, preceded!( ) )); -named!(literal(&str) -> Literal, alt!(int | bool_ | string)); +named!(unit(&str) -> Literal, map!(complete!(tag!("()")), |_| Literal::Unit)); + +named!(literal(&str) -> Literal, alt!(int | bool_ | string | unit)); named!(literal_expr(&str) -> Expr, map!(literal, Expr::Literal)); @@ -270,7 +272,6 @@ named!(funcref(&str) -> Expr, alt!( named!(no_arg_call(&str) -> Expr, do_parse!( fun: funcref - >> multispace0 >> complete!(tag!("()")) >> (Expr::Call { fun: Box::new(fun), @@ -432,6 +433,11 @@ pub(crate) mod tests { } #[test] + fn unit() { + assert_eq!(test_parse!(expr, "()"), Expr::Literal(Literal::Unit)); + } + + #[test] fn bools() { assert_eq!( test_parse!(expr, "true"), @@ -516,6 +522,18 @@ pub(crate) mod tests { } #[test] + fn unit_call() { + let res = test_parse!(expr, "f ()"); + assert_eq!( + res, + Expr::Call { + fun: ident_expr("f"), + args: vec![Expr::Literal(Literal::Unit)] + } + ) + } + + #[test] fn call_with_args() { let res = test_parse!(expr, "f x 1"); assert_eq!( |