comparaison logic

This commit is contained in:
WanderingPenwing 2024-12-10 17:20:13 +01:00
parent 989f1f17fd
commit b82fdb8073
3 changed files with 138 additions and 34 deletions

View file

@ -4,17 +4,19 @@ impl Pendragon {
pub fn elements_booleen(&self, arguments: &str) -> Result<Vec<Element>, ErreurPendragon> {
let texte = arguments
.replace("ouvre la parenthèse", "ouvre-la-parenthese")
.replace("ferme la parenthèse", "ferme-la-parenthese");
.replace("est égal à", "est-egal-a");
.replace("est différent de", "est-different-de");
.replace("est supérieur ou égal à", "est-superieur-ou-egal-a");
.replace("est inférieur ou égal à", "est-inferieur-ou-egal-a");
.replace("est supérieur à", "est-superieur-a");
.replace("ferme la parenthèse", "ferme-la-parenthese")
.replace("est égal à", "est-egal-a")
.replace("est différent de", "est-different-de")
.replace("est supérieur ou égal à", "est-superieur-ou-egal-a")
.replace("est inférieur ou égal à", "est-inferieur-ou-egal-a")
.replace("est supérieur à", "est-superieur-a")
.replace("est inférieur à", "est-inferieur-a");
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 comparaison: Vec<Element> = Vec::new();
let mut pile_inconnu: Vec<String> = Vec::new();
let mut possible_comparaison: Option<Comparaison> = None;
for element in elements_texte {
match element {
@ -51,12 +53,36 @@ impl Pendragon {
}
}
autre => {
if !format_de_variable(autre) {
return Err(ErreurPendragon::MauvaisArgument(format!("{}", autre)))
}
self.programme.variable_est_de_type(autre, TypeElement::Booleen)?;
if format_de_variable(autre) {
if let Ok(_) = self.programme.variable_est_de_type(autre, TypeElement::Booleen) {
expression.push(Element::Variable(autre.into(), TypeElement::Booleen));
} else {
pile_inconnu.push(autre.into());
continue;
}
} else if let Ok(type_comparaison) = texte_comme_comparaison(autre) {
if let Some(comparaison) = possible_comparaison {
return Err(ErreurPendragon::BooleenInvalide(format!("besoin d'un operateur booleen entre {:?} et {:?}", comparaison, type_comparaison)))
}
let mut comparaison = Comparaison::nouvelle();
self.ajoute_comparaison_membre(&mut comparaison, &pile_inconnu.join(" "))?;
comparaison.ajoute_type(type_comparaison)?;
pile_inconnu = Vec::new();
continue;
} else {
pile_inconnu.push(autre.into());
continue;
}
}
}
if !pile_inconnu.is_empty() {
let Some(mut comparaison) = possible_comparaison else {
return Err(ErreurPendragon::BooleenInvalide(format!("{:?}", pile_inconnu)))
};
self.ajoute_comparaison_membre(&mut comparaison, &pile_inconnu.join(" "))?;
expression.push(Element::Comparaison(comparaison.clone()));
pile_inconnu = Vec::new();
possible_comparaison = None;
}
}
@ -66,6 +92,35 @@ impl Pendragon {
Ok(expression)
}
pub fn ajoute_comparaison_membre(&self, comparaison: &mut Comparaison, texte: &str) -> Result<(), ErreurPendragon> {
let membre = if let Ok(elements_nombre) = self.elements_nombre(texte) {
elements_nombre
} else if let Ok(elements_booleen) = self.elements_booleen(texte) {
elements_booleen
} else if let Ok(elements_texte) = self.elements_texte(texte) {
elements_texte
} else {
return Err(ErreurPendragon::MauvaisArgument(texte.to_string()));
};
let Some(element) = membre.first() else {
return Err(ErreurPendragon::ComparaisonInvalide("il n'y a pas de d'élément dans le membre ajouté".into()))
};
if comparaison.type_comparaison.is_none() {
comparaison.membre_a = membre;
return Ok(());
}
let Some(element_de_comparaison) = comparaison.membre_a.first() else {
return Err(ErreurPendragon::ComparaisonInvalide("il n'y a pas de premier membre".into()))
};
if element_de_comparaison.type_element() != element.type_element() {
return Err(ErreurPendragon::MauvaisType(
format!("{:?}", element), element.type_element().nom(),
element_de_comparaison.type_element().nom()))
}
comparaison.membre_b = membre;
Ok(())
}
}
pub fn affiche_booleen(expression: Vec<Element>, variables: &HashMap<String, Element>) -> Result<String, ErreurPendragon> {
@ -139,6 +194,18 @@ pub fn texte_comme_booleen(texte: &str) -> Result<Element, ErreurPendragon> {
}
}
pub fn texte_comme_comparaison(texte: &str) -> Result<TypeComparaison, ErreurPendragon> {
match texte {
"est-egal-a" => Ok(TypeComparaison::Egal),
"est-different-de" => Ok(TypeComparaison::Different),
"est-superieur-ou-egal-a" => Ok(TypeComparaison::SuperieurEgal),
"est-inferieur-ou-egal-a" => Ok(TypeComparaison::InferieurEgal),
"est-superieur-a" => Ok(TypeComparaison::Superieur),
"est-inferieur-a" => Ok(TypeComparaison::Inferieur),
_ => Err(ErreurPendragon::ComparaisonInvalide(format!("\"{}\" n'est pas un type de comparaison", texte))),
}
}

