1
1
Fork 0
mirror of https://github.com/azur1s/bobbylisp.git synced 2024-10-16 02:37:40 -05:00

expr and block expr

This commit is contained in:
Natapat Samutpong 2022-02-17 12:32:50 +07:00
parent fce1760198
commit f56965bdb6
3 changed files with 32 additions and 13 deletions

View file

@ -1,2 +1,4 @@
fun foo a b = a + b; fun foo a b = a + b;
fun bar a b = { a + b };
let res = foo(34, 35); let res = foo(34, 35);
let res = { foo(34, 35) };

View file

@ -54,6 +54,8 @@ pub fn lexer() -> impl Parser<char, Vec<(Token, Span)>, Error = Simple<char>> {
let delimiter = choice(( let delimiter = choice((
just('('), just('('),
just(')'), just(')'),
just('{'),
just('}'),
)).map(|c| Token::Delimiter(c)); )).map(|c| Token::Delimiter(c));
let symbol = choice(( let symbol = choice((
@ -101,12 +103,12 @@ pub enum Expr {
Let { Let {
name: String, name: String,
value: Box<Self>, value: Vec<Self>,
}, },
Fun { Fun {
name: String, name: String,
args: Vec<String>, args: Vec<String>,
body: Box<Self>, body: Vec<Self>,
}, },
Call { Call {
name: Box<Self>, name: Box<Self>,
@ -129,7 +131,7 @@ fn expr_parser() -> impl Parser<Token, Expr, Error = Simple<Token>> + Clone {
_ => Err(Simple::expected_input_found(span, Vec::new(), Some(token))), _ => Err(Simple::expected_input_found(span, Vec::new(), Some(token))),
}).labelled("literal"); }).labelled("literal");
let items = expr.clone() let args = expr.clone()
.chain(just(Token::Comma) .chain(just(Token::Comma)
.ignore_then(expr.clone()).repeated()) .ignore_then(expr.clone()).repeated())
.then_ignore(just(Token::Comma).or_not()) .then_ignore(just(Token::Comma).or_not())
@ -145,7 +147,7 @@ fn expr_parser() -> impl Parser<Token, Expr, Error = Simple<Token>> + Clone {
let call = atom let call = atom
.then( .then(
items args
.delimited_by( .delimited_by(
just(Token::Delimiter('(')), just(Token::Delimiter('(')),
just(Token::Delimiter(')'))) just(Token::Delimiter(')')))
@ -195,26 +197,37 @@ fn expr_parser() -> impl Parser<Token, Expr, Error = Simple<Token>> + Clone {
}).labelled("expression"); }).labelled("expression");
let declare = recursive(|decl| { 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) let declare_var = just(Token::Let)
.ignore_then(ident) .ignore_then(ident)
.then_ignore(just(Token::Assign)) .then_ignore(just(Token::Assign))
.then(expr.clone()) .then(
decl_block.clone()
.or(decl.clone().repeated().at_most(1))
)
.then_ignore(just(Token::Semicolon)) .then_ignore(just(Token::Semicolon))
.map(|(name, rhs)| Expr::Let { .map(|(name, value)| Expr::Let {
name, name,
value: Box::new(rhs), value,
}); });
let declare_fun = just(Token::Fun) let declare_fun = just(Token::Fun)
.ignore_then(ident) .ignore_then(ident)
.then(ident.repeated()) .then(ident.repeated())
.then_ignore(just(Token::Assign)) .then_ignore(just(Token::Assign))
.then(expr.clone()) .then(
decl_block.clone()
.or(decl.clone().repeated().at_most(1))
)
.then_ignore(just(Token::Semicolon)) .then_ignore(just(Token::Semicolon))
.map(|((name, args), body)| Expr::Fun { .map(|((name, args), body)| Expr::Fun {
name, name,
args, args,
body: Box::new(body), body,
}); });
declare_var declare_var

View file

@ -20,10 +20,14 @@ fn main() {
let (tokens, lex_error) = lexer().parse_recovery(src.as_str()); let (tokens, lex_error) = lexer().parse_recovery(src.as_str());
let len = src.chars().count(); let len = src.chars().count();
let (ast, parse_error) = parser().parse_recovery(Stream::from_iter(len..len + 1, tokens.clone().unwrap().into_iter())); let (ast, parse_error) = parser().parse_recovery(Stream::from_iter(len..len + 1, tokens.clone().unwrap().into_iter()));
if parse_error.is_empty() { if lex_error.is_empty() {
println!("{:#?}", ast); if parse_error.is_empty() {
println!("{:#?}", ast);
} else {
eprintln!("{:#?}", parse_error);
}
} else { } else {
println!("{:?}", parse_error); eprintln!("{:#?}", lex_error);
} }
}, },
} }