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
|
#pragma once
#include "repr.h"
#include "typeInfo.h"
#include <functional>
#include <optional>
template<typename T>
using opt = std::optional<T>;
template<typename T>
opt<T> find(const std::vector<T> & ts, std::function<bool(T)> f)
{
for (auto t : ts)
if (f(t))
return t;
return nullopt;
}
opt<Function> findFunction(
const Program & p,
const std::string & name,
const std::vector<std::string> & namespacePrefixes)
{
if (namespacePrefixes.empty())
{
return find<Function>(p.functions, [&](Function f) { return f.name == name; });
}
auto n = find<Namespace>(p.namespaces, [&](Namespace n) { return n.name == namespacePrefixes[0]; });
if (!n.has_value())
return nullopt;
std::vector<Namespace> namespaces = { n.value() };
for (int i = 1; i < namespacePrefixes.size(); i++)
{
n = find<Namespace>(n.value().namespaces, [&](Namespace n) { return n.name == namespacePrefixes[i]; });
if (!n.has_value())
return nullopt;
namespaces.push_back(n.value());
}
for (int i = namespaces.size()-1; i >= 0; i--)
{
auto f = find<Function>(namespaces[i].functions, [&](Function f) { return f.name == name; });
if (f.has_value())
return f.value();
}
return find<Function>(p.functions, [&](Function f) { return f.name == name; });
}
opt<Struct> findStruct(
const Program & p,
const std::string & name,
const std::vector<std::string> & namespacePrefixes)
{
if (namespacePrefixes.empty())
{
return find<Struct>(p.structs, [&](Struct s) { return s.name == name; });
}
auto n = find<Namespace>(p.namespaces, [&](Namespace n) { return n.name == namespacePrefixes[0]; });
if (!n.has_value())
return nullopt;
for (int i = 1; i < namespacePrefixes.size(); i++)
{
n = find<Namespace>(n.value().namespaces, [&](Namespace n) { return n.name == namespacePrefixes[i]; });
if (!n.has_value())
return nullopt;
}
return find<Struct>(n.value().structs, [&](Struct s) { return s.name == name; });
}
opt<Variable> findVariable(
const Program & p,
const std::string & name,
std::shared_ptr<Context> ctx)
{
auto it = ctx;
while (it != nullptr)
{
auto v = find<Variable>(it->variables, [&](Variable v) { return v.name == name; });
if (v.has_value())
return v;
it = it->parent;
}
return nullopt;
}
opt<Function> findStructMethod(
const Program & p,
const std::string & name,
TypeInfo ti)
{
if (!ti.isStruct)
return nullopt;
auto s = findStruct(p, ti.type.name, ti.type.namespacePrefixes);
if (!s.has_value())
return nullopt;
return find<StructMember<Function>>(s.value().methods, [&](Function f) { return f.name == name; });
}
opt<Variable> findStructMember(
const Program & p,
TypeInfo ti,
const std::string & name)
{
auto s = findStruct(p, ti.type.name, ti.type.namespacePrefixes);
if (!s.has_value())
return nullopt;
return find<StructMember<Variable>>(s.value().members, [&](Variable v) { return v.name == name; });
}
|