upd: first version of function call

This commit is contained in:
2023-11-09 17:28:41 +08:00
parent 9cc802fb7a
commit 5ad5615586
4 changed files with 100 additions and 13 deletions

View File

@ -18,7 +18,7 @@ std::any VariableContainer::ReadVariable(const std::string &name) {
throw InterpretException(("ReadVariable: " + name + " not found").c_str());
}
void VariableContainer::WriteVariable(const std::string &name,
const std::any &value) {
const std::any &value, bool cover) {
if (StackScopes.empty()) {
GlobalScope[name] = value;
return;
@ -28,6 +28,10 @@ void VariableContainer::WriteVariable(const std::string &name,
top[name] = value;
return;
}
if (cover) {
top[name] = value;
return;
}
if (GlobalScope.find(name) != GlobalScope.end()) {
GlobalScope[name] = value;
return;
@ -43,9 +47,88 @@ void FucntionContainer::AddFunction(const std::string &name,
}
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()) {
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();
}