upd: first version of atom

This commit is contained in:
2023-11-09 09:40:43 +08:00
parent a2a8c45af1
commit cfdc5e5a1c
5 changed files with 169 additions and 14 deletions

View File

@ -2,21 +2,26 @@
#define NAMESCOPE_H #define NAMESCOPE_H
#include <any> #include <any>
#include <stack>
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
#include "utils.h" #include "utils.h"
class NameScopeClass { class FucntionContainer {
struct FunctionItem {
; ;
}; };
struct FunctionItem
{
;
}; };
struct FucntionContainer class VariableContainer {
{ std::unordered_map<std::string, std::any> GlobalScope;
; std::stack<std::unordered_map<std::string, std::any>> StackScopes;
public:
void CreateFrame();
void DestroyFrame();
std::any ReadVariable(const std::string &name);
void WriteVariable(const std::string &name, const std::any &value);
}; };
#endif #endif

View File

@ -2,8 +2,13 @@
#define UTILS_H #define UTILS_H
#include <any> #include <any>
#include <exception> #include <exception>
#include <iomanip>
#include <sstream>
#include <stdexcept> #include <stdexcept>
#include <string>
#include <vector> #include <vector>
#include "int2048/int2048.h"
class InterpretException : public std::exception { class InterpretException : public std::exception {
public: public:
InterpretException() {} InterpretException() {}
@ -38,4 +43,15 @@ struct FlowType {
}; };
struct NoneType {}; 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 #endif

View File

@ -8,7 +8,7 @@
#include "names.h" #include "names.h"
#include "utils.h" #include "utils.h"
NameScopeClass GlobalScope, StackScope; VariableContainer Variables;
FucntionContainer Functions; FucntionContainer Functions;
std::any EvalVisitor::visitFile_input(Python3Parser::File_inputContext *ctx) { 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) { std::any EvalVisitor::visitAtom(Python3Parser::AtomContext *ctx) {
// throw FatalError("Not implemented in function visitAtom"); if (ctx->NONE())
return visitChildren(ctx); 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) { std::any EvalVisitor::visitTestlist(Python3Parser::TestlistContext *ctx) {

View File

@ -1,3 +1,36 @@
#include "names.h" #include "names.h"
#include "utils.h" #include "utils.h"
inline void VariableContainer::CreateFrame() {
StackScopes.push(std::unordered_map<std::string, std::any>());
}
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;
}

View File

@ -1 +1,79 @@
#include "utils.h" #include "utils.h"
inline ZYM::int2048 Any2Int(const std::any &value) {
if (auto ptr = std::any_cast<ZYM::int2048>(&value))
return *ptr;
else if (auto ptr = std::any_cast<int>(&value))
return std::move(ZYM::int2048(*ptr));
else if (auto ptr = std::any_cast<double>(&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<bool>(&value))
return std::move(ZYM::int2048((long long)(*ptr)));
else if (auto ptr = std::any_cast<std::string>(&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<double>(&value))
return *ptr;
else if (auto ptr = std::any_cast<ZYM::int2048>(&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<bool>(&value))
return (double)(*ptr);
else if (auto ptr = std::any_cast<std::string>(&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<double>(&value)) {
buf << std::setiosflags(std::ios::fixed) << std::setprecision(15) << *ptr;
} else if (auto ptr = std::any_cast<bool>(&value)) {
if (*ptr)
buf << "True";
else
buf << "False";
} else if (auto ptr = std::any_cast<ZYM::int2048>(&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<ZYM::int2048>(&value)) {
return (*ptr) != 0;
} else if (auto ptr = std::any_cast<double>(&value)) {
return (*ptr) != 0;
} else if (auto ptr = std::any_cast<bool>(&value)) {
return *ptr;
} else if (auto ptr = std::any_cast<std::string>(&value)) {
return (*ptr) != "";
} else
throw FatalError("Any2Bool: unknown type");
}