This commit is contained in:
WanderingPenwing 2024-12-13 18:11:16 +01:00
parent 27fba9c4bf
commit 1969e1bd8c
7 changed files with 128 additions and 27 deletions

View file

@ -1 +1 @@
{"categories":[{"name":"todo","content":[{"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":"test multiple space in texte","description":"// Hello there","id":3},{"name":"test puis in texte","description":"// Hello there","id":2},{"name":"enchainement puis","description":"// Hello there","id":5},{"name":"guillemet mal ferme","description":"// Hello there","id":4},{"name":"display element","description":"for better print","id":6},{"name":"puis à la ligne, alinéa","description":"// Hello there","id":1},{"name":"teste double tiret","description":"// Hello there","id":2},{"name":"teste puis seul","description":"tout seul, seul devant, seul fin","id":3},{"name":"erreur calcul bool/nombre","description":"affiche element precedent lorsque mauvais enchainement","id":1},{"name":"multiple compilation error","description":"// Hello there","id":1},{"name":"tests mod","description":"// Hello there","id":3}]},{"name":"bug","content":[]},{"name":"to test","content":[{"name":"test variable","description":"// Hello there","id":2}]},{"name":"bonus","content":[{"name":"stop cheating with \"-\"","description":"// Hello there","id":5},{"name":"affiche ligne et position erreur","description":"// Hello there","id":1},{"name":"pour numero de ligne execution","description":"sauvegarde numero de ligne dans la commande\n\ncommande.ligne(12)","id":3},{"name":"standardizer erreur","description":"regarder les texte répétés","id":1}]},{"name":"+","content":[]}]}
{"categories":[{"name":"todo","content":[{"name":"verifie si bloc pas vide","description":"// Hello there","id":2},{"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":"test multiple space in texte","description":"// Hello there","id":3},{"name":"test puis in texte","description":"// Hello there","id":2},{"name":"enchainement puis","description":"// Hello there","id":5},{"name":"guillemet mal ferme","description":"// Hello there","id":4},{"name":"display element","description":"for better print","id":6},{"name":"puis à la ligne, alinéa","description":"// Hello there","id":1},{"name":"teste double tiret","description":"// Hello there","id":2},{"name":"teste puis seul","description":"tout seul, seul devant, seul fin","id":3},{"name":"erreur calcul bool/nombre","description":"affiche element precedent lorsque mauvais enchainement","id":1},{"name":"multiple compilation error","description":"// Hello there","id":1},{"name":"tests mod","description":"// Hello there","id":3},{"name":"if","description":"implémente if avec des guillemets de délimitation","id":1}]},{"name":"bug","content":[]},{"name":"to test","content":[{"name":"test variable","description":"// Hello there","id":2},{"name":"teste if","description":"// Hello there","id":3}]},{"name":"bonus","content":[{"name":"stop cheating with \"-\"","description":"// Hello there","id":5},{"name":"affiche ligne et position erreur","description":"// Hello there","id":1},{"name":"pour numero de ligne execution","description":"sauvegarde numero de ligne dans la commande\n\ncommande.ligne(12)","id":3},{"name":"standardizer erreur","description":"regarder les texte répétés","id":1}]},{"name":"+","content":[]}]}

View file

