summaryrefslogtreecommitdiff
path: root/src/types.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/types.hpp')
-rw-r--r--src/types.hpp241
1 files changed, 133 insertions, 108 deletions
diff --git a/src/types.hpp b/src/types.hpp
index 997031de..8e869f19 100644
--- a/src/types.hpp
+++ b/src/types.hpp
@@ -13,17 +13,6 @@ class ExprNode;
class Expr;
}
-/// Representation of restrictions placed on a type before it is made concrete
-// Possible bounds:
-// - Known to be a tuple of various inner types
-// - Unknown struct / enum
-// - Impls a trait
-// - Unknown
-class TypeBounds
-{
-
-};
-
class PrettyPrintType
{
const TypeRef& m_type;
@@ -37,117 +26,168 @@ public:
friend ::std::ostream& operator<<(::std::ostream& os, const PrettyPrintType& v);
};
+struct TypeArgRef
+{
+ ::std::string name;
+ unsigned int level;
+ const AST::TypeParams* params;
+};
+
+struct Type_Function:
+ public Serialisable
+{
+ bool is_unsafe;
+ ::std::string m_abi;
+ ::std::unique_ptr<TypeRef> m_rettype;
+ ::std::vector<TypeRef> m_arg_types;
+
+ Type_Function() {}
+ Type_Function(bool is_unsafe, ::std::string abi, ::std::unique_ptr<TypeRef> ret, ::std::vector<TypeRef> args):
+ is_unsafe(is_unsafe),
+ m_abi(abi),
+ m_rettype(mv$(ret)),
+ m_arg_types(mv$(args))
+ {}
+ Type_Function(const Type_Function& other);
+
+ Ordering ord(const Type_Function& x) const;
+
+ SERIALISABLE_PROTOTYPES();
+};
+
+TAGGED_ENUM(TypeData, None,
+ (None, ()),
+ (Any, ()),
+ (Unit, ()),
+ (Primitive, (
+ enum eCoreType core_type;
+ )),
+ (Function, (
+ Type_Function info;
+ )),
+ (Tuple, (
+ ::std::vector<TypeRef> inner_types;
+ )),
+ (Borrow, (
+ bool is_mut;
+ ::std::unique_ptr<TypeRef> inner;
+ )),
+ (Pointer, (
+ bool is_mut;
+ ::std::unique_ptr<TypeRef> inner;
+ )),
+ (Array, (
+ ::std::unique_ptr<TypeRef> inner;
+ ::std::shared_ptr<AST::ExprNode> size;
+ )),
+ (Generic, (
+ ::std::string name;
+ unsigned int level;
+ const AST::TypeParams* params;
+ )),
+ (Path, (
+ AST::Path path;
+ )),
+ (TraitObject, (
+ ::std::vector<AST::Path> traits;
+ ))
+ );
+
/// A type
class TypeRef:
public Serialisable
{
- /// Class
- enum Class {
- NONE,
- ANY, //< '_' - Wildcard
- //BOUNDED, //< '_: Traits' - Bounded type (a resolved type parameter usually)
- UNIT, //< '()' - Unit / void
- PRIMITIVE, //< Any primitive (builtin type)
- FUNCTION,
- TUPLE,
- REFERENCE,
- POINTER,
- ARRAY,
- GENERIC,
- PATH,
- MULTIDST, // Multi-trait DST (e.g. Trait + Send + Sync)
- };
-
- Class m_class;
- enum eCoreType m_core_type;
- bool m_is_inner_mutable;
-
- AST::Path m_path; // local = argument
- ::std::vector<TypeRef> m_inner_types;
- ::std::shared_ptr<AST::ExprNode> m_size_expr; //< Can be null (unsized array)
+ TypeData m_data;
/// A generic pointer, used for tagging with extra information
/// e.g. The source TypeParams for GENERIC
const void* m_tagged_ptr;
public:
+ TypeRef(TypeRef&& other) noexcept:
+ m_data( mv$(other.m_data) )
+ {}
+
+ TypeRef(const TypeRef& other)
+ {
+ switch( other.m_data.tag() )
+ {
+ #define _COPY(VAR) case TypeData::VAR: m_data = TypeData::make_##VAR(other.m_data.as_##VAR()); break;
+ #define _CLONE(VAR, code...) case TypeData::VAR: { auto& old = other.m_data.as_##VAR(); m_data = TypeData::make_##VAR(code); } break;
+ _COPY(None)
+ _COPY(Any)
+ _COPY(Unit)
+ _COPY(Primitive)
+ _COPY(Function)
+ _COPY(Tuple)
+ _CLONE(Borrow, { old.is_mut, box$(TypeRef(*old.inner)) })
+ _CLONE(Pointer, { old.is_mut, box$(TypeRef(*old.inner)) })
+ _CLONE(Array, { box$(TypeRef(*old.inner)), old.size })
+ _COPY(Generic)
+ _COPY(Path)
+ _COPY(TraitObject)
+ #undef _COPY
+ #undef _CLONE
+ }
+ }
+ TypeRef& operator=(const TypeRef& other) {
+ *this = TypeRef(other);
+ return *this;
+ }
+
TypeRef():
- m_class(ANY)
+ m_data(TypeData::make_Any({}))
{}
struct TagInvalid {};
TypeRef(TagInvalid):
- m_class(NONE)
- {}
-
- struct TagBoundedAny {};
- TypeRef(TagBoundedAny, ::std::vector<TypeRef> traits):
- m_class(ANY),
- m_inner_types( ::std::move(traits) )
+ m_data(TypeData::make_None({}))
{}
struct TagUnit {}; // unit maps to a zero-length tuple, just easier to type
TypeRef(TagUnit):
- m_class(UNIT)
+ m_data(TypeData::make_Unit({}))
{}
struct TagPrimitive {};
TypeRef(TagPrimitive, enum eCoreType type):
- m_class(PRIMITIVE),
- m_core_type(type)
+ m_data(TypeData::make_Primitive({type}))
{}
TypeRef(enum eCoreType type):
- m_class(PRIMITIVE),
- m_core_type(type)
+ m_data(TypeData::make_Primitive({type}))
{}
struct TagTuple {};
TypeRef(TagTuple _, ::std::vector<TypeRef> inner_types):
- m_class(TUPLE),
- m_inner_types( ::std::move(inner_types) )
+ m_data(TypeData::make_Tuple({::std::move(inner_types)}))
{}
struct TagFunction {};
TypeRef(TagFunction, ::std::string abi, ::std::vector<TypeRef> args, TypeRef ret):
- m_class(FUNCTION),
- m_path( {AST::PathNode( ::std::move(abi), {})} ), // abuse path for string
- m_inner_types( ::std::move(args) )
- {
- m_inner_types.push_back( ::std::move(ret) );
- }
+ m_data(TypeData::make_Function({ Type_Function( false, abi, box$(ret), mv$(args) ) }))
+ {}
struct TagReference {};
TypeRef(TagReference _, bool is_mut, TypeRef inner_type):
- m_class(REFERENCE),
- m_is_inner_mutable(is_mut),
- m_inner_types({::std::move(inner_type)})
+ m_data(TypeData::make_Borrow({ is_mut, ::make_unique_ptr(mv$(inner_type)) }))
{}
struct TagPointer {};
TypeRef(TagPointer _, bool is_mut, TypeRef inner_type):
- m_class(POINTER),
- m_is_inner_mutable(is_mut),
- m_inner_types({::std::move(inner_type)})
+ m_data(TypeData::make_Pointer({ is_mut, ::make_unique_ptr(mv$(inner_type)) }))
{}
struct TagSizedArray {};
TypeRef(TagSizedArray _, TypeRef inner_type, ::std::shared_ptr<AST::ExprNode> size):
- m_class(ARRAY),
- m_inner_types({::std::move(inner_type)}),
- m_size_expr( ::std::move(size) )
+ m_data(TypeData::make_Array({ ::make_unique_ptr(mv$(inner_type)), mv$(size) }))
{}
struct TagUnsizedArray {};
TypeRef(TagUnsizedArray _, TypeRef inner_type):
- m_class(ARRAY),
- m_inner_types({::std::move(inner_type)})
+ m_data(TypeData::make_Array({ ::make_unique_ptr(mv$(inner_type)), ::std::shared_ptr<AST::ExprNode>() }))
{}
struct TagArg {};
TypeRef(TagArg, ::std::string name):
- m_class(GENERIC),
- m_path( ::std::move(name) ),
- m_tagged_ptr(nullptr)
+ m_data(TypeData::make_Generic({ name, 0, nullptr }))
{}
TypeRef(TagArg, ::std::string name, const AST::TypeParams& params):
- m_class(GENERIC),
- m_path( ::std::move(name) ),
- m_tagged_ptr(&params)
+ m_data(TypeData::make_Generic({ name, 0, &params }))
{}
TypeRef(::std::string name):
TypeRef(TagArg(), ::std::move(name))
@@ -155,19 +195,15 @@ public:
struct TagPath {};
TypeRef(TagPath, AST::Path path):
- m_class(PATH),
- m_path( ::std::move(path) )
+ m_data(TypeData::make_Path({ ::std::move(path) }))
{}
TypeRef(AST::Path path):
TypeRef(TagPath(), ::std::move(path))
{}
TypeRef( ::std::vector<AST::Path> traits ):
- m_class(MULTIDST)
- {
- for( auto& t : traits )
- m_inner_types.push_back( TypeRef(::std::move(t)) );
- }
+ m_data(TypeData::make_TraitObject({ ::std::move(traits) }))
+ {}
/// Dereference the type (return the result of *type_instance)
bool deref(bool is_implicit);
@@ -183,33 +219,33 @@ public:
/// Returns true if the type is fully known (all sub-types are not wildcards)
bool is_concrete() const;
- bool is_unbounded() const { return m_class == ANY && m_inner_types.size() == 0; }
- bool is_wildcard() const { return m_class == ANY; }
+ bool is_unbounded() const { return m_data.is_Any(); }
+ bool is_wildcard() const { return m_data.is_Any(); }
- bool is_unit() const { return m_class == UNIT; }
- bool is_primitive() const { return m_class == PRIMITIVE; }
+ bool is_unit() const { return m_data.is_Unit(); }
+ bool is_primitive() const { return m_data.is_Primitive(); }
- bool is_path() const { return m_class == PATH; }
- const AST::Path& path() const { assert(is_path()); return m_path; }
- AST::Path& path() { assert(is_path()); return m_path; }
+ bool is_path() const { return m_data.is_Path(); }
+ const AST::Path& path() const { return m_data.as_Path().path; }
+ AST::Path& path() { return m_data.as_Path().path; }
- bool is_type_param() const { return m_class == GENERIC; }
- const ::std::string& type_param() const { assert(is_type_param()); return m_path[0].name(); }
+ bool is_type_param() const { return m_data.is_Generic(); }
+ const ::std::string& type_param() const { return m_data.as_Generic().name; }
void set_type_params_ptr(const AST::TypeParams& p) { assert(is_type_param()); m_tagged_ptr = &p; };
const AST::TypeParams* type_params_ptr() const {
assert(is_type_param());
return reinterpret_cast<const AST::TypeParams*>(m_tagged_ptr);
}
- bool is_reference() const { return m_class == REFERENCE; }
- bool is_pointer() const { return m_class == POINTER; }
- bool is_tuple() const { return m_class == TUPLE; }
+ bool is_reference() const { return m_data.is_Borrow(); }
+ bool is_pointer() const { return m_data.is_Pointer(); }
+ bool is_tuple() const { return m_data.is_Tuple(); }
- ::std::vector<TypeRef>& sub_types() { return m_inner_types; }
- const ::std::vector<TypeRef>& sub_types() const { return m_inner_types; }
+ //::std::vector<TypeRef>& sub_types() { return m_inner_types; }
+ //const ::std::vector<TypeRef>& sub_types() const { return m_inner_types; }
- void add_trait(TypeRef trait) { assert(is_wildcard()); m_inner_types.push_back( ::std::move(trait) ); }
- const ::std::vector<TypeRef>& traits() const { assert(is_wildcard()); return m_inner_types; }
+ //void add_trait(TypeRef trait) { assert(is_wildcard()); m_inner_types.push_back( ::std::move(trait) ); }
+ //const ::std::vector<TypeRef>& traits() const { assert(is_wildcard()); return m_inner_types; }
/// Returns 0 if types are identical, 1 if TypeRef::TagArg is present in one, and -1 if form differs
int equal_no_generic(const TypeRef& x) const;
@@ -224,20 +260,9 @@ public:
friend class PrettyPrintType;
friend ::std::ostream& operator<<(::std::ostream& os, const TypeRef& tr);
-
- static const char* class_name(TypeRef::Class c);
- friend void operator>>(::Deserialiser& d, TypeRef::Class& c);
+ static ::std::unique_ptr<TypeRef> from_deserialiser(Deserialiser& s);
SERIALISABLE_PROTOTYPES();
};
-class Type_Function:
- public Serialisable
-{
- bool is_unsafe;
- ::std::string m_abi;
- TypeRef m_rettype;
- ::std::vector<TypeRef> m_arg_types;
-};
-
#endif // TYPES_HPP_INCLUDED