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":[]}]}
|
||||||
|
|
35
src/main.rs
35
src/main.rs
|
@ -1,5 +1,6 @@
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
mod pendragon;
|
mod pendragon;
|
||||||
use pendragon::*;
|
use pendragon::*;
|
||||||
|
@ -17,22 +18,34 @@ fn main() {
|
||||||
let chemin_de_fichier = &arguments[1];
|
let chemin_de_fichier = &arguments[1];
|
||||||
let mut pendragon = Pendragon::nouveau();
|
let mut pendragon = Pendragon::nouveau();
|
||||||
|
|
||||||
match fs::read_to_string(chemin_de_fichier) {
|
let lecture = fs::read_to_string(chemin_de_fichier);
|
||||||
Ok(contenu) => {
|
|
||||||
let Ok(_) = pendragon.compile(contenu) else {
|
if let Err(raison) = lecture {
|
||||||
eprintln!("\n# Échec de la compilation");
|
eprintln!("Fichier illisible : {}", raison);
|
||||||
return
|
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 {
|
if debug_mode {
|
||||||
println!("{}\n", pendragon.programme);
|
println!("{}\n", pendragon.programme);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
println!("# Exécution de '{}'.\n", chemin_de_fichier);
|
||||||
|
let debut = Instant::now();
|
||||||
if let Err(raison) = pendragon.programme.execute() {
|
if let Err(raison) = pendragon.programme.execute() {
|
||||||
eprintln!("Erreur Execution : {}", raison);
|
eprintln!("\nErreur : {}", raison);
|
||||||
|
eprintln!("\n# Échec de l'exécution.");
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
|
||||||
Err(raison) => {
|
println!("\n# Exécution Ok. ({:.2?})", debut.elapsed());
|
||||||
eprintln!("Fichier illisible : {}", raison);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,27 @@
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use super::*;
|
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 {
|
pub enum ErreurPendragon {
|
||||||
CommandeInconnue(String),
|
CommandeInconnue(String),
|
||||||
ManqueArgument,
|
ManqueArgument,
|
||||||
|
@ -11,7 +32,7 @@ pub enum ErreurPendragon {
|
||||||
MauvaisArgument(String),
|
MauvaisArgument(String),
|
||||||
VariableInconnue(String),
|
VariableInconnue(String),
|
||||||
MauvaisType(String, String, String),
|
MauvaisType(String, String, String),
|
||||||
ManquePoint,
|
ManquePonctuation,
|
||||||
Lecture(String),
|
Lecture(String),
|
||||||
CalculBooleen(String),
|
CalculBooleen(String),
|
||||||
CalculEntier(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::MauvaisArgument(message) => write!(f, "La commande a reçu un mauvais argument, {}.", message),
|
||||||
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::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::Lecture(raison) => write!(f, "Lecture d'entrées utilisateur impossible : {}.", raison),
|
||||||
Self::CalculBooleen(raison) => write!(f, "Calcul booleen échoué, {}.", raison),
|
Self::CalculBooleen(raison) => write!(f, "Calcul booleen échoué, {}.", raison),
|
||||||
Self::CalculEntier(raison) => write!(f, "Calcul entier échoué, {}.", raison),
|
Self::CalculEntier(raison) => write!(f, "Calcul entier échoué, {}.", raison),
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::time::Instant;
|
|
||||||
|
|
||||||
pub mod nombre;
|
pub mod nombre;
|
||||||
pub mod texte;
|
pub mod texte;
|
||||||
|
@ -20,38 +19,42 @@ impl Pendragon {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compile(&mut self, contenu: String) -> Result<(), ErreurPendragon> {
|
pub fn compile(&mut self, contenu: String) -> Result<(), ErreurCompilation> {
|
||||||
println!();
|
let texte: Vec<&str> = contenu.split('\n').collect();
|
||||||
let debut = Instant::now();
|
for (index_ligne, ligne) in texte.iter().enumerate() {
|
||||||
let contenu_propre = contenu.replace("\n", " ");
|
let ligne = ligne.trim();
|
||||||
let mut texte: Vec<&str> = contenu_propre.split('.').collect();
|
let phrases: Vec<&str> = ligne.split_inclusive(|c| c == ',' || c == '.').collect();
|
||||||
let reste = texte.pop();
|
let Some(derniere_phrase) = phrases.last() else {
|
||||||
if reste != Some("") {
|
continue
|
||||||
eprintln!("Erreur Compilation, phrase {} : Il manque un point.", texte.len() + 1);
|
};
|
||||||
return Err(ErreurPendragon::ManquePoint)
|
if !derniere_phrase.ends_with('.') && !derniere_phrase.ends_with(',') {
|
||||||
|
return Err(ErreurCompilation::nouvelle(index_ligne, ErreurPendragon::ManquePonctuation))
|
||||||
}
|
}
|
||||||
for (index_phrase, phrase) in texte.iter().enumerate() {
|
for phrase in phrases {
|
||||||
let phrase = phrase.trim();
|
if phrase.ends_with(".") {
|
||||||
match self.compile_phrase(phrase) {
|
if phrase.starts_with("Nota Bene :") {
|
||||||
Ok(commande) => {self.programme.ajoute_commande(commande)},
|
continue
|
||||||
Err(raison) => {
|
}
|
||||||
eprintln!("Erreur phrase {} : {}", index_phrase + 1, raison);
|
match self.compile_commande(&phrase[..phrase.len() - 1]) {
|
||||||
return Err(raison)
|
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(())
|
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 phrase = phrase.trim();
|
||||||
let parties: Vec<&str> = phrase.splitn(2, ' ').collect();
|
let parties: Vec<&str> = phrase.splitn(2, ' ').collect();
|
||||||
if parties.len() == 1 {
|
if parties.len() == 1 {
|
||||||
return Err(ErreurPendragon::ManqueArgument)
|
return Err(ErreurPendragon::ManqueArgument)
|
||||||
}
|
}
|
||||||
if parties[1].contains("Définis") || parties[1].contains("Modifie") || parties[1].contains("Affiche") || parties[1].contains("Demande") {
|
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] {
|
match parties[0] {
|
||||||
"Définis" => self.definis(parties[1]),
|
"Définis" => self.definis(parties[1]),
|
||||||
|
|
|
@ -15,6 +15,7 @@ impl Pendragon {
|
||||||
let elements_texte: Vec<&str> = texte.split(" ").collect();
|
let elements_texte: Vec<&str> = texte.split(" ").collect();
|
||||||
let mut expression: Vec<Element> = Vec::new();
|
let mut expression: Vec<Element> = Vec::new();
|
||||||
let mut pile_operateurs: Vec<Operateur> = Vec::new();
|
let mut pile_operateurs: Vec<Operateur> = Vec::new();
|
||||||
|
let mut precede_par_operation: bool = true;
|
||||||
|
|
||||||
for element in elements_texte {
|
for element in elements_texte {
|
||||||
match element {
|
match element {
|
||||||
|
@ -58,24 +59,43 @@ impl Pendragon {
|
||||||
}
|
}
|
||||||
pile_operateurs.push(Operateur::Divise);
|
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" => {
|
"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() {
|
while let Some(operateur) = pile_operateurs.pop() {
|
||||||
if operateur == Operateur::ParentheseEntier {
|
if operateur == Operateur::ParentheseEntier {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
expression.push(Element::Operateur(operateur));
|
expression.push(Element::Operateur(operateur));
|
||||||
}
|
}
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
autre => {
|
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) {
|
if format_de_variable(autre) {
|
||||||
self.programme.variable_est_de_type(autre, TypeElement::Entier)?;
|
self.programme.variable_est_de_type(autre, TypeElement::Entier)?;
|
||||||
expression.push(Element::Variable(autre.into(), TypeElement::Entier));
|
expression.push(Element::Variable(autre.into(), TypeElement::Entier));
|
||||||
} else {
|
} else {
|
||||||
expression.push(texte_comme_nombre(autre)?);
|
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() {
|
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);
|
pile.push(nombre_b + nombre_a);
|
||||||
}
|
}
|
||||||
Operateur::Moins => {
|
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);
|
pile.push(nombre_b - nombre_a);
|
||||||
}
|
}
|
||||||
Operateur::Fois => {
|
Operateur::Fois => {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::time::Instant;
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
@ -54,8 +53,6 @@ impl Programme {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn execute(&self) -> Result<(), ErreurPendragon> {
|
pub fn execute(&self) -> Result<(), ErreurPendragon> {
|
||||||
let debut = Instant::now();
|
|
||||||
println!("# Execution...\n");
|
|
||||||
let mut variables_globales: HashMap<String, Element> = HashMap::new();
|
let mut variables_globales: HashMap<String, Element> = HashMap::new();
|
||||||
for commande in &self.commandes {
|
for commande in &self.commandes {
|
||||||
match commande {
|
match commande {
|
||||||
|
@ -79,7 +76,6 @@ impl Programme {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
println!("\n# Exécution Ok. ({:.2?})", debut.elapsed());
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ impl Pendragon {
|
||||||
pub fn elements_texte(&self, arguments: &str) -> Result<Vec<Element>, ErreurPendragon> {
|
pub fn elements_texte(&self, arguments: &str) -> Result<Vec<Element>, ErreurPendragon> {
|
||||||
let mut expression: Vec<Element> = Vec::new();
|
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 {
|
if expression.len() > 0 {
|
||||||
expression.push(Element::Operateur(Operateur::Virgule));
|
expression.push(Element::Operateur(Operateur::Virgule));
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ mod test {
|
||||||
let a = 2345678;
|
let a = 2345678;
|
||||||
let b = 987654;
|
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(a),
|
||||||
nombre::nombre_comme_texte(b)));
|
nombre::nombre_comme_texte(b)));
|
||||||
match possible_expression {
|
match possible_expression {
|
||||||
|
|
16
test.dr
16
test.dr
|
@ -1,8 +1,10 @@
|
||||||
Affiche soixante-dix.
|
Définis A comme entier.
|
||||||
Affiche soixante-et-onze.
|
Définis B comme entier.
|
||||||
<<<<<<< HEAD
|
Définis C comme entier.
|
||||||
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.
|
Nota Bene : A est la variable pour un polynôme.
|
||||||
=======
|
|
||||||
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.
|
|
||||||
|
|
||||||
>>>>>>> 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