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:
parent
fce1760198
commit
f56965bdb6
|
@ -1,2 +1,4 @@
|
||||||
fun foo a b = a + b;
|
fun foo a b = a + b;
|
||||||
let res = foo(34, 35);
|
fun bar a b = { a + b };
|
||||||
|
let res = foo(34, 35);
|
||||||
|
let res = { foo(34, 35) };
|
|
@ -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
|
||||||
|
|
10
src/main.rs
10
src/main.rs
|
@ -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);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue