added input
This commit is contained in:
parent
25e2a01dd1
commit
ba6facd439
|
@ -1,11 +1,28 @@
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::io;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
pub mod nombres;
|
pub mod nombres;
|
||||||
|
pub mod texte;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|
||||||
|
#[derive(PartialEq, Debug)]
|
||||||
|
pub enum Variable {
|
||||||
|
Entier(usize),
|
||||||
|
Texte(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Variable {
|
||||||
|
pub fn nom_type(&self) -> String {
|
||||||
|
match self {
|
||||||
|
Self::Entier(_) => "entier".into(),
|
||||||
|
Self::Texte(_) => "texte".into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub enum ErreurSophie {
|
pub enum ErreurSophie {
|
||||||
CommandeInconnue(String),
|
CommandeInconnue(String),
|
||||||
PhraseVide,
|
PhraseVide,
|
||||||
|
@ -14,13 +31,8 @@ pub enum ErreurSophie {
|
||||||
MauvaisArgument(String),
|
MauvaisArgument(String),
|
||||||
DesequilibreParenthese,
|
DesequilibreParenthese,
|
||||||
VariableInconnue(String),
|
VariableInconnue(String),
|
||||||
MauvaisType(String),
|
MauvaisType(String, String, String),
|
||||||
}
|
ProblemeTerminal(String),
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
|
||||||
pub enum Variable {
|
|
||||||
Entier(usize),
|
|
||||||
Texte(String),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for ErreurSophie {
|
impl fmt::Display for ErreurSophie {
|
||||||
|
@ -33,7 +45,8 @@ impl fmt::Display for ErreurSophie {
|
||||||
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::DesequilibreParenthese => write!(f, "Les parenthèses sont déséquilibrés."),
|
Self::DesequilibreParenthese => write!(f, "Les parenthèses sont déséquilibrés."),
|
||||||
Self::VariableInconnue(nom) => write!(f, "La variable \"{}\" est inconnue.", nom),
|
Self::VariableInconnue(nom) => write!(f, "La variable \"{}\" est inconnue.", nom),
|
||||||
Self::MauvaisType(attendu) => write!(f, "La variable est du mauvais type, {}.", attendu),
|
Self::MauvaisType(nom, type_variable, type_attendu) => write!(f, "La variable {} est du mauvais type ({}), attendais {}.", nom, type_variable, type_attendu),
|
||||||
|
Self::ProblemeTerminal(probleme) => write!(f, "Problème d'accès terminal : {}.", probleme),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,41 +127,54 @@ impl Sophie {
|
||||||
return Err(ErreurSophie::VariableInconnue(variable_nom))
|
return Err(ErreurSophie::VariableInconnue(variable_nom))
|
||||||
}
|
}
|
||||||
|
|
||||||
let valeur = self.operation(&contenu)?;
|
let valeur = match self.variables[&variable_nom] {
|
||||||
self.variables.insert(variable_nom, Variable::Entier(valeur));
|
Variable::Entier(_) => Variable::Entier(self.operation(&contenu)?),
|
||||||
|
Variable::Texte(_) => Variable::Texte(self.texte(&contenu)?),
|
||||||
|
};
|
||||||
|
self.variables.insert(variable_nom, valeur);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn affiche(&self, arguments: &str) -> Result<(), ErreurSophie> {
|
fn affiche(&self, arguments: &str) -> Result<(), ErreurSophie> {
|
||||||
let liste_arguments: Vec<&str> = arguments.split(',').collect();
|
println!("{}", self.texte(arguments)?);
|
||||||
|
|
||||||
let mut texte = "".to_string();
|
|
||||||
|
|
||||||
for argument in liste_arguments {
|
|
||||||
let argument: &str = argument.trim();
|
|
||||||
if argument.starts_with('"') {
|
|
||||||
if argument.ends_with('"') {
|
|
||||||
texte += &argument[1..argument.len()-1];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let resultat = self.operation(argument)?;
|
|
||||||
texte += &nombres::nombre_comme_texte(resultat);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
println!("{}", texte);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn demande(&self, arguments: &str) -> Result<(), ErreurSophie> {
|
fn demande(&mut self, arguments: &str) -> Result<(), ErreurSophie> {
|
||||||
println!("- demande : {}", arguments);
|
let (variable_nom, _) = nom_de_variable(arguments, "")?;
|
||||||
|
|
||||||
|
if !self.variables.contains_key(&variable_nom) {
|
||||||
|
return Err(ErreurSophie::VariableInconnue(variable_nom))
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("Quelle valeur pour {} ?", variable_nom);
|
||||||
|
let mut reponse: String = String::new();
|
||||||
|
if let Err(_) = io::stdin().read_line(&mut reponse) {
|
||||||
|
return Err(ErreurSophie::ProblemeTerminal("lecture d'entrées utilisateur impossible".into()))
|
||||||
|
}
|
||||||
|
|
||||||
|
let contenu = reponse.trim();
|
||||||
|
|
||||||
|
let valeur = match self.variables[&variable_nom] {
|
||||||
|
Variable::Entier(_) => Variable::Entier(self.operation(contenu)?),
|
||||||
|
Variable::Texte(_) => Variable::Texte(contenu.into()),
|
||||||
|
};
|
||||||
|
self.variables.insert(variable_nom, valeur);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn nom_de_variable(arguments: &str, separateur: &str) -> Result<(String, String), ErreurSophie> {
|
fn nom_de_variable(arguments: &str, separateur: &str) -> Result<(String, String), ErreurSophie> {
|
||||||
let parties: Vec<&str> = arguments.splitn(2, separateur).collect();
|
let parties = if separateur == "" {
|
||||||
let nom_variable: String = parties[0].trim().to_string();
|
vec![arguments, ""]
|
||||||
|
} else {
|
||||||
|
arguments.splitn(2, separateur).collect()
|
||||||
|
};
|
||||||
|
|
||||||
|
let nom_variable = parties[0].trim().to_string();
|
||||||
|
|
||||||
if parties.len() == 1 {
|
if parties.len() == 1 {
|
||||||
return Err(ErreurSophie::ManqueArgument)
|
return Err(ErreurSophie::ManqueArgument)
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,7 +101,7 @@ impl Sophie {
|
||||||
if texte.chars().next().map_or(false, |c| c.is_uppercase()) {
|
if texte.chars().next().map_or(false, |c| c.is_uppercase()) {
|
||||||
if self.variables.contains_key(texte) {
|
if self.variables.contains_key(texte) {
|
||||||
let Variable::Entier(nombre) = self.variables[texte] else {
|
let Variable::Entier(nombre) = self.variables[texte] else {
|
||||||
return Err(ErreurSophie::MauvaisType("attendais entier".to_string()))
|
return Err(ErreurSophie::MauvaisType(texte.into(), self.variables[texte].nom_type(), "entier".into()))
|
||||||
};
|
};
|
||||||
return Ok(nombre);
|
return Ok(nombre);
|
||||||
} else {
|
} else {
|
||||||
|
@ -184,7 +184,7 @@ fn petit_nombre_comme_texte(nombre: usize) -> String {
|
||||||
|
|
||||||
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é_union = if nombre - unité > 0 && unité > 0 && nombre > 16 {
|
let unité_union = if nombre - unité > 0 && unité > 0 && (nombre%100 > 16 || nombre%100 < 10) {
|
||||||
UNION.to_string()
|
UNION.to_string()
|
||||||
} else {
|
} else {
|
||||||
"".to_string()
|
"".to_string()
|
||||||
|
|
|
@ -103,10 +103,26 @@ fn teste_maths() {
|
||||||
nombres::nombre_comme_texte(e)));
|
nombres::nombre_comme_texte(e)));
|
||||||
match resultat {
|
match resultat {
|
||||||
Ok(nombre) => {
|
Ok(nombre) => {
|
||||||
assert_eq!(nombre, a*b+(c-d)/e, "Echec de l'opération mathématique, got {}", nombre);
|
assert_eq!(nombre, a*b+(c-d)/e, "Echec de l'opération mathématique, résultat : {}", nombre);
|
||||||
}
|
}
|
||||||
Err(raison) => {
|
Err(raison) => {
|
||||||
panic!("Execution échouée pour multiplication, avec l'erreur : {}", raison);
|
panic!("Execution échouée pour multiplication, avec l'erreur : {}", raison);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------- anti-test
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn teste_echec_modification() {
|
||||||
|
let mut sophie = Sophie::new();
|
||||||
|
let resultat = sophie.execute_phrase("Modifie Variable avec deux");
|
||||||
|
let Err(raison) = resultat else {
|
||||||
|
panic!("Ne devrais pas pouvoir modifier une variable non définie");
|
||||||
|
};
|
||||||
|
if let ErreurSophie::VariableInconnue(nom) = raison {
|
||||||
|
assert_eq!(nom, "Variable", "Mauvais nom de variable reconnu : {}", nom);
|
||||||
|
} else {
|
||||||
|
panic!("Modification échouée avec erreur imprévue : {}", raison);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
35
src/sophie/texte.rs
Normal file
35
src/sophie/texte.rs
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
use super::Sophie;
|
||||||
|
use super::ErreurSophie;
|
||||||
|
use super::Variable;
|
||||||
|
use super::nombres;
|
||||||
|
|
||||||
|
impl Sophie {
|
||||||
|
pub fn texte(&self, arguments: &str) -> Result<String, ErreurSophie> {
|
||||||
|
let liste_arguments: Vec<&str> = arguments.split(',').collect();
|
||||||
|
|
||||||
|
let mut texte = "".to_string();
|
||||||
|
|
||||||
|
for argument in liste_arguments {
|
||||||
|
let argument: &str = argument.trim();
|
||||||
|
if argument.starts_with('"') {
|
||||||
|
if argument.ends_with('"') {
|
||||||
|
texte += &argument[1..argument.len()-1];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let resultat: String = if argument.contains(" ") {
|
||||||
|
nombres::nombre_comme_texte(self.operation(argument)?)
|
||||||
|
} else {
|
||||||
|
if !self.variables.contains_key(argument) {
|
||||||
|
return Err(ErreurSophie::VariableInconnue(argument.into()))
|
||||||
|
}
|
||||||
|
match self.variables[argument] {
|
||||||
|
Variable::Entier(nombre) => nombres::nombre_comme_texte(nombre),
|
||||||
|
Variable::Texte(ref contenu) => contenu.to_string(),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
texte += &resultat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(texte)
|
||||||
|
}
|
||||||
|
}
|
11
test.sp
11
test.sp
|
@ -1,3 +1,14 @@
|
||||||
Définie A comme entier.
|
Définie A comme entier.
|
||||||
Modifie A avec mille-cinq-cent-cinquante-cinq fois treize.
|
Modifie A avec mille-cinq-cent-cinquante-cinq fois treize.
|
||||||
Affiche "A : ", A.
|
Affiche "A : ", A.
|
||||||
|
Définie B comme texte.
|
||||||
|
Modifie B avec "hello there", " general", " Kenobi".
|
||||||
|
Affiche "Combo : ", B, " / ", ouvre la parenthèse un plus cinq ferme la parenthèse fois ouvre la parenthèse huit moins un ferme la parenthèse.
|
||||||
|
Modifie B avec deux plus trois.
|
||||||
|
Demande B.
|
||||||
|
Affiche "Texte B : ", B.
|
||||||
|
Demande A.
|
||||||
|
Modifie A avec A fois deux.
|
||||||
|
Affiche "fois deux : ", A.
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue