improving performance by refactoring:

-> declaration lookup (it's own loop at the start)
-> indent check (starting at index 2, jumpting by 2 steps, since block levels increase by 2 spaces each time)
-> removed function start and end bracket from src vector
This commit is contained in:
DrFrugal 2024-01-30 08:37:42 +01:00
parent 45dd86e289
commit a0ff3fde4d
2 changed files with 42 additions and 37 deletions

View File

@ -4,11 +4,12 @@
#include <format> #include <format>
#include <optional> #include <optional>
#include <regex> #include <regex>
#include <set>
#include <stack> #include <stack>
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
std::regex decl_rgx(R"(^ (?:int|uint|BOOL) (\w+);)"); // currently only considering these types for declarations std::regex decl_rgx(R"(^ (\S+) (\S+)(?: \[)?(\d+?)?\]?;$)"); // capturing type, name and array size
std::regex ass_rgx(R"(^ +?(\w+) = (.+);)"); // OwO std::regex ass_rgx(R"(^ +?(\w+) = (.+);)"); // OwO
std::regex if_rgx(R"(if \((.+)\) )"); std::regex if_rgx(R"(if \((.+)\) )");
std::regex usg_rgx(R"(,"(Usage: [^;]+).?"[, \)])"); // .? is a workaround to prevent raw string from closing std::regex usg_rgx(R"(,"(Usage: [^;]+).?"[, \)])"); // .? is a workaround to prevent raw string from closing
@ -175,8 +176,8 @@ std::optional<int> eval(std::string& infix, locals& lcls)
bool FunctionInfo::prc_varmap_rgx(bool prc_in, const std::string& ln_in, std::regex& rgx, locals& lcls) bool FunctionInfo::prc_varmap_rgx(bool prc_in, const std::string& ln_in, std::regex& rgx, locals& lcls)
{ {
std::string ln = ln_in; std::string ln = ln_in;
bool fnd = false;
varmap& params = prc_in ? in : out; varmap& params = prc_in ? in : out;
bool fnd = false;
while (std::regex_search(ln, match, rgx)) while (std::regex_search(ln, match, rgx))
{ {
fnd = true; fnd = true;
@ -313,6 +314,24 @@ FunctionInfo::FunctionInfo(std::vector<std::string> src)
addr = std::stoi(&src[0][13], 0, 16); // no use of prsi - values occur once -> no caching wanted addr = std::stoi(&src[0][13], 0, 16); // no use of prsi - values occur once -> no caching wanted
nm = src[1].substr(13, src[1].find_first_of('(') - 13); nm = src[1].substr(13, src[1].find_first_of('(') - 13);
locals lcls; // local variables
std::set<std::string> track_types = { "BOOL", "int", "uint", "undefined4"}; // only track locals of these types
std::string type;
int idx = 2;
if (!src[idx].starts_with(" return "))
{ // process local variable declarations
for (; idx < src.size(); idx++)
{
std::string& ln = src[idx];
if (std::regex_search(ln, match, decl_rgx))
{
if (!track_types.count(match[1])) continue; // not interested in type
lcls[match[2]] = 0; // track with init value 0
}
else break; // found no more declaration
}
}
std::string ind; // indentation - keeping track of current block level std::string ind; // indentation - keeping track of current block level
std::string lp_utl = ""; // currently in a loop until this line is reached std::string lp_utl = ""; // currently in a loop until this line is reached
std::string skp_ass_utl = ""; std::string skp_ass_utl = "";
@ -320,47 +339,34 @@ FunctionInfo::FunctionInfo(std::vector<std::string> src)
std::string cond; std::string cond;
std::optional<int> er; // eval result std::optional<int> er; // eval result
bool is_if_ln; bool is_if_ln;
bool prc_decl = true; // process variable declarations
bool enc_usg = false; // encountered usg bool enc_usg = false; // encountered usg
uint ret_val; // return value uint ret_val; // return value
std::string infix; std::string infix;
lp_track lp_track; // keeps track where the loop started lp_track lp_track; // keeps track where the loop started
std::unordered_map<std::string, bool> push_track; // keeps track if on this indent level a push has happened std::unordered_map<std::string, bool> push_track; // keeps track if on this indent level a push has happened
locals lcls; // local variables for (; idx < src.size(); idx++) // skip right to the lines which matter
for (int idx = 3; idx < src.size(); idx++) // skip right to the lines which matter
{ {
std::string& ln = src[idx]; std::string& ln = src[idx];
// reset line tracking variables
is_if_ln = false; is_if_ln = false;
if (prc_decl) int i = 2;
{ // if local variable definition parsing is enabled
if (ln == " ")
{ // reached end variable definition block, no further processing required
prc_decl = false;
continue;
}
if (std::regex_search(ln, match, decl_rgx)) lcls[match[1]] = 0; // track with init value 0
continue; // no need to do further processing
}
int i = 0;
while (i < ln.length()) while (i < ln.length())
{ {
if (ln[i] != ' ') if (ln[i] != ' ') break;
{ i += 2;
}
ind = ln.substr(0, i); ind = ln.substr(0, i);
break;
}
i++;
}
switch (ln[i]) switch (ln[i])
{ {
case '}': case '}':
if (ln == ind + '}')
{ // block end, maybe simple while or for loop end
if (lp_track.find(ind) != lp_track.end()) if (lp_track.find(ind) != lp_track.end())
lp_track.erase(ind); // reached loop end { // closing bracket of a loop
break; lp_track[ind].iter--;
if (lp_track[ind].iter < 0)
{ // max iterations exceeded
prs_msg.push_back(std::format("max iterations exceeded in: {}", idx + 1));
}
} }
if (std::regex_search(ln, match, dowhl_cond_rgx)) if (std::regex_search(ln, match, dowhl_cond_rgx))
{ {
@ -516,11 +522,9 @@ FunctionInfo::FunctionInfo(std::vector<std::string> src)
if (skp_ass_utl == "\1") skp_ass_utl = ""; if (skp_ass_utl == "\1") skp_ass_utl = "";
if (!skp_push_utl.empty() && ln.starts_with(skp_push_utl)) skp_push_utl = ""; // reset skip since ln has been reached now if (!skp_push_utl.empty() && ln.starts_with(skp_push_utl)) skp_push_utl = ""; // reset skip since ln has been reached now
if (skp_push_utl == "\1") skp_push_utl = ""; // reset temporary skip which was used for 1 ln if (skp_push_utl == "\1") skp_push_utl = ""; // reset temporary skip which was used for 1 ln
} }
cln_varmap(true); // clean input varmap cln_varmap(true); // clean inputs
cln_varmap(false); // clean output varmap cln_varmap(false); // clean outputs
chk_vld(); // check validity of parsed data chk_vld(); // check validity of parsed data
int i = 0;
} }

View File

@ -101,11 +101,10 @@ int main()
{ {
if (ln.empty()) continue; // skip empty lines if (ln.empty()) continue; // skip empty lines
if (ln.starts_with("/*")) continue; // skip block comment lines if (ln.starts_with("/*")) continue; // skip block comment lines
if (ln.starts_with("// ADDRESS - ")) if (ln == "{") continue; // skip function opening bracked
{
rec_src = true; // found starting line of function soure if (ln.starts_with("// ADDRESS - ")) rec_src = true; // found starting line of function soure
}
if (rec_src) src.push_back(ln);
if (ln == "}") if (ln == "}")
{ // end of function code reached { // end of function code reached
auto fi = FunctionInfo(src); auto fi = FunctionInfo(src);
@ -114,7 +113,9 @@ int main()
cnt++; cnt++;
src.clear(); src.clear();
rec_src = false; rec_src = false;
continue;
} }
if (rec_src) src.push_back(ln);
} }
tend = std::chrono::high_resolution_clock::now(); tend = std::chrono::high_resolution_clock::now();