Übersetzung der Instruktionen
This commit is contained in:
parent
67b763f20f
commit
a408629030
6
.github/workflows/main.yml
vendored
6
.github/workflows/main.yml
vendored
|
@ -2,9 +2,9 @@ name: Rust
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [ principale ]
|
branches: [ hauptzweig ]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ principale ]
|
branches: [ hauptzweig ]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
ci:
|
ci:
|
||||||
|
@ -26,7 +26,7 @@ jobs:
|
||||||
toolchain: ${{ matrix.rust }}
|
toolchain: ${{ matrix.rust }}
|
||||||
override: true
|
override: true
|
||||||
|
|
||||||
- name: Lancer les exemples
|
- name: Examples
|
||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
command: run
|
command: run
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
"rouille_proc_macro",
|
"rost_proc_macro",
|
||||||
"examples"
|
"examples"
|
||||||
]
|
]
|
||||||
|
|
77
README.md
77
README.md
|
@ -1,31 +1,26 @@
|
||||||
# rouille
|
# rost
|
||||||
|
|
||||||
![](https://github.com/bnjbvr/rouille/raw/principale/logo.jpeg)
|
<p align="center"><img src="logo.jpg" alt="Rust German Logo"></p>
|
||||||
|
|
||||||
Aren't you _le tired_ from writing Rust programs in English? Do you like saying
|
Aren't you _das Müde_ from writing Rust programs in English? Do you like saying
|
||||||
"merde" a lot? Would you like to try something different, in an exotic and
|
"scheiße" 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
|
funny-sounding language? Would you want to bring some German touch to your
|
||||||
programs?
|
programs?
|
||||||
|
|
||||||
**rouille** (French for _Rust_) is here to save your day, as it allows you to
|
**rost** (German for _Rust_) is here to save your day, as it allows you to
|
||||||
write Rust programs in French, using French keywords, French function names,
|
write Rust programs in German, using German keywords, German function names,
|
||||||
French idioms.
|
German idioms.
|
||||||
|
|
||||||
This has been designed to be used as the official programming language to
|
You're don't feel at ease using only German words? Don't worry!
|
||||||
develop the future French sovereign operating system. If you're from the French
|
German Rust is fully compatible with English-Rust, so you can mix both at your
|
||||||
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
|
|
||||||
convenience.
|
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
|
```rust
|
||||||
rouille::rouille! {
|
rost::rost! {
|
||||||
utilisons std::collections::Dictionnaire comme Dico;
|
utilisons std::collections::Dictionnaire comme Dico;
|
||||||
|
|
||||||
convention CléValeur {
|
convention CléValeur {
|
||||||
|
@ -55,44 +50,26 @@ rouille::rouille! {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Support for regional languages
|
## Other examples
|
||||||
|
|
||||||
```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
|
|
||||||
|
|
||||||
See the [examples](./examples/src/main.rs) to get a rough sense of the whole
|
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
|
* the [frech](https://github.com/bnjbvr/rouille) and [dutch](https://github.com/jeroenhd/roest) can do it, so we can as well!
|
||||||
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.
|
|
||||||
|
|
||||||
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
|
## Die Lizenzbestimmungen
|
||||||
- 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
|
|
||||||
|
|
||||||
[WTFPL](http://www.wtfpl.net/).
|
[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
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
[package]
|
[package]
|
||||||
name = "rouille_examples"
|
name = "rost_examples"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rouille = { path = "../rouille_proc_macro/" }
|
rost = { path = "../rost_proc_macro/" }
|
||||||
|
|
|
@ -1,85 +1,76 @@
|
||||||
rouille::rouille! {
|
rost::rost! {
|
||||||
externe cagette rouille;
|
benutze std::collections::Wörterbuch als Wöbu;
|
||||||
|
|
||||||
utilisons std::collections::Dictionnaire comme Dico;
|
vereinbarung SchlüsselWert {
|
||||||
|
funktion schreibe(&selbst, schlsl: Zeichenkette, wert: Zeichenkette);
|
||||||
convention CléValeur {
|
funktion lese(&selbst, schlsl: Zeichenkette) -> Ergebnis<Möglichkeit<&Zeichenkette>, Zeichenkette>;
|
||||||
fonction écrire(&soi, clé: Chaine, valeur: Chaine);
|
|
||||||
fonction lire(&soi, clé: Chaine) -> Résultat<PeutÊtre<&Chaine>, Chaine>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
statique mutable DICTIONNAIRE: PeutÊtre<Dico<Chaine, Chaine>> = Rien;
|
statisch änd WÖRTERBUCH: Möglichkeit<Wöbu<Zeichenkette, Zeichenkette>> = Nichts;
|
||||||
|
|
||||||
structure Concrète;
|
struktur Konkret;
|
||||||
|
|
||||||
réalisation CléValeur pour Concrète {
|
umstz SchlüsselWert für Konkret {
|
||||||
fonction écrire(&soi, clé: Chaine, valeur: Chaine) {
|
|
||||||
soit dico = dangereux {
|
funktion schreibe(&selbst, schlsl: Zeichenkette, wert: Zeichenkette) {
|
||||||
DICTIONNAIRE.prendre_ou_insérer_avec(Défaut::défaut)
|
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<PeutÊtre<&Chaine>, Chaine> {
|
|
||||||
si soit Quelque(dico) = dangereux { DICTIONNAIRE.en_réf() } {
|
funktion lese(&selbst, schlsl: Zeichenkette) -> Ergebnis<Möglichkeit<&Zeichenkette>, Zeichenkette> {
|
||||||
Bien(dico.lire(&clé))
|
wenn lass Etwas(wöbu) = gefährlich { WÖRTERBUCH.als_ref() } {
|
||||||
} sinon {
|
Gut(wöbu.hole(&schlsl))
|
||||||
Arf("fetchez le dico".vers())
|
} anderenfalls {
|
||||||
|
Fehler("Holt das Wörterbuch".hinein())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public(cagette) fonction peut_etre(i: u32) -> PeutÊtre<Résultat<u32, Chaine>> {
|
öffentlich(kiste) funktion vielleicht(i: u32) -> Möglichkeit<Ergebnis<u32, Zeichenkette>> {
|
||||||
si i % 2 == 1 {
|
wenn i % 2 == 1 {
|
||||||
si i == 42 {
|
wenn i == 42 {
|
||||||
Quelque(Arf(Chaine::depuis("merde")))
|
Etwas(Fehler(Zeichenkette::von("Scheiße")))
|
||||||
} sinon {
|
} anderenfalls {
|
||||||
Quelque(Bien(33))
|
Etwas(Gut(33))
|
||||||
}
|
}
|
||||||
} sinon {
|
} anderenfalls {
|
||||||
Rien
|
Nichts
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
asynchrone fonction exemple() {
|
asynchron funktion beispiel() {
|
||||||
}
|
}
|
||||||
|
|
||||||
asynchrone fonction exemple2() {
|
asynchron funktion beispiel2() {
|
||||||
exemple().attend;
|
beispiel().erwarte;
|
||||||
}
|
}
|
||||||
|
|
||||||
fonction principale() {
|
funktion einstieg() {
|
||||||
soit mutable x = 31;
|
lass änd x = 31;
|
||||||
|
|
||||||
selon x {
|
entspreche x {
|
||||||
42 => {
|
42 => {
|
||||||
affiche!("omelette du fromage")
|
ausgabe!("Wienerschnitzel")
|
||||||
}
|
}
|
||||||
_ => affiche!("voila")
|
_ => ausgabe!("Na geht doch")
|
||||||
}
|
}
|
||||||
|
|
||||||
pour i de 0..10 {
|
für i in 0..10 {
|
||||||
soit val = boucle {
|
lass val = schleife {
|
||||||
arrête i;
|
abbruch i;
|
||||||
};
|
};
|
||||||
|
|
||||||
tant que x < val {
|
während keins x < val {
|
||||||
x += 1;
|
x += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
x = si soit Quelque(resultat) = peut_etre(i) {
|
x = wenn lass Etwas(ergebnis) = vielleicht(i) {
|
||||||
resultat.déballer()
|
ergebnis.entpacken()
|
||||||
} sinon {
|
} anderenfalls {
|
||||||
12
|
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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
[package]
|
[package]
|
||||||
name = "rouille"
|
name = "rost"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
111
rost_proc_macro/src/lib.rs
Normal file
111
rost_proc_macro/src/lib.rs
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
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() {
|
||||||
|
"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<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 rost(item: TokenStream) -> TokenStream {
|
||||||
|
let mut returned = Vec::new();
|
||||||
|
replace_stream(item, &mut returned);
|
||||||
|
let mut out = TokenStream::new();
|
||||||
|
out.extend(returned);
|
||||||
|
out
|
||||||
|
}
|
|
@ -1,111 +0,0 @@
|
||||||
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é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<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