comparaison logic
This commit is contained in:
parent
989f1f17fd
commit
b82fdb8073
|
@ -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))),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue