Parse function calls
This commit is contained in:
parent
1d7007ab9a
commit
0a795f1450
50
src/parse.rs
50
src/parse.rs
|
@ -245,7 +245,7 @@ pub enum Expr<'a> {
|
|||
Local(&'a str),
|
||||
Member(&'a str),
|
||||
Group(Box<Expr<'a>>),
|
||||
FuncCall(&'a str, Vec<Expr<'a>>),
|
||||
FnCall(&'a str, Vec<Expr<'a>>),
|
||||
If {
|
||||
test_expr: Box<Expr<'a>>,
|
||||
then_body: BranchBody<'a>,
|
||||
|
@ -255,8 +255,21 @@ pub enum Expr<'a> {
|
|||
|
||||
impl<'a> Expr<'a> {
|
||||
pub fn build_start(tok: Token, lexer: &mut Lexer<'a>) -> (Option<Self>, Token) {
|
||||
let mut next = None;
|
||||
|
||||
let lhs = match tok {
|
||||
Token::Identifier => Self::Local(lexer.slice()),
|
||||
Token::Identifier => {
|
||||
let local = lexer.slice();
|
||||
let tok = lexer.next().unwrap();
|
||||
next = Some(tok);
|
||||
match tok {
|
||||
Token::ParanOpen => {
|
||||
next = None;
|
||||
Self::FnCall(local, Self::eat_args(lexer))
|
||||
}
|
||||
_ => Self::Local(local),
|
||||
}
|
||||
}
|
||||
Token::Dot => Self::Member(lexer.eat_expect_id()),
|
||||
Token::ParanOpen => {
|
||||
let (inner, next) = Self::build(lexer);
|
||||
|
@ -273,9 +286,13 @@ impl<'a> Expr<'a> {
|
|||
_ => lexer.panic_message("Unexpected token"),
|
||||
};
|
||||
|
||||
let (rhs, next) = Self::eat_op(lexer);
|
||||
if let Some((op, rhs)) = rhs {
|
||||
(Some(Self::BinaryOp(op, Box::new((lhs, rhs)))), next)
|
||||
let next = next.unwrap_or_else(|| lexer.next().unwrap());
|
||||
|
||||
if let Some(op) = BinaryOp::from_token(next) {
|
||||
match Self::build(lexer) {
|
||||
(Some(rhs), tail) => (Some(Self::BinaryOp(op, Box::new((lhs, rhs)))), tail),
|
||||
_ => lexer.panic_message("Expected right-hand expression"),
|
||||
}
|
||||
} else {
|
||||
(Some(lhs), next)
|
||||
}
|
||||
|
@ -285,16 +302,22 @@ impl<'a> Expr<'a> {
|
|||
Self::build_start(lexer.next().unwrap(), lexer)
|
||||
}
|
||||
|
||||
fn eat_op(lexer: &mut Lexer<'a>) -> (Option<(BinaryOp, Self)>, Token) {
|
||||
let tok = lexer.next().unwrap();
|
||||
if let Some(op) = BinaryOp::from_token(tok) {
|
||||
pub fn eat_args(lexer: &mut Lexer<'a>) -> Vec<Self> {
|
||||
let mut args = Vec::new();
|
||||
|
||||
loop {
|
||||
match Self::build(lexer) {
|
||||
(Some(rhs), tail) => (Some((op, rhs)), tail),
|
||||
_ => lexer.panic_message("Expected right-hand expression"),
|
||||
(Some(arg), Token::Comma) => args.push(arg),
|
||||
(Some(arg), Token::ParanClose) => {
|
||||
args.push(arg);
|
||||
break;
|
||||
}
|
||||
(None, Token::ParanClose) => break,
|
||||
_ => lexer.panic_message("Unexpected token"),
|
||||
}
|
||||
} else {
|
||||
(None, tok)
|
||||
}
|
||||
|
||||
args
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -435,6 +458,7 @@ mod tests {
|
|||
use super::*;
|
||||
|
||||
fn parse_expr(source: &str) {
|
||||
println!("Source: {}", source);
|
||||
let mut lex = Lexer::new(source);
|
||||
let expr = Expr::build(&mut lex);
|
||||
println!("{:#?}", expr);
|
||||
|
@ -463,7 +487,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn func_call() {
|
||||
parse_expr("func_call();");
|
||||
parse_expr("func_call(1 + 2, 3, 4 * 5);");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Reference in New Issue