Compare commits

..

2 commits

Author SHA1 Message Date
Michael Lohr 0b4fbdcc89
Autres langues 2021-09-11 18:37:04 +02:00
Benjamin Bouvier 3d67732c59 cassééééééééééééééééééééééééééééééééé 2021-09-11 16:11:38 +02:00
11 changed files with 245 additions and 220 deletions

View file

@ -1,29 +1,32 @@
name: "Kontinuierliche Integration"
name: Rust
on:
push:
branches: [ hauptzweig ]
branches: [ principale ]
pull_request:
branches: [ hauptzweig ]
branches: [ principale ]
jobs:
ci:
runs-on: ubuntu-latest
env:
RUST_BACKTRACE: 1
runs-on: ubuntu-latest
strategy:
matrix:
rust:
- stable
- nightly
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: ${{ matrix.rust }}
override: true
- name: Run examples
- name: Lancer les exemples
uses: actions-rs/cargo@v1
with:
command: run

View file

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

13
LIZENZ
View file

@ -1,13 +0,0 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2021 Benjamin Bouvier <email missing>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.

116
README.md
View file

@ -1,77 +1,103 @@
# rost
# rouille
<p align="center"><img src="logo.jpg" alt="Rust German Logo"></p>
![](https://github.com/bnjbvr/rouille/raw/principale/logo.jpeg)
Aren't you _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
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
programs?
**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.
**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.
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
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
convenience.
Here's an example of what can be achieved with Rost:
Here's an example of what can be achieved with Rouille:
## struct and impl (aka Konvention und Umsetzung)
### struct and impl (aka convention et réalisation)
```rust
rost::rost! {
benutze std::collections::Wörterbuch als Wöbu;
rouille::rouille! {
utilisons std::collections::Dictionnaire comme Dico;
eigenschaft SchlüsselWert {
funktion schreibe(&selbst, schlsl: Zeichenkette, wert: Zeichenkette);
funktion lese(&selbst, schlsl: Zeichenkette) -> Ergebnis<Möglichkeit<&Zeichenkette>, Zeichenkette>;
convention CléValeur {
fonction écrire(&soi, clé: Chaine, valeur: Chaine);
fonction lire(&soi, clé: Chaine) -> PeutÊtre<&Chaine>;
}
statisch änd WÖRTERBUCH: Möglichkeit<Wöbu<Zeichenkette, Zeichenkette>> = Nichts;
statique mutable DICTIONNAIRE: PeutÊtre<Dico<Chaine, Chaine>> = Rien;
struktur Konkret;
structure Concrète;
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)
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)
};
wöbu.einfügen(schlsl, wert);
dico.insérer(clé, valeur);
}
funktion lese(&selbst, schlsl: Zeichenkette) -> Ergebnis<Möglichkeit<&Zeichenkette>, Zeichenkette> {
wenn lass Etwas(wöbu) = gefährlich { WÖRTERBUCH.als_ref() } {
Gut(wöbu.hole(&schlsl))
} anderenfalls {
Fehler("Holt das Wörterbuch".hinein())
fonction lire(&soi, clé: Chaine) -> Résultat<PeutÊtre<&Chaine>, Chaine> {
si soit Quelque(dico) = dangereux { DICTIONNAIRE.en_réf() } {
Bien(dico.lire(&clé))
} sinon {
Arf("fetchez le dico".vers())
}
}
}
}
```
## Other examples
### 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
See the [examples](./examples/src/main.rs) to get a rough sense of the whole
syntax. Gut so!
syntax. Voilà, that's it.
## but why would you do dis?
## les contributions
* the [French](https://github.com/bnjbvr/rouille) and [Dutch](https://github.com/jeroenhd/roest) can do it, so we can as well!
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.
## Mitwirken
Please don't introduce swear words, though: we will not excuse your French.
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/).
## but why would you do zat
## Die Lizenzbestimmungen
- 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
## Other languages
- Dutch: [roest](https://github.com/jeroenhd/roest)
- German: [rost](https://github.com/michidk/rost)
## un grand merci
- [@VentGrey](https://twitter.com/VentGrey) for making a logo!
## la license
[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

View file

@ -1,9 +1,9 @@
[package]
name = "rost_examples"
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]
rost = { path = "../rost_proc_macro/" }
rouille = { path = "../rouille_proc_macro/" }

View file

@ -1,76 +1,85 @@
rost::rost! {
benutze std::collections::Wörterbuch als Wöbu;
rouille::rouille! {
externe cagette rouille;
eigenschaft SchlüsselWert {
funktion schreibe(&selbst, schlsl: Zeichenkette, wert: Zeichenkette);
funktion lese(&selbst, schlsl: Zeichenkette) -> Ergebnis<Möglichkeit<&Zeichenkette>, Zeichenkette>;
utilisons std::collections::Dictionnaire comme Dico;
convention CléValeur {
fonction écrire(&soi, clé: Chaine, valeur: Chaine);
fonction lire(&soi, clé: Chaine) -> Résultat<PeutÊtre<&Chaine>, Chaine>;
}
statisch änd WÖRTERBUCH: Möglichkeit<Wöbu<Zeichenkette, Zeichenkette>> = Nichts;
statique mutable DICTIONNAIRE: PeutÊtre<Dico<Chaine, Chaine>> = Rien;
struktur Konkret;
structure Concrète;
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)
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)
};
wöbu.einfügen(schlsl, wert);
dico.insérer(clé, valeur);
}
funktion lese(&selbst, schlsl: Zeichenkette) -> Ergebnis<Möglichkeit<&Zeichenkette>, Zeichenkette> {
wenn lass Etwas(wöbu) = gefährlich { WÖRTERBUCH.als_ref() } {
Gut(wöbu.hole(&schlsl))
} anderenfalls {
Fehler("Holt das Wörterbuch".hinein())
fonction lire(&soi, clé: Chaine) -> Résultat<PeutÊtre<&Chaine>, Chaine> {
si soit Quelque(dico) = dangereux { DICTIONNAIRE.en_réf() } {
Bien(dico.lire(&clé))
} sinon {
Arf("fetchez le dico".vers())
}
}
}
öffentlich(kiste) funktion vielleicht(i: u32) -> Möglichkeit<Ergebnis<u32, Zeichenkette>> {
wenn i % 2 == 1 {
wenn i == 42 {
Etwas(Fehler(Zeichenkette::von("Scheiße")))
} anderenfalls {
Etwas(Gut(33))
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))
}
} anderenfalls {
Nichts
} sinon {
Rien
}
}
asynchron funktion beispiel() {
asynchrone fonction exemple() {
}
asynchron funktion beispiel2() {
beispiel().abwarten;
asynchrone fonction exemple2() {
exemple().attend;
}
funktion einstieg() {
lass änd x = 31;
fonction principale() {
soit mutable x = 31;
entspreche x {
selon x {
42 => {
ausgabe!("Wienerschnitzel")
affiche!("omelette du fromage")
}
_ => ausgabe!("Na geht doch")
_ => affiche!("voila")
}
für i in 0..10 {
lass val = schleife {
abbruch i;
pour i de 0..10 {
soit val = boucle {
arrête i;
};
während keins x < val {
tant que x < val {
x += 1;
}
x = wenn lass Etwas(ergebnis) = vielleicht(i) {
ergebnis.entpacken()
} anderenfalls {
x = si soit Quelque(resultat) = peut_etre(i) {
resultat.déballer()
} sinon {
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
}
}

BIN
logo.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 293 KiB

BIN
logo.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

View file

@ -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() {
"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",
"abwarten" => "await",
"schleife" => "loop",
"schiebe" => "move",
"kiste" => "crate",
"unerreichbarer_code" => "unreachable_code",
"als" => "as",
"konstante" => "const",
"eigenschaft" => "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
}

View file

@ -1,5 +1,5 @@
[package]
name = "rost"
name = "rouille"
version = "0.1.0"
edition = "2018"

View 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() {
"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",
"" => "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
}