If expressions

This commit is contained in:
mars 2022-03-01 13:06:38 -07:00
parent 0a795f1450
commit 6217b83cd8
1 changed files with 31 additions and 15 deletions

View File

@ -53,7 +53,7 @@ pub enum Definition<'a> {
associated_struct: Option<(&'a str, bool)>,
name: &'a str,
signature: FnSig<'a>,
body: FnBody<'a>,
body: BranchBody<'a>,
},
Interface {
name: &'a str,
@ -97,7 +97,7 @@ impl<'a> Definition<'a> {
lexer.panic_message("Expected open brace");
}
let body = FnBody::build(lexer);
let body = BranchBody::build(lexer);
Self::Function {
name,
@ -193,12 +193,12 @@ pub struct FnArg<'a> {
}
#[derive(Debug)]
pub struct FnBody<'a> {
pub struct BranchBody<'a> {
pub statements: Vec<Statement<'a>>,
pub tail_expr: Option<Expr<'a>>,
pub tail_expr: Option<Box<Expr<'a>>>,
}
impl<'a> FnBody<'a> {
impl<'a> BranchBody<'a> {
pub fn build(lexer: &mut Lexer<'a>) -> Self {
let mut statements = Vec::new();
@ -215,7 +215,8 @@ impl<'a> FnBody<'a> {
_ => lexer.panic_message("Unexpected token"),
}
}
Token::Identifier => match Expr::build_start(tok, lexer) {
Token::BraceClose => break,
_ => match Expr::build_start(tok, lexer) {
(None, Token::Semicolon | Token::BraceClose) => {}
(Some(expr), Token::Semicolon) => statements.push(Statement::Expr(expr)),
(Some(expr), Token::BraceClose) => {
@ -224,14 +225,12 @@ impl<'a> FnBody<'a> {
}
_ => lexer.panic_message("Unexpected token"),
},
Token::BraceClose => break,
_ => lexer.panic_message("Expected let or expression"),
}
}
Self {
statements,
tail_expr,
tail_expr: tail_expr.map(|x| Box::new(x)),
}
}
}
@ -278,6 +277,24 @@ impl<'a> Expr<'a> {
}
Self::Group(Box::new(inner.unwrap()))
}
Token::If => {
let test_expr = match Self::build(lexer) {
(Some(test_expr), Token::BraceOpen) => Box::new(test_expr),
(None, Token::BraceOpen) => lexer.panic_message("Expected test expression"),
_ => lexer.panic_message("Expected opening brace"),
};
let then_body = BranchBody::build(lexer);
lexer.eat_expect(Token::Else);
lexer.eat_expect(Token::BraceOpen);
let else_body = BranchBody::build(lexer);
Self::If {
test_expr,
then_body,
else_body,
}
}
Token::BinaryInteger => Self::Literal(Literal::BinaryInteger(lexer.slice())),
Token::OctalInteger => Self::Literal(Literal::OctalInteger(lexer.slice())),
Token::HexInteger => Self::Literal(Literal::HexInteger(lexer.slice())),
@ -413,12 +430,6 @@ impl<'a> Statement<'a> {
}
}
#[derive(Debug)]
pub struct BranchBody<'a> {
pub statements: Vec<Statement<'a>>,
pub tail_expression: Box<Expr<'a>>,
}
#[cfg(test)]
mod tests {
use super::*;
@ -485,6 +496,11 @@ mod tests {
parse_expr(".member1 * .member2;");
}
#[test]
fn if_expr() {
parse_expr("if true { 1 } else { 0 };");
}
#[test]
fn func_call() {
parse_expr("func_call(1 + 2, 3, 4 * 5);");