Basic functionality of the crate is now present.

This commit is contained in:
Thelie 2022-03-26 23:06:38 +01:00
parent 616ab17008
commit ec7ba974da
12 changed files with 773 additions and 666 deletions

View file

@ -13,13 +13,7 @@ edition = "2021"
[lib]
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]
serde = { version = "1.0", features = ["derive"] }
syn = { version = "1.0", features = ["full"] }
proc-macro2 = "1.0"
sing_macros = { path = "./sing_macros", version = "0.1.0" }
sing_parse = { path = "./sing_parse", version = "0.1.0" }
sing_util = { path = "./sing_util", version = " 0.1.0" }

View file

@ -1,5 +1,5 @@
[package]
name = "sing_derive"
name = "sing_macros"
version = "0.1.0"
edition = "2021"

View file

@ -2,3 +2,5 @@ use syn::custom_keyword;
custom_keyword!(ioe);
custom_keyword!(msg);
custom_keyword!(equal);
custom_keyword!(different);

File diff suppressed because it is too large Load diff

View file

@ -16,4 +16,6 @@ lalrpop = "0.19"
syn = "1"
regex = "1"
lalrpop-util = "0.19"
lalrpop = "0.19"
lalrpop = "0.19"
sing_util = { path = "../sing_util" }
serde = { version = "1.0", features = ["derive"] }

View file

@ -1,5 +1,8 @@
use std::fmt;
use sing_util::TraitCallMessage;
use serde::{Serialize, Deserialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CallObj {
trait_string: Option<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 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut repr = String::new();

View file

@ -13,10 +13,10 @@ Descriptor: (Option<String>, String, usize) = {
<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();
Data: Vec<String> = Value+;
Data: Vec<String> = Value*;
Value: String = r" [0-9a-zA-Z]*" => (<>[1..<>.chars().count()]).to_string();

View file

@ -1,3 +1,7 @@
use std::{error::Error};
pub use callobj::CallObj;
#[macro_use] extern crate lalrpop_util;
extern crate lalrpop;
@ -5,6 +9,15 @@ mod callobj;
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)]
mod tests {
use crate::fun_parser;

View file

@ -3,10 +3,11 @@ use std::{error::Error, collections::HashMap};
use proc_macro2::TokenStream;
use serde::{Serialize, Deserialize};
use serde_wrapper::TokenStreamWrapper;
pub use serde_wrapper::TokenStreamWrapper;
mod serde_wrapper;
/// Represents a trait as Function names associated with tokenstreams.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TraitProfile{
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)]
pub enum DeduplicatedFunctionProfile {
Single(String, TokenStreamWrapper),
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 {
fn get_fun_name() -> String;
fn get_trait_name() -> String;
fn get_params() -> Vec<String>;
fn new_params(p: Vec<String>);
type Representation;
fn get_fun_name(&self) -> 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)]

View file

@ -1,8 +1,10 @@
use std::{str::FromStr, fmt::{self, format}, error::Error};
use std::{str::FromStr, error::Error};
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)]
pub struct TokenStreamWrapper(String);
@ -14,62 +16,3 @@ impl TokenStreamWrapper {
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)
}
}
*/

View file

@ -1,70 +1,3 @@
use core::fmt::Debug;
use proc_macro2::TokenStream;
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);
}
}
pub use sing_macros::*;
pub use sing_parse::*;
pub use sing_util::TraitCallMessage;

View file

@ -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)
}
}