better ordre calcul number/bool

This commit is contained in:
WanderingPenwing 2024-12-13 11:09:43 +01:00
parent 1fe024e9ff
commit 90322f7bcf
8 changed files with 187 additions and 82 deletions

View file

@ -1 +1 @@
{"categories":[{"name":"todo","content":[{"name":"erreur calcul bool/nombre","description":"affiche element precedent lorsque mauvais enchainement","id":1},{"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":"puis à la ligne, alinéa","description":"// Hello there","id":1}]},{"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":"test multiple space in texte","description":"// Hello there","id":3},{"name":"test puis in texte","description":"// Hello there","id":2},{"name":"enchainement puis","description":"// Hello there","id":5},{"name":"guillemet mal ferme","description":"// Hello there","id":4},{"name":"display element","description":"for better print","id":6}]},{"name":"bug","content":[]},{"name":"to test","content":[{"name":"tests mod","description":"// Hello there","id":3},{"name":"test variable","description":"// Hello there","id":2}]},{"name":"bonus","content":[{"name":"stop cheating with \"-\"","description":"// Hello there","id":5},{"name":"affiche ligne et position erreur","description":"// Hello there","id":1},{"name":"pour numero de ligne execution","description":"sauvegarde numero de ligne dans la commande\n\ncommande.ligne(12)","id":3}]},{"name":"+","content":[]}]} {"categories":[{"name":"todo","content":[{"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":"test multiple space in texte","description":"// Hello there","id":3},{"name":"test puis in texte","description":"// Hello there","id":2},{"name":"enchainement puis","description":"// Hello there","id":5},{"name":"guillemet mal ferme","description":"// Hello there","id":4},{"name":"display element","description":"for better print","id":6},{"name":"puis à la ligne, alinéa","description":"// Hello there","id":1},{"name":"teste double tiret","description":"// Hello there","id":2},{"name":"teste puis seul","description":"tout seul, seul devant, seul fin","id":3},{"name":"erreur calcul bool/nombre","description":"affiche element precedent lorsque mauvais enchainement","id":1}]},{"name":"bug","content":[]},{"name":"to test","content":[{"name":"tests mod","description":"// Hello there","id":3},{"name":"test variable","description":"// Hello there","id":2}]},{"name":"bonus","content":[{"name":"stop cheating with \"-\"","description":"// Hello there","id":5},{"name":"affiche ligne et position erreur","description":"// Hello there","id":1},{"name":"pour numero de ligne execution","description":"sauvegarde numero de ligne dans la commande\n\ncommande.ligne(12)","id":3},{"name":"standardizer erreur","description":"regarder les texte répétés","id":1}]},{"name":"+","content":[]}]}

View file

