diff --git a/include/compiler.h b/include/compiler.h index a1d20a7..0fdfad8 100644 --- a/include/compiler.h +++ b/include/compiler.h @@ -8,6 +8,7 @@ #include #include #include +#include namespace volt { @@ -19,11 +20,21 @@ namespace volt bool taken; }; + struct block_cache + { + size_t start; + size_t end; + size_t resume; + }; + class compiler { error &error_; + bool running_cache_; + size_t current_cache_; context context_; std::vector branches_; + std::unordered_map cache_; std::function &)> inspect_; diff --git a/include/metadata.h b/include/metadata.h index 4177b5f..9f124d6 100644 --- a/include/metadata.h +++ b/include/metadata.h @@ -24,11 +24,122 @@ namespace volt struct metadata { + size_t hash_tokens = 0; metatype type; metarange range; std::string data; std::vector tokens; + + void add_token(const token_t &tk); + }; + + inline void metadata::add_token(const token_t &tk) + { + tokens.emplace_back(tk); + hash_tokens += tk.hash(); + } + + class metainfo + { + size_t hash_metadata = 0; + std::vector metadata_; + + public: + typedef metadata value_type; + + void add_metadata(const metadata &data); + size_t hash() const; + + void push_back(const metadata &data); + metadata &back(); + void remove(size_t idx); + void clear(); + size_t size() const; + void resize(size_t new_size); + + const metadata &operator[](size_t idx) const; + std::vector &operator=(std::vector &&other) noexcept; + std::vector::iterator begin() noexcept; + std::vector::iterator end() noexcept; + std::vector::const_iterator begin() const noexcept; + std::vector::const_iterator end() const noexcept; }; + + + inline void metainfo::remove(size_t idx) + { + if (idx > metadata_.size()) { + return; + } + + metadata_.erase(metadata_.begin() + idx); + } + + inline size_t metainfo::hash() const + { + return hash_metadata; + } + + inline void metainfo::push_back(const metadata &data) + { + add_metadata(data); + } + + inline std::vector &metainfo::operator=(std::vector &&other) noexcept + { + return metadata_.operator=(other); + } + + inline void metainfo::resize(size_t new_size) + { + metadata_.resize(new_size); + } + + inline std::vector::iterator metainfo::begin() noexcept + { + return metadata_.begin(); + } + + inline std::vector::iterator metainfo::end() noexcept + { + return metadata_.end(); + } + + inline std::vector::const_iterator metainfo::begin() const noexcept + { + return metadata_.begin(); + } + + inline std::vector::const_iterator metainfo::end() const noexcept + { + return metadata_.end(); + } + + inline const metadata &metainfo::operator[](size_t idx) const + { + return metadata_[idx]; + } + + inline size_t metainfo::size() const + { + return metadata_.size(); + } + + inline metadata &metainfo::back() + { + return metadata_.back(); + } + + inline void metainfo::clear() + { + metadata_.clear(); + } + + inline void metainfo::add_metadata(const metadata &data) + { + metadata_.emplace_back(data); + hash_metadata += data.hash_tokens; + } } #endif // METADATA_H diff --git a/include/token.h b/include/token.h index 7820410..39b1d62 100644 --- a/include/token.h +++ b/include/token.h @@ -3,6 +3,7 @@ #include #include +#include #define TOKENS \ X(IDENTIFIER) \ @@ -140,8 +141,16 @@ namespace volt std::string to_string() const; token_types type() const; value_t value() const; + + size_t hash() const; }; + inline size_t token_t::hash() const + { + std::hash hash_string; + return hash_string(to_string()); + } + inline std::string token_t::to_string() const { std::string ret = "token: " + get_token_name(type_) + diff --git a/include/types.h b/include/types.h index 376706e..4183af1 100644 --- a/include/types.h +++ b/include/types.h @@ -13,7 +13,6 @@ namespace volt { - using metainfo = std::vector; using tokens = std::vector; using user_var = std::variantsecond.resume = context_.get_counter() - 1; + context_.jump_to(cache_it->second.start); + + running_cache_ = true; + current_cache_ = cache_it->first; + } return true; } diff --git a/src/scan.cpp b/src/scan.cpp index f7990b5..b8fc237 100644 --- a/src/scan.cpp +++ b/src/scan.cpp @@ -37,7 +37,7 @@ namespace volt mtdt = text_block(content, i, false); } - metainfo_.emplace_back(mtdt); + metainfo_.add_metadata(mtdt); // text blocks don't require special treatment if (mtdt.type == metatype::TEXT) { @@ -45,7 +45,7 @@ namespace volt } // on the other hand, code blocks is scanned and - // tokenized into metainfo_ + // tokenized into metainfo // NOTE: code block will be reverted to text block // if it finds any issue during this phase scan_iterator it(mtdt.data); @@ -63,6 +63,7 @@ namespace volt // IMPORTANT: empty space between opening and closing tags metadata metadata = { + 0, metatype::CODE, {position, position}, "", @@ -166,6 +167,7 @@ namespace volt bool force) { metadata metadata = { + 0, metatype::TEXT, {position, position}, "", @@ -224,7 +226,7 @@ namespace volt switch(token) { #define X(tk, name) case tk: \ - data.tokens.emplace_back(token_t(token_types::name)); \ + data.add_token(token_t(token_types::name)); \ it.next(); \ break; SINGLE_TOKEN @@ -285,7 +287,7 @@ namespace volt } string str = (len == 0) ? "" : it.substr(start, len); - data.tokens.emplace_back(token_t(token_types::STRING, str)); + data.add_token(token_t(token_types::STRING, str)); } void scan::parse_number(const scan_iterator &it, metadata &data) @@ -305,7 +307,7 @@ namespace volt number = number * 10 + digit; } - data.tokens.emplace_back(token_t(token_types::NUMBER, + data.add_token(token_t(token_types::NUMBER, to_string(number))); } @@ -328,10 +330,10 @@ namespace volt const string &text = it.substr(start, len); if (keywords_.find(text) != keywords_.end()) { - data.tokens.emplace_back(token_t(keywords_[text])); + data.add_token(token_t(keywords_[text])); } else { - data.tokens.emplace_back(token_t(token_types::IDENTIFIER, text)); + data.add_token(token_t(token_types::IDENTIFIER, text)); } } }