From f56965bdb60930b019fda48713ea717f44c2b7ed Mon Sep 17 00:00:00 2001 From: Natapat Samutpong Date: Thu, 17 Feb 2022 12:32:50 +0700 Subject: [PATCH] expr and block expr --- example/ex.hyc | 4 +++- src/front/parse.rs | 31 ++++++++++++++++++++++--------- src/main.rs | 10 +++++++--- 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/example/ex.hyc b/example/ex.hyc index 80ba9bb..b1d878f 100644 --- a/example/ex.hyc +++ b/example/ex.hyc @@ -1,2 +1,4 @@ fun foo a b = a + b; -let res = foo(34, 35); \ No newline at end of file +fun bar a b = { a + b }; +let res = foo(34, 35); +let res = { foo(34, 35) }; \ No newline at end of file diff --git a/src/front/parse.rs b/src/front/parse.rs index 7330752..fae79b2 100644 --- a/src/front/parse.rs +++ b/src/front/parse.rs @@ -54,6 +54,8 @@ pub fn lexer() -> impl Parser, Error = Simple> { let delimiter = choice(( just('('), just(')'), + just('{'), + just('}'), )).map(|c| Token::Delimiter(c)); let symbol = choice(( @@ -101,12 +103,12 @@ pub enum Expr { Let { name: String, - value: Box, + value: Vec, }, Fun { name: String, args: Vec, - body: Box, + body: Vec, }, Call { name: Box, @@ -129,7 +131,7 @@ fn expr_parser() -> impl Parser> + Clone { _ => Err(Simple::expected_input_found(span, Vec::new(), Some(token))), }).labelled("literal"); - let items = expr.clone() + let args = expr.clone() .chain(just(Token::Comma) .ignore_then(expr.clone()).repeated()) .then_ignore(just(Token::Comma).or_not()) @@ -145,7 +147,7 @@ fn expr_parser() -> impl Parser> + Clone { let call = atom .then( - items + args .delimited_by( just(Token::Delimiter('(')), just(Token::Delimiter(')'))) @@ -195,26 +197,37 @@ fn expr_parser() -> impl Parser> + Clone { }).labelled("expression"); let declare = recursive(|decl| { + let decl_block = decl.clone() + .or(expr.clone()) + .repeated() + .delimited_by(just(Token::Delimiter('{')), just(Token::Delimiter('}'))); + let declare_var = just(Token::Let) .ignore_then(ident) .then_ignore(just(Token::Assign)) - .then(expr.clone()) + .then( + decl_block.clone() + .or(decl.clone().repeated().at_most(1)) + ) .then_ignore(just(Token::Semicolon)) - .map(|(name, rhs)| Expr::Let { + .map(|(name, value)| Expr::Let { name, - value: Box::new(rhs), + value, }); let declare_fun = just(Token::Fun) .ignore_then(ident) .then(ident.repeated()) .then_ignore(just(Token::Assign)) - .then(expr.clone()) + .then( + decl_block.clone() + .or(decl.clone().repeated().at_most(1)) + ) .then_ignore(just(Token::Semicolon)) .map(|((name, args), body)| Expr::Fun { name, args, - body: Box::new(body), + body, }); declare_var diff --git a/src/main.rs b/src/main.rs index b714f95..d96d138 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,10 +20,14 @@ fn main() { let (tokens, lex_error) = lexer().parse_recovery(src.as_str()); let len = src.chars().count(); let (ast, parse_error) = parser().parse_recovery(Stream::from_iter(len..len + 1, tokens.clone().unwrap().into_iter())); - if parse_error.is_empty() { - println!("{:#?}", ast); + if lex_error.is_empty() { + if parse_error.is_empty() { + println!("{:#?}", ast); + } else { + eprintln!("{:#?}", parse_error); + } } else { - println!("{:?}", parse_error); + eprintln!("{:#?}", lex_error); } }, }