Commit a81eb0e4 authored by s_kleplj's avatar s_kleplj
Browse files

optimized to 0.60

parent da28db02
...@@ -4,15 +4,31 @@ ...@@ -4,15 +4,31 @@
#include "macrosol.hpp" #include "macrosol.hpp"
namespace macrosol { namespace macrosol {
bool macroprocessor_impl::process( bool macroprocessor_impl::process(
const std::string& s, const std::string& s,
std::string& output std::string& output
) {
const bool is_def = parse(s);
if (is_def) {
define();
return false;
} else {
expand(output);
return true;
}
}
bool macroprocessor_impl::parse(
const std::string& s
) { ) {
parsed.clear(); parsed.clear();
bool is_def = false; bool is_def = false;
for ( for (
auto [i, j] = std::tuple{s.cbegin(), s.cend()};; auto&& [i, j] = std::tuple{s.cbegin(), s.cend()};;
++i ++i
) { ) {
if (j != s.cend()) { if (j != s.cend()) {
...@@ -38,7 +54,10 @@ bool macroprocessor_impl::process( ...@@ -38,7 +54,10 @@ bool macroprocessor_impl::process(
} }
} }
if (is_def) { return is_def;
}
void macroprocessor_impl::define() {
auto&& [it, inserted] = words_.try_emplace( auto&& [it, inserted] = words_.try_emplace(
parsed[0], parsed[0],
parsed[0]); parsed[0]);
...@@ -47,15 +66,15 @@ bool macroprocessor_impl::process( ...@@ -47,15 +66,15 @@ bool macroprocessor_impl::process(
const_cast<std::string_view&>(it->first) = it->second.name_; const_cast<std::string_view&>(it->first) = it->second.name_;
} else { } else {
it->second.value_.clear(); it->second.value_.clear();
it->second.length = 0; it->second.expanded_ = true;
} }
if (parsed.size() != 1) { if (parsed.size() != 1) {
std::vector<word*>* vector = &(it->second.value_); auto vector = &(it->second.value_);
vector->reserve(parsed.size() - 1); vector->reserve(parsed.size() - 1);
for (auto i = parsed.cbegin() + 1; i != parsed.cend(); ++i) { for (auto i = parsed.cbegin() + 1; i != parsed.cend(); ++i) {
auto&& [it, inserted] = words_.try_emplace( auto [it, inserted] = words_.try_emplace(
*i, *i,
*i, *i,
true); true);
...@@ -67,35 +86,15 @@ bool macroprocessor_impl::process( ...@@ -67,35 +86,15 @@ bool macroprocessor_impl::process(
vector->emplace_back(&it->second); vector->emplace_back(&it->second);
} }
} }
}
return false; void macroprocessor_impl::expand(
} else { std::string& output
std::size_t length = 0; ) const {
found.clear();
found.reserve(parsed.size());
for (auto&& p : parsed) {
auto it = words_.find(p);
if (it != words_.end()) {
std::size_t w_length = it->second.update_length() + 1;
found.emplace_back(&it->second);
if (w_length > 0) {
length += w_length + 1;
}
} else {
found.emplace_back(nullptr);
length += p.size() + 1;
}
}
output.reserve(length);
for (std::size_t i = 0; i < parsed.size(); ++i) { for (std::size_t i = 0; i < parsed.size(); ++i) {
if (found[i] != nullptr) { auto it = words_.find(parsed[i]);
found[i]->append_to(output); if (it != words_.end()) {
it->second.append_to(output);
} else { } else {
output += parsed[i]; output += parsed[i];
output += ' '; output += ' ';
...@@ -105,9 +104,6 @@ bool macroprocessor_impl::process( ...@@ -105,9 +104,6 @@ bool macroprocessor_impl::process(
if (output.size() > 0) { if (output.size() > 0) {
output.pop_back(); output.pop_back();
} }
return true;
}
} }
template class macroprocessor< policy_scalar>; template class macroprocessor< policy_scalar>;
......
...@@ -37,8 +37,7 @@ class view_hasher { ...@@ -37,8 +37,7 @@ class view_hasher {
std::size_t operator()(const std::string_view& a) const { std::size_t operator()(const std::string_view& a) const {
std::size_t ret = 0; std::size_t ret = 0;
for (std::size_t i = 0; i < strength; ++i) { for (std::size_t i = 0; i < strength; ++i) {
ret *= 26; ret |= i < a.size() ? ((a[i] | 32) - 'a') << (i * 8) : 0;
ret += i < a.size() ? (a[i] | 32) - 'a' : 0;
} }
return ret; return ret;
...@@ -48,64 +47,42 @@ class view_hasher { ...@@ -48,64 +47,42 @@ class view_hasher {
class macroprocessor_impl { class macroprocessor_impl {
public: public:
bool process(const std::string& s, std::string& output); bool process(const std::string& s, std::string& output);
bool parse(const std::string& s);
void define();
void expand(std::string& output) const;
private: private:
struct word { struct word {
word (std::string_view name) : word (std::string_view name) :
value_{}, value_{},
name_{std::string{name}}, name_{name},
length{0} expanded_{true}
{} {}
word (std::string_view name, bool) : word (std::string_view name, bool) :
value_{}, value_{},
name_{std::string{name}}, name_{name},
length{name_.size()} expanded_{false}
{} {}
void append_to(std::string& output) const { void append_to(std::string& output) const {
if (length == 0) { if (!expanded_) {
return;
}
if (value_.size() == 0 && length > 0) {
output += name_; output += name_;
output += ' '; output += ' ';
} else { } else {
for (word* w : value_) { for (const word* w : value_) {
if (w->length > 0) {
w->append_to(output); w->append_to(output);
} }
} }
} }
}
std::size_t update_length() {
if (value_.size() != 0 || length == 0) {
length = 0;
for (word* w : value_) {
std::size_t w_length = w->update_length();
if (w_length > 0) {
length += w_length + 1;
}
}
if (length > 0) {
--length;
}
}
return length;
}
std::vector<word*> value_; std::vector<const word*> value_;
const std::string name_; std::string name_;
std::size_t length; bool expanded_;
}; };
std::unordered_map<std::string_view, word, view_hasher<3>> words_; std::unordered_map<std::string_view, word, view_hasher<4>> words_;
std::vector<std::string_view> parsed; std::vector<std::string_view> parsed;
std::vector<const word*> found;
}; };
template< typename policy> template< typename policy>
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment