Initial commit

This commit is contained in:
Thelie 2022-02-19 11:37:31 +01:00
commit 6ff32bd4a4
7 changed files with 190 additions and 0 deletions

14
.gitignore vendored Normal file
View file

@ -0,0 +1,14 @@
# Rust
/target
Cargo.lock
# Version control and locks.
*.orig
*.swp
*~
.#*
\#*\#
ChangeLog
[0-9]*.patch
[0-9]*.txt
/vc-dwim-log-*

19
Cargo.toml Normal file
View file

@ -0,0 +1,19 @@
[package]
name = "sing"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
build = "build.rs"
[lib]
proc-macro = true
[build-dependencies]
lalrpop = "0.19"
[dependencies]
syn = "1"
regex = "1"
lalrpop-util = "0.19"
lalrpop = "0.19"

34
TODO Normal file
View file

@ -0,0 +1,34 @@
# Sing
Std
I/o
Negotiator
Generator
## What is sing meant to be?
- Provide stdio interface to traits
- not like serde because it's for traits instead of objects
- not like clap since it works at run time, not before
- similar ease of use as both of the above though
## How to get there
- Using lalrpop (in a feature flag)
- Maybe utilize serde
- Look at how clap handles states between macro calls
- They operate on a singleton lol
- This would need to store All traits and their functions
- It should also own (locked) Stdin, Stdout and Stderr (or any one Read and two Write objects)
- This bad boi would also implement the main loop for the cli application.
## Links oder so lül
https://serde.rs/impl-serializer.html
https://docs.serde.rs/serde/trait.Serializer.html
https://docs.rs/proc-macro2/1.0.36/proc_macro2/
https://docs.rs/syn/1.0.86/syn/
https://github.com/clap-rs/clap/blob/master/src/derive.rs
https://github.com/clap-rs/clap
https://github.com/clap-rs/clap/blob/v3.0.14/examples/tutorial_builder/README.md
https://www.morling.dev/blog/whats-in-a-good-error-message/

5
build.rs Normal file
View file

@ -0,0 +1,5 @@
extern crate lalrpop;
fn main() {
lalrpop::process_root().unwrap();
}

47
src/callobj.rs Normal file
View file

@ -0,0 +1,47 @@
use std::fmt;
pub struct CallObj {
trait_string: Option<String>,
fun_string: String,
index: usize,
data: Vec<String>,
}
impl CallObj {
pub fn new((trait_string, fun_string, index): (Option<String>, String, usize), data: Vec<String>) -> Self {
Self{
trait_string,
fun_string,
index,
data,
}
}
}
impl fmt::Display for CallObj {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut repr = String::new();
match &self.trait_string {
Some(tstr) => {
repr.push_str(tstr);
repr.push('>');
},
None => {}
}
repr.push_str(&self.fun_string);
if self.index != usize::MAX {
repr.push('>');
repr.push_str(&self.index.to_string());
}
for element in &self.data {
repr.push(' ');
repr.push_str(element);
}
write!(f, "{}", repr)
}
}

22
src/fun_parser.lalrpop Normal file
View file

@ -0,0 +1,22 @@
use std::str::FromStr;
use crate::callobj::CallObj;
grammar;
pub Call: CallObj = {
<Descriptor> <Data> => CallObj::new(<>),
};
Descriptor: (Option<String>, String, usize) = {
<t: (<Identifier> ">")?> <f: Identifier> ">" <i: Index> => (t, f, i),
<t: (<Identifier> ">")?> <f:Identifier> => (t, f, usize::MAX),
}
Identifier: String = r"[A-Z][a-zA-Z]*" => <>.to_string();
Index: usize = r"[1-9][0-9]*" => usize::from_str(<>).unwrap();
Data: Vec<String> = Value+;
Value: String = r" [0-9a-zA-Z]*" => (<>[1..<>.chars().count()]).to_string();

49
src/lib.rs Normal file
View file

@ -0,0 +1,49 @@
use proc_macro::TokenStream;
#[macro_use] extern crate lalrpop_util;
extern crate lalrpop;
mod callobj;
lalrpop_mod!(fun_parser);
#[proc_macro_derive(HelloMacro)]
pub fn hello_macro_derive(input: TokenStream) -> TokenStream {
let _friend = lalrpop::process_root();
println!("Hello world!");
fun_parser::CallParser::new();
input
}
#[cfg(test)]
mod tests {
use crate::fun_parser;
#[test]
fn it_works() {
let result = 2 + 2;
assert_eq!(result, 4);
}
#[test]
fn parser_parses() {
let test_str = "Trait>Fun>1 arg1 arg2 arg3";
assert!(fun_parser::CallParser::new()
.parse(test_str)
.is_ok());
}
#[test]
fn parser_parses_correctly() {
let test_str: &str = "Trait>Fun>1 arg1 arg2 arg3";
println!("[{}]",
fun_parser::CallParser::new()
.parse(test_str).unwrap()
);
assert!(format!( "{}",
fun_parser::CallParser::new()
.parse(test_str).unwrap()
) == test_str);
}
}