@ -32,7 +32,7 @@ impl Pendragon {
self.fin_comparaison("vrai", &mut pile_inconnu, &mut pile_operateurs, &mut expression, &mut possible_comparaison)?; self.fin_comparaison("vrai", &mut pile_inconnu, &mut pile_operateurs, &mut expression, &mut possible_comparaison)?;
expression.push(Element::Booleen(true)); expression.push(Element::Booleen(true));
if !precede_par_operation { if !precede_par_operation {
return Err(ErreurPendragon::CalculBooleen(format!("il manque un opérateur entre '{}' et 'vrai'", element_precedent))) return Err(ErreurPendragon::OrdreCalculBooleen("opérateur".into(), element_precedent.into(), "vrai".into()))
} }
precede_par_operation = false; precede_par_operation = false;
continue; continue;
@ -41,7 +41,7 @@ impl Pendragon {
self.fin_comparaison("faux", &mut pile_inconnu, &mut pile_operateurs, &mut expression, &mut possible_comparaison)?; self.fin_comparaison("faux", &mut pile_inconnu, &mut pile_operateurs, &mut expression, &mut possible_comparaison)?;
expression.push(Element::Booleen(false)); expression.push(Element::Booleen(false));
if !precede_par_operation { if !precede_par_operation {
return Err(ErreurPendragon::CalculBooleen(format!("il manque un opérateur entre '{}' et 'faux'", element_precedent))) return Err(ErreurPendragon::OrdreCalculBooleen("opérateur".into(), element_precedent.into(), "faux".into()))
} }
precede_par_operation = false; precede_par_operation = false;
continue; continue;
@ -50,7 +50,7 @@ impl Pendragon {
self.fin_comparaison("non", &mut pile_inconnu, &mut pile_operateurs, &mut expression, &mut possible_comparaison)?; self.fin_comparaison("non", &mut pile_inconnu, &mut pile_operateurs, &mut expression, &mut possible_comparaison)?;
pile_operateurs.push(Operateur::Non); pile_operateurs.push(Operateur::Non);
if !precede_par_operation { if !precede_par_operation {
return Err(ErreurPendragon::CalculBooleen(format!("il manque un opérateur entre '{}' et 'non'", element_precedent))) return Err(ErreurPendragon::OrdreCalculBooleen("opérateur".into(), element_precedent.into(), "non".into()))
} }
continue; continue;
} }
@ -78,14 +78,14 @@ impl Pendragon {
} }
"ouvre-la-parenthese" => { "ouvre-la-parenthese" => {
if !precede_par_operation && pile_inconnu.len() > 0 { if !precede_par_operation && pile_inconnu.len() > 0 {
return Err(ErreurPendragon::CalculBooleen(format!("il manque un opérateur entre '{}' et l'ouverture de la parenthèse", element_precedent))) return Err(ErreurPendragon::OrdreCalculBooleen("opérateur".into(), element_precedent.into(), "l'ouverture de la parenthèse".into()))
} }
pile_inconnu.push("ouvre-la-parenthese".into()); pile_inconnu.push("ouvre-la-parenthese".into());
continue; continue;
} }
"ferme-la-parenthese" => { "ferme-la-parenthese" => {
if precede_par_operation { if precede_par_operation {
return Err(ErreurPendragon::CalculBooleen(format!("il manque un booleen entre '{}' et la fermeture de la parenthèse", element_precedent))) return Err(ErreurPendragon::OrdreCalculBooleen("booleen".into(), element_precedent.into(), "la fermeture de la parenthèse".into()))
} }
let nombre_parenthese = compare_parentheses(&pile_inconnu); let nombre_parenthese = compare_parentheses(&pile_inconnu);
if nombre_parenthese.0 > nombre_parenthese.1 { if nombre_parenthese.0 > nombre_parenthese.1 {
@ -111,7 +111,7 @@ impl Pendragon {
} }
} else if let Ok(type_comparaison) = texte_comme_comparaison(autre) { } else if let Ok(type_comparaison) = texte_comme_comparaison(autre) {
if let Some(comparaison) = possible_comparaison { if let Some(comparaison) = possible_comparaison {
return Err(ErreurPendragon::BooleenInvalide(format!("il manque un operateur booleen entre '{}' et '{}'", comparaison, type_comparaison))) return Err(ErreurPendragon::ComparaisonInvalide(format!("il manque un operateur booleen entre les comparaisons '{}' et '{}'", comparaison, type_comparaison)))
} }
let mut comparaison = Comparaison::nouvelle(); let mut comparaison = Comparaison::nouvelle();
let nombre_parenthese = compare_parentheses(&pile_inconnu); let nombre_parenthese = compare_parentheses(&pile_inconnu);
@ -131,7 +131,7 @@ impl Pendragon {
} }
} }
if precede_par_operation { if precede_par_operation {
return Err(ErreurPendragon::CalculBooleen(format!("il manque un booleen entre '{}' et '{}'", element_precedent, element))) return Err(ErreurPendragon::OrdreCalculBooleen("booleen".into(), element_precedent.into(), element.into()))
} }
precede_par_operation = true; precede_par_operation = true;
} }
@ -457,7 +457,7 @@ mod test {
let Err(raison) = pendragon.elements_booleen(texte) else { let Err(raison) = pendragon.elements_booleen(texte) else {
panic!("Devrait détecter une erreur pour '{}'", texte); panic!("Devrait détecter une erreur pour '{}'", texte);
}; };
let ErreurPendragon::CalculBooleen(_) = raison else { let ErreurPendragon::OrdreCalculBooleen(_,_,_) = raison else {
panic!("Devrait détecter une erreur de calcul booléen pour '{}', a déclenché : {}", texte, raison); panic!("Devrait détecter une erreur de calcul booléen pour '{}', a déclenché : {}", texte, raison);
}; };
} }

