If expressions
This commit is contained in:
parent
0a795f1450
commit
6217b83cd8
46
src/parse.rs
46
src/parse.rs
|
@ -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);");
|
||||
|
|
Loading…
Reference in New Issue