blob: a1876d358024f2726db3243345248f59273a006d (
plain)
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
118
119
120
121
122
123
|
/**
** \file type/class.cc
** \brief Implementation for type/class.hh.
*/
#include <ostream>
#include <misc/algorithm.hh>
#include <type/class.hh>
#include <type/visitor.hh>
namespace type
{
Class::Class(const Class* super)
: Type()
, id_(fresh_id())
, super_(super)
, subclasses_()
{}
void Class::accept(ConstVisitor& v) const { v(*this); }
void Class::accept(Visitor& v) { v(*this); }
const Type* Class::attr_type(misc::symbol key) const
{
// FIXME DONE: Some code was deleted here.
const auto& attribute = std::ranges::find_if(
attrs_,
[&key] (const misc::symbol& name) { return name == key; },
[] (const Attribute& attr) { return attr.name_get(); }
);
return attribute != attrs_.end() ? &attribute->type_get() : nullptr;
}
const Type* Class::meth_type(misc::symbol key) const
{
// FIXME DONE: Some code was deleted here.
const auto& method = std::ranges::find_if(
meths_,
[&key] (const misc::symbol& name) { return name == key; },
[] (const Method* const meth) { return meth->name_get(); }
);
return method != meths_.end() ? &(*method)->type_get() : nullptr;
}
// FIXME DONE: Some code was deleted here (Find common super class).
const Class* Class::common_root(const Class& other) const
{
// temporary note: i'm tired so maybe the algo sucks ass :c
if (*this == other)
{
return this;
}
std::vector<const Class*> super_classes;
for (auto this_sc = this; this_sc != nullptr; this_sc = this_sc->super_)
{
super_classes.push_back(this_sc);
}
for (auto other_sc = &other; other_sc != nullptr; other_sc = other_sc->super_)
{
if (auto matching = std::ranges::find(super_classes, other_sc);
matching != super_classes.end())
{
return *matching;
}
}
return nullptr;
}
// FIXME DONE: Some code was deleted here (Super class soundness test).
bool Class::sound() const
{
auto reference = this;
std::vector<const Class*> previous;
while (reference != nullptr)
{
if (std::ranges::find(previous, reference) != previous.end())
{
return false;
}
previous.push_back(reference);
reference = reference->super_;
}
return true;
}
// FIXME DONE: Some code was deleted here (Special implementation of "compatible_with" for Class).
bool Class::compatible_with(const Type& other) const
{
if (Type::compatible_with(other) || dynamic_cast<const Nil*>(&other))
{
return true;
}
const auto ptr = dynamic_cast<const Class*>(&other);
return ptr && common_root(*ptr);
}
const Class& Class::object_instance()
{
// FIXME DONE: Some code was deleted here.
static const Class object { nullptr };
return object;
}
unsigned Class::fresh_id()
{
static unsigned counter_ = 0;
return counter_++;
}
} // namespace type
|