View file

@ -13,6 +13,9 @@ impl ErreurCompilation {
erreur, erreur,
} }
} }
pub fn raison(&self) -> ErreurPendragon {
self.erreur.clone()
}
} }
@ -22,20 +25,28 @@ impl fmt::Display for ErreurCompilation {
} }
} }
#[derive(PartialEq, Debug, Clone)]
pub enum ErreurPendragon { pub enum ErreurPendragon {
CommandeInconnue(String), CommandeInconnue(String),
ManqueArgument, ManqueArgument,
NombreInvalide(String),
BooleenInvalide(String),
TexteInvalide(String),
ComparaisonInvalide(String),
MauvaisArgument(String), MauvaisArgument(String),
ManquePonctuation,
NombreInvalide(String),
CalculEntier(String),
OrdreCalculEntier(String, String, String),
TexteInvalide(String),
BooleenInvalide(String),
ComparaisonInvalide(String),
CalculBooleen(String),
OrdreCalculBooleen(String, String, String),
VariableInconnue(String), VariableInconnue(String),
MauvaisType(String, String, String), MauvaisType(String, String, String),
ManquePonctuation,
Lecture(String), Lecture(String),
CalculBooleen(String),
CalculEntier(String),
} }
impl fmt::Display for ErreurPendragon { impl fmt::Display for ErreurPendragon {
@ -43,17 +54,24 @@ impl fmt::Display for ErreurPendragon {
match self { match self {
Self::CommandeInconnue(commande) => write!(f, "La commande \"{}\" est inconnue.", commande), Self::CommandeInconnue(commande) => write!(f, "La commande \"{}\" est inconnue.", commande),
Self::ManqueArgument => write!(f, "Il manque un argument."), Self::ManqueArgument => write!(f, "Il manque un argument."),
Self::NombreInvalide(nombre) => write!(f, "Le nombre \"{}\" est mal orthographié.", nombre),
Self::TexteInvalide(raison) => write!(f, "Le texte est invalide, {}.", raison),
Self::BooleenInvalide(booleen) => write!(f, "Le booleen \"{}\" est invalide.", booleen),
Self::ComparaisonInvalide(raison) => write!(f, "La comparaison est invalide, {}.", raison),
Self::MauvaisArgument(message) => write!(f, "La commande a reçu un mauvais argument, {}.", message), Self::MauvaisArgument(message) => write!(f, "La commande a reçu un mauvais argument, {}.", message),
Self::ManquePonctuation => write!(f, "Il manque la ponctuation de la phrase."),
Self::NombreInvalide(nombre) => write!(f, "Le nombre \"{}\" est mal orthographié.", nombre),
Self::CalculEntier(raison) => write!(f, "Calcul entier échoué, {}.", raison),
Self::OrdreCalculEntier(manque, precedent, suivant) => write!(f, "Calcul entier échoué, il manque un {} entre '{}' et '{}'.", manque, precedent, suivant),
Self::TexteInvalide(raison) => write!(f, "Le texte est invalide, {}.", raison),
Self::BooleenInvalide(booleen) => write!(f, "Le booleen \"{}\" est invalide.", booleen),
Self::CalculBooleen(raison) => write!(f, "Calcul booleen échoué, {}.", raison),
Self::ComparaisonInvalide(raison) => write!(f, "La comparaison est invalide, {}.", raison),
Self::OrdreCalculBooleen(manque, precedent, suivant) => write!(f, "Calcul boolen échoué, il manque un {} entre '{}' et '{}'.", manque, precedent, suivant),
Self::VariableInconnue(nom) => write!(f, "La variable \"{}\" est inconnue.", nom), 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::MauvaisType(nom, type_variable, type_attendu) => write!(f, "La {} est du mauvais type ({}), attendais {}.", nom, type_variable, type_attendu),
Self::ManquePonctuation => write!(f, "Il manque la ponctuation de la phrase."),
Self::Lecture(raison) => write!(f, "Lecture d'entrées utilisateur impossible : {}.", raison), 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

@ -32,7 +32,7 @@ impl Pendragon {
} }
for phrase in phrases { for phrase in phrases {
if phrase.ends_with(".") { if phrase.ends_with(".") {
if phrase.starts_with("Nota Bene :") { if phrase.replace(" ", "").starts_with("NotaBene:") {
continue continue
} }
match self.compile_commande(&phrase[..phrase.len() - 1]) { match self.compile_commande(&phrase[..phrase.len() - 1]) {
@ -131,12 +131,46 @@ mod test {
#[test] #[test]
fn commentaire_valide() { fn commentaire_valide() {
panic!("todo"); let mut pendragon = Pendragon::nouveau();
let commentaires = [
"Nota Bene : ceci est un commentaire.",
"NotaBene : ceci est un commentaire.",
"Nota Bene: ceci est un commentaire.",
"NotaBene: ceci est un commentaire.",
"Nota Bene :ceci est un commentaire.",
"NotaBene :ceci est un commentaire.",
"Nota Bene:ceci est un commentaire.",
"NotaBene:ceci est un commentaire."
];
for commentaire in commentaires {
match pendragon.compile(commentaire.into()) {
Ok(_) => assert_eq!(pendragon.programme.commandes.len(), 0, "Le commentaire '{}' ne devrait pas générer de commande", commentaire),
Err(raison) => panic!("Erreur de compilation du commentaire '{}' : {}", commentaire, raison)
}
}
} }
#[test] #[test]
fn commentaire_invalide() { fn commentaire_invalide() {
panic!("todo"); let mut pendragon = Pendragon::nouveau();
let commentaires = [
"Nota Bene ceci n'est pas un commentaire.",
"Nota bene : ceci n'est pas un commentaire.",
"Nota ene: ceci n'est pas un commentaire.",
"notaBene: ceci n'est pas un commentaire.",
"NotBene :ceci n'est pas un commentaire.",
"NotaBenececi n'est pas un commentaire.",
"notabene:ceci n'est pas un commentaire.",
"NNotaBene:ceci n'est pas un commentaire."
];
for commentaire in commentaires {
let Err(erreur) = pendragon.compile(commentaire.into()) else {
panic!("Ne devrait pas pouvoir compiler un commentaire invalide '{}'", commentaire);
};
let ErreurPendragon::CommandeInconnue(_) = erreur.raison() else {
panic!("Erreur inattendue de compilation du commentaire '{}' : {}", commentaire, erreur.raison());
};
}
} }
#[test] #[test]

View file

@ -67,14 +67,14 @@ impl Pendragon {
} }
"ouvre-la-parenthese" => { "ouvre-la-parenthese" => {
if !precede_par_operation { if !precede_par_operation {
return Err(ErreurPendragon::CalculEntier(format!("il manque un opérateur entre '{}' l'ouverture de parenthèse", element_precedent))) return Err(ErreurPendragon::OrdreCalculEntier("opérateur".into(), element_precedent.into(), "l'ouverture de parenthèse".into()))
} }
pile_operateurs.push(Operateur::ParentheseEntier); pile_operateurs.push(Operateur::ParentheseEntier);
continue continue
} }
"ferme-la-parenthese" => { "ferme-la-parenthese" => {
if precede_par_operation { if precede_par_operation {
return Err(ErreurPendragon::CalculEntier(format!("il manque un nombre entre '{}' et la fermeture de parenthèse", element_precedent))) return Err(ErreurPendragon::OrdreCalculEntier("nombre".into(), element_precedent.into(), "la fermeture de parenthèse".into()))
} }
while let Some(operateur) = pile_operateurs.pop() { while let Some(operateur) = pile_operateurs.pop() {
if operateur == Operateur::ParentheseEntier { if operateur == Operateur::ParentheseEntier {
@ -86,7 +86,7 @@ impl Pendragon {
} }
autre => { autre => {
if !precede_par_operation { if !precede_par_operation {
return Err(ErreurPendragon::CalculEntier(format!("il manque un opérateur entre '{}' et '{}'", element_precedent, autre))) return Err(ErreurPendragon::OrdreCalculEntier("opérateur".into(), element_precedent.into(), autre.into()))
} }
precede_par_operation = false; precede_par_operation = false;
if format_de_variable(autre) { if format_de_variable(autre) {
@ -99,7 +99,7 @@ impl Pendragon {
} }
} }
if precede_par_operation { if precede_par_operation {
return Err(ErreurPendragon::CalculEntier(format!("il manque un nombre entre '{}' et '{}'", element_precedent, element))) return Err(ErreurPendragon::OrdreCalculEntier("nombre".into(), element_precedent.into(), element.into()))
} }
precede_par_operation = true; precede_par_operation = true;
} }
@ -222,8 +222,6 @@ fn petit_nombre_comme_texte(nombre: usize) -> String {
let dizaine = (nombre % 100) / 10; let dizaine = (nombre % 100) / 10;
let unité = nombre % 10; let unité = nombre % 10;
let décalage_dizaine = if [1, 7, 9].contains(&dizaine) {1} else {0};
let centaine_texte = if centaine > 1 { let centaine_texte = if centaine > 1 {
format!("{}{}cent", NOMS_UNITES[centaine], UNION) format!("{}{}cent", NOMS_UNITES[centaine], UNION)
} else if centaine > 0 { } else if centaine > 0 {
@ -232,28 +230,23 @@ fn petit_nombre_comme_texte(nombre: usize) -> String {
"".to_string() "".to_string()
}; };
let dizaine_union = if centaine > 0 && dizaine > 0 { let décalage_dizaine = if [1, 7, 9].contains(&dizaine) {1} else {0};
UNION.to_string()
} else {
"".to_string()
};
let dizaine_texte = NOMS_DIZAINES[dizaine - décalage_dizaine]; let dizaine_texte = NOMS_DIZAINES[dizaine - décalage_dizaine];
let séparation = if unité == 1 && ![0, 1, 8, 9].contains(&dizaine) {UNION.to_string() + "et"} else {"".to_string()}; let séparation = if unité == 1 && ![0, 1, 8, 9].contains(&dizaine) {UNION.to_string() + "et"} else {"".to_string()};
let unité_texte = if [1, 7, 9].contains(&dizaine) {NOMS_UNITES_DIX[unité]} else {NOMS_UNITES[unité]};
let unité_union = if (nombre - unité > 0 && unité > 0 && (nombre%100 > 16 || nombre%100 < 10)) || (unité == 0 && dizaine == 7) { let mut texte_nombre = format!("{}{}{}{}{}{}", centaine_texte, UNION, dizaine_texte, séparation, UNION, unité_texte);
UNION.to_string()
} else {
"".to_string()
};
let unité_texte = if [1, 7, 9].contains(&dizaine) {
unité_union + NOMS_UNITES_DIX[unité]
} else {
unité_union + NOMS_UNITES[unité]
};
format!("{}{}{}{}{}", centaine_texte, dizaine_union, dizaine_texte, séparation, unité_texte) while texte_nombre.contains("--") {
texte_nombre = texte_nombre.replace("--","-");
}
if texte_nombre.starts_with("-") {
texte_nombre = texte_nombre[1..texte_nombre.len()].to_string();
}
if texte_nombre.ends_with("-") {
texte_nombre = texte_nombre[0..texte_nombre.len()-1].to_string();
}
texte_nombre
} }
pub fn texte_comme_nombre(texte: &str) -> Result<Element, ErreurPendragon> { pub fn texte_comme_nombre(texte: &str) -> Result<Element, ErreurPendragon> {
@ -378,10 +371,14 @@ fn texte_comme_petit_nombre(texte: &str) -> Result<usize, ErreurPendragon> {
mod test { mod test {
use std::collections::HashMap; use std::collections::HashMap;
use super::*; use super::*;
#[test] #[test]
fn conversion_nombres_texte() { fn conversion_nombres_texte() {
for i in [0, 1, 42, 70, 123, 999, 1031, 1_001_091, 72_036_854_775_807usize].iter() { for i in [0, 1, 42, 70, 123, 999, 1031, 1_001_091, 72_036_854_775_807usize, 2345678*987654].iter() {
let texte = nombre_comme_texte(*i); // Convert number to text let texte = nombre_comme_texte(*i); // Convert number to text
if texte.contains("--") {
panic!("Il y a deux tirets pour {} : {}", i, texte);
}
match texte_comme_nombre(&texte) { // Convert text back to number match texte_comme_nombre(&texte) { // Convert text back to number
Ok(nombre) => { Ok(nombre) => {
assert_eq!(Element::Entier(*i), nombre, "Nombre inexact : {}, texte : {}", i, texte); assert_eq!(Element::Entier(*i), nombre, "Nombre inexact : {}, texte : {}", i, texte);
@ -440,7 +437,7 @@ mod test {
let Err(raison) = pendragon.elements_nombre(texte) else { let Err(raison) = pendragon.elements_nombre(texte) else {
panic!("Devrait détecter une erreur pour '{}'", texte); panic!("Devrait détecter une erreur pour '{}'", texte);
}; };
let ErreurPendragon::CalculEntier(_) = raison else { let ErreurPendragon::OrdreCalculEntier(_,_,_) = raison else {
panic!("Devrait détecter une erreur de calcul entier pour '{}', a déclenché : {}", texte, raison); panic!("Devrait détecter une erreur de calcul entier pour '{}', a déclenché : {}", texte, raison);
}; };
} }

View file

@ -37,47 +37,46 @@ impl Pendragon {
pile_inconnu.push(element.into()); pile_inconnu.push(element.into());
continue; continue;
} }
self.puis(&mut expression, &mut pile_inconnu)?; expression.extend(self.puis(&expression, &pile_inconnu)?);
pile_inconnu = Vec::new();
expression.push(Element::Operateur(Operateur::Puis));
} }
self.puis(&mut expression, &mut pile_inconnu)?; expression.extend(self.puis(&expression, &pile_inconnu)?);
pile_inconnu = Vec::new();
expression.push(Element::Operateur(Operateur::Puis));
Ok(expression) Ok(expression)
} }
pub fn puis(&self, expression: &mut Vec<Element>, pile_inconnu: &mut Vec<String>) -> Result<(), ErreurPendragon> { pub fn puis(&self, expression: &Vec<Element>, pile_inconnu: &Vec<String>) -> Result<Vec<Element>, ErreurPendragon> {
let Some(premier_element) = pile_inconnu.first() else {
if let Some(dernier_element) = expression.last() { if let Some(dernier_element) = expression.last() {
if let Element::Texte(_) = dernier_element.clone() { if let Element::Texte(_) = dernier_element.clone() {
if pile_inconnu.is_empty() { return Ok(vec![]);
expression.push(Element::Operateur(Operateur::Puis));
return Ok(());
} }
} }
}
let Some(premier_element) = pile_inconnu.first() else {
return Err(ErreurPendragon::TexteInvalide("il manque un élément avant le puis".into())) return Err(ErreurPendragon::TexteInvalide("il manque un élément avant le puis".into()))
}; };
let total_inconnu = pile_inconnu.join(" ");
if total_inconnu == "alinéa" {
return Ok(vec![Element::Texte("\t".into())])
}
if total_inconnu == "retour à la ligne" {
return Ok(vec![Element::Texte("\n".into())])
}
if pile_inconnu.len() == 1 && format_de_variable(premier_element) { if pile_inconnu.len() == 1 && format_de_variable(premier_element) {
expression.push(Element::Variable(premier_element.into(), self.programme.variable(premier_element)?)); return Ok(vec![Element::Variable(premier_element.into(), self.programme.variable(premier_element)?)]);
*pile_inconnu = Vec::new();
expression.push(Element::Operateur(Operateur::Puis));
return Ok(());
} }
let Err(raison) = self.elements_nombre(premier_element) else { let Err(raison) = self.elements_nombre(premier_element) else {
expression.extend(self.elements_nombre(&pile_inconnu.join(" "))?); return self.elements_nombre(&total_inconnu)
*pile_inconnu = Vec::new();
expression.push(Element::Operateur(Operateur::Puis));
return Ok(())
}; };
if let ErreurPendragon::CalculEntier(_) = raison { if let ErreurPendragon::CalculEntier(_) = raison {
return Err(raison) return Err(raison)
} }
let Err(raison) = self.elements_booleen(premier_element) else { let Err(raison) = self.elements_booleen(premier_element) else {
expression.extend(self.elements_booleen(&pile_inconnu.join(" "))?); return self.elements_booleen(&total_inconnu)
*pile_inconnu = Vec::new();
expression.push(Element::Operateur(Operateur::Puis));
return Ok(());
}; };
let ErreurPendragon::CalculBooleen(_) = raison else { let ErreurPendragon::CalculBooleen(_) = raison else {
return Err(ErreurPendragon::MauvaisArgument(pile_inconnu.join(" ").to_string())); return Err(ErreurPendragon::TexteInvalide(format!("'{}' ne peut pas être converti en texte", pile_inconnu.join(" "))));
}; };
Err(raison) Err(raison)
} }
@ -145,14 +144,14 @@ mod test {
let a = 2345678; let a = 2345678;
let b = 987654; let b = 987654;
let possible_expression = pendragon.elements_texte(&format!("\"hello\" puis {} fois {} puis \"there\" puis vrai ou faux puis trois puis deux", let possible_expression = pendragon.elements_texte(&format!("\"hello\" puis {} fois {} puis \"there\" puis vrai ou faux puis trois puis deux puis alinéa puis retour à la ligne",
nombre::nombre_comme_texte(a), nombre::nombre_comme_texte(a),
nombre::nombre_comme_texte(b))); nombre::nombre_comme_texte(b)));
match possible_expression { match possible_expression {
Ok(expression) => { Ok(expression) => {
match calcule_texte(expression, &HashMap::new()) { match calcule_texte(expression, &HashMap::new()) {
Ok(texte) => { Ok(texte) => {
let vrai_texte = format!("hello{}therevraitroisdeux", nombre::nombre_comme_texte(a*b)); let vrai_texte = format!("hello{}therevraitroisdeux\t\n", nombre::nombre_comme_texte(a*b));
assert_eq!(texte, vrai_texte, "Calcul d'expression (texte) donne un mauvais résultat : {}", texte); assert_eq!(texte, vrai_texte, "Calcul d'expression (texte) donne un mauvais résultat : {}", texte);
} }
Err(raison) => { Err(raison) => {
@ -189,6 +188,9 @@ mod test {
let textes = vec![ let textes = vec![
"trois puis puis un", "trois puis puis un",
"\" test", "\" test",
"puis",
"un puis",
"puis un",
]; ];
for texte in textes { for texte in textes {
let Err(raison) = pendragon.elements_texte(texte) else { let Err(raison) = pendragon.elements_texte(texte) else {

View file

@ -0,0 +1,54 @@
pub enum MotCle {
Definis,
Modifie,
Affiche,
Demande,
Si,
Sinon,
NotaBene,
Plus,
Moins,
Fois,
Divise,
Et,
Ou,
Non,
OuvreParenthese,
FermeParenthese,
Puis,
Alinea,
RetourLigne,
}
pub impl MotCle {
fn comme_texte(&self) -> String {
match Self {
Self::Definis,
Self::Modifie,
Self::Affiche,
Self::Demande,
Self::Si,
Self::Sinon,
Self::NotaBene,
Plus,
Moins,
Fois,
Divise,
Et,
Ou,
Non,
OuvreParenthese,
FermeParenthese,
Puis,
Alinea,
RetourLigne,
}
}
fn depuis_texte(texte: &str) -> Self {
match texte {
}
}

View file

@ -1,9 +1,9 @@
Définis A comme entier. Définis A comme entier. Définis F comme texte.
Définis B comme entier. Définis B comme entier.
Définis C comme entier. Définis C comme entier.
Nota Bene : A est la variable pour un polynôme. Nota Bene : A est la variable pour un polynôme.
Modifie A avec dix-sept. Modifie A avec dix-sept plus trois.
Modifie C avec six-cent-soixante-douze. Modifie C avec six-cent-soixante-douze.
Modifie B avec trois fois A fois ouvre la parenthèse trois fois A plus C ferme la parenthèse. Modifie B avec trois fois A fois ouvre la parenthèse trois fois A plus C ferme la parenthèse.
Nota Bene : 3*A*(3*A+C). Nota Bene : 3*A*(3*A+C).
@ -16,4 +16,4 @@ Définis Bool comme booléen.
Modifie Bool avec vrai. Modifie Bool avec vrai.
Affiche vrai et faux. Affiche vrai et faux.
Affiche trois plus un. Affiche alinéa puis trois plus un puis retour à la ligne puis "test".