diff options
Diffstat (limited to 'users/glittershark/achilles/src/parser')
-rw-r--r-- | users/glittershark/achilles/src/parser/expr.rs | 22 | ||||
-rw-r--r-- | users/glittershark/achilles/src/parser/mod.rs | 27 | ||||
-rw-r--r-- | users/glittershark/achilles/src/parser/type_.rs | 2 |
3 files changed, 46 insertions, 5 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!( diff --git a/users/glittershark/achilles/src/parser/mod.rs b/users/glittershark/achilles/src/parser/mod.rs index 652b083fdae5..3e0081bd391d 100644 --- a/users/glittershark/achilles/src/parser/mod.rs +++ b/users/glittershark/achilles/src/parser/mod.rs @@ -1,9 +1,9 @@ use nom::character::complete::{multispace0, multispace1}; use nom::error::{ErrorKind, ParseError}; -use nom::{alt, char, complete, do_parse, many0, named, separated_list0, tag, terminated}; +use nom::{alt, char, complete, do_parse, eof, many0, named, separated_list0, tag, terminated}; #[macro_use] -mod macros; +pub(crate) mod macros; mod expr; mod type_; @@ -136,7 +136,11 @@ named!(pub decl(&str) -> Decl, alt!( extern_decl )); -named!(pub toplevel(&str) -> Vec<Decl>, terminated!(many0!(decl), multispace0)); +named!(pub toplevel(&str) -> Vec<Decl>, do_parse!( + decls: many0!(decl) + >> multispace0 + >> eof!() + >> (decls))); #[cfg(test)] mod tests { @@ -215,4 +219,21 @@ mod tests { }] ) } + + #[test] + fn return_unit() { + assert_eq!( + test_parse!(decl, "fn g _ = ()"), + Decl::Fun { + name: "g".try_into().unwrap(), + body: Fun { + args: vec![Arg { + ident: "_".try_into().unwrap(), + type_: None, + }], + body: Expr::Literal(Literal::Unit), + }, + } + ) + } } diff --git a/users/glittershark/achilles/src/parser/type_.rs b/users/glittershark/achilles/src/parser/type_.rs index 1e6e380bb823..8a1081e2521f 100644 --- a/users/glittershark/achilles/src/parser/type_.rs +++ b/users/glittershark/achilles/src/parser/type_.rs @@ -29,6 +29,7 @@ named!(pub type_(&str) -> Type, alt!( tag!("float") => { |_| Type::Float } | tag!("bool") => { |_| Type::Bool } | tag!("cstring") => { |_| Type::CString } | + tag!("()") => { |_| Type::Unit } | function_type => { |ft| Type::Function(ft) }| ident => { |id| Type::Var(id) } | delimited!( @@ -51,6 +52,7 @@ mod tests { assert_eq!(test_parse!(type_, "float"), Type::Float); assert_eq!(test_parse!(type_, "bool"), Type::Bool); assert_eq!(test_parse!(type_, "cstring"), Type::CString); + assert_eq!(test_parse!(type_, "()"), Type::Unit); } #[test] |