Ajout des instructions.

This commit is contained in:
2024-05-21 08:44:11 +02:00
parent 3e27109d2a
commit de653f9bc5
6 changed files with 118 additions and 30 deletions

View File

@@ -1,4 +1,5 @@
use crate::expr::{Binary, Expr, ExprVisitor, Grouping, Literal, Unary};
use crate::stmt::{ExpressionStatement, PrintStatement, StatementVisitor};
pub struct ASTPrinter {
pub(crate) depth: u32
@@ -60,3 +61,21 @@ impl ExprVisitor<()> for ASTPrinter {
}
}
}
impl StatementVisitor<()> for ASTPrinter {
fn visit_expr_stmt(&mut self, e: &ExpressionStatement) -> () {
println!("{} EXPR_STMT(", self.ast_tab());
self.depth+=1;
self.visit_expr(&e.expr);
self.depth-=1;
print!(") ");
}
fn visit_print(&mut self, p: &PrintStatement) -> () {
println!("{} EXPR_STMT(", self.ast_tab());
self.depth+=1;
self.visit_expr(&p.expr);
self.depth-=1;
print!(") ");
}
}

View File

@@ -1,11 +1,13 @@
use crate::token::Token;
#[derive(Clone)]
pub struct Binary {
pub left: Box<Expr>,
pub operator: Token,
pub right: Box<Expr>,
}
#[derive(Clone)]
pub struct Grouping {
pub expression: Box<Expr>,
}
@@ -18,11 +20,13 @@ pub enum Literal {
LiteralNil,
}
#[derive(Clone)]
pub struct Unary {
pub operator: Token,
pub right: Box<Expr>,
}
#[derive(Clone)]
pub enum Expr {
BinaryExpr(Binary),
GroupingExpr(Grouping),

View File

@@ -7,10 +7,12 @@ use crate::expr::Literal::LiteralNumber;
use crate::expr::Literal::LiteralBool;
use crate::expr::Literal::LiteralNil;
use crate::expr::{Binary, Expr, ExprVisitor, Grouping, Literal, Unary};
use crate::stmt::{ExpressionStatement, PrintStatement, StatementVisitor};
use crate::token_type::TokenType;
pub struct Interpreter;
#[derive(Debug)]
pub struct RuntimeError {
pub(crate) message: String
}
@@ -146,3 +148,23 @@ impl ExprVisitor<Result<Literal, RuntimeError>> for Interpreter {
}
}
}
impl StatementVisitor<()> for Interpreter {
fn visit_expr_stmt(&mut self, e: &ExpressionStatement) -> () {
self.visit_expr(&e.expr).expect("Erreur pendant l'évaluation de l'expression.");
}
fn visit_print(&mut self, p: &PrintStatement) -> () {
match self.visit_expr(&p.expr) {
Ok(lit) => match (lit) {
Literal::LiteralNumber(f) => { println!("{}", f); }
Literal::LiteralString(s) => { println!("{}", s); }
Literal::LiteralBool(b) => { println!("{}", b); }
Literal::LiteralNil => { println!("nul")}
}
Err(e) => panic!("{}", e.message)
}
}
}

View File

@@ -2,7 +2,7 @@ use std::{env, fs, io};
use std::io::Write;
use std::process;
use crate::astprinter::ASTPrinter;
use crate::expr::{ExprVisitor, Literal};
use crate::expr::ExprVisitor;
use crate::interpreter::Interpreter;
use crate::parser::Parser;
@@ -13,8 +13,10 @@ mod token_type;
mod expr;
mod astprinter;
mod parser;
mod stmt;
use crate::scanner::Scanner;
use crate::stmt::{Statement, StatementVisitor};
// Exit codes from #include <sysexits.h>
const EX_OK: i32 = 0;
@@ -71,26 +73,24 @@ fn run(src: String) -> i32 {
println!("Parser");
let mut parser = Parser::new( scanner.tokens );
match parser.parse() {
Some(expr) => {
println!("AST");
let mut printer = ASTPrinter { depth: 0 };
printer.visit_expr(&expr);
println!("Interpretation");
let mut interpreter = Interpreter;
let result = interpreter.visit_expr(&expr);
match result {
Ok(r) => { match r {
Literal::LiteralNumber(f) => { println!("Resultat numérique = {}", f); }
Literal::LiteralString(s) => { println!("Résultat chaîne = {}", s); }
Literal::LiteralBool(b) => { println!("Résultat booléen = {}", b); }
Literal::LiteralNil => { println!("Résultat nul")}
}}
Err(e) => { println!("Erreur d'exécution : {}", e.message); return EX_EXECERR; }
}
println!();
},
None => { println!("An error occurred while parsing expression."); return EX_DATAERR; }
let program = parser.parse();
println!("AST");
let mut printer = ASTPrinter { depth: 0 };
for s in program.clone() {
match s {
Statement::Expression(e) => { printer.visit_expr_stmt(&e) }
Statement::Print(p) => { printer.visit_print(&p) }
}
}
println!("Interpretation");
let mut interpreter = Interpreter;
for s in program {
match s {
Statement::Expression(e) => { interpreter.visit_expr_stmt(&e) }
Statement::Print(p) => { interpreter.visit_print(&p) }
}
}
EX_OK
@@ -101,4 +101,4 @@ fn run(src: String) -> i32 {
// https://github.com/munificent/craftinginterpreters/wiki/Lox-implementations#rust
// Pause :
// http://www.craftinginterpreters.com/statements-and-state.html
// http://www.craftinginterpreters.com/statements-and-state.html#global-variables

View File

@@ -2,12 +2,14 @@ use crate::expr::{Binary, Expr, Grouping, Unary};
use crate::expr::Literal::{LiteralBool, LiteralNumber, LiteralString};
use crate::token::Token;
use crate::token_type::TokenType;
use crate::stmt::{ExpressionStatement, PrintStatement, Statement};
pub struct Parser {
tokens: Vec<Token>,
current: usize
}
#[derive(Debug)]
pub struct ParseError {
message: String
}
@@ -203,13 +205,32 @@ impl Parser {
}
}
pub fn parse(&mut self) -> Option<Expr> {
match self.expression() {
Ok(expr) => Some(expr),
Err(error) => {
println!("Error while parsing expression : {}",error.message);
None
}
fn statement(&mut self) -> Statement {
if self.match_token(&[TokenType::Print]) {
self.print_statement()
} else {
self.expr_statement()
}
}
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 expr_statement(&mut self) -> Statement {
let e = self.expression().unwrap();
self.consume(&TokenType::Semicolon, String::from("; attendu")).unwrap();
Statement::Expression(ExpressionStatement{ expr: e })
}
pub fn parse(&mut self) -> Vec<Statement> {
let mut statements= Vec::new();
while !self.is_at_end() {
statements.push(self.statement());
}
statements
}
}

22
src/stmt.rs Normal file
View File

@@ -0,0 +1,22 @@
use crate::expr::Expr;
#[derive(Clone)]
pub enum Statement {
Expression(ExpressionStatement),
Print(PrintStatement)
}
#[derive(Clone)]
pub struct ExpressionStatement {
pub expr: Expr
}
#[derive(Clone)]
pub struct PrintStatement {
pub expr: Expr
}
pub trait StatementVisitor<T> {
fn visit_expr_stmt(&mut self, e: &ExpressionStatement) -> T;
fn visit_print(&mut self, p: &PrintStatement) -> T;
}