commentaires, et verification d'expression booleenne

This commit is contained in:
WanderingPenwing 2024-12-11 17:52:25 +01:00
parent 3d0e04f4fb
commit ec8fa1bcf8
9 changed files with 115 additions and 58 deletions

View file

@ -1,2 +1 @@
{"categories":[{"name":"todo","content":[{"name":"commentaires","description":"// Hello there","id":3},{"name":"compile time verification","description":"odre des termes rpn","id":1},{"name":"error context","description":"// Hello there","id":2},{"name":"test correct error","description":"// Hello there","id":3},{"name":"if","description":"implémente if avec des guillemets de délimitation","id":1},{"name":"scope variable","description":"// Hello there","id":6},{"name":"while","description":"implémente un while","id":2},{"name":"else","description":"// Hello there","id":7},{"name":"break","description":"// Hello there","id":8},{"name":"continue","description":"// Hello there","id":9},{"name":"compilation","description":"// Hello there","id":3}]},{"name":"in progress","content":[]},{"name":"done","content":[{"name":"comparaison","description":"// Hello there","id":2},{"name":"booleen type","description":"// Hello there","id":4},{"name":"soixante-dix","description":"// Hello there","id":1},{"name":"parenthese comparaison","description":"// Hello there","id":1},{"name":"test comparaison","description":"// Hello there","id":4}]},{"name":"bug","content":[]},{"name":"to test","content":[]},{"name":"bonus","content":[{"name":"stop cheating with \"-\"","description":"// Hello there","id":5}]},{"name":"+","content":[]}]}
{"categories":[{"name":"todo","content":[{"name":"test correct error","description":"manque point\nmauvaise expression mathematique","id":3},{"name":"if","description":"implémente if avec des guillemets de délimitation","id":1},{"name":"scope variable","description":"// Hello there","id":6},{"name":"while","description":"implémente un while","id":2},{"name":"else","description":"// Hello there","id":7},{"name":"break","description":"// Hello there","id":8},{"name":"continue","description":"// Hello there","id":9},{"name":"compilation","description":"// Hello there","id":3}]},{"name":"in progress","content":[]},{"name":"done","content":[{"name":"comparaison","description":"// Hello there","id":2},{"name":"booleen type","description":"// Hello there","id":4},{"name":"soixante-dix","description":"// Hello there","id":1},{"name":"parenthese comparaison","description":"// Hello there","id":1},{"name":"test comparaison","description":"// Hello there","id":4},{"name":"error ligne compilation","description":"// Hello there","id":2},{"name":"commentaires","description":"// Hello there","id":3},{"name":"compile time verification","description":"odre des termes rpn","id":1}]},{"name":"bug","content":[]},{"name":"to test","content":[]},{"name":"bonus","content":[{"name":"stop cheating with \"-\"","description":"// Hello there","id":5},{"name":"affiche ligne et position erreur","description":"// Hello there","id":1}]},{"name":"+","content":[]}]}

View file

