Add function pointer types to syntax tree
diff --git a/syntax/check.rs b/syntax/check.rs
index ef3faff..be61226 100644
--- a/syntax/check.rs
+++ b/syntax/check.rs
@@ -167,6 +167,7 @@
Type::UniquePtr(_) => "unique_ptr".to_owned(),
Type::Ref(_) => "reference".to_owned(),
Type::Str(_) => "&str".to_owned(),
+ Type::Fn(_) => "function pointer".to_owned(),
Type::Void(_) => "()".to_owned(),
}
}
diff --git a/syntax/impls.rs b/syntax/impls.rs
index 6baa122..57b42d1 100644
--- a/syntax/impls.rs
+++ b/syntax/impls.rs
@@ -1,4 +1,4 @@
-use crate::syntax::{ExternFn, Ref, Signature, Ty1, Type};
+use crate::syntax::{ExternFn, Receiver, Ref, Signature, Ty1, Type};
use std::hash::{Hash, Hasher};
use std::mem;
use std::ops::Deref;
@@ -20,6 +20,7 @@
Type::UniquePtr(t) => t.hash(state),
Type::Ref(t) => t.hash(state),
Type::Str(t) => t.hash(state),
+ Type::Fn(t) => t.hash(state),
Type::Void(_) => {}
}
}
@@ -35,6 +36,7 @@
(Type::UniquePtr(lhs), Type::UniquePtr(rhs)) => lhs == rhs,
(Type::Ref(lhs), Type::Ref(rhs)) => lhs == rhs,
(Type::Str(lhs), Type::Str(rhs)) => lhs == rhs,
+ (Type::Fn(lhs), Type::Fn(rhs)) => lhs == rhs,
(Type::Void(_), Type::Void(_)) => true,
(_, _) => false,
}
@@ -103,3 +105,62 @@
inner.hash(state);
}
}
+
+impl Eq for Signature {}
+
+impl PartialEq for Signature {
+ fn eq(&self, other: &Signature) -> bool {
+ let Signature {
+ fn_token: _,
+ receiver,
+ args,
+ ret,
+ throws,
+ } = self;
+ let Signature {
+ fn_token: _,
+ receiver: receiver2,
+ args: args2,
+ ret: ret2,
+ throws: throws2,
+ } = other;
+ receiver == receiver2 && args == args2 && ret == ret2 && throws == throws2
+ }
+}
+
+impl Hash for Signature {
+ fn hash<H: Hasher>(&self, state: &mut H) {
+ let Signature {
+ fn_token: _,
+ receiver,
+ args,
+ ret,
+ throws,
+ } = self;
+ receiver.hash(state);
+ args.hash(state);
+ ret.hash(state);
+ throws.hash(state);
+ }
+}
+
+impl Eq for Receiver {}
+
+impl PartialEq for Receiver {
+ fn eq(&self, other: &Receiver) -> bool {
+ let Receiver { mutability, ident } = self;
+ let Receiver {
+ mutability: mutability2,
+ ident: ident2,
+ } = other;
+ mutability.is_some() == mutability2.is_some() && ident == ident2
+ }
+}
+
+impl Hash for Receiver {
+ fn hash<H: Hasher>(&self, state: &mut H) {
+ let Receiver { mutability, ident } = self;
+ mutability.is_some().hash(state);
+ ident.hash(state);
+ }
+}
diff --git a/syntax/mod.rs b/syntax/mod.rs
index f2e1c1c..6274cf1 100644
--- a/syntax/mod.rs
+++ b/syntax/mod.rs
@@ -59,6 +59,7 @@
pub throws: bool,
}
+#[derive(Eq, PartialEq, Hash)]
pub struct Var {
pub ident: Ident,
pub ty: Type,
@@ -75,6 +76,7 @@
UniquePtr(Box<Ty1>),
Ref(Box<Ref>),
Str(Box<Ref>),
+ Fn(Box<Signature>),
Void(Span),
}
diff --git a/syntax/tokens.rs b/syntax/tokens.rs
index 52c47d5..3bbe872 100644
--- a/syntax/tokens.rs
+++ b/syntax/tokens.rs
@@ -1,7 +1,7 @@
use crate::syntax::atom::Atom::*;
use crate::syntax::{Derive, ExternFn, Ref, Ty1, Type, Var};
use proc_macro2::{Ident, Span, TokenStream};
-use quote::{quote_spanned, ToTokens};
+use quote::{quote, quote_spanned, ToTokens};
use syn::Token;
impl ToTokens for Type {
@@ -16,6 +16,21 @@
}
Type::RustBox(ty) | Type::UniquePtr(ty) => ty.to_tokens(tokens),
Type::Ref(r) | Type::Str(r) => r.to_tokens(tokens),
+ Type::Fn(f) => {
+ let fn_token = f.fn_token;
+ let args = &f.args;
+ tokens.extend(quote!(#fn_token(#(#args),*)));
+ let mut ret = match &f.ret {
+ Some(ret) => quote!(#ret),
+ None => quote!(()),
+ };
+ if f.throws {
+ ret = quote!(::std::result::Result<#ret, _>);
+ }
+ if f.ret.is_some() || f.throws {
+ tokens.extend(quote!(-> #ret));
+ }
+ }
Type::Void(span) => tokens.extend(quote_spanned!(*span=> ())),
}
}
diff --git a/syntax/types.rs b/syntax/types.rs
index f9f87f3..f65b12f 100644
--- a/syntax/types.rs
+++ b/syntax/types.rs
@@ -26,6 +26,14 @@
Type::Ident(_) | Type::Str(_) | Type::Void(_) => {}
Type::RustBox(ty) | Type::UniquePtr(ty) => visit(all, &ty.inner),
Type::Ref(r) => visit(all, &r.inner),
+ Type::Fn(f) => {
+ if let Some(ret) = &f.ret {
+ visit(all, ret);
+ }
+ for arg in &f.args {
+ visit(all, &arg.ty);
+ }
+ }
}
}