feat: Add support for if and compound statements.
This commit is contained in:
10
src/ast.rs
10
src/ast.rs
@@ -67,5 +67,15 @@ pub enum Statement {
|
|||||||
value: Option<Expression>,
|
value: Option<Expression>,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
If {
|
||||||
|
condition: Expression,
|
||||||
|
then: Box<Statement>,
|
||||||
|
elze: Option<Box<Statement>>,
|
||||||
|
},
|
||||||
|
|
||||||
|
Compound {
|
||||||
|
body: Vec<Statement>,
|
||||||
|
},
|
||||||
|
|
||||||
Expr(Expression),
|
Expr(Expression),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ pub mod parser;
|
|||||||
pub mod token;
|
pub mod token;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut parser = Parser::new("let index = 12 + 3;");
|
let mut parser = Parser::new("if a < 12 { let b = 10; } else { let c = 20; }");
|
||||||
|
|
||||||
println!("{:#?}", parser.parse_statement());
|
println!("{:#?}", parser.parse_statement());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ impl<'src> Parser<'src> {
|
|||||||
pub fn parse_statement(&mut self) -> ParserResult<Statement> {
|
pub fn parse_statement(&mut self) -> ParserResult<Statement> {
|
||||||
match self.peek_no_eof()?.kind {
|
match self.peek_no_eof()?.kind {
|
||||||
TokenKind::KwLet => self.parse_let_statement(),
|
TokenKind::KwLet => self.parse_let_statement(),
|
||||||
|
TokenKind::KwIf => self.parse_if_statement(),
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
let expr = self.parse_expression(0)?;
|
let expr = self.parse_expression(0)?;
|
||||||
@@ -68,6 +69,42 @@ impl<'src> Parser<'src> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_if_statement(&mut self) -> ParserResult<Statement> {
|
||||||
|
self.expect(&[TokenKind::KwIf])?;
|
||||||
|
|
||||||
|
let condition = self.parse_expression(0)?;
|
||||||
|
let then = Box::new(self.parse_compound_statement()?);
|
||||||
|
let elze = if self.is_peek(TokenKind::KwElse) {
|
||||||
|
self.consume();
|
||||||
|
|
||||||
|
Some(Box::new(if self.is_peek(TokenKind::KwIf) {
|
||||||
|
self.parse_if_statement()?
|
||||||
|
} else {
|
||||||
|
self.parse_compound_statement()?
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Statement::If {
|
||||||
|
condition,
|
||||||
|
then,
|
||||||
|
elze,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_compound_statement(&mut self) -> ParserResult<Statement> {
|
||||||
|
let mut body = Vec::new();
|
||||||
|
self.expect(&[TokenKind::LeftBrace])?;
|
||||||
|
|
||||||
|
while !self.is_peek(TokenKind::RightBrace) {
|
||||||
|
body.push(self.parse_statement()?);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.expect(&[TokenKind::RightBrace])?;
|
||||||
|
Ok(Statement::Compound { body })
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_let_statement(&mut self) -> ParserResult<Statement> {
|
fn parse_let_statement(&mut self) -> ParserResult<Statement> {
|
||||||
self.expect(&[TokenKind::KwLet])?;
|
self.expect(&[TokenKind::KwLet])?;
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ pub enum TokenKind {
|
|||||||
KwFn,
|
KwFn,
|
||||||
KwIf,
|
KwIf,
|
||||||
KwLet,
|
KwLet,
|
||||||
|
KwElse,
|
||||||
KwLoop,
|
KwLoop,
|
||||||
KwWhile,
|
KwWhile,
|
||||||
KwBreak,
|
KwBreak,
|
||||||
@@ -183,6 +184,7 @@ impl<'src> Tokenizer<'src> {
|
|||||||
"fn" => TokenKind::KwFn,
|
"fn" => TokenKind::KwFn,
|
||||||
"if" => TokenKind::KwIf,
|
"if" => TokenKind::KwIf,
|
||||||
"let" => TokenKind::KwLet,
|
"let" => TokenKind::KwLet,
|
||||||
|
"else" => TokenKind::KwElse,
|
||||||
"loop" => TokenKind::KwLoop,
|
"loop" => TokenKind::KwLoop,
|
||||||
"while" => TokenKind::KwWhile,
|
"while" => TokenKind::KwWhile,
|
||||||
"break" => TokenKind::KwBreak,
|
"break" => TokenKind::KwBreak,
|
||||||
|
|||||||
Reference in New Issue
Block a user