@ -37,7 +37,7 @@ fn main() {
debug::message_compilation_ok(debut.elapsed());
if debug_mode {
println!("{}\n", pendragon.programme);
println!("\n{}\n", pendragon.programme);
}

View file

@ -170,17 +170,24 @@ impl Pendragon {
}
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 mut membre: Vec<Element> = vec![];
match self.elements_nombre(texte) {
Ok(elements_nombre) => membre = elements_nombre,
Err(raison) => if let ErreurPendragon::OrdreCalculEntier(_,_,_) = raison {return Err(raison)},
}
if membre.is_empty() {
match self.elements_booleen(texte) {
Ok(elements_booleen) => membre = elements_booleen,
Err(raison) => if let ErreurPendragon::OrdreCalculBooleen(_,_,_) = raison {return Err(raison)},
}
}
if membre.is_empty() {
if let Ok(elements_texte) = self.elements_texte(texte) {
membre = elements_texte;
}
}
let Some(element) = membre.first() else {
return Err(ErreurPendragon::ComparaisonInvalide("il n'y a pas de d'élément dans le membre ajouté".into()))
return Err(ErreurPendragon::MauvaisArgument(texte.to_string()))
};
if comparaison.type_comparaison.is_none() {
comparaison.membre_a = membre;

View file

@ -64,8 +64,10 @@ impl fmt::Display for ErreurCompilation {
#[derive(PartialEq, Debug, Clone)]
pub enum ErreurPendragon {
CommandeInconnue(String),
BlocInconnu(String),
ManqueArgument,
MauvaisArgument(String),
MauvaiseIndentation(String),
ManquePonctuation,
NombreInvalide(String),
@ -89,8 +91,10 @@ impl fmt::Display for ErreurPendragon {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {//'
match self {
Self::CommandeInconnue(commande) => write!(f, "La commande \"{}\" est inconnue.", commande),
Self::BlocInconnu(bloc) => write!(f, "Le bloc \"{}\" est inconnu.", bloc),
Self::ManqueArgument => write!(f, "Il manque un argument."),
Self::MauvaisArgument(message) => write!(f, "La commande a reçu un mauvais argument, {}.", message),
Self::MauvaiseIndentation(message) => write!(f, "L'indentation est mauvaise, {}.", message),
Self::ManquePonctuation => write!(f, "Il manque la ponctuation de la phrase."),
Self::NombreInvalide(nombre) => write!(f, "Le nombre \"{}\" est mal orthographié.", nombre),

View file

@ -22,7 +22,11 @@ impl Pendragon {
pub fn compile(&mut self, contenu: String) -> Result<(), Vec<ErreurCompilation>> {
let texte: Vec<&str> = contenu.split('\n').collect();
let mut erreurs: Vec<ErreurCompilation> = vec![];
let mut indentation_niveau: usize = 0;
let mut pile_bloc: Vec<Bloc> = vec![];
for (index_ligne, ligne) in texte.iter().enumerate() {
let indentation_ligne = ligne.chars().take_while(|&c| c == '\t').count();
let ligne = ligne.trim();
let phrases: Vec<&str> = ligne.split_inclusive(|c| c == ',' || c == '.').collect();
let Some(derniere_phrase) = phrases.last() else {
@ -31,18 +35,47 @@ impl Pendragon {
if !derniere_phrase.ends_with('.') && !derniere_phrase.ends_with(',') {
erreurs.push(ErreurCompilation::nouvelle(index_ligne, ligne.into(), ErreurPendragon::ManquePonctuation))
}
while indentation_ligne < indentation_niveau {
let Some(bloc_actuel) = pile_bloc.pop() else {
erreurs.push(ErreurCompilation::nouvelle(index_ligne, ligne.into(), ErreurPendragon::MauvaiseIndentation(format!("croyais être à {} niveau", indentation_niveau)),));
indentation_niveau = 0;
continue;
};
if let Some(bloc_precedent) = pile_bloc.last_mut() {
bloc_precedent.ajoute_bloc(bloc_actuel);
} else {
self.programme.ajoute_bloc(bloc_actuel);
}
indentation_niveau -= 1;
}
for phrase in phrases {
if phrase.ends_with(".") {
if phrase.replace(" ", "").starts_with("NotaBene:") {
continue
}
match self.compile_commande(&phrase[..phrase.len() - 1]) {
Ok(commande) => self.programme.ajoute_commande(commande),
Ok(commande) => {
if let Some(bloc_actuel) = pile_bloc.last_mut() {
bloc_actuel.ajoute_commande(commande);
} else {
self.programme.ajoute_commande(commande);
}
}
Err(raison) => erreurs.push(ErreurCompilation::nouvelle(index_ligne, ligne.into(), raison)),
}
continue;
}
println!("todo : {}", phrase);
match self.compile_bloc(&phrase[..phrase.len() - 1]) {
Ok(bloc) => {
pile_bloc.push(bloc);
}
Err(raison) => {
erreurs.push(ErreurCompilation::nouvelle(index_ligne, ligne.into(), raison));
pile_bloc.push(Bloc::nouveau(vec![Element::Booleen(false)]));
}
}
indentation_niveau += 1;
}
}
if erreurs.len() > 0 {
@ -57,7 +90,7 @@ impl Pendragon {
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") {
if contient_mot_cle(parties[1]) {
return Err(ErreurPendragon::ManquePonctuation)
}
match parties[0] {
@ -68,6 +101,22 @@ impl Pendragon {
autre => Err(ErreurPendragon::CommandeInconnue(autre.into())),
}
}
fn compile_bloc(&mut self, phrase: &str) -> Result<Bloc, ErreurPendragon> {
let phrase = phrase.trim();
let parties: Vec<&str> = phrase.splitn(2, ' ').collect();
if parties.len() == 1 {
return Err(ErreurPendragon::ManqueArgument)
}
if contient_mot_cle(parties[1]) {
return Err(ErreurPendragon::ManquePonctuation)
}
match parties[0] {
"Si" => Ok(Bloc::nouveau(self.elements_booleen(parties[1])?)),
autre => Err(ErreurPendragon::BlocInconnu(autre.into())),
}
}
fn affiche(&self, arguments: &str) -> Result<Commande, ErreurPendragon> {
Ok(Commande::Affiche(self.elements_texte(arguments)?))
@ -103,6 +152,14 @@ impl Pendragon {
}
}
fn contient_mot_cle(texte: &str) -> bool {
texte.contains("Définis") ||
texte.contains("Modifie") ||
texte.contains("Affiche") ||
texte.contains("Demande") ||
texte.contains("Si")
}
fn nom_de_variable(arguments: &str, separateur: &str) -> Result<(String, String), ErreurPendragon> {
let parties = if separateur == "" {
vec![arguments, ""]

View file

@ -20,6 +20,10 @@ impl Programme {
self.contenu.push(Phrase::Commande(commande));
}
pub fn ajoute_bloc(&mut self, bloc: Bloc) {
self.contenu.push(Phrase::Bloc(bloc));
}
pub fn ajoute_variable(&mut self, nom: String, type_variable: TypeElement) -> Result<(), ErreurPendragon> {
let Err(raison) = self.variable(&nom) else {
return Err(ErreurPendragon::MauvaisArgument(format!("la variable \"{}\" existe déjà", nom)))
@ -55,11 +59,10 @@ impl Programme {
pub fn execute(&self) -> Result<(), ErreurPendragon> {
let mut variables_globales: HashMap<String, Element> = HashMap::new();
for phrase in &self.contenu {
let Phrase::Commande(commande) = phrase else {
println!("doit executer bloc");
continue;
};
commande.execute(&mut variables_globales)?;
match phrase {
Phrase::Commande(commande) => commande.execute(&mut variables_globales)?,
Phrase::Bloc(bloc) => bloc.execute(&mut variables_globales)?,
}
}
Ok(())
}
@ -70,6 +73,36 @@ pub struct Bloc {
contenu: Vec<Phrase>,
}
impl Bloc {
pub fn nouveau(condition: Vec<Element>) -> Self {
Self {
condition,
contenu: vec![],
}
}
pub fn ajoute_commande(&mut self, commande: Commande) {
self.contenu.push(Phrase::Commande(commande));
}
pub fn ajoute_bloc(&mut self, bloc: Bloc) {
self.contenu.push(Phrase::Bloc(bloc));
}
pub fn execute(&self, variables: &mut HashMap<String, Element>) -> Result<(), ErreurPendragon> {
if !booleen::calcule_booleen(self.condition.clone(), variables)? {
return Ok(());
}
for phrase in &self.contenu {
match phrase {
Phrase::Commande(commande) => commande.execute(variables)?,
Phrase::Bloc(bloc) => bloc.execute(variables)?,
}
}
Ok(())
}
}
pub enum Phrase {
Bloc(Bloc),
Commande(Commande),

14
test.dr
View file

@ -3,17 +3,17 @@ Définis B comme entier.
Définis C comme entier.
Nota Bene : A est la variable pour un polynôme.
Modifie A avec dix-sept plus trois.
Demande A.
Modifie C avec six-cent-soixante-douze.
Modifie B avec trois fois A fois ouvre la parenthèse trois fois A plus C ferme la parenthèse.
Nota Bene : 3*A*(3*A+C).
Affiche "Résultat : " puis B.
Si A supérieur ou égal à deux trois,
Si A est inférieur ou égal à trois,
Affiche "A<=3".
Si B est inférieur ou égal à trois,
Affiche "B<=3".
Affiche "fin B".
Définis Bool comme booléen.
Modifie Bool avec vrai.
Affiche vrai et faux.
Affiche alinéa puis trois plus un puis retour à la ligne puis "test".
Affiche "test".