34 #include <unordered_map>
60 std::string _loop_type,
61 std::string _identifier,
74 assertiont(std::string _identifier, std::string _content)
90 using functionst = std::list<std::pair<std::regex, functiont>>;
98 using objectst = std::list<std::pair<std::regex, objectt>>;
112 auto sources =
config[
"sources"];
114 if(!sources.is_null())
116 if(!sources.is_array())
121 if(!source.is_string())
137 if(!include.is_string())
140 this->
includes.push_back(include.value);
153 if(!define.is_string())
156 this->
defines.push_back(define.value);
173 if(!
function.is_object())
178 const auto function_name = function_entry.first;
179 const auto &items = function_entry.second;
181 if(!items.is_array())
191 if(!function_item.is_string())
194 auto item_string = function_item.value;
200 split[0] ==
"ensures" || split[0] ==
"requires" ||
201 split[0] ==
"assigns")
203 std::ostringstream rest;
204 join_strings(rest, split.begin() + 1, split.end(),
' ');
206 function_config.
contract.emplace_back(split[0], rest.str());
208 else if(split[0] ==
"assert" && split.size() >= 3)
210 std::ostringstream rest;
211 join_strings(rest, split.begin() + 2, split.end(),
' ');
213 function_config.
assertions.emplace_back(split[1], rest.str());
216 (split[0] ==
"for" || split[0] ==
"while" || split[0] ==
"loop") &&
217 split.size() >= 3 && split[2] ==
"invariant")
219 std::ostringstream rest;
220 join_strings(rest, split.begin() + 3, split.end(),
' ');
223 split[0], split[1], rest.str());
225 else if(split[0] ==
"stub")
227 std::ostringstream rest;
228 join_strings(rest, split.begin() + 1, split.end(),
' ');
230 function_config.
stub = rest.str();
232 else if(split[0] ==
"remove")
234 if(split.size() == 1)
237 if(split[1] ==
"static")
241 "unexpected remove entry " + split[1]);
245 "unexpected function entry " + split[0]);
263 if(!
object.is_object())
268 const auto &object_name = object_entry.first;
269 const auto &items = object_entry.second;
271 if(!items.is_array())
280 if(!object_item.is_string())
283 auto item_string = object_item.value;
288 if(split[0] ==
"remove")
290 if(split.size() == 1)
293 if(split[1] ==
"static")
297 "unexpected remove entry " + split[1]);
301 "unexpected object entry " + split[0]);
323 std::vector<std::string> argv = {
"cc",
"-E", source_file};
325 for(
const auto &include :
c_wrangler.includes)
327 argv.push_back(
"-I");
328 argv.push_back(include);
332 argv.push_back(std::string(
"-D") + define);
334 std::ostringstream result;
336 auto run_result =
run(
"cc", argv,
"", result,
"");
346 std::vector<std::string> argv = {
"cc",
"-E",
"-dM", source_file};
348 for(
const auto &include :
config.includes)
350 argv.push_back(
"-I");
351 argv.push_back(include);
354 std::ostringstream result;
356 auto run_result =
run(
"cc", argv,
"", result,
"");
361 defines.
parse(result.str());
371 if(function_config.
stub.has_value() && declaration.
has_body())
374 out << function_config.
stub.value();
382 if(t.text ==
"static")
385 out << std::string(6,
' ');
409 for(
const auto &entry : function_config.
contract)
411 << defines(entry.content) <<
')';
413 std::map<std::string, std::string> loop_invariants;
416 loop_invariants[entry.loop_type + entry.identifier] = entry.content;
418 if(loop_invariants.empty())
425 std::size_t for_count = 0, while_count = 0;
430 const auto &token = *(t++);
436 const auto &invariant =
442 if(!invariant.empty())
445 for(; t != t_end; t++)
448 << defines(invariant) <<
')';
451 else if(token ==
"for")
454 const auto &invariant =
460 if(!invariant.empty())
463 for(; t != t_end; t++)
466 << defines(invariant) <<
')';
484 if(t.text ==
"static")
487 out << std::string(6,
' ');
514 if(declaration.
is_function() && name_opt.has_value())
516 for(
const auto &entry :
config.functions)
518 if(std::regex_match(name_opt->text, entry.first))
527 else if(!declaration.
is_function() && name_opt.has_value())
529 for(
const auto &entry :
config.objects)
531 if(std::regex_match(name_opt->text, entry.first))
546 const std::string &in,
550 std::ostringstream out;
551 std::istringstream in_str(in);
555 for(
const auto &declaration : parsed)
570 for(
auto &source_file :
c_wrangler.source_files)
584 std::cout << mangled;