Line | Branch | Exec | Source |
---|---|---|---|
1 | #ifndef LYTHON_SEMA_BINDINGS_HEADER | ||
2 | #define LYTHON_SEMA_BINDINGS_HEADER | ||
3 | |||
4 | #include "dependencies/coz_wrap.h" | ||
5 | #include "sema/builtin.h" | ||
6 | |||
7 | namespace lython { | ||
8 | |||
9 | struct BindingEntry { | ||
10 | BindingEntry(StringRef a = StringRef(), | ||
11 | Node* b = nullptr, | ||
12 | TypeExpr* c = nullptr, | ||
13 | 25 | bool dynamic = false): | |
14 | 25 | name(a), | |
15 | 25 | value(b), type(c), dynamic(dynamic) {} | |
16 | |||
17 | bool operator==(BindingEntry const& b) const { | ||
18 | return name == b.name && value == b.value && type == b.type; | ||
19 | } | ||
20 | |||
21 | StringRef name; | ||
22 | Node* value = nullptr; | ||
23 | TypeExpr* type = nullptr; | ||
24 | bool dynamic = false; // used to specify that this entry is dynamic | ||
25 | // and its address can change at runtime | ||
26 | }; | ||
27 | |||
28 | std::ostream& print(std::ostream& out, BindingEntry const& entry); | ||
29 | |||
30 | struct Bindings { | ||
31 | Bindings() { | ||
32 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | bindings.reserve(128); |
33 | |||
34 | #define TYPE(name) add(String(#name), name##_t(), Type_t()); | ||
35 | |||
36 |
75/150✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 19 taken 1 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 23 not taken.
✓ Branch 26 taken 1 times.
✗ Branch 27 not taken.
✓ Branch 29 taken 1 times.
✗ Branch 30 not taken.
✓ Branch 32 taken 1 times.
✗ Branch 33 not taken.
✓ Branch 37 taken 1 times.
✗ Branch 38 not taken.
✓ Branch 40 taken 1 times.
✗ Branch 41 not taken.
✓ Branch 44 taken 1 times.
✗ Branch 45 not taken.
✓ Branch 47 taken 1 times.
✗ Branch 48 not taken.
✓ Branch 50 taken 1 times.
✗ Branch 51 not taken.
✓ Branch 55 taken 1 times.
✗ Branch 56 not taken.
✓ Branch 58 taken 1 times.
✗ Branch 59 not taken.
✓ Branch 62 taken 1 times.
✗ Branch 63 not taken.
✓ Branch 65 taken 1 times.
✗ Branch 66 not taken.
✓ Branch 68 taken 1 times.
✗ Branch 69 not taken.
✓ Branch 73 taken 1 times.
✗ Branch 74 not taken.
✓ Branch 76 taken 1 times.
✗ Branch 77 not taken.
✓ Branch 80 taken 1 times.
✗ Branch 81 not taken.
✓ Branch 83 taken 1 times.
✗ Branch 84 not taken.
✓ Branch 86 taken 1 times.
✗ Branch 87 not taken.
✓ Branch 91 taken 1 times.
✗ Branch 92 not taken.
✓ Branch 94 taken 1 times.
✗ Branch 95 not taken.
✓ Branch 98 taken 1 times.
✗ Branch 99 not taken.
✓ Branch 101 taken 1 times.
✗ Branch 102 not taken.
✓ Branch 104 taken 1 times.
✗ Branch 105 not taken.
✓ Branch 109 taken 1 times.
✗ Branch 110 not taken.
✓ Branch 112 taken 1 times.
✗ Branch 113 not taken.
✓ Branch 116 taken 1 times.
✗ Branch 117 not taken.
✓ Branch 119 taken 1 times.
✗ Branch 120 not taken.
✓ Branch 122 taken 1 times.
✗ Branch 123 not taken.
✓ Branch 127 taken 1 times.
✗ Branch 128 not taken.
✓ Branch 130 taken 1 times.
✗ Branch 131 not taken.
✓ Branch 134 taken 1 times.
✗ Branch 135 not taken.
✓ Branch 137 taken 1 times.
✗ Branch 138 not taken.
✓ Branch 140 taken 1 times.
✗ Branch 141 not taken.
✓ Branch 145 taken 1 times.
✗ Branch 146 not taken.
✓ Branch 148 taken 1 times.
✗ Branch 149 not taken.
✓ Branch 152 taken 1 times.
✗ Branch 153 not taken.
✓ Branch 155 taken 1 times.
✗ Branch 156 not taken.
✓ Branch 158 taken 1 times.
✗ Branch 159 not taken.
✓ Branch 163 taken 1 times.
✗ Branch 164 not taken.
✓ Branch 166 taken 1 times.
✗ Branch 167 not taken.
✓ Branch 170 taken 1 times.
✗ Branch 171 not taken.
✓ Branch 173 taken 1 times.
✗ Branch 174 not taken.
✓ Branch 176 taken 1 times.
✗ Branch 177 not taken.
✓ Branch 181 taken 1 times.
✗ Branch 182 not taken.
✓ Branch 184 taken 1 times.
✗ Branch 185 not taken.
✓ Branch 188 taken 1 times.
✗ Branch 189 not taken.
✓ Branch 191 taken 1 times.
✗ Branch 192 not taken.
✓ Branch 194 taken 1 times.
✗ Branch 195 not taken.
✓ Branch 199 taken 1 times.
✗ Branch 200 not taken.
✓ Branch 202 taken 1 times.
✗ Branch 203 not taken.
✓ Branch 206 taken 1 times.
✗ Branch 207 not taken.
✓ Branch 209 taken 1 times.
✗ Branch 210 not taken.
✓ Branch 212 taken 1 times.
✗ Branch 213 not taken.
✓ Branch 217 taken 1 times.
✗ Branch 218 not taken.
✓ Branch 220 taken 1 times.
✗ Branch 221 not taken.
✓ Branch 224 taken 1 times.
✗ Branch 225 not taken.
✓ Branch 227 taken 1 times.
✗ Branch 228 not taken.
✓ Branch 230 taken 1 times.
✗ Branch 231 not taken.
✓ Branch 235 taken 1 times.
✗ Branch 236 not taken.
✓ Branch 238 taken 1 times.
✗ Branch 239 not taken.
✓ Branch 242 taken 1 times.
✗ Branch 243 not taken.
✓ Branch 245 taken 1 times.
✗ Branch 246 not taken.
✓ Branch 248 taken 1 times.
✗ Branch 249 not taken.
✓ Branch 253 taken 1 times.
✗ Branch 254 not taken.
✓ Branch 256 taken 1 times.
✗ Branch 257 not taken.
✓ Branch 260 taken 1 times.
✗ Branch 261 not taken.
✓ Branch 263 taken 1 times.
✗ Branch 264 not taken.
✓ Branch 266 taken 1 times.
✗ Branch 267 not taken.
|
1 | BUILTIN_TYPES(TYPE) |
37 | |||
38 | #undef TYPE | ||
39 | |||
40 | // Builtin constant | ||
41 |
5/10✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
|
1 | add(String("None"), None(), None_t()); |
42 |
5/10✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
|
1 | add(String("True"), True(), bool_t()); |
43 |
5/10✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
|
1 | add(String("False"), False(), bool_t()); |
44 | 1 | } | |
45 | |||
46 | // returns the varid it was inserted as | ||
47 | inline int add(StringRef const& name, Node* value, TypeExpr* type) { | ||
48 | COZ_BEGIN("T::Bindings::add"); | ||
49 | |||
50 | 25 | auto size = int(bindings.size()); | |
51 | |||
52 | 25 | bool dynamic = !nested; | |
53 |
3/6✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 25 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 25 times.
✗ Branch 8 not taken.
|
25 | bindings.push_back({name, value, type, dynamic}); |
54 | |||
55 |
2/2✓ Branch 0 taken 21 times.
✓ Branch 1 taken 4 times.
|
25 | if (!nested) { |
56 | 21 | global_index += 1; | |
57 | } | ||
58 | |||
59 | COZ_PROGRESS_NAMED("Bindings::add"); | ||
60 | COZ_END("T::Bindings::add"); | ||
61 | 25 | return size; | |
62 | } | ||
63 | |||
64 | inline void set_type(int varid, TypeExpr* type) { | ||
65 |
2/6✗ Branch 0 not taken.
✓ Branch 1 taken 127 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 127 times.
|
127 | if (varid < 0 && varid > bindings.size()) |
66 | ✗ | return; | |
67 | |||
68 | 127 | bindings[varid].type = type; | |
69 | } | ||
70 | |||
71 | inline void set_value(int varid, Node* value) { bindings[varid].value = value; } | ||
72 | |||
73 | inline TypeExpr* get_type(int varid) const { | ||
74 |
5/6✓ Branch 0 taken 239 times.
✓ Branch 1 taken 512 times.
✓ Branch 3 taken 239 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 239 times.
✓ Branch 6 taken 512 times.
|
751 | if (varid < 0 && varid > bindings.size()) |
75 | 239 | return nullptr; | |
76 | 512 | return bindings[varid].type; | |
77 | } | ||
78 | |||
79 | inline Node* get_value(int varid) const { | ||
80 | COZ_BEGIN("T::Bindings::get_value"); | ||
81 | |||
82 | 251 | Node* result = nullptr; | |
83 | |||
84 |
5/6✓ Branch 0 taken 4 times.
✓ Branch 1 taken 247 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 247 times.
✓ Branch 6 taken 4 times.
|
251 | if (!(varid < 0 && varid > bindings.size())) |
85 | 247 | result = bindings[varid].value; | |
86 | |||
87 | COZ_PROGRESS_NAMED("Bindings::get_value"); | ||
88 | COZ_END("T::Bindings::get_value"); | ||
89 | 251 | return result; | |
90 | } | ||
91 | |||
92 | StringRef get_name(int varid) const { | ||
93 | if (varid < 0 && varid > bindings.size()) | ||
94 | return StringRef(); | ||
95 | return bindings[varid].name; | ||
96 | } | ||
97 | |||
98 | bool is_dynamic(int varid) const { return varid >= global_index; } | ||
99 | |||
100 | int get_varid(StringRef name) const { | ||
101 | COZ_BEGIN("T::Bindings::get_varid"); | ||
102 | |||
103 | 1047 | auto start = std::rbegin(bindings); | |
104 | 1047 | auto end = std::rend(bindings); | |
105 | |||
106 | 1047 | int value = -1; | |
107 | 1047 | int i = 0; | |
108 |
3/4✓ Branch 1 taken 12033 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11778 times.
✓ Branch 4 taken 255 times.
|
12033 | while (start != end) { |
109 |
3/4✓ Branch 1 taken 11778 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 792 times.
✓ Branch 5 taken 10986 times.
|
11778 | if (start->name == name) { |
110 | 792 | value = int(bindings.size()) - i - 1; | |
111 | 792 | break; | |
112 | } | ||
113 | 10986 | ++start; | |
114 | 10986 | i += 1; | |
115 | } | ||
116 | |||
117 | COZ_PROGRESS_NAMED("Bindings::get_varid"); | ||
118 | COZ_END("T::Bindings::get_varid"); | ||
119 | 1047 | return value; | |
120 | } | ||
121 | |||
122 | String __str__() const { | ||
123 | StringStream ss; | ||
124 | dump(ss); | ||
125 | return ss.str(); | ||
126 | } | ||
127 | |||
128 | void dump(std::ostream& out) const; | ||
129 | |||
130 | Array<BindingEntry> bindings; | ||
131 | |||
132 | // We keep track of when the global binding starts | ||
133 | // so we know when we need to do a dynamic lookup of a static one | ||
134 | int global_index = 0; | ||
135 | bool nested = false; | ||
136 | }; | ||
137 | |||
138 | struct Scope { | ||
139 | Scope(Bindings& array): bindings(array), oldsize(bindings.bindings.size()) { | ||
140 | 220 | bindings.nested = true; | |
141 | 220 | } | |
142 | |||
143 | ~Scope() { | ||
144 | 220 | bindings.bindings.resize(oldsize); | |
145 | 220 | bindings.nested = false; | |
146 | 220 | } | |
147 | |||
148 | Bindings& bindings; | ||
149 | std::size_t oldsize; | ||
150 | }; | ||
151 | |||
152 | struct ScopedFlag { | ||
153 | ScopedFlag(Dict<StringRef, bool>& array, StringRef flag): flags(array), flag(flag) { | ||
154 | flags[flag] = true; | ||
155 | } | ||
156 | |||
157 | ~ScopedFlag() { flags.erase(flag); } | ||
158 | |||
159 | Dict<StringRef, bool>& flags; | ||
160 | StringRef flag; | ||
161 | }; | ||
162 | |||
163 | } // namespace lython | ||
164 | |||
165 | #endif | ||
166 |