diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..167fdd5 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +patreon: UltiRequiem diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0256e97 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +**/*/target +*/target +/target +Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..30c9572 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,5 @@ +[workspace] +members = [ + "rustico_proc_macro", + "examples" +] diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..46a29c7 --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +MIT License + +Copyright (c) 2022 Eliaz Bobadilla + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/examples/Cargo.toml b/examples/Cargo.toml new file mode 100644 index 0000000..2c14818 --- /dev/null +++ b/examples/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "rustico_examples" +version = "0.1.0" +edition = "2018" + + +[dependencies] +rustico = { path = "../rustico_proc_macro" } diff --git a/examples/src/main.rs b/examples/src/main.rs new file mode 100644 index 0000000..1545f8e --- /dev/null +++ b/examples/src/main.rs @@ -0,0 +1,81 @@ +rustico::rustico! { + usando std::collections::Diccionario; + + sobrecarga Hola { + funcion escribe(&yo, llave: Texto, valor: Texto); + funcion consigue(&yo, llave: Texto) -> Resultado, Texto>; + } + + statico mutable DICCIONARIO: Opcion> = Ninguno; + + structura Concreto; + + implementa Hola para Concreto { + funcion escribe(&yo, llave: Texto, valor: Texto) { + deja dico = inseguro { + DICCIONARIO.obten_o_inserta_con(Defecto::defecto) + }; + dico.insérer(llave, valor); + } + funcion consigue(&yo, llave: Texto) -> Resultado, Texto> { + si deja Algunos(dico) = inseguro { DICCIONARIO.como_referencia() } { + Bien(dico.consigue(&llave)) + } sino { + Error("fetchez le dico".dentro_de()) + } + } + } + + publico(caja) funcion quizas(i: u32) -> Opcion> { + si i % 2 == 1 { + si i == 42 { + Algunos(Error(Texto::desde("merde"))) + } sino { + Algunos(Bien(33)) + } + } sino { + Ninguno + } + } + + asyncrona funcion example() { + } + + asyncrona funcion example2() { + example().espera; + } + + funcion principal() { + deja mutable x = 31; + + machea x { + 42 => { + imprime!("chales") + } + _ => imprime!("Buenas!") + } + + para i de 0..10 { + deja val = loopea { + rompe i; + }; + + mientras Difuso x < val { + x += 1; + } + + x = si deja Algunos(resultado) = quizas(i) { + resultado.pelar() + } sino { + 12 + }; + } + + } + + #[permite(codigo_inusado)] + funcion secundario() { + chales!("oh non"); + ups!("fetchez la vache"); + } +} diff --git a/rustico_proc_macro/Cargo.toml b/rustico_proc_macro/Cargo.toml new file mode 100644 index 0000000..a3246bd --- /dev/null +++ b/rustico_proc_macro/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "rustico" +version = "0.1.0" +edition = "2018" + +[lib] +proc-macro = true diff --git a/rustico_proc_macro/src/lib.rs b/rustico_proc_macro/src/lib.rs new file mode 100644 index 0000000..22c5b7a --- /dev/null +++ b/rustico_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() { + "Error" => "Err", + "Bien" => "Ok", + "Texto" => "String", + "Diccionario" => "HashMap", + "Defecto" => "Default", + "Errorsaso" => "Error", + "Opcion" => "Option", + "Algunos" => "Some", + "Ninguno" => "None", + "Resultado" => "Result", + "Yo" => "Self", + "imprime" => "println", + "rompe" => "break", + "asyncrona" => "async", + "espera" => "await", + "loopea" => "loop", + "muevete" => "move", + "caja" => "crate", + "codigo_inusado" => "unreachable_code", + "como" => "as", + "constante" => "const", + "sobrecarga" => "trait", + "inseguro" => "unsafe", + "de" => "in", + "desde" => "from", + "dinamico" => "dyn", + "pelar" => "unwrap", + "defecto" => "default", + "como_referencia" => "as_ref", + "es" => "io", + "externa" => "extern", + "falso" => "false", + "funcion" => "fn", + "piola" => "super", + "insérer" => "insert", + "consigue" => "get", + "permite" => "allow", + "chales" | "ups" => "panic", + "modulo" => "mod", + "mutable" => "mut", + "nuevo" => "new", + "donde" => "where", + "para" => "for", + "obten_o_inserta_con" => "get_or_insert_with", + "principal" => "main", + "publico" => "pub", + "Difuso" => None?, + "retorna" => "return", + "implementa" => "impl", + "referencia" => "ref", + "machea" => "match", + "si" => "if", + "sino" => "else", + "yo" => "self", + "deja" => "let", + "statico" => "static", + "structura" => "struct", + "confia" => "expect", + "mientras" => "while", + "usando" => "use", + "dentro_de" => "into", + "verdad" => "true", + "enumerado" => "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 rustico(item: TokenStream) -> TokenStream { + let mut returned = Vec::new(); + replace_stream(item, &mut returned); + let mut out = TokenStream::new(); + out.extend(returned); + out +}