From cfdc5e5a1c9ba8cc36f3259daaedff9f8df6abb6 Mon Sep 17 00:00:00 2001 From: ZhuangYumin Date: Thu, 9 Nov 2023 09:40:43 +0800 Subject: [PATCH] upd: first version of atom --- include/names.h | 23 ++++++++----- include/utils.h | 16 +++++++++ src/Evalvisitor.cpp | 29 ++++++++++++++-- src/names.cpp | 35 +++++++++++++++++++- src/utils.cpp | 80 ++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 169 insertions(+), 14 deletions(-) diff --git a/include/names.h b/include/names.h index 08e55c5..2c4f937 100644 --- a/include/names.h +++ b/include/names.h @@ -2,21 +2,26 @@ #define NAMESCOPE_H #include +#include #include #include #include #include "utils.h" -class NameScopeClass { - ; +class FucntionContainer { + struct FunctionItem { + ; + }; }; -struct FunctionItem -{ - ; -}; -struct FucntionContainer -{ - ; +class VariableContainer { + std::unordered_map GlobalScope; + std::stack> StackScopes; + + public: + void CreateFrame(); + void DestroyFrame(); + std::any ReadVariable(const std::string &name); + void WriteVariable(const std::string &name, const std::any &value); }; #endif \ No newline at end of file diff --git a/include/utils.h b/include/utils.h index f173268..923d3f1 100644 --- a/include/utils.h +++ b/include/utils.h @@ -2,8 +2,13 @@ #define UTILS_H #include #include +#include +#include #include +#include #include + +#include "int2048/int2048.h" class InterpretException : public std::exception { public: InterpretException() {} @@ -38,4 +43,15 @@ struct FlowType { }; struct NoneType {}; + +ZYM::int2048 Any2Int(const std::any &value); +double Any2Float(const std::any &value); +std::string Any2String(const std::any &value); +bool Any2Bool(const std::any &value); + +struct RawVarible { + std::string name; + RawVarible() {} + RawVarible(const std::string &name) : name(name) {} +}; #endif \ No newline at end of file diff --git a/src/Evalvisitor.cpp b/src/Evalvisitor.cpp index 39b6b8e..3ace0c7 100644 --- a/src/Evalvisitor.cpp +++ b/src/Evalvisitor.cpp @@ -8,7 +8,7 @@ #include "names.h" #include "utils.h" -NameScopeClass GlobalScope, StackScope; +VariableContainer Variables; FucntionContainer Functions; std::any EvalVisitor::visitFile_input(Python3Parser::File_inputContext *ctx) { @@ -141,8 +141,31 @@ std::any EvalVisitor::visitTrailer(Python3Parser::TrailerContext *ctx) { } std::any EvalVisitor::visitAtom(Python3Parser::AtomContext *ctx) { - // throw FatalError("Not implemented in function visitAtom"); - return visitChildren(ctx); + if (ctx->NONE()) + return NoneType(); + else if (ctx->TRUE()) + return true; + else if (ctx->FALSE()) + return false; + else if (ctx->NUMBER()) { + std::string num = ctx->getText(); + if (num.find('.') == std::string::npos) + return std::move(ZYM::int2048(num)); + else + return std::stod(num); + } else if (ctx->test()) + return visitTest(ctx->test()); + else if (ctx->NAME()) { + return RawVarible(ctx->getText()); + } else { + auto string_lists = ctx->STRING(); + std::string res; + for (auto item : string_lists) { + const std::string &tmp = item->getText(); + res.append(tmp, 1, tmp.size() - 2); + } + return res; + } } std::any EvalVisitor::visitTestlist(Python3Parser::TestlistContext *ctx) { diff --git a/src/names.cpp b/src/names.cpp index a2f9e3d..7f0cd14 100644 --- a/src/names.cpp +++ b/src/names.cpp @@ -1,3 +1,36 @@ #include "names.h" -#include "utils.h" \ No newline at end of file +#include "utils.h" + +inline void VariableContainer::CreateFrame() { + StackScopes.push(std::unordered_map()); +} +void VariableContainer::DestroyFrame() { + if (StackScopes.empty()) throw FatalError("DestroyFrame: empty stack"); + StackScopes.pop(); +} +std::any VariableContainer::ReadVariable(const std::string &name) { + if (StackScopes.size()) { + auto &top = StackScopes.top(); + if (top.find(name) != top.end()) return top[name]; + } + if (GlobalScope.find(name) != GlobalScope.end()) return GlobalScope[name]; + throw InterpretException(("ReadVariable: " + name + " not found").c_str()); +} +void VariableContainer::WriteVariable(const std::string &name, + const std::any &value) { + if (StackScopes.empty()) { + GlobalScope[name] = value; + return; + } + auto &top = StackScopes.top(); + if (top.find(name) != top.end()) { + top[name] = value; + return; + } + if (GlobalScope.find(name) != GlobalScope.end()) { + GlobalScope[name] = value; + return; + } + top[name] = value; +} \ No newline at end of file diff --git a/src/utils.cpp b/src/utils.cpp index cab9269..18930b3 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -1 +1,79 @@ -#include "utils.h" \ No newline at end of file +#include "utils.h" + +inline ZYM::int2048 Any2Int(const std::any &value) { + if (auto ptr = std::any_cast(&value)) + return *ptr; + else if (auto ptr = std::any_cast(&value)) + return std::move(ZYM::int2048(*ptr)); + else if (auto ptr = std::any_cast(&value)) { + std::stringstream buf; + buf << std::fixed << std::setprecision(0) << *ptr; + std::string tmp; + buf >> tmp; + return std::move(ZYM::int2048(tmp)); + } else if (auto ptr = std::any_cast(&value)) + return std::move(ZYM::int2048((long long)(*ptr))); + else if (auto ptr = std::any_cast(&value)) { + std::string str = *ptr; + size_t dot_position = str.find('.'); + if (dot_position != std::string::npos) { + std::string integer_part = str.substr(0, dot_position); + str = integer_part; + } + return std::move(ZYM::int2048(str)); + } else + throw FatalError("Any2Int2048: unknown type"); +} + +double Any2Float(const std::any &value) { + if (auto ptr = std::any_cast(&value)) + return *ptr; + else if (auto ptr = std::any_cast(&value)) { + double res = 0; + std::stringstream buf; + buf << *ptr; + std::string tmp; + buf >> tmp; + int p = 0; + if (tmp[0] == '-') p++; + for (; p < tmp.size(); p++) res = res * 10 + tmp[p] - '0'; + if (tmp[0] == '-') res = -res; + return res; + } else if (auto ptr = std::any_cast(&value)) + return (double)(*ptr); + else if (auto ptr = std::any_cast(&value)) + return std::stod(*ptr); + else + throw FatalError("Any2Float: unknown type"); +} + +std::string Any2String(const std::any &value) { + std::stringstream buf; + std::string res; + if (auto ptr = std::any_cast(&value)) { + buf << std::setiosflags(std::ios::fixed) << std::setprecision(15) << *ptr; + } else if (auto ptr = std::any_cast(&value)) { + if (*ptr) + buf << "True"; + else + buf << "False"; + } else if (auto ptr = std::any_cast(&value)) + buf << *ptr; + else + throw FatalError("Any2String: unknown type"); + buf >> res; + return res; +} + +bool Any2Bool(const std::any &value) { + if (auto ptr = std::any_cast(&value)) { + return (*ptr) != 0; + } else if (auto ptr = std::any_cast(&value)) { + return (*ptr) != 0; + } else if (auto ptr = std::any_cast(&value)) { + return *ptr; + } else if (auto ptr = std::any_cast(&value)) { + return (*ptr) != ""; + } else + throw FatalError("Any2Bool: unknown type"); +} \ No newline at end of file