From 85dce7f39fe5e80e1a449401801ee1c9a846842f Mon Sep 17 00:00:00 2001 From: Gerald Pinder Date: Fri, 10 Jan 2025 00:28:27 -0500 Subject: [PATCH] Initial commit for frontend --- .gitignore | 1 + Cargo.lock | 47 +++++++++++++++++ Cargo.toml | 9 ++++ src/lib.rs | 146 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 203 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 src/lib.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..2393fcf --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,47 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "comlexr" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "syn" +version = "2.0.96" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..f8dc816 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "comlexr" +version = "0.1.0" +edition = "2021" + +[dependencies] +proc-macro2 = "1.0.92" +quote = "1.0.38" +syn = { version = "2.0.96", features = ["full"] } diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..9630031 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,146 @@ +use syn::{bracketed, parse::Parse, punctuated::Punctuated, token, Token}; + +struct Command { + program: Program, + args: Option>, +} + +impl Parse for Command { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + let program = input.parse()?; + + if input.is_empty() { + Ok(Command { + program, + args: None, + }) + } else { + _ = input.parse::()?; + Ok(Command { + program, + args: Some(input.parse_terminated(Arg::parse, Token![,])?), + }) + } + } +} + +struct Program(syn::LitStr); + +impl Parse for Program { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + input.parse().map(Self) + } +} + +enum Arg { + Expression(syn::Expr), + ForIter { + for_key: Token![for], + expr: syn::Expr, + }, + ForInIterMulti { + for_iter: ForIter, + arrow_token: Token![=>], + args: MultiArg, + }, + ForInIterSingle { + for_iter: ForIter, + arrow_token: Token![=>], + arg: SingleArg, + }, + IfLetMulti { + if_let: IfLet, + arrow_token: Token![=>], + args: MultiArg, + }, + IfLetSingle { + if_let: IfLet, + arrow_token: Token![=>], + arg: SingleArg, + }, + IfMulti { + expr: syn::Expr, + arrow_token: Token![=>], + args: MultiArg, + }, + IfSingle { + expr: syn::Expr, + arrow_token: Token![=>], + arg: SingleArg, + }, +} + +impl Parse for Arg { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + input.parse() + } +} + +struct Pattern(syn::Pat); + +impl Parse for Pattern { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + input.call(syn::Pat::parse_single).map(Self) + } +} + +struct ForIter { + for_token: Token![for], + pattern: Pattern, + in_token: Token![in], + iter: syn::Expr, +} + +impl Parse for ForIter { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + Ok(ForIter { + for_token: input.parse()?, + pattern: input.parse()?, + in_token: input.parse()?, + iter: input.parse()?, + }) + } +} + +struct IfLet { + if_token: Token![if], + let_token: Token![let], + pattern: Pattern, + eq_token: Token![=], + expr: syn::Expr, +} + +impl Parse for IfLet { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + Ok(IfLet { + if_token: input.parse()?, + let_token: input.parse()?, + pattern: input.parse()?, + eq_token: input.parse()?, + expr: input.parse()?, + }) + } +} + +struct SingleArg(syn::Expr); + +impl Parse for SingleArg { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + input.parse().map(Self) + } +} + +struct MultiArg { + bracket: token::Bracket, + args: Punctuated, +} + +impl Parse for MultiArg { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + let args; + Ok(MultiArg { + bracket: bracketed!(args in input), + args: input.parse_terminated(SingleArg::parse, Token![,])?, + }) + } +}