Basic functionality of the crate is now present.
This commit is contained in:
parent
616ab17008
commit
ec7ba974da
12 changed files with 773 additions and 666 deletions
12
Cargo.toml
12
Cargo.toml
|
@ -13,13 +13,7 @@ edition = "2021"
|
||||||
[lib]
|
[lib]
|
||||||
bench = false
|
bench = false
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
# build = "build.rs"
|
|
||||||
#
|
|
||||||
# [build-dependencies]
|
|
||||||
# lalrpop = "0.19"
|
|
||||||
#
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
sing_macros = { path = "./sing_macros", version = "0.1.0" }
|
||||||
syn = { version = "1.0", features = ["full"] }
|
sing_parse = { path = "./sing_parse", version = "0.1.0" }
|
||||||
proc-macro2 = "1.0"
|
sing_util = { path = "./sing_util", version = " 0.1.0" }
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
[package]
|
[package]
|
||||||
name = "sing_derive"
|
name = "sing_macros"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
|
|
@ -2,3 +2,5 @@ use syn::custom_keyword;
|
||||||
|
|
||||||
custom_keyword!(ioe);
|
custom_keyword!(ioe);
|
||||||
custom_keyword!(msg);
|
custom_keyword!(msg);
|
||||||
|
custom_keyword!(equal);
|
||||||
|
custom_keyword!(different);
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -16,4 +16,6 @@ lalrpop = "0.19"
|
||||||
syn = "1"
|
syn = "1"
|
||||||
regex = "1"
|
regex = "1"
|
||||||
lalrpop-util = "0.19"
|
lalrpop-util = "0.19"
|
||||||
lalrpop = "0.19"
|
lalrpop = "0.19"
|
||||||
|
sing_util = { path = "../sing_util" }
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
|
@ -1,5 +1,8 @@
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use sing_util::TraitCallMessage;
|
||||||
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct CallObj {
|
pub struct CallObj {
|
||||||
trait_string: Option<String>,
|
trait_string: Option<String>,
|
||||||
fun_string: String,
|
fun_string: String,
|
||||||
|
@ -18,6 +21,26 @@ impl CallObj {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TraitCallMessage for CallObj {
|
||||||
|
type Representation = String;
|
||||||
|
|
||||||
|
fn get_fun_name(&self) -> String {
|
||||||
|
self.fun_string.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_trait_name(&self) -> Option<String> {
|
||||||
|
self.trait_string.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_params(&self) -> Vec<Self::Representation> {
|
||||||
|
self.data.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_params(&mut self, p: Vec<Self::Representation>) {
|
||||||
|
self.data = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Display for CallObj {
|
impl fmt::Display for CallObj {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
let mut repr = String::new();
|
let mut repr = String::new();
|
||||||
|
|
|
@ -13,10 +13,10 @@ Descriptor: (Option<String>, String, usize) = {
|
||||||
<t: (<Identifier> ">")?> <f:Identifier> => (t, f, usize::MAX),
|
<t: (<Identifier> ">")?> <f:Identifier> => (t, f, usize::MAX),
|
||||||
}
|
}
|
||||||
|
|
||||||
Identifier: String = r"[A-Z][a-zA-Z]*" => <>.to_string();
|
Identifier: String = r"[a-zA-Z]*" => <>.to_string();
|
||||||
|
|
||||||
Index: usize = r"[1-9][0-9]*" => usize::from_str(<>).unwrap();
|
Index: usize = r"[1-9][0-9]*" => usize::from_str(<>).unwrap();
|
||||||
|
|
||||||
Data: Vec<String> = Value+;
|
Data: Vec<String> = Value*;
|
||||||
|
|
||||||
Value: String = r" [0-9a-zA-Z]*" => (<>[1..<>.chars().count()]).to_string();
|
Value: String = r" [0-9a-zA-Z]*" => (<>[1..<>.chars().count()]).to_string();
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
use std::{error::Error};
|
||||||
|
|
||||||
|
pub use callobj::CallObj;
|
||||||
|
|
||||||
#[macro_use] extern crate lalrpop_util;
|
#[macro_use] extern crate lalrpop_util;
|
||||||
extern crate lalrpop;
|
extern crate lalrpop;
|
||||||
|
|
||||||
|
@ -5,6 +9,15 @@ mod callobj;
|
||||||
|
|
||||||
lalrpop_mod!(fun_parser);
|
lalrpop_mod!(fun_parser);
|
||||||
|
|
||||||
|
pub fn callobj_to_string(o: CallObj) -> Result<String, Box<dyn Error>> {
|
||||||
|
Ok(o.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn callobj_from_string(s: String) -> Result<CallObj, Box<dyn Error>> {
|
||||||
|
// TODO: This should use a "?", but for some reason the error references s
|
||||||
|
Ok(fun_parser::CallParser::new().parse(&s).unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::fun_parser;
|
use crate::fun_parser;
|
||||||
|
|
|
@ -3,10 +3,11 @@ use std::{error::Error, collections::HashMap};
|
||||||
|
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
use serde_wrapper::TokenStreamWrapper;
|
pub use serde_wrapper::TokenStreamWrapper;
|
||||||
|
|
||||||
mod serde_wrapper;
|
mod serde_wrapper;
|
||||||
|
|
||||||
|
/// Represents a trait as Function names associated with tokenstreams.
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct TraitProfile{
|
pub struct TraitProfile{
|
||||||
functions: HashMap<String, TokenStreamWrapper>,
|
functions: HashMap<String, TokenStreamWrapper>,
|
||||||
|
@ -37,17 +38,23 @@ impl TraitProfile{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Represents the state of a function name,
|
||||||
|
/// with it either being only present once or existing multiple times.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum DeduplicatedFunctionProfile {
|
pub enum DeduplicatedFunctionProfile {
|
||||||
Single(String, TokenStreamWrapper),
|
Single(String, TokenStreamWrapper),
|
||||||
Multiple(Vec<String>),
|
Multiple(Vec<String>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Needs to be implemented by all structs that are used as
|
||||||
|
/// function calls that are sent through a sing I/O stream
|
||||||
pub trait TraitCallMessage {
|
pub trait TraitCallMessage {
|
||||||
fn get_fun_name() -> String;
|
type Representation;
|
||||||
fn get_trait_name() -> String;
|
|
||||||
fn get_params() -> Vec<String>;
|
fn get_fun_name(&self) -> String;
|
||||||
fn new_params(p: Vec<String>);
|
fn get_trait_name(&self) -> Option<String>;
|
||||||
|
fn get_params(&self) -> Vec<Self::Representation>;
|
||||||
|
fn new_params(&mut self, p: Vec<Self::Representation>);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
use std::{str::FromStr, fmt::{self, format}, error::Error};
|
use std::{str::FromStr, error::Error};
|
||||||
|
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use serde::{Serialize, Serializer, Deserialize, Deserializer, de::{Visitor, self}};
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
|
/// Wraps the proc_macro2 Tokenstream type,
|
||||||
|
/// so it can be serialized and deserialized.
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct TokenStreamWrapper(String);
|
pub struct TokenStreamWrapper(String);
|
||||||
|
|
||||||
|
@ -14,62 +16,3 @@ impl TokenStreamWrapper {
|
||||||
Ok(TokenStream::from_str(&self.0.clone())?)
|
Ok(TokenStream::from_str(&self.0.clone())?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
impl Serialize for TokenStreamWrapper {
|
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
|
|
||||||
where
|
|
||||||
S: Serializer
|
|
||||||
{
|
|
||||||
let inner = &self.0;
|
|
||||||
serializer.serialize_newtype_struct("Lifetime", &inner.to_string())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'de> Deserialize<'de> for TokenStreamWrapper {
|
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
||||||
where
|
|
||||||
D: Deserializer<'de>
|
|
||||||
{
|
|
||||||
let tok_str = deserializer.deserialize_string(TokenStreamVisitor)?;
|
|
||||||
|
|
||||||
match TokenStream::from_str(tok_str.as_str()) {
|
|
||||||
Ok(t) => Ok(Self(t)),
|
|
||||||
Err(e) => Err(de::Error::custom(
|
|
||||||
format!("string does not represent a valid TokenStream: {}", e)
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct TokenStreamVisitor;
|
|
||||||
|
|
||||||
impl<'de> Visitor<'de> for TokenStreamVisitor {
|
|
||||||
type Value = String;
|
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
formatter.write_str("A string representing a TokenStream")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
|
|
||||||
where
|
|
||||||
E: de::Error,
|
|
||||||
{
|
|
||||||
Ok(value.to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_borrowed_str<E>(self, value: &'de str) -> Result<Self::Value, E>
|
|
||||||
where
|
|
||||||
E: de::Error,
|
|
||||||
{
|
|
||||||
Ok(value.to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
|
|
||||||
where
|
|
||||||
E: de::Error,
|
|
||||||
{
|
|
||||||
Ok(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
73
src/lib.rs
73
src/lib.rs
|
@ -1,70 +1,3 @@
|
||||||
use core::fmt::Debug;
|
pub use sing_macros::*;
|
||||||
|
pub use sing_parse::*;
|
||||||
use proc_macro2::TokenStream;
|
pub use sing_util::TraitCallMessage;
|
||||||
use serde::{Serialize, Deserialize};
|
|
||||||
use serde_wrapper::TokenStreamWrapper;
|
|
||||||
|
|
||||||
mod serde_wrapper;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
||||||
struct TraitProfile{
|
|
||||||
//functions: HashMap<String, FunctionProfile>,
|
|
||||||
functions: Vec<TokenStreamWrapper>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TraitProfile{
|
|
||||||
pub fn new(streams: Vec<TokenStream>) -> Self {
|
|
||||||
let mut inner = vec!();
|
|
||||||
|
|
||||||
for stream in streams {
|
|
||||||
inner.push(TokenStreamWrapper::new(stream));
|
|
||||||
}
|
|
||||||
|
|
||||||
Self{
|
|
||||||
functions: inner
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
enum DeduplicatedFunctionProfile {
|
|
||||||
Single(String, TokenStreamWrapper),
|
|
||||||
Multiple(Vec<String>, TokenStreamWrapper),
|
|
||||||
}
|
|
||||||
|
|
||||||
/*impl<T> Evaluator<T> {
|
|
||||||
fn deduplicate_functions(&self) -> Self<T> {
|
|
||||||
let mut self = self.clone();
|
|
||||||
let mut functions: HashMap<String, DeduplicatedFunctionProfile>;
|
|
||||||
|
|
||||||
for (t_name, t_profile) in self.traits {
|
|
||||||
for (fun_name, fun_profile) in t_profile.functions {
|
|
||||||
if !functions.contains_key(fun_name) {
|
|
||||||
self.functions.insert(fun_name, DeduplicatedFunctionProfile::Single(t_name, fun_profile))
|
|
||||||
} else {
|
|
||||||
let other = self.functions.remove(fun_name).unwrap();
|
|
||||||
|
|
||||||
let traits: Vec<String>;
|
|
||||||
match other {
|
|
||||||
DeduplicatedFunctionProfile::Single(t, _) => traits = vec!(t),
|
|
||||||
DeduplicatedFunctionProfile::Multiple(ts, _) => traits = ts,
|
|
||||||
}
|
|
||||||
|
|
||||||
self.functions.insert(fun_name, DeduplicatedFunctionProfile::Multiple(traits, fun_profile))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_works() {
|
|
||||||
let result = 2 + 2;
|
|
||||||
assert_eq!(result, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,71 +0,0 @@
|
||||||
use std::{str::FromStr, fmt::{self, format}};
|
|
||||||
|
|
||||||
use proc_macro2::TokenStream;
|
|
||||||
use serde::{Serialize, Serializer, Deserialize, Deserializer, de::{Visitor, self}};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct TokenStreamWrapper(TokenStream);
|
|
||||||
|
|
||||||
impl TokenStreamWrapper {
|
|
||||||
pub fn new(stream: TokenStream) -> Self {
|
|
||||||
Self(stream)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Serialize for TokenStreamWrapper {
|
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
|
|
||||||
where
|
|
||||||
S: Serializer
|
|
||||||
{
|
|
||||||
let inner = &self.0;
|
|
||||||
serializer.serialize_newtype_struct("Lifetime", &inner.to_string())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'de> Deserialize<'de> for TokenStreamWrapper {
|
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
||||||
where
|
|
||||||
D: Deserializer<'de>
|
|
||||||
{
|
|
||||||
let tok_str = deserializer.deserialize_string(TokenStreamVisitor)?;
|
|
||||||
|
|
||||||
match TokenStream::from_str(&tok_str.as_str()) {
|
|
||||||
Ok(t) => Ok(Self(t)),
|
|
||||||
Err(e) => Err(de::Error::custom(
|
|
||||||
format!("string does not represent a valid TokenStream: {}", e)
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct TokenStreamVisitor;
|
|
||||||
|
|
||||||
impl<'de> Visitor<'de> for TokenStreamVisitor {
|
|
||||||
type Value = String;
|
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
formatter.write_str("A string representing a TokenStream")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
|
|
||||||
where
|
|
||||||
E: de::Error,
|
|
||||||
{
|
|
||||||
Ok(value.to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_borrowed_str<E>(self, value: &'de str) -> Result<Self::Value, E>
|
|
||||||
where
|
|
||||||
E: de::Error,
|
|
||||||
{
|
|
||||||
Ok(value.to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
|
|
||||||
where
|
|
||||||
E: de::Error,
|
|
||||||
{
|
|
||||||
Ok(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in a new issue