diff --git a/lang/app/main.cpp b/lang/app/main.cpp index 40f0e57..f7004cf 100644 --- a/lang/app/main.cpp +++ b/lang/app/main.cpp @@ -11,8 +11,10 @@ int main(int argc, char **argv) { // - SourcesManager sources_manager; + app::SourcesManager sources_manager( + utils::BuildPrintLog(std::cout), + printers::Printer(std::cout, 2, 80, true)); sources_manager.AddFile(filename); - sources_manager.Print(std::cout); + sources_manager.Print(); } diff --git a/lang/app/sources_manager.hpp b/lang/app/sources_manager.hpp index fb6c6bd..436318c 100644 --- a/lang/app/sources_manager.hpp +++ b/lang/app/sources_manager.hpp @@ -14,10 +14,28 @@ #include #include +namespace app { + +using Exprs = nodes::NodeStorage; // nodes::ExprStorage; +using Types = nodes::TypeStorage; +using Names = names::NameTree; +using Positions = core::DependentStorage; +using Printer = printers::Printer; + +// TODO: partial host ?? (part of params are stored in each executor, use if +// constexpr requires) (for Printer, State, ...) +using ExecutorHost = + core::ExecutorHost; + class SourcesManager { public: + SourcesManager(Log &&log, Printer &&printer) + : executor_host_(std::move(log), {}, {}, {}, {}, {}, std::move(printer)), + statements_{} {} + void AddFile(const std::string &filename) { - Log::Context logc(executor_.log(), Log::Area::kParse); + Log::Context logc(executor_host_.log(), Log::Area::kParse); std::ifstream in; in.open(filename); @@ -37,7 +55,8 @@ public: {{"There are some parsing errors in file"}} /*,parse_tree.get_root()*/); } - builders::BuilderTask statements_builder(executor_); + builders::Executor executor(executor_host_); + builders::BuilderTask statements_builder(executor); auto new_statements = statements_builder(parse_tree.get_root(), {}); @@ -49,14 +68,8 @@ public: new_statements.clear(); } - void Print(std::ostream &out) { - printers::Printer printer(out, 2, 80, true); - - // TODO: FIXME: share executor - printers::Executor executor( - utils::BuildPrintLog(std::cout), - printers::Exprs{executor_.state()}, - std::move(printer)); + void Print() { // TODO: any output + printers::Executor executor(executor_host_); printers::PrintTask{executor}(statements_, {}); } @@ -69,7 +82,8 @@ public: } private: - builders::Executor executor_ = - builders::Executor(utils::BuildPrintLog(std::cout), {}, {}, {}, {}, {}); - std::vector statements_ = {}; + ExecutorHost executor_host_; + std::vector statements_; }; + +} // namespace app diff --git a/lang/utils/include/core_utils.hpp b/lang/utils/include/core_utils.hpp new file mode 100644 index 0000000..bb307ae --- /dev/null +++ b/lang/utils/include/core_utils.hpp @@ -0,0 +1,9 @@ +#pragma once + +namespace core { + +struct None { + static constexpr const char *name = "Executor"; +}; + +} // namespace core diff --git a/lang/utils/include/counter.hpp b/lang/utils/include/counter.hpp new file mode 100644 index 0000000..a2457c9 --- /dev/null +++ b/lang/utils/include/counter.hpp @@ -0,0 +1,50 @@ +#pragma once + +#include "core_utils.hpp" +#include "log.hpp" + +namespace core { + +template + requires requires() { Tag::name; } +class CounterElem; + +template + requires requires() { Tag::name; } +class Counter { + friend class CounterElem; + +public: + Counter() = default; + + ~Counter() { + utils::Assert(count_ == 0, + std::format("counter has been failed, count={}, tag={}", + count_, Tag::name)); + } + +private: + void inc() { ++count_; } + + void dec() { + utils::Assert(count_ != 0, "counter internal error, can't dec zero"); + --count_; + } + +private: + size_t count_ = 0; +}; + +template + requires requires() { Tag::name; } +class CounterElem { +public: + CounterElem(Counter &counter) : counter_(counter) { counter_.inc(); } + + ~CounterElem() { counter_.dec(); } + +private: + Counter &counter_; +}; + +} // namespace core diff --git a/lang/utils/include/executor.hpp b/lang/utils/include/executor.hpp index 7dd871c..7d7c561 100644 --- a/lang/utils/include/executor.hpp +++ b/lang/utils/include/executor.hpp @@ -1,25 +1,70 @@ #pragma once +#include "counter.hpp" #include "log.hpp" namespace core { -struct None {}; - template class Task; -template class ExecutorState { +// + +namespace utils { +struct ExecutorTag { + static constexpr const char *name = "Executor"; +}; +} // namespace utils + +template class ExecutorStateHost { public: - ExecutorState(State &&state) : state_(std::move(state)) {} + ExecutorStateHost(State &&state) : state_(std::move(state)) {} + + State &operator*() { return state_; } + const State &operator*() const { return state_; } protected: State state_; }; +template +class ExecutorHost : public ExecutorStateHost... { +public: + ExecutorHost(Log &&log, States &&...states) + : ExecutorStateHost(std::move(states))..., log_(std::move(log)) {} + + template T &state() { return ExecutorStateHost::state_; } + template const T &state() const { + return ExecutorStateHost::state_; + } + + // + + Log &log() { return log_; } + const Log &log() const { return log_; } + + Counter &counter() { return counter_; } + +private: + Log log_; + Counter counter_; +}; + +// + +template class ExecutorState { +public: + ExecutorState(ExecutorStateHost &host) : state_(*host) {} + +protected: + State &state_; +}; + template class Executor : public ExecutorState... { public: - Executor(Log &&log, States &&...states) - : ExecutorState(std::move(states))..., log_(std::move(log)) {} + template + Executor(ExecutorHost &host) + : ExecutorState(host)..., log_(host.log()), + counter_(host.counter()) {} // @@ -38,7 +83,8 @@ public: const Log &log() const { return log_; } private: - Log log_; + Log &log_; + CounterElem counter_; }; template @@ -50,14 +96,6 @@ public: // - // template Ret Run(const N& node, NArgs&& args) - // { - // Task task(executor); - // return task(node, std::forward(args)); - // } - - // - virtual Ret operator()(const Node &node, const Args &args = {}) = 0; // diff --git a/lang/utils/include/storage.hpp b/lang/utils/include/storage.hpp index 0214b9e..4c694c7 100644 --- a/lang/utils/include/storage.hpp +++ b/lang/utils/include/storage.hpp @@ -49,8 +49,8 @@ template class DependentStorage : public Storage { public: void ForceInsert(Id id, T elem) { - utils::Assert(Storage::data_.insert({id, std::move(elem)}).second, - std::format("insert failed, id={}", *id)); + ::utils::Assert(Storage::data_.insert({id, std::move(elem)}).second, + std::format("insert failed, id={}", *id)); } bool Insert(Id id, T &&elem) {