diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 8f44509..461e66e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,9 +2,9 @@ name: Rust on: push: - branches: [ principale ] + branches: [ hauptzweig ] pull_request: - branches: [ principale ] + branches: [ hauptzweig ] jobs: ci: @@ -26,7 +26,7 @@ jobs: toolchain: ${{ matrix.rust }} override: true - - name: Lancer les exemples + - name: Examples uses: actions-rs/cargo@v1 with: command: run diff --git a/Cargo.toml b/Cargo.toml index 45d1a1f..ee16fdc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] members = [ - "rouille_proc_macro", + "rost_proc_macro", "examples" ] diff --git a/README.md b/README.md index 600e5ce..8453909 100644 --- a/README.md +++ b/README.md @@ -1,31 +1,26 @@ -# rouille +# rost -![](https://github.com/bnjbvr/rouille/raw/principale/logo.jpeg) +

Rust German Logo

-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 and -funny-sounding language? Would you want to bring some French touch to your +Aren't you _das Müde_ from writing Rust programs in English? Do you like saying +"scheiße" a lot? Would you like to try something different, in an exotic and +funny-sounding language? Would you want to bring some German touch to your programs? -**rouille** (French for _Rust_) is here to save your day, as it allows you to -write Rust programs in French, using French keywords, French function names, -French idioms. +**rost** (German for _Rust_) is here to save your day, as it allows you to +write Rust programs in German, using German keywords, German function names, +German idioms. -This has been designed to be used as the official programming language to -develop the future French sovereign operating system. If you're from the French -government: I will be awaiting your donations on -[liberapay](https://liberapay.com/bnjbvr/). - -You're from Quebec and don't feel at ease using only French words? Don't worry! -French Rust is fully compatible with English-Rust, so you can mix both at your +You're don't feel at ease using only German words? Don't worry! +German Rust is fully compatible with English-Rust, so you can mix both at your convenience. -Here's an example of what can be achieved with Rouille: +Here's an example of what can be achieved with Rost: -### struct and impl (aka convention et réalisation) +## struct and impl (aka Konvention und Umsetzung) ```rust -rouille::rouille! { +rost::rost! { utilisons std::collections::Dictionnaire comme Dico; convention CléValeur { @@ -55,44 +50,26 @@ rouille::rouille! { } ``` -### Support for regional languages - -```rust -#[légal(code_inaccessible)] -fonction secondaire() { - merde!("oh non"); // for the true French experience - calisse!("tabernacle"); // for friends speaking fr-ca - oups!("fetchez la vache"); // in SFW contexts -} -``` - -### Other examples +## Other examples See the [examples](./examples/src/main.rs) to get a rough sense of the whole -syntax. Voilà, that's it. +syntax. Gut so! -## les contributions +## but why would you do dis? -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. +* the [frech](https://github.com/bnjbvr/rouille) and [dutch](https://github.com/jeroenhd/roest) can do it, so we can as well! -Please don't introduce swear words, though: we will not excuse your French. +## Mitwirken -## but why would you do zat +First of all, _vielen Dank_ for considering participating to this joke, the +German government will thank you later! Feel free to throw in a few identifiers +here and there, and open a pull-request against the `hauptzweig` (German for +`main`) branch. The initial translation was made by [Shemnei](https://github.com/Shemnei/) and [michidk](https://github.com/michidk/). -- horsin around -- playing with raw proc macros -- making a bit of fun about programming languages that do this seriously, - though I can see their utility. -- winking at [Marcel](https://github.com/brouberol/marcel) -- c'est chic - -## un grand merci - -- [@VentGrey](https://twitter.com/VentGrey) for making a logo! - -## la license +## Die Lizenzbestimmungen [WTFPL](http://www.wtfpl.net/). + +Image attributions: +* "Brezel und Filzhut zum Oktoberfest" by Tim Reckmann | a59.de is licensed under CC BY 2.0 +* "Lederhose" is licensed under CC BY-NC-SA 4.0 diff --git a/examples/Cargo.toml b/examples/Cargo.toml index ae9a6ba..74a522e 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -1,9 +1,9 @@ [package] -name = "rouille_examples" +name = "rost_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/" } +rost = { path = "../rost_proc_macro/" } diff --git a/examples/src/main.rs b/examples/src/main.rs index 6a13971..fbcab08 100644 --- a/examples/src/main.rs +++ b/examples/src/main.rs @@ -1,85 +1,76 @@ -rouille::rouille! { - externe cagette rouille; +rost::rost! { + benutze std::collections::Wörterbuch als Wöbu; - utilisons std::collections::Dictionnaire comme Dico; - - convention CléValeur { - fonction écrire(&soi, clé: Chaine, valeur: Chaine); - fonction lire(&soi, clé: Chaine) -> Résultat, Chaine>; + vereinbarung SchlüsselWert { + funktion schreibe(&selbst, schlsl: Zeichenkette, wert: Zeichenkette); + funktion lese(&selbst, schlsl: Zeichenkette) -> Ergebnis, Zeichenkette>; } - statique mutable DICTIONNAIRE: PeutÊtre> = Rien; + statisch änd WÖRTERBUCH: Möglichkeit> = Nichts; - structure Concrète; + struktur Konkret; - réalisation CléValeur pour Concrète { - fonction écrire(&soi, clé: Chaine, valeur: Chaine) { - soit dico = dangereux { - DICTIONNAIRE.prendre_ou_insérer_avec(Défaut::défaut) + umstz SchlüsselWert für Konkret { + + funktion schreibe(&selbst, schlsl: Zeichenkette, wert: Zeichenkette) { + lass wöbu = gefährlich { + WÖRTERBUCH.hole_oder_füge_ein_mit(Standard::standard) }; - dico.insérer(clé, valeur); + wöbu.einfügen(schlsl, wert); } - fonction lire(&soi, clé: Chaine) -> Résultat, Chaine> { - si soit Quelque(dico) = dangereux { DICTIONNAIRE.en_réf() } { - Bien(dico.lire(&clé)) - } sinon { - Arf("fetchez le dico".vers()) + + funktion lese(&selbst, schlsl: Zeichenkette) -> Ergebnis, Zeichenkette> { + wenn lass Etwas(wöbu) = gefährlich { WÖRTERBUCH.als_ref() } { + Gut(wöbu.hole(&schlsl)) + } anderenfalls { + Fehler("Holt das Wörterbuch".hinein()) } } } - public(cagette) fonction peut_etre(i: u32) -> PeutÊtre> { - si i % 2 == 1 { - si i == 42 { - Quelque(Arf(Chaine::depuis("merde"))) - } sinon { - Quelque(Bien(33)) + öffentlich(kiste) funktion vielleicht(i: u32) -> Möglichkeit> { + wenn i % 2 == 1 { + wenn i == 42 { + Etwas(Fehler(Zeichenkette::von("Scheiße"))) + } anderenfalls { + Etwas(Gut(33)) } - } sinon { - Rien + } anderenfalls { + Nichts } } - asynchrone fonction exemple() { + asynchron funktion beispiel() { } - asynchrone fonction exemple2() { - exemple().attend; + asynchron funktion beispiel2() { + beispiel().erwarte; } - fonction principale() { - soit mutable x = 31; + funktion einstieg() { + lass änd x = 31; - selon x { + entspreche x { 42 => { - affiche!("omelette du fromage") + ausgabe!("Wienerschnitzel") } - _ => affiche!("voila") + _ => ausgabe!("Na geht doch") } - pour i de 0..10 { - soit val = boucle { - arrête i; + für i in 0..10 { + lass val = schleife { + abbruch i; }; - tant que x < val { + während keins x < val { x += 1; } - x = si soit Quelque(resultat) = peut_etre(i) { - resultat.déballer() - } sinon { + x = wenn lass Etwas(ergebnis) = vielleicht(i) { + ergebnis.entpacken() + } anderenfalls { 12 }; } - - secondaire(); - } - - #[légal(code_inaccessible)] - fonction secondaire() { - merde!("oh non"); // for the true French experience - calisse!("tabernacle"); // for friends speaking fr-ca - oups!("fetchez la vache"); // in SFW contexts } } diff --git a/logo.jpeg b/logo.jpeg deleted file mode 100644 index 1d34c71..0000000 Binary files a/logo.jpeg and /dev/null differ diff --git a/logo.jpg b/logo.jpg new file mode 100644 index 0000000..8732dca Binary files /dev/null and b/logo.jpg differ diff --git a/rouille_proc_macro/Cargo.toml b/rost_proc_macro/Cargo.toml similarity index 91% rename from rouille_proc_macro/Cargo.toml rename to rost_proc_macro/Cargo.toml index 862a0a6..83903b0 100644 --- a/rouille_proc_macro/Cargo.toml +++ b/rost_proc_macro/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "rouille" +name = "rost" version = "0.1.0" edition = "2018" diff --git a/rost_proc_macro/src/lib.rs b/rost_proc_macro/src/lib.rs new file mode 100644 index 0000000..a5feedc --- /dev/null +++ b/rost_proc_macro/src/lib.rs @@ -0,0 +1,111 @@ +use proc_macro::{Group, Ident, TokenStream, TokenTree}; + +fn replace_ident(ident: Ident) -> Option { + let ident_str = ident.to_string(); + + let new_str = match ident_str.as_str() { + "Fehler" => "Err", + "Gut" => "Ok", + "Zeichenkette" => "String", + "Wörterbuch" => "HashMap", + "Standard" => "Default", + "Fehlfunktion" => "Error", + "Möglichkeit" => "Option", + "Etwas" => "Some", + "Nichts" => "None", + "Ergebnis" => "Result", + "Selbst" => "Self", + "ausgabe" => "println", + "abbruch" => "break", + "asynchron" => "async", + "erwarte" => "await", + "schleife" => "loop", + "schiebe" => "move", + "kiste" => "crate", + "unerreichbarer_code" => "unreachable_code", + "als" => "as", + "konstante" => "const", + "vereinbarung" => "trait", + "gefährlich" => "unsafe", + "in" => "in", + "von" => "from", + "dynamisch" => "dyn", + "entpacken" => "unwrap", + "standard" => "default", + "als_ref" => "as_ref", + "ea" => "io", + "extern" => "extern", + "falsch" => "false", + "funktion" => "fn", + "übergeordnet" => "super", + "einfügen" => "insert", + "hole" => "get", + "erlaube" => "allow", + "panik" | "scheiße" | "mist" | "ups" => "panic", + "modul" => "mod", + "änd" => "mut", + "neu" => "new", + "who" => "where", + "für" => "for", + "hole_oder_füge_ein_mit" => "get_or_insert_with", + "einstieg" => "main", + "öffentlich" => "pub", + "keins" => None?, + "zurückgebe" => "return", + "umstz" => "impl", + "ref" => "ref", + "entspreche" => "match", + "wenn" => "if", + "anderenfalls" => "else", + "selbst" => "self", + "lass" => "let", + "statisch" => "static", + "struktur" => "struct", + "erwarte" => "expect", + "während" => "while", + "benutze" => "use", + "hinein" => "into", + "wahr" => "true", + "aufzählung" => "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) { + 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) { + for tok in ts { + replace_tree(tok, out) + } +} + +#[proc_macro] +pub fn rost(item: TokenStream) -> TokenStream { + let mut returned = Vec::new(); + replace_stream(item, &mut returned); + let mut out = TokenStream::new(); + out.extend(returned); + out +} diff --git a/rouille_proc_macro/src/lib.rs b/rouille_proc_macro/src/lib.rs deleted file mode 100644 index 36c1938..0000000 --- a/rouille_proc_macro/src/lib.rs +++ /dev/null @@ -1,111 +0,0 @@ -use proc_macro::{Group, Ident, TokenStream, TokenTree}; - -fn replace_ident(ident: Ident) -> Option { - let ident_str = ident.to_string(); - - let new_str = match ident_str.as_str() { - "Arf" => "Err", - "Bien" => "Ok", - "Chaine" => "String", - "Dictionnaire" => "HashMap", - "Défaut" => "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", - "code_inaccessible" => "unreachable_code", - "comme" => "as", - "constant" => "const", - "convention" => "trait", - "dangereux" => "unsafe", - "de" => "in", - "depuis" => "from", - "dynamique" => "dyn", - "déballer" => "unwrap", - "défaut" => "default", - "en_réf" => "as_ref", - "es" => "io", - "externe" => "extern", - "faux" => "false", - "fonction" => "fn", - "génial" => "super", - "insérer" => "insert", - "lire" => "get", - "légal" => "allow", - "merde" | "calisse" | "oups" => "panic", - "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", - "réalisation" => "impl", - "réf" => "ref", - "selon" => "match", - "si" => "if", - "sinon" => "else", - "soi" => "self", - "soit" => "let", - "statique" => "static", - "structure" => "struct", - "suppose" => "expect", - "tant" => "while", - "utilisons" => "use", - "vers" => "into", - "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) { - 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) { - 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 -}