feat: Add support for expression and let statements.
This commit is contained in:
11
src/ast.rs
11
src/ast.rs
@@ -58,3 +58,14 @@ pub enum BinaryOp {
|
|||||||
Assign,
|
Assign,
|
||||||
Member,
|
Member,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
pub enum Statement {
|
||||||
|
Let {
|
||||||
|
name: Box<str>,
|
||||||
|
name_span: Span,
|
||||||
|
value: Option<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("user.age >= 18");
|
let mut parser = Parser::new("let index = 12 + 3;");
|
||||||
|
|
||||||
println!("{:#?}", parser.parse_expression(0));
|
println!("{:#?}", parser.parse_statement());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,10 +36,64 @@ impl<'src> Parser<'src> {
|
|||||||
self.peek().ok_or(ParserError::UnexpectedEof)
|
self.peek().ok_or(ParserError::UnexpectedEof)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_peek(&mut self, kind: TokenKind) -> bool {
|
||||||
|
self.peek().is_some_and(|tok| tok.kind == kind)
|
||||||
|
}
|
||||||
|
|
||||||
fn consume(&mut self) -> Option<Token<'src>> {
|
fn consume(&mut self) -> Option<Token<'src>> {
|
||||||
self.tokens.next()
|
self.tokens.next()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn expect(&mut self, kinds: &'static [TokenKind]) -> ParserResult<Token<'src>> {
|
||||||
|
match self.consume() {
|
||||||
|
Some(tok) if kinds.contains(&tok.kind) => Ok(tok),
|
||||||
|
Some(tok) => Err(ParserError::UnexpectedToken {
|
||||||
|
expected: kinds,
|
||||||
|
found: tok.kind,
|
||||||
|
span: tok.span,
|
||||||
|
}),
|
||||||
|
None => Err(ParserError::UnexpectedEof),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse_statement(&mut self) -> ParserResult<Statement> {
|
||||||
|
match self.peek_no_eof()?.kind {
|
||||||
|
TokenKind::KwLet => self.parse_let_statement(),
|
||||||
|
|
||||||
|
_ => {
|
||||||
|
let expr = self.parse_expression(0)?;
|
||||||
|
self.expect(&[TokenKind::Semicolon])?;
|
||||||
|
Ok(Statement::Expr(expr))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_let_statement(&mut self) -> ParserResult<Statement> {
|
||||||
|
self.expect(&[TokenKind::KwLet])?;
|
||||||
|
|
||||||
|
let (name, name_span) = {
|
||||||
|
let token = self.expect(&[TokenKind::Identifier])?;
|
||||||
|
|
||||||
|
(token.text.to_string().into_boxed_str(), token.span)
|
||||||
|
};
|
||||||
|
|
||||||
|
let value = if self.is_peek(TokenKind::Assign) {
|
||||||
|
self.consume();
|
||||||
|
|
||||||
|
Some(self.parse_expression(0)?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
self.expect(&[TokenKind::Semicolon])?;
|
||||||
|
|
||||||
|
Ok(Statement::Let {
|
||||||
|
name,
|
||||||
|
name_span,
|
||||||
|
value,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn parse_expression(&mut self, min_binding_power: u8) -> ParserResult<Expression> {
|
pub fn parse_expression(&mut self, min_binding_power: u8) -> ParserResult<Expression> {
|
||||||
let mut left = self.parse_leading_expression()?;
|
let mut left = self.parse_leading_expression()?;
|
||||||
|
|
||||||
@@ -71,6 +125,8 @@ impl<'src> Parser<'src> {
|
|||||||
span,
|
span,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(left)
|
Ok(left)
|
||||||
|
|||||||
Reference in New Issue
Block a user