This repository was archived by the owner on Oct 12, 2026. It is now read-only.
Repository navigation
Expand file tree
/
Copy pathType.hpp
More file actions
117 lines (79 loc) · 3 KB
/
Copy pathType.hpp
File metadata and controls
117 lines (79 loc) · 3 KB
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
110
111
112
113
114
115
116
117
#pragma once
#include <memory>
#include <string>
#include <vector>
// These are runtime-types different from frontend::type.
// Forward declaration of value-structure, cannot import directly due to circular-dependency.
namespace lbd::runtime
{
struct Value;
}
// TODO: Maybe move instead of copying the reference.
namespace lbd::runtime::type
{
enum class TypeTag
{
Float,
String,
Closure,
NativeFunction,
List,
Any
};
[[nodiscard]] TypeTag typeTagFromValue(const Value &value);
[[nodiscard]] std::string typeTagToString(TypeTag tag);
// TODO: Implement move-constructor and possibly move-assignment-operator.
// TODO: Overload operator<< for printing.
struct Type
{
virtual ~Type() = default;
[[nodiscard]] virtual bool matches(const Value &value) const = 0;
[[nodiscard]] virtual bool equals(const Type &otherType) const = 0;
[[nodiscard]] virtual std::string toString() const = 0;
[[nodiscard]] virtual bool isCallable() const = 0;
[[nodiscard]] bool allowsHardCheck() const;
protected:
/// Do not force the thunk for type-checking if disabled, check using the thunk's unevaluated-expression.
bool hardCheck = true;
};
struct SimpleType final : Type
{
explicit SimpleType(TypeTag tag, bool hardCheck = true);
~SimpleType() override = default;
[[nodiscard]] bool matches(const Value &value) const override;
[[nodiscard]] bool equals(const Type &otherType) const override;
[[nodiscard]] std::string toString() const override;
[[nodiscard]] bool isCallable() const override;
private:
TypeTag tag;
};
// TODO: List should not have element-type, as we can add any type to it.
struct ListType final : Type
{
~ListType() override = default;
[[nodiscard]] bool matches(const Value &value) const override;
[[nodiscard]] bool equals(const Type &otherType) const override;
[[nodiscard]] std::string toString() const override;
[[nodiscard]] bool isCallable() const override;
};
struct FunctionType final : Type
{
explicit FunctionType(const std::vector<std::shared_ptr<Type>> &argumentTypes,
const std::shared_ptr<Type> &returnType, bool isVariadic = false);
~FunctionType() override = default;
[[nodiscard]] const Type &getReturnType() const;
[[nodiscard]] bool matches(const Value &value) const override;
[[nodiscard]] bool matchesArgumentTypes(Context &context, const std::vector<std::shared_ptr<Thunk>> &thunks) const;
[[nodiscard]] bool matchesReturnType(const Value &value) const;
[[nodiscard]] bool equals(const Type &otherType) const override;
[[nodiscard]] std::string toString() const override;
[[nodiscard]] bool isCallable() const override;
[[nodiscard]] int arity() const;
private:
std::vector<std::shared_ptr<Type>> argumentTypes;
std::shared_ptr<Type> returnType;
bool isVariadic;
std::shared_ptr<Type> variadicType;
};
[[nodiscard]] std::shared_ptr<Type> typeFromValue(const Value &value);
}