Variables globales (déclaration, affectation avec une expression et évaluation)
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
use crate::expr::{Binary, Expr, Grouping, Unary};
|
||||
use crate::expr::{Binary, Expr, Grouping, Unary, Variable};
|
||||
use crate::expr::Literal::{LiteralBool, LiteralNumber, LiteralString};
|
||||
use crate::token::Token;
|
||||
use crate::token_type::TokenType;
|
||||
use crate::stmt::{ExpressionStatement, PrintStatement, Statement};
|
||||
use crate::stmt::{ExpressionStatement, PrintStatement, Statement, VarStatement};
|
||||
|
||||
pub struct Parser {
|
||||
tokens: Vec<Token>,
|
||||
@@ -60,15 +60,12 @@ impl Parser {
|
||||
return self.tokens[self.current - 1].clone();
|
||||
}
|
||||
|
||||
fn consume(&mut self, token_type: &TokenType, message: String) -> Result<(), ParseError> {
|
||||
fn consume(&mut self, token_type: &TokenType, message: String) -> Result<Token, ParseError> {
|
||||
if self.check(token_type) {
|
||||
self.advance();
|
||||
return Ok(());
|
||||
Ok(self.advance())
|
||||
} else {
|
||||
Err(ParseError { message })
|
||||
}
|
||||
|
||||
Err(ParseError {
|
||||
message
|
||||
})
|
||||
}
|
||||
|
||||
fn synchronise(&mut self) {
|
||||
@@ -192,6 +189,10 @@ impl Parser {
|
||||
if self.match_token(&[TokenType::String]) {
|
||||
return Ok(Expr::LiteralExpr(LiteralString(self.previous().literal)));
|
||||
}
|
||||
if self.match_token(&[TokenType::Identifier]) {
|
||||
return Ok(Expr::VariableExpr(Variable { name: self.previous() } ));
|
||||
}
|
||||
|
||||
if self.match_token(&[TokenType::LeftParen]) {
|
||||
let expr = self.expression()?;
|
||||
self.consume(&TokenType::RightParen, String::from("Expect ')' after expression."))?;
|
||||
@@ -205,7 +206,7 @@ impl Parser {
|
||||
}
|
||||
}
|
||||
|
||||
fn statement(&mut self) -> Statement {
|
||||
fn statement(&mut self) -> Result<Statement, ParseError> {
|
||||
if self.match_token(&[TokenType::Print]) {
|
||||
self.print_statement()
|
||||
} else {
|
||||
@@ -213,22 +214,53 @@ impl Parser {
|
||||
}
|
||||
}
|
||||
|
||||
fn print_statement(&mut self) -> Statement {
|
||||
let e = self.expression().unwrap();
|
||||
self.consume(&TokenType::Semicolon, String::from("; attendu")).unwrap();
|
||||
Statement::Print(PrintStatement{ expr: e })
|
||||
fn print_statement(&mut self) -> Result<Statement, ParseError> {
|
||||
match self.expression() {
|
||||
Ok(e) => {
|
||||
self.consume(&TokenType::Semicolon, String::from("; attendu"))?;
|
||||
Ok(Statement::Print(PrintStatement{ expr: e }))
|
||||
}
|
||||
Err(e ) => { Err(e) }
|
||||
}
|
||||
}
|
||||
|
||||
fn expr_statement(&mut self) -> Statement {
|
||||
let e = self.expression().unwrap();
|
||||
self.consume(&TokenType::Semicolon, String::from("; attendu")).unwrap();
|
||||
Statement::Expression(ExpressionStatement{ expr: e })
|
||||
fn expr_statement(&mut self) -> Result<Statement, ParseError> {
|
||||
match self.expression() {
|
||||
Ok(e) => {
|
||||
self.consume(&TokenType::Semicolon, String::from("; attendu"))?;
|
||||
Ok(Statement::Expression(ExpressionStatement{ expr: e }))
|
||||
}
|
||||
Err(e ) => { Err(e) }
|
||||
}
|
||||
}
|
||||
|
||||
fn declaration(&mut self) -> Result<Statement, ParseError> {
|
||||
if self.match_token(&[TokenType::Var]) {
|
||||
self.var_declaration()
|
||||
} else {
|
||||
self.statement()
|
||||
}
|
||||
}
|
||||
|
||||
fn var_declaration(&mut self) -> Result<Statement, ParseError> {
|
||||
let name = self.consume(&TokenType::Identifier, String::from("nom de variable attendu"))?;
|
||||
|
||||
let mut initializer: Option<Expr> = None;
|
||||
if self.match_token(&[TokenType::Equal]) {
|
||||
initializer = Some(self.expression()?);
|
||||
}
|
||||
|
||||
self.consume(&TokenType::Semicolon, String::from("; attendu"))?;
|
||||
Ok(Statement::Var(VarStatement{ token: name, initializer }))
|
||||
}
|
||||
|
||||
pub fn parse(&mut self) -> Vec<Statement> {
|
||||
let mut statements= Vec::new();
|
||||
while !self.is_at_end() {
|
||||
statements.push(self.statement());
|
||||
match self.declaration() {
|
||||
Ok(stmt) => statements.push(stmt),
|
||||
Err(_e) => self.synchronise(),
|
||||
}
|
||||
}
|
||||
|
||||
statements
|
||||
|
||||
Reference in New Issue
Block a user