upd: first version of function call
This commit is contained in:
@ -5,6 +5,7 @@
|
|||||||
#include <stack>
|
#include <stack>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "Evalvisitor.h"
|
||||||
#include "Python3ParserBaseVisitor.h"
|
#include "Python3ParserBaseVisitor.h"
|
||||||
#include "int2048/int2048.h"
|
#include "int2048/int2048.h"
|
||||||
class InterpretException : public std::exception {
|
class InterpretException : public std::exception {
|
||||||
@ -71,14 +72,6 @@ struct FunctionItem {
|
|||||||
const std::vector<ParaArguItemType> ¶_list)
|
const std::vector<ParaArguItemType> ¶_list)
|
||||||
: code_address(code_address), para_list(para_list) {}
|
: code_address(code_address), para_list(para_list) {}
|
||||||
};
|
};
|
||||||
class FucntionContainer {
|
|
||||||
std::unordered_map<std::string, FunctionItem> FunctionIndex;
|
|
||||||
|
|
||||||
public:
|
|
||||||
void AddFunction(const std::string &name, const FunctionItem &item);
|
|
||||||
std::any CallFunction(const std::string &name,
|
|
||||||
const std::vector<ParaArguItemType> &args);
|
|
||||||
};
|
|
||||||
class VariableContainer {
|
class VariableContainer {
|
||||||
std::unordered_map<std::string, std::any> GlobalScope;
|
std::unordered_map<std::string, std::any> GlobalScope;
|
||||||
std::stack<std::unordered_map<std::string, std::any>> StackScopes;
|
std::stack<std::unordered_map<std::string, std::any>> StackScopes;
|
||||||
@ -87,7 +80,17 @@ class VariableContainer {
|
|||||||
void CreateFrame();
|
void CreateFrame();
|
||||||
void DestroyFrame();
|
void DestroyFrame();
|
||||||
std::any ReadVariable(const std::string &name);
|
std::any ReadVariable(const std::string &name);
|
||||||
void WriteVariable(const std::string &name, const std::any &value);
|
void WriteVariable(const std::string &name, const std::any &value,
|
||||||
|
bool cover = false);
|
||||||
|
};
|
||||||
|
class FucntionContainer {
|
||||||
|
std::unordered_map<std::string, FunctionItem> FunctionIndex;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void AddFunction(const std::string &name, const FunctionItem &item);
|
||||||
|
std::any CallFunction(const std::string &name,
|
||||||
|
const std::vector<ParaArguItemType> &args,
|
||||||
|
VariableContainer &Varables);
|
||||||
};
|
};
|
||||||
std::any DeQuate(std::any val, VariableContainer &Variables);
|
std::any DeQuate(std::any val, VariableContainer &Variables);
|
||||||
|
|
||||||
|
@ -347,7 +347,7 @@ std::any EvalVisitor::visitAtom_expr(Python3Parser::Atom_exprContext *ctx) {
|
|||||||
std::vector<ParaArguItemType> args =
|
std::vector<ParaArguItemType> args =
|
||||||
std::any_cast<std::vector<ParaArguItemType>>(
|
std::any_cast<std::vector<ParaArguItemType>>(
|
||||||
visitTrailer(ctx->trailer()));
|
visitTrailer(ctx->trailer()));
|
||||||
return Functions.CallFunction(func_name, args);
|
return Functions.CallFunction(func_name, args, Variables);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::any EvalVisitor::visitTrailer(Python3Parser::TrailerContext *ctx) {
|
std::any EvalVisitor::visitTrailer(Python3Parser::TrailerContext *ctx) {
|
||||||
|
@ -18,7 +18,7 @@ std::any VariableContainer::ReadVariable(const std::string &name) {
|
|||||||
throw InterpretException(("ReadVariable: " + name + " not found").c_str());
|
throw InterpretException(("ReadVariable: " + name + " not found").c_str());
|
||||||
}
|
}
|
||||||
void VariableContainer::WriteVariable(const std::string &name,
|
void VariableContainer::WriteVariable(const std::string &name,
|
||||||
const std::any &value) {
|
const std::any &value, bool cover) {
|
||||||
if (StackScopes.empty()) {
|
if (StackScopes.empty()) {
|
||||||
GlobalScope[name] = value;
|
GlobalScope[name] = value;
|
||||||
return;
|
return;
|
||||||
@ -28,6 +28,10 @@ void VariableContainer::WriteVariable(const std::string &name,
|
|||||||
top[name] = value;
|
top[name] = value;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (cover) {
|
||||||
|
top[name] = value;
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (GlobalScope.find(name) != GlobalScope.end()) {
|
if (GlobalScope.find(name) != GlobalScope.end()) {
|
||||||
GlobalScope[name] = value;
|
GlobalScope[name] = value;
|
||||||
return;
|
return;
|
||||||
@ -43,9 +47,88 @@ void FucntionContainer::AddFunction(const std::string &name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::any FucntionContainer::CallFunction(
|
std::any FucntionContainer::CallFunction(
|
||||||
const std::string &name, const std::vector<ParaArguItemType> &args) {
|
const std::string &name, const std::vector<ParaArguItemType> &args,
|
||||||
|
VariableContainer &Variables) {
|
||||||
|
if (name == "print") {
|
||||||
|
bool is_first = true;
|
||||||
|
for (int i = 0; i < args.size(); i++) {
|
||||||
|
if (is_first) std::cout << ' ';
|
||||||
|
is_first = false;
|
||||||
|
std::string buf = Any2String(args[i].value);
|
||||||
|
std::cout << buf;
|
||||||
|
}
|
||||||
|
std::cout << '\n';
|
||||||
|
return nullptr;
|
||||||
|
} else if (name == "str") {
|
||||||
|
if (args.size() != 1)
|
||||||
|
throw InterpretException(
|
||||||
|
"CallFunction: str() should take exactly one argument");
|
||||||
|
return Any2String(args[0].value);
|
||||||
|
} else if (name == "int") {
|
||||||
|
if (args.size() == 1) {
|
||||||
|
return Any2Int(args[0].value);
|
||||||
|
} else {
|
||||||
|
throw InterpretException(
|
||||||
|
"CallFunction: int() should take exactly one argument");
|
||||||
|
}
|
||||||
|
} else if (name == "float") {
|
||||||
|
if (args.size() == 1) {
|
||||||
|
return Any2Float(args[0].value);
|
||||||
|
} else {
|
||||||
|
throw InterpretException(
|
||||||
|
"CallFunction: float() should take exactly one argument");
|
||||||
|
}
|
||||||
|
} else if (name == "bool") {
|
||||||
|
if (args.size() == 1) {
|
||||||
|
return Any2Bool(args[0].value);
|
||||||
|
} else {
|
||||||
|
throw InterpretException(
|
||||||
|
"CallFunction: bool() should take exactly one argument");
|
||||||
|
}
|
||||||
|
}
|
||||||
if (FunctionIndex.find(name) == FunctionIndex.end()) {
|
if (FunctionIndex.find(name) == FunctionIndex.end()) {
|
||||||
throw InterpretException("CallFunction: function not found");
|
throw InterpretException("CallFunction: function not found");
|
||||||
}
|
}
|
||||||
// TODO
|
const FunctionItem &func = FunctionIndex[name];
|
||||||
|
std::unordered_set<std::string> args_with_data;
|
||||||
|
Variables.CreateFrame();
|
||||||
|
for (int i = 0; i < args.size(); i++)
|
||||||
|
if (args[i].name != "") {
|
||||||
|
Variables.WriteVariable(args[i].name, args[i].value, true);
|
||||||
|
args_with_data.insert(args[i].name);
|
||||||
|
}
|
||||||
|
int p_src = 0;
|
||||||
|
for (int i = 0; i < func.para_list.size(); i++) {
|
||||||
|
while (p_src < args.size() &&
|
||||||
|
args_with_data.find(args[p_src].name) != args_with_data.end())
|
||||||
|
p_src++;
|
||||||
|
if (p_src >= args.size()) break;
|
||||||
|
while (i < func.para_list.size() &&
|
||||||
|
args_with_data.find(func.para_list[i].name) != args_with_data.end())
|
||||||
|
i++;
|
||||||
|
if (i >= func.para_list.size()) break;
|
||||||
|
Variables.WriteVariable(func.para_list[i].name, args[p_src].value, true);
|
||||||
|
args_with_data.insert(func.para_list[i].name);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < func.para_list.size(); i++) {
|
||||||
|
while (i < func.para_list.size() &&
|
||||||
|
args_with_data.find(func.para_list[i].name) != args_with_data.end())
|
||||||
|
i++;
|
||||||
|
if (i >= func.para_list.size()) break;
|
||||||
|
if (!func.para_list[i].value.has_value())
|
||||||
|
throw InterpretException("CallFunction: function parameter not found");
|
||||||
|
Variables.WriteVariable(func.para_list[i].name, func.para_list[i].value,
|
||||||
|
true);
|
||||||
|
args_with_data.insert(func.para_list[i].name);
|
||||||
|
}
|
||||||
|
EvalVisitor vis;
|
||||||
|
std::any res = vis.visit(func.code_address);
|
||||||
|
Variables.DestroyFrame();
|
||||||
|
FlowType *flow = std::any_cast<FlowType>(&res);
|
||||||
|
if(!flow)
|
||||||
|
{
|
||||||
|
if(flow->ReturnValueLists.size()==1) return flow->ReturnValueLists[0];
|
||||||
|
else return flow->ReturnValueLists;
|
||||||
|
}
|
||||||
|
return NoneType();
|
||||||
}
|
}
|
Reference in New Issue
Block a user