@ -1,10 +1,11 @@
use std::env;
use std::fs;
use std::time::Instant;
mod pendragon;
use pendragon::*;
fn main() {
fn main() {
let arguments: Vec<String> = env::args().collect();
if arguments.len() < 2 {
@ -17,22 +18,34 @@ fn main() {
let chemin_de_fichier = &arguments[1];
let mut pendragon = Pendragon::nouveau();
match fs::read_to_string(chemin_de_fichier) {
Ok(contenu) => {
let Ok(_) = pendragon.compile(contenu) else {
eprintln!("\n# Échec de la compilation");
return
};
if debug_mode {
println!("{}\n", pendragon.programme);
}
if let Err(raison) = pendragon.programme.execute() {
eprintln!("Erreur Execution : {}", raison);
return
}
}
Err(raison) => {
eprintln!("Fichier illisible : {}", raison);
}
let lecture = fs::read_to_string(chemin_de_fichier);
if let Err(raison) = lecture {
eprintln!("Fichier illisible : {}", raison);
return
}
println!("# Compilation de '{}'.", chemin_de_fichier);
let debut = Instant::now();
if let Err(raison) = pendragon.compile(lecture.unwrap()) {
eprintln!("\n{}", raison);
eprintln!("\n# Échec de la compilation.");
return
}
println!("# Compilation Ok. ({:.2?})\n", debut.elapsed());
if debug_mode {
println!("{}\n", pendragon.programme);
}
println!("# Exécution de '{}'.\n", chemin_de_fichier);
let debut = Instant::now();
if let Err(raison) = pendragon.programme.execute() {
eprintln!("\nErreur : {}", raison);
eprintln!("\n# Échec de l'exécution.");
return
}
println!("\n# Exécution Ok. ({:.2?})", debut.elapsed());
}

View file

@ -383,7 +383,7 @@ mod test {
nombre::nombre_comme_texte(e),
));
let bonne_reponse = !((6+a) > 2*b) && (c/2 < (d-1) || !(e == 2));
match possible_expression{
match possible_expression {
Ok(expression) => {
match calcule_booleen(expression.clone(), &HashMap::new()) {
Ok(booleen) => {

View file

@ -1,6 +1,27 @@
use std::fmt;
use super::*;
pub struct ErreurCompilation {
index_ligne: usize,
erreur: ErreurPendragon,
}
impl ErreurCompilation {
pub fn nouvelle(index_ligne: usize, erreur: ErreurPendragon) -> Self {
Self {
index_ligne,
erreur,
}
}
}
impl fmt::Display for ErreurCompilation {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {//'
write!(f, "Erreur ligne {} : {}", self.index_ligne + 1, self.erreur)
}
}
pub enum ErreurPendragon {
CommandeInconnue(String),
ManqueArgument,
@ -11,7 +32,7 @@ pub enum ErreurPendragon {
MauvaisArgument(String),
VariableInconnue(String),
MauvaisType(String, String, String),
ManquePoint,
ManquePonctuation,
Lecture(String),
CalculBooleen(String),
CalculEntier(String),
@ -29,7 +50,7 @@ impl fmt::Display for ErreurPendragon {
Self::MauvaisArgument(message) => write!(f, "La commande a reçu un mauvais argument, {}.", message),
Self::VariableInconnue(nom) => write!(f, "La variable \"{}\" est inconnue.", nom),
Self::MauvaisType(nom, type_variable, type_attendu) => write!(f, "La {} est du mauvais type ({}), attendais {}.", nom, type_variable, type_attendu),
Self::ManquePoint => write!(f, "Il manque un point."),
Self::ManquePonctuation => write!(f, "Il manque la ponctuation de la phrase."),
Self::Lecture(raison) => write!(f, "Lecture d'entrées utilisateur impossible : {}.", raison),
Self::CalculBooleen(raison) => write!(f, "Calcul booleen échoué, {}.", raison),
Self::CalculEntier(raison) => write!(f, "Calcul entier échoué, {}.", raison),

View file

@ -1,5 +1,4 @@
use std::collections::HashMap;
use std::time::Instant;
pub mod nombre;
pub mod texte;
@ -20,38 +19,42 @@ impl Pendragon {
}
}
pub fn compile(&mut self, contenu: String) -> Result<(), ErreurPendragon> {
println!();
let debut = Instant::now();
let contenu_propre = contenu.replace("\n", " ");
let mut texte: Vec<&str> = contenu_propre.split('.').collect();
let reste = texte.pop();
if reste != Some("") {
eprintln!("Erreur Compilation, phrase {} : Il manque un point.", texte.len() + 1);
return Err(ErreurPendragon::ManquePoint)
}
for (index_phrase, phrase) in texte.iter().enumerate() {
let phrase = phrase.trim();
match self.compile_phrase(phrase) {
Ok(commande) => {self.programme.ajoute_commande(commande)},
Err(raison) => {
eprintln!("Erreur phrase {} : {}", index_phrase + 1, raison);
return Err(raison)
pub fn compile(&mut self, contenu: String) -> Result<(), ErreurCompilation> {
let texte: Vec<&str> = contenu.split('\n').collect();
for (index_ligne, ligne) in texte.iter().enumerate() {
let ligne = ligne.trim();
let phrases: Vec<&str> = ligne.split_inclusive(|c| c == ',' || c == '.').collect();
let Some(derniere_phrase) = phrases.last() else {
continue
};
if !derniere_phrase.ends_with('.') && !derniere_phrase.ends_with(',') {
return Err(ErreurCompilation::nouvelle(index_ligne, ErreurPendragon::ManquePonctuation))
}
for phrase in phrases {
if phrase.ends_with(".") {
if phrase.starts_with("Nota Bene :") {
continue
}
match self.compile_commande(&phrase[..phrase.len() - 1]) {
Ok(commande) => self.programme.ajoute_commande(commande),
Err(raison) => return Err(ErreurCompilation::nouvelle(index_ligne, raison)),
}
continue;
}
println!("todo : {}", phrase);
}
}
println!("# Compilation Ok. ({:.2?})\n", debut.elapsed());
Ok(())
}
fn compile_phrase(&mut self, phrase: &str) -> Result<Commande, ErreurPendragon> {
fn compile_commande(&mut self, phrase: &str) -> Result<Commande, ErreurPendragon> {
let phrase = phrase.trim();
let parties: Vec<&str> = phrase.splitn(2, ' ').collect();
if parties.len() == 1 {
return Err(ErreurPendragon::ManqueArgument)
}
if parties[1].contains("Définis") || parties[1].contains("Modifie") || parties[1].contains("Affiche") || parties[1].contains("Demande") {
return Err(ErreurPendragon::ManquePoint)
return Err(ErreurPendragon::ManquePonctuation)
}
match parties[0] {
"Définis" => self.definis(parties[1]),

View file

@ -15,6 +15,7 @@ impl Pendragon {
let elements_texte: Vec<&str> = texte.split(" ").collect();
let mut expression: Vec<Element> = Vec::new();
let mut pile_operateurs: Vec<Operateur> = Vec::new();
let mut precede_par_operation: bool = true;
for element in elements_texte {
match element {
@ -58,24 +59,43 @@ impl Pendragon {
}
pile_operateurs.push(Operateur::Divise);
}
"ouvre-la-parenthese" => pile_operateurs.push(Operateur::ParentheseEntier),
"ouvre-la-parenthese" => {
if !precede_par_operation {
return Err(ErreurPendragon::CalculEntier("il manque un opérateur avant l'ouverture de parenthèse".into()))
}
pile_operateurs.push(Operateur::ParentheseEntier);
continue
}
"ferme-la-parenthese" => {
if precede_par_operation {
return Err(ErreurPendragon::CalculEntier("il manque un nombre avant la fermeture de parenthèse".into()))
}
while let Some(operateur) = pile_operateurs.pop() {
if operateur == Operateur::ParentheseEntier {
break;
}
expression.push(Element::Operateur(operateur));
}
continue
}
autre => {
if !precede_par_operation {
return Err(ErreurPendragon::CalculEntier(format!("il manque un opérateur avant le nombre '{}'", autre)))
}
precede_par_operation = false;
if format_de_variable(autre) {
self.programme.variable_est_de_type(autre, TypeElement::Entier)?;
expression.push(Element::Variable(autre.into(), TypeElement::Entier));
} else {
expression.push(texte_comme_nombre(autre)?);
}
continue;
}
}
if precede_par_operation {
return Err(ErreurPendragon::CalculEntier(format!("il manque un nombre avant l'opérateur '{}'", element)))
}
precede_par_operation = true;
}
while let Some(operateur) = pile_operateurs.pop() {
@ -124,6 +144,9 @@ pub fn calcule_nombre(expression: Vec<Element>, variables: &HashMap<String, Elem
pile.push(nombre_b + nombre_a);
}
Operateur::Moins => {
if nombre_b < nombre_a {
return Err(ErreurPendragon::CalculEntier(format!("a essayé de soustraire {} à {}", nombre_a, nombre_b)))
}
pile.push(nombre_b - nombre_a);
}
Operateur::Fois => {

View file

@ -1,6 +1,5 @@
use std::io;
use std::collections::HashMap;
use std::time::Instant;
use super::*;
@ -54,8 +53,6 @@ impl Programme {
}
pub fn execute(&self) -> Result<(), ErreurPendragon> {
let debut = Instant::now();
println!("# Execution...\n");
let mut variables_globales: HashMap<String, Element> = HashMap::new();
for commande in &self.commandes {
match commande {
@ -79,7 +76,6 @@ impl Programme {
}
}
}
println!("\n# Exécution Ok. ({:.2?})", debut.elapsed());
Ok(())
}
}

View file

@ -4,7 +4,7 @@ impl Pendragon {
pub fn elements_texte(&self, arguments: &str) -> Result<Vec<Element>, ErreurPendragon> {
let mut expression: Vec<Element> = Vec::new();
for argument in arguments.split(',').map(|arg| arg.trim()) {
for argument in arguments.split("puis").map(|arg| arg.trim()) {
if expression.len() > 0 {
expression.push(Element::Operateur(Operateur::Virgule));
}
@ -93,7 +93,7 @@ mod test {
let a = 2345678;
let b = 987654;
let possible_expression = pendragon.elements_texte(&format!("\"hello\", {} fois {}, \"there\", vrai ou faux",
let possible_expression = pendragon.elements_texte(&format!("\"hello\" puis {} fois {} puis \"there\" puis vrai ou faux",
nombre::nombre_comme_texte(a),
nombre::nombre_comme_texte(b)));
match possible_expression {

16
test.dr
View file

@ -1,8 +1,10 @@
Affiche soixante-dix.
Affiche soixante-et-onze.
<<<<<<< HEAD
Affiche vrai et ouvre la parenthèse six plus un est supérieur à ouvre la parenthèse deux fois deux ferme la parenthèse ferme la parenthèse.
=======
Affiche vrai et ouvre la parenthèse six plus un est supérieur à ouvre la parenthèse deux fois deux ferme la parenthèse ferme la parenthèse.
Définis A comme entier.
Définis B comme entier.
Définis C comme entier.
Nota Bene : A est la variable pour un polynôme.
>>>>>>> main
Modifie A avec dix-sept.
Demande C.
Modifie B avec trois fois A fois A plus deux fois A plus C.
Affiche "Résultat : " puis B.