40
40
#include " entry_struct_func_compiler.h"
41
41
#include < iomanip>
42
42
#include < iostream>
43
+ const std::vector<std::pair<std::string, std::string>> REPLACEMENTS = {
44
+ {" function" , " fn" },
45
+ {" m_entry" , " pair" },
46
+ {" _s_pair_" , " _pair_str_" },
47
+ {" fixed_arr" , " arr" }};
43
48
using namespace yaksha ;
44
49
entry_struct_func_compiler::entry_struct_func_compiler (ykdt_pool *pool)
45
50
: pool_(pool), counter_(0 ), autogen_structs_list_(), autogen_structs_(),
46
51
autogen_func_typedefs_(), autogen_func_typedef_list_(),
47
52
counter_functions_(0 ), code_(), code_fnc_(), counter_tuples_(0 ),
48
53
autogen_tuple_list_(), autogen_tuples_(), code_tuples_(),
49
- counter_bin_data_(0 ), autogen_bin_data_(), bin_data_(), counter_fxa_(0 ) {}
54
+ counter_bin_data_(0 ), autogen_bin_data_(), bin_data_(), counter_fxa_(0 ),
55
+ forward_decls_(), name_improvements_() {}
50
56
std::string entry_struct_func_compiler::compile (ykdatatype *entry_dt,
51
57
datatype_compiler *dtc) {
52
58
std::string repr = entry_dt->as_string ();
53
59
if (autogen_structs_.find (repr) != autogen_structs_.end ()) {
54
- return " struct ykentry" + std::to_string (autogen_structs_[repr]);
60
+ return " struct " +
61
+ improve_name (repr,
62
+ " ykentry" + std::to_string (autogen_structs_[repr]));
55
63
}
56
64
entry_data d{};
57
65
d.incremented_id_ = counter_++;
@@ -66,24 +74,22 @@ std::string entry_struct_func_compiler::compile(ykdatatype *entry_dt,
66
74
return " <><>" ;
67
75
}
68
76
std::stringstream code{};
69
- code << " struct ykentry" << d.incremented_id_ << " { "
77
+ std::string name =
78
+ improve_name (repr, " ykentry" + std::to_string (d.incremented_id_ ));
79
+ code << " struct " << name << " { "
70
80
<< dtc->convert_dt (d.key_dt_ , datatype_location::STRUCT, " " , " " )
71
81
<< " key; "
72
82
<< dtc->convert_dt (d.val_dt_ , datatype_location::STRUCT, " " , " " )
73
83
<< " value; };\n " ;
74
84
code_ << code.str ();
75
85
autogen_structs_list_.emplace_back (d);
76
86
autogen_structs_[repr] = d.incremented_id_ ;
77
- return " struct ykentry" + std::to_string (d.incremented_id_ );
87
+ forward_decls_ << " struct " << name << " ;\n " ;
88
+ return " struct " + improve_name (repr, name);
78
89
}
79
90
void entry_struct_func_compiler::compile_forward_declarations (
80
91
std::stringstream &target) {
81
- for (auto &e : autogen_structs_list_) {
82
- target << " struct ykentry" << e.incremented_id_ << " ;\n " ;
83
- }
84
- for (auto &e : autogen_tuple_list_) {
85
- target << " struct yktuple" << e.incremented_id_ << " ;\n " ;
86
- }
92
+ target << forward_decls_.str ();
87
93
}
88
94
void entry_struct_func_compiler::compile_structures (std::stringstream &target) {
89
95
target << code_.str ();
@@ -97,7 +103,8 @@ entry_struct_func_compiler::compile_function_dt(ykdatatype *function_dt,
97
103
datatype_compiler *dtc) {
98
104
std::string fdt_str = function_dt->as_string ();
99
105
if (autogen_func_typedefs_.find (fdt_str) != autogen_func_typedefs_.end ()) {
100
- return " ykfncptr" + std::to_string (autogen_func_typedefs_[fdt_str]);
106
+ return improve_name (
107
+ fdt_str, " ykfncptr" + std::to_string (autogen_func_typedefs_[fdt_str]));
101
108
}
102
109
// Check assumption that must not happen
103
110
if (!function_dt->is_function () || function_dt->args_ .size () != 2 ||
@@ -122,7 +129,9 @@ entry_struct_func_compiler::compile_function_dt(ykdatatype *function_dt,
122
129
code << " <><>" ;
123
130
}
124
131
unsigned int current_num = counter_functions_++;
125
- code << " (*ykfncptr" << current_num << " )(" ;
132
+ std::string name =
133
+ improve_name (fdt_str, " ykfncptr" + std::to_string (current_num));
134
+ code << " (*" << name << " )(" ;
126
135
if (input->args_ .empty ()) {
127
136
code << " void" ;
128
137
} else {
@@ -142,7 +151,7 @@ entry_struct_func_compiler::compile_function_dt(ykdatatype *function_dt,
142
151
func_data d{input, output, current_num};
143
152
autogen_func_typedef_list_.emplace_back (d);
144
153
autogen_func_typedefs_[fdt_str] = current_num;
145
- return " ykfncptr " + std::to_string (current_num) ;
154
+ return name ;
146
155
}
147
156
void entry_struct_func_compiler::compile_function_defs (
148
157
std::stringstream &target) {
@@ -155,13 +164,17 @@ std::string entry_struct_func_compiler::compile_tuple(ykdatatype *tuple_dt,
155
164
datatype_compiler *dtc) {
156
165
std::string repr = tuple_dt->as_string ();
157
166
if (autogen_tuples_.find (repr) != autogen_tuples_.end ()) {
158
- return " struct yktuple" + std::to_string (autogen_tuples_[repr]);
167
+ std::string name =
168
+ improve_name (repr, " yktuple" + std::to_string (autogen_tuples_[repr]));
169
+ return " struct " + name;
159
170
}
160
171
tuple_data d{};
161
172
d.incremented_id_ = counter_tuples_++;
162
173
d.tuple_dt_ = tuple_dt;
163
174
std::stringstream code{};
164
- code << " struct yktuple" << d.incremented_id_ << " {" ;
175
+ std::string name =
176
+ improve_name (repr, " yktuple" + std::to_string (d.incremented_id_ ));
177
+ code << " struct " << name << " {" ;
165
178
size_t i = 1 ;
166
179
for (ykdatatype *dt_arg : d.tuple_dt_ ->args_ ) {
167
180
code << " " << dtc->convert_dt (dt_arg, datatype_location::STRUCT, " " , " " )
@@ -172,7 +185,8 @@ std::string entry_struct_func_compiler::compile_tuple(ykdatatype *tuple_dt,
172
185
code_ << code.str ();
173
186
autogen_tuple_list_.emplace_back (d);
174
187
autogen_tuples_[repr] = d.incremented_id_ ;
175
- return " struct yktuple" + std::to_string (d.incremented_id_ );
188
+ forward_decls_ << " struct " << name << " ;\n " ;
189
+ return " struct " + name;
176
190
}
177
191
bool entry_struct_func_compiler::has_bin_data () {
178
192
return !autogen_bin_data_.empty ();
@@ -212,14 +226,17 @@ void entry_struct_func_compiler::compile_binary_data_to(
212
226
}
213
227
std::string
214
228
entry_struct_func_compiler::compile_fixed_array (ykdatatype *fixed_array_dt,
215
- datatype_compiler *dtc) {
229
+ datatype_compiler *dtc) {
216
230
std::string fxa_str = fixed_array_dt->as_string ();
217
231
if (autogen_fxa_.find (fxa_str) != autogen_fxa_.end ()) {
218
- return " ykfxa" + std::to_string (autogen_fxa_[fxa_str]);
232
+ return improve_name (fxa_str,
233
+ " ykfxa" + std::to_string (autogen_fxa_[fxa_str]));
219
234
}
220
235
// Check assumption that must not happen
221
- if (!fixed_array_dt->is_fixed_size_array () || fixed_array_dt->args_ .size () != 2 ||
222
- fixed_array_dt->args_ [0 ]->is_sm_entry () || fixed_array_dt->args_ [1 ]->is_m_entry ()) {
236
+ if (!fixed_array_dt->is_fixed_size_array () ||
237
+ fixed_array_dt->args_ .size () != 2 ||
238
+ fixed_array_dt->args_ [0 ]->is_sm_entry () ||
239
+ fixed_array_dt->args_ [1 ]->is_m_entry ()) {
223
240
// Must not happen
224
241
return " <><>" ;
225
242
}
@@ -229,22 +246,85 @@ entry_struct_func_compiler::compile_fixed_array(ykdatatype *fixed_array_dt,
229
246
ykdatatype *target_datatype = fixed_array_dt->args_ [0 ];
230
247
ykdatatype *size_specifier = fixed_array_dt->args_ [1 ];
231
248
code << " typedef " ;
232
- code << dtc->convert_dt (target_datatype, datatype_location::STRUCT, " " , " " )
233
- << " " ;
249
+ code << dtc->convert_dt (target_datatype, datatype_location::STRUCT, " " , " " )
250
+ << " " ;
234
251
unsigned int current_num = counter_fxa_++;
235
- code << " ykfxa" << current_num << " [" ;
252
+ std::string name =
253
+ improve_name (fxa_str, " ykfxa" + std::to_string (current_num));
254
+ code << name << " [" ;
236
255
code << size_specifier->token_ ->token_ ;
237
256
code << " ];\n " ;
238
257
// write the finalized code here
239
258
code_fxa_ << code.str ();
240
259
tuple_data d{fixed_array_dt, current_num};
241
260
autogen_fxa_list_.emplace_back (d);
242
261
autogen_fxa_[fxa_str] = current_num;
243
- return " ykfxa " + std::to_string (current_num) ;
262
+ return name ;
244
263
}
245
264
void entry_struct_func_compiler::compiled_fixed_array_to (
246
265
std::stringstream &target) {
247
266
target << code_fxa_.str ();
248
267
}
249
- bool entry_struct_func_compiler::has_fixed_arrays () { return !autogen_fxa_.empty (); }
268
+ bool entry_struct_func_compiler::has_fixed_arrays () {
269
+ return !autogen_fxa_.empty ();
270
+ }
271
+ std::string sanitize_name (const std::string &input) {
272
+ auto is_valid_char = [](char c) { return std::isalnum (c) || c == ' _' ; };
273
+ std::string result;
274
+ for (size_t i = 0 ; i < input.length (); ++i) {
275
+ char c = input[i];
276
+ if (is_valid_char (c)) {
277
+ if (std::isupper (c)) {
278
+ result += " _" ;
279
+ result += static_cast <char >(std::tolower (c));
280
+ } else {
281
+ result += c;
282
+ }
283
+ } else {
284
+ result += ' _' ;
285
+ }
286
+ }
287
+ // Remove double underscores
288
+ std::size_t dunder = result.find (" __" );
289
+ while (dunder != std::string::npos) {
290
+ result.erase (dunder, 1 );
291
+ dunder = result.find (" __" );
292
+ }
293
+ // Remove leading and trailing underscores
294
+ result.erase (result.begin (),
295
+ std::find_if (result.begin (), result.end (),
296
+ [](unsigned char ch) { return ch != ' _' ; }));
297
+ result.erase (std::find_if (result.rbegin (), result.rend (),
298
+ [](unsigned char ch) { return ch != ' _' ; })
299
+ .base (),
300
+ result.end ());
301
+ result = " yt_" + result;
302
+ // Replace
303
+ for (const auto &replacement : REPLACEMENTS) {
304
+ size_t pos;
305
+ while ((pos = result.find (replacement.first )) != std::string::npos) {
306
+ result.replace (pos, replacement.first .length (), replacement.second );
307
+ }
308
+ }
309
+ return result;
310
+ }
311
+ std::string entry_struct_func_compiler::improve_name (
312
+ const std::string &yaksha_datatype_string,
313
+ const std::string &numbered_name) {
314
+ if (name_improvements_.find (yaksha_datatype_string) !=
315
+ name_improvements_.end ()) {
316
+ return name_improvements_[yaksha_datatype_string];
317
+ }
318
+ std::string improved = sanitize_name (yaksha_datatype_string);
319
+ // too large use numbered name
320
+ if (improved.size () > 60 || improved.empty ()) { improved = numbered_name; }
321
+ // conflict, so use numbered name
322
+ if (reverse_name_improvements_.find (improved) !=
323
+ reverse_name_improvements_.end ()) {
324
+ improved = numbered_name;
325
+ }
326
+ name_improvements_[yaksha_datatype_string] = improved;
327
+ reverse_name_improvements_[improved] = yaksha_datatype_string;
328
+ return improved;
329
+ }
250
330
entry_struct_func_compiler::~entry_struct_func_compiler () = default ;
0 commit comments