1- export module CppUtils.Language.MetaCircularEvaluator ;
1+ export module CppUtils.Language.MetaCircularVirtualMachine ;
22
33import std;
44import CppUtils.Container.MeshNetwork;
@@ -12,7 +12,7 @@ export namespace CppUtils::Language
1212{
1313 namespace v1
1414 {
15- struct MetaCircularEvaluator
15+ struct MetaCircularVirtualMachine
1616 {
1717 using Cursor = String::Cursor<std::string_view>;
1818
@@ -70,7 +70,7 @@ export namespace CppUtils::Language
7070 return scopes.back().get();
7171 }
7272
73- std::unordered_map<Type::Token, std::function<std::expected<void, std::string_view>(Cursor&, const ASTNode&, MetaCircularEvaluator &)>> functions;
73+ std::unordered_map<Type::Token, std::function<std::expected<void, std::string_view>(Cursor&, const ASTNode&, MetaCircularVirtualMachine &)>> functions;
7474 ASTNode rootAst = {0uz, {ASTNode{Type::hash("main")}}};
7575 std::vector<std::reference_wrapper<ASTNode>> scopes = {std::ref(rootAst)};
7676 bool exit = false;
@@ -79,36 +79,65 @@ export namespace CppUtils::Language
7979
8080 inline namespace v2
8181 {
82- struct MetaCircularEvaluator
82+ struct MetaCircularVirtualMachine
8383 {
8484 using MeshNodePtr = Container::MeshNodePtr<Type::Token, Type::Token>;
8585
8686 MeshNodePtr context = MeshNodePtr::makeRoot(0uz);
87- std::unordered_map<Type::Token, std::function<std::expected<void, std::string_view>(MetaCircularEvaluator &, MeshNodePtr)>> functions;
87+ std::unordered_map<Type::Token, std::function<std::expected<void, std::string_view>(MetaCircularVirtualMachine &, MeshNodePtr)>> functions;
8888 Thread::ThreadPool threadPool;
8989 std::size_t instructionPosition = 0;
9090
91- template<class T = MetaCircularEvaluator >
91+ template<class T = MetaCircularVirtualMachine >
9292 inline auto addFunction(Type::Token token, auto&& function) -> void
9393 {
9494 using namespace String::Literals;
9595
9696 if (not functions.contains(token))
9797 {
98- functions[token] = [function = std::forward<decltype(function)>(function)](MetaCircularEvaluator & interpreter, MeshNodePtr instruction) -> std::expected<void, std::string_view> {
98+ functions[token] = [function = std::forward<decltype(function)>(function)](MetaCircularVirtualMachine & interpreter, MeshNodePtr instruction) -> std::expected<void, std::string_view> {
9999 return function(static_cast<T&>(interpreter), instruction);
100100 };
101101 if (not context.contains(token))
102102 context[token] >> MeshNodePtr::make(token);
103103 }
104104 }
105105
106- inline MetaCircularEvaluator()
106+ template<String::FixedString Name>
107+ static auto arithmeticOperation(auto&& operation)
108+ {
109+ return [operation = std::forward<decltype(operation)>(operation)](MetaCircularVirtualMachine&, MeshNodePtr instruction) -> std::expected<void, std::string_view> {
110+ using namespace String::Literals;
111+
112+ static constexpr auto lhsError = Name + ": Missing lhs";
113+ static constexpr auto rhsError = Name + ": Missing rhs";
114+ static constexpr auto resultError = Name + ": Missing result";
115+
116+ auto lhs = instruction.at("lhs"_token).and_then([](auto branch) { return branch.front(); });
117+ if (not lhs)
118+ return std::unexpected{static_cast<std::string_view>(lhsError)};
119+
120+ auto rhs = instruction.at("rhs"_token).and_then([](auto branch) { return branch.front(); });
121+ if (not rhs)
122+ return std::unexpected{static_cast<std::string_view>(rhsError)};
123+
124+ auto result = instruction.at("result"_token).and_then([](auto branch) { return branch.front(); });
125+ if (not result)
126+ return std::unexpected{static_cast<std::string_view>(resultError)};
127+
128+ const auto lhsValue = lhs->getValue().value();
129+ const auto rhsValue = rhs->getValue().value();
130+ result->setValue(operation(lhsValue, rhsValue));
131+ return {};
132+ };
133+ }
134+
135+ inline MetaCircularVirtualMachine()
107136 {
108137 using namespace std::literals;
109138 using namespace String::Literals;
110139
111- addFunction("define"_token, [](MetaCircularEvaluator &, MeshNodePtr instruction) {
140+ addFunction("define"_token, [](MetaCircularVirtualMachine &, MeshNodePtr instruction) {
112141 return instruction.at("value"_token)
113142 .and_then([](auto valueBranch) { return valueBranch.back(); })
114143 .and_then([&instruction](auto valueNode) {
@@ -121,7 +150,7 @@ export namespace CppUtils::Language
121150 });
122151 });
123152
124- addFunction("jump"_token, [](MetaCircularEvaluator & interpreter, MeshNodePtr instruction) -> std::expected<void, std::string_view> {
153+ addFunction("jump"_token, [](MetaCircularVirtualMachine & interpreter, MeshNodePtr instruction) -> std::expected<void, std::string_view> {
125154 auto conditionNode = instruction.at("condition"_token).and_then([](auto branch) { return branch.front(); });
126155 if (conditionNode and conditionNode->getValue().value() == 0)
127156 return {};
@@ -134,12 +163,12 @@ export namespace CppUtils::Language
134163 return {};
135164 });
136165
137- addFunction("return"_token, [](MetaCircularEvaluator & interpreter, MeshNodePtr) -> std::expected<void, std::string_view> {
166+ addFunction("return"_token, [](MetaCircularVirtualMachine & interpreter, MeshNodePtr) -> std::expected<void, std::string_view> {
138167 interpreter.instructionPosition = std::numeric_limits<std::size_t>::max() - 1;
139168 return {};
140169 });
141170
142- addFunction("link"_token, [](MetaCircularEvaluator &, MeshNodePtr instruction) -> std::expected<void, std::string_view> {
171+ addFunction("link"_token, [](MetaCircularVirtualMachine &, MeshNodePtr instruction) -> std::expected<void, std::string_view> {
143172 return instruction.at("source"_token).and_then([&](auto sources) {
144173 return instruction.at("branch"_token).and_then([&](auto branches) -> std::expected<void, std::string_view> {
145174 for (auto branch : branches)
@@ -156,7 +185,7 @@ export namespace CppUtils::Language
156185 });
157186 });
158187
159- addFunction("unlink"_token, [](MetaCircularEvaluator &, MeshNodePtr instruction) -> std::expected<void, std::string_view> {
188+ addFunction("unlink"_token, [](MetaCircularVirtualMachine &, MeshNodePtr instruction) -> std::expected<void, std::string_view> {
160189 auto sourcesBranch = instruction.at("source"_token);
161190 if (not sourcesBranch)
162191 return std::unexpected{"unlink: Missing source"sv};
@@ -178,7 +207,7 @@ export namespace CppUtils::Language
178207 return {};
179208 });
180209
181- addFunction("=="_token, [](MetaCircularEvaluator &, MeshNodePtr instruction) -> std::expected<void, std::string_view> {
210+ addFunction("=="_token, [](MetaCircularVirtualMachine &, MeshNodePtr instruction) -> std::expected<void, std::string_view> {
182211 auto lhs = instruction.at("lhs"_token).and_then([](auto branch) { return branch.front(); });
183212 if (not lhs)
184213 return std::unexpected{"==: Missing lhs"sv};
@@ -197,7 +226,7 @@ export namespace CppUtils::Language
197226 return {};
198227 });
199228
200- addFunction("not"_token, [](MetaCircularEvaluator &, MeshNodePtr instruction) -> std::expected<void, std::string_view> {
229+ addFunction("not"_token, [](MetaCircularVirtualMachine &, MeshNodePtr instruction) -> std::expected<void, std::string_view> {
201230 auto value = instruction.at("value"_token).and_then([](auto branch) { return branch.front(); });
202231 if (not value)
203232 return std::unexpected{"not: Missing value"sv};
@@ -206,9 +235,16 @@ export namespace CppUtils::Language
206235 value->setValue(result);
207236 return {};
208237 });
238+
239+ addFunction("+"_token, arithmeticOperation<"+">(std::plus<>{}));
240+ addFunction("-"_token, arithmeticOperation<"-">(std::minus<>{}));
241+ addFunction("*"_token, arithmeticOperation<"*">(std::multiplies<>{}));
242+ addFunction("/"_token, arithmeticOperation<"/">(std::divides<>{}));
243+ addFunction("%"_token, arithmeticOperation<"%">(std::modulus<>{}));
244+ addFunction("<"_token, arithmeticOperation<"<">(std::less<>{}));
209245 }
210246
211- virtual ~MetaCircularEvaluator () = default;
247+ virtual ~MetaCircularVirtualMachine () = default;
212248
213249 [[nodiscard]] inline auto get(Type::Token token) -> std::expected<MeshNodePtr, std::string_view>
214250 {
0 commit comments