View file

@ -7,6 +7,7 @@ pub enum ErreurPendragon {
NombreInvalide(String),
BooleenInvalide(String),
TexteInvalide(String),
ComparaisonInvalide(String),
MauvaisArgument(String),
VariableInconnue(String),
MauvaisType(String, String, String),
@ -23,10 +24,11 @@ impl fmt::Display for ErreurPendragon {
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 mal orthographié.", booleen),
Self::BooleenInvalide(booleen) => write!(f, "Le booleen \"{}\" est ivalide.", 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::VariableInconnue(nom) => write!(f, "La variable \"{}\" est inconnue.", nom),
Self::MauvaisType(nom, type_variable, type_attendu) => write!(f, "La variable {} 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::ManquePoint => write!(f, "Il manque un point."),
Self::Lecture(raison) => write!(f, "Lecture d'entrées utilisateur impossible : {}.", raison),
Self::CalculBooleen(raison) => write!(f, "Calcul booleen échoué, {}.", raison),

View file

@ -160,7 +160,7 @@ impl Element {
match self {
Self::Entier(_) => TypeElement::Entier,
Self::Texte(_) => TypeElement::Texte,
Self::Booleen(_) || Self::Comparaison(_) => TypeElement::Booleen,
Self::Booleen(_) | Self::Comparaison(_) => TypeElement::Booleen,
Self::Variable(_, type_element) => type_element.clone(),
Self::Operateur(operateur) => operateur.type_element(),
}
@ -191,16 +191,51 @@ impl Operateur {
}
}
pub enum Comparaison {
Egal(Element, Element),
Different(Element, Element),
Superieur(Element, Element),
Inferieur(Element, Element),
SuperieurEgal(Element, Element),
InferieurEgal(Element, Element)
#[derive(Clone, Debug, PartialEq)]
pub struct Comparaison {
pub type_comparaison: Option<TypeComparaison>,
pub membre_a: Vec<Element>,
pub membre_b: Vec<Element>,
}
impl Comparaison {
pub fn nouvelle() -> Self {
Self {
type_comparaison: None,
membre_a: vec![],
membre_b: vec![]
}
}
pub fn ajoute_type(&mut self, type_comparaison: TypeComparaison) -> Result<(), ErreurPendragon> {
let Some(element) = self.membre_a.first() else {
return Err(ErreurPendragon::ComparaisonInvalide("il n'y a pas de premier membre".into()))
};
if let TypeComparaison::Egal = type_comparaison {
self.type_comparaison = Some(type_comparaison);
return Ok(());
}
if let TypeComparaison::Different = type_comparaison {
self.type_comparaison = Some(type_comparaison);
return Ok(());
}
if let TypeElement::Entier = element.type_element() {
self.type_comparaison = Some(type_comparaison);
return Ok(());
}
return Err(ErreurPendragon::ComparaisonInvalide(format!("voulait comparer {} avec {:?}", element.type_element().nom(), type_comparaison)))
}
}
#[derive(Clone, Debug, PartialEq)]
pub enum TypeComparaison {
Egal,
Different,
SuperieurEgal,
InferieurEgal,
Superieur,
Inferieur,
}