Commit initial.
This commit is contained in:
commit
ff6ac4cf35
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
**/*/target
|
||||||
|
*/target
|
||||||
|
/target
|
||||||
|
Cargo.lock
|
5
Cargo.toml
Normal file
5
Cargo.toml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[workspace]
|
||||||
|
members = [
|
||||||
|
"rouille_proc_macro",
|
||||||
|
"examples"
|
||||||
|
]
|
28
README.md
Normal file
28
README.md
Normal 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
9
examples/Cargo.toml
Normal 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
69
examples/src/main.rs
Normal 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 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
rouille_proc_macro/Cargo.toml
Normal file
11
rouille_proc_macro/Cargo.toml
Normal 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
|
105
rouille_proc_macro/src/lib.rs
Normal file
105
rouille_proc_macro/src/lib.rs
Normal 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",
|
||||||
|
"où" => "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
|
||||||
|
}
|
Loading…
Reference in a new issue