Commit initial.

This commit is contained in:
Benjamin Bouvier 2021-09-09 19:40:29 +02:00
commit ff6ac4cf35
7 changed files with 231 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
**/*/target
*/target
/target
Cargo.lock

5
Cargo.toml Normal file
View File

@ -0,0 +1,5 @@
[workspace]
members = [
"rouille_proc_macro",
"examples"
]

28
README.md Normal file
View File

@ -0,0 +1,28 @@
# rouille
Aren't you *le tired* from writing Rust programs in English? Do you like saying
"merde" a lot? Would you like to try something different, in an exotic
language?
**rouille** (French for *Rust*) is here to save the day, and allows one to
write Rust programs in French. See the [examples](./examples/src/main.rs) for
more details about what can be done with it.
## contributions
First of all, *merci beaucoup* for considering participating to this joke, the
French government will thank you later! Feel free to throw in a few identifiers
here and there, and open a pull-request against the `principale` (French for
`main`) branch.
## but why would you do zat
- horsin around
- making a bit of fun of programming languages using French keywords
- winking at [Marcel](https://github.com/brouberol/marcel)
- playing with raw proc macros
- c'est chic
## license
[WTFPL](http://www.wtfpl.net/).

9
examples/Cargo.toml Normal file
View File

@ -0,0 +1,9 @@
[package]
name = "rouille_examples"
version = "0.1.0"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
rouille = { path = "../rouille_proc_macro/" }

69
examples/src/main.rs Normal file
View File

@ -0,0 +1,69 @@
rouille::rouille! {
utilisons std::collections::Dictionnaire comme Dico;
interface CléValeur {
fonction écrire(&soi, clé: Chaine, valeur: Chaine);
fonction lire(&soi, clé: Chaine) -> PeutÊtre<&Chaine>;
}
statique mutable DICTIONNAIRE: PeutÊtre<Dico<Chaine, Chaine>> = Rien;
structure Concrète;
implémentation CléValeur pour Concrète {
fonction écrire(&soi, clé: Chaine, valeur: Chaine) {
soit dico = dangereux {
DICTIONNAIRE.prendre_ou_insérer_avec(Défault::défault)
};
dico.insérer(clé, valeur);
}
fonction lire(&soi, clé: Chaine) -> PeutÊtre<&Chaine> {
soit dico = dangereux {
DICTIONNAIRE.prendre_ou_insérer_avec(Défault::défault)
};
dico.lire(&clé)
}
}
public(cagette) fonction peut_etre(i: u32) -> PeutÊtre<Résultat<u32, Chaine>> {
si i % 2 == 1 {
si i == 42 {
Quelque(Arf(Chaine::depuis("merde")))
} sinon {
Quelque(Bien(33))
}
} sinon {
Rien
}
}
asynchrone fonction exemple() {
}
asynchrone fonction exemple2() {
exemple().attend;
}
fonction principale() {
soit mutable x = 31;
correspond x {
42 => {
affiche!("omelette du fromage")
}
_ => affiche!("voila")
}
pour i de 0..10 {
soit val = boucle {
arrête i;
};
tant que x < val {
x += 1;
}
x = si soit Quelque(resultat) = peut_etre(i) {
resultat.déballer()
} else { 12 };
}
}
}

View File

@ -0,0 +1,11 @@
[package]
name = "rouille"
version = "0.1.0"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
[lib]
proc-macro = true

View File

@ -0,0 +1,105 @@
use proc_macro::{Group, Ident, TokenStream, TokenTree};
fn replace_ident(ident: Ident) -> Option<TokenTree> {
let ident_str = ident.to_string();
let new_str = match ident_str.as_str() {
"Arf" => "Err",
"Bien" => "Ok",
"Chaine" => "String",
"Dictionnaire" => "HashMap",
"Défault" => "Default",
"Erreur" => "Error",
"PeutÊtre" => "Option",
"Quelque" => "Some",
"Rien" => "None",
"Résultat" => "Result",
"Soi" => "Self",
"affiche" => "println",
"arrête" => "break",
"asynchrone" => "async",
"attend" => "await",
"boucle" => "loop",
"bouge" => "move",
"cagette" => "crate",
"comme" => "as",
"constant" => "const",
"correspond" => "match",
"dangereux" => "unsafe",
"de" => "in",
"depuis" => "from",
"dynamique" => "dyn",
"déballer" => "unwrap",
"défault" => "default",
"es" => "io",
"externe" => "extern",
"faux" => "false",
"fonction" => "fn",
"génial" => "super",
"implémentation" => "impl",
"insérer" => "insert",
"interface" => "trait",
"lire" => "get",
"module" => "mod",
"mutable" => "mut",
"nouveau" => "new",
"" => "where",
"pour" => "for",
"prendre_ou_insérer_avec" => "get_or_insert_with",
"principale" => "main",
"public" => "pub",
"que" => None?,
"renvoie" => "return",
"si" => "if",
"sinon" => "else",
"soi" => "self",
"soit" => "let",
"statique" => "static",
"structure" => "struct",
"suppose" => "expect",
"tant" => "while",
"utilisons" => "use",
"vrai" => "true",
"énumération" => "enum",
_ => &ident_str,
};
let new_ident = Ident::new(new_str, ident.span());
Some(TokenTree::Ident(new_ident))
}
fn replace_tree(tok: TokenTree, out: &mut Vec<TokenTree>) {
match tok {
TokenTree::Group(group) => {
let mut group_elem = Vec::new();
replace_stream(group.stream(), &mut group_elem);
let mut new_stream = TokenStream::new();
new_stream.extend(group_elem);
out.push(TokenTree::Group(Group::new(group.delimiter(), new_stream)));
}
TokenTree::Ident(ident) => {
if let Some(ident) = replace_ident(ident) {
out.push(ident);
}
}
TokenTree::Punct(..) | TokenTree::Literal(..) => {
out.push(tok);
}
}
}
fn replace_stream(ts: TokenStream, out: &mut Vec<TokenTree>) {
for tok in ts {
replace_tree(tok, out)
}
}
#[proc_macro]
pub fn rouille(item: TokenStream) -> TokenStream {
let mut returned = Vec::new();
replace_stream(item, &mut returned);
let mut out = TokenStream::new();
out.extend(returned);
out
}