commentaires, et verification d'expression booleenne
This commit is contained in:
parent
3d0e04f4fb
commit
ec8fa1bcf8
|
@ -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":[]}]}
|
49
src/main.rs
49
src/main.rs
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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]),
|
||||
|
|
|
@ -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 => {
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
16
test.dr
|
@ -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.
|
Loading…
Reference in a new issue