1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
#ifndef TYPES_HPP_INCLUDED
#define TYPES_HPP_INCLUDED
#include <memory>
#include "common.hpp"
#include "coretypes.hpp"
#include "ast/path.hpp"
#include <serialise.hpp>
namespace AST {
class ExprNode;
class Expr;
}
class TypeRef:
public Serialisable
{
enum Class {
ANY,
UNIT,
PRIMITIVE,
TUPLE,
REFERENCE,
POINTER,
ARRAY,
GENERIC,
PATH,
};
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)
public:
TypeRef():
m_class(ANY)
{}
struct TagUnit {}; // unit maps to a zero-length tuple, just easier to type
TypeRef(TagUnit):
m_class(UNIT)
{}
struct TagPrimitive {};
TypeRef(TagPrimitive, enum eCoreType type):
m_class(PRIMITIVE),
m_core_type(type)
{}
struct TagTuple {};
TypeRef(TagTuple _, ::std::vector<TypeRef> inner_types):
m_class(TUPLE),
m_inner_types( ::std::move(inner_types) )
{}
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)})
{}
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)})
{}
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) )
{}
struct TagUnsizedArray {};
TypeRef(TagUnsizedArray _, TypeRef inner_type):
m_class(ARRAY),
m_inner_types({::std::move(inner_type)})
{}
struct TagArg {};
TypeRef(TagArg, ::std::string name):
m_class(GENERIC),
m_path({AST::PathNode(name, {})})
{}
TypeRef(::std::string name):
TypeRef(TagArg(), ::std::move(name))
{}
struct TagPath {};
TypeRef(TagPath, AST::Path path):
m_class(PATH),
m_path( ::std::move(path) )
{}
TypeRef(AST::Path path):
TypeRef(TagPath(), ::std::move(path))
{}
bool is_path() const { return m_class == PATH; }
AST::Path& path() { assert(is_path()); return m_path; }
::std::vector<TypeRef>& sub_types() { return m_inner_types; }
friend ::std::ostream& operator<<(::std::ostream& os, const TypeRef& tr);
SERIALISABLE_PROTOTYPES();
};
#endif // TYPES_HPP_INCLUDED
|