Parse function calls

This commit is contained in:
mars 2022-03-01 12:53:20 -07:00
parent 1d7007ab9a
commit 0a795f1450
1 changed files with 37 additions and 13 deletions

View File

@ -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]