123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369 |
- #include "core-activation.h"
- #include "inter.h"
- #include "core-init.h"
- #include "msg.h"
- #include "code.h"
- #include "core-exception.h"
- namespace aFuncore {
- /**
- * 创建基本Activation
- * 自动继承上层VarList和UpMessage
- * 自动压入inter
- * @param inter_
- */
- Activation::Activation(Inter &inter_)
- : inter{inter_}, line{0},
- up{inter_.activation == nullptr ? nullptr : &inter_.activation->up}, down{}{
- if (inter_.activation != nullptr) {
- varlist.connect(inter_.activation->varlist);
- line = inter_.activation->line;
- path = inter_.activation->path;
- } else {
- auto global = new VarSpace(inter);
- varlist.push(inter_.getProtectVarSpace());
- varlist.push(global);
- global->delReference();
- path = "";
- }
- inter.pushActivation(this);
- }
- static void ActivationTopProgress(Message *msg, Inter &inter, Activation &activation){
- auto *t = dynamic_cast<TopMessage *>(msg);
- if (t)
- t->topProgress(inter, activation);
- };
- /**
- * 析构Activation
- * 注意: 不会自动从inter中弹出
- * 释放Varlist并且将DownMessage压入上层
- */
- Activation::~Activation(){
- if (inter.activation != nullptr)
- down.joinMsg(inter.activation->down);
- else
- down.forEach(ActivationTopProgress, std::ref(inter), std::ref(*this));
- }
- void Activation::endRun() {
- }
- /**
- * 运行代码
- * @param code
- */
- void Activation::runCode(const Code::ByteCode *code){
- auto code_type = code->getType();
- if (code_type == Code::ByteCode::code_start) { // start 不处理 msg
- auto *none = new Object("None", inter);
- down.pushMessage("NORMAL", new NormalMessage(none));
- none->delReference();
- } else {
- if (code_type == Code::ByteCode::code_element) {
- runCodeElement(code);
- } else
- switch (code->getBlockType()) {
- case Code::ByteCode::block_p: // 顺序执行
- runCodeBlockP(code);
- break;
- case Code::ByteCode::block_b:
- runCodeBlockB(code);
- break;
- case Code::ByteCode::block_c:
- runCodeBlockC(code);
- break;
- default:
- errorLog(aFunCoreLogger, "Error block type.");
- break;
- }
- }
- }
- void Activation::runCodeElement(const Code::ByteCode *code){
- std::string literaler_name;
- bool in_protect = false;
- Object *obj = nullptr;
- if (inter.checkLiteral(code->getElement(), literaler_name, in_protect)) {
- if (in_protect)
- obj = inter.getProtectVarSpace()->findObject(literaler_name);
- else
- obj = varlist.findObject(literaler_name);
- auto literaler = dynamic_cast<Literaler *>(obj);
- if (literaler != nullptr)
- literaler->getObject(code->getElement(), code->getPrefix(), inter, *this);
- else
- down.pushMessage("ERROR", new ErrorMessage("TypeError", "Error type of literal.", this));
- } else {
- obj = varlist.findObject(code->getElement());
- if (obj != nullptr) {
- auto cbv = dynamic_cast<CallBackVar *>(obj);
- if (cbv != nullptr && cbv->isCallBack(inter, *this))
- cbv->callBack(inter, *this);
- else
- down.pushMessage("NORMAL", new NormalMessage(obj));
- } else
- down.pushMessage("ERROR",
- new ErrorMessage("NameError", std::string("Variable ") + code->getElement() + " not fount.",
- this));
- }
- }
- void Activation::runCodeBlockP(const Code::ByteCode *code){
- new ExeActivation(code->getSon(), inter);
- }
- void Activation::runCodeBlockC(const Code::ByteCode *code){
- new FuncActivation(code, inter);
- }
- void Activation::runCodeBlockB(const Code::ByteCode *code){
- new FuncActivation(code, inter);
- }
- Activation::ActivationStatus ExeActivation::getCode(const Code::ByteCode *&code){
- code = next;
- if (code == nullptr)
- return as_end;
- if (!first) {
- auto msg = down.getMessage<NormalMessage>("NORMAL");
- if (msg == nullptr)
- return as_end;
- else
- down.popMessage("NORMAL");
- delete msg;
- }
- first = false;
- line = code->getFileLine();
- path = code->getFilePath();
- next = code->toNext();
- return as_run;
- }
- Activation::VarList::~VarList() {
- for (auto &t : varspace)
- t->delReference();
- }
- /**
- * 访问变量
- * @param name 变量名
- * @return
- */
- Var *Activation::VarList::findVar(const std::string &name){
- Var *ret = nullptr;
- for (auto tmp = varspace.begin(), end = varspace.end(); tmp != end && ret == nullptr; tmp++)
- ret = (*tmp)->findVar(name);
- return ret;
- }
- /**
- * 定义变量
- * 若定义出现redefine则退出报错
- * 若出现fail则跳到下一个变量空间尝试定义
- * @param name 变量名
- * @param data 变量(Object)
- * @return
- */
- bool Activation::VarList::defineVar(const std::string &name, Object *data){
- VarSpace::VarOperationFlat ret = VarSpace::vof_fail;
- for (auto tmp = varspace.begin(), end = varspace.end(); tmp != end && ret == VarSpace::vof_fail; tmp++)
- ret = (*tmp)->defineVar(name, data);
- return ret == VarSpace::vof_success;
- }
- /**
- * 定义变量
- * 若定义出现redefine则退出报错
- * 若出现fail则跳到下一个变量空间尝试定义
- * @param name 变量名
- * @param data 变量(Var)
- * @return
- */
- bool Activation::VarList::defineVar(const std::string &name, Var *data){
- VarSpace::VarOperationFlat ret = VarSpace::vof_fail;
- for (auto tmp = varspace.begin(), end = varspace.end(); tmp != end && ret == VarSpace::vof_fail; tmp++)
- ret = (*tmp)->defineVar(name, data);
- return ret == VarSpace::vof_success;
- }
- /**
- * 设置变量的值
- * 若not_var则跳到下一个变量空间
- * 若fail则结束
- * @param name 变量名
- * @param data 数据
- * @return
- */
- bool Activation::VarList::setVar(const std::string &name, Object *data){
- VarSpace::VarOperationFlat ret = VarSpace::vof_not_var;
- for (auto tmp = varspace.begin(), end = varspace.end(); tmp != end && ret == VarSpace::vof_not_var; tmp++)
- ret = (*tmp)->setVar(name, data);
- return ret == VarSpace::vof_success;
- }
- /**
- * 删除变量
- * 若not_var则跳到下一个变量空间
- * 若fail则结束
- * @param name
- * @return
- */
- bool Activation::VarList::delVar(const std::string &name){
- VarSpace::VarOperationFlat ret = VarSpace::vof_not_var;
- for (auto tmp = varspace.begin(), end = varspace.end(); tmp != end && ret == VarSpace::vof_not_var; tmp++)
- ret = (*tmp)->delVar(name);
- return ret == VarSpace::vof_success;
- }
- void Activation::VarList::clear(){
- for (auto &t: varspace)
- t->delReference();
- varspace.clear();
- }
- void Activation::VarList::connect(VarList &new_varlist){
- for (auto &t: new_varlist.varspace) {
- t->addReference();
- this->varspace.push_back(t);
- }
- }
- TopActivation::TopActivation(const Code &code, Inter &inter_) : ExeActivation(code, inter_), base{code} {
- }
- FuncActivation::FuncActivation(Function *func_, Inter &inter_) : Activation(inter_), call{nullptr}, acl_begin{}, acl_end{} {
- on_tail = false; // 跳过所有阶段
- status = func_get_func;
- func = func_;
- func->addReference();
- }
- FuncActivation::~FuncActivation(){
- if (func != nullptr)
- func->delReference();
- delete call_func;
- }
- Activation::ActivationStatus FuncActivation::getCode(const Code::ByteCode *&code) {
- if (on_tail)
- return as_end;
- if (status == func_first) {
- switch (call->getBlockType()) {
- case Code::ByteCode::block_c:
- status = func_get_func;
- code = call->getSon();
- if (code == nullptr) {
- line = 0;
- down.pushMessage("ERROR", new ErrorMessage("SyntaxError", "Callback without code.", this));
- return as_end;
- }
- line = code->getFileLine();
- if (!code->getFilePath().empty())
- path = code->getFilePath();
- return as_run;
- case Code::ByteCode::block_b: {
- std::string prefix;
- if (!inter.getEnvVarSpace().findString("sys:prefix", prefix) ||
- prefix.size() != Inter::PREFIX_COUNT)
- prefix = "''";
- char quote = prefix[Inter::prefix_quote];
- for (Code::ByteCode *var = call->getSon(); var != nullptr; var = var->toNext()) {
- if (var->getType() != Code::ByteCode::code_element || var->getPrefix() == quote ||
- inter.checkLiteral(var->getElement()))
- continue;
- Object *obj = varlist.findObject(var->getElement());
- if (obj == nullptr || !dynamic_cast<Function *>(obj) ||
- !dynamic_cast<Function *>(obj)->isInfix())
- continue;
- func = dynamic_cast<Function *>(obj);
- if (func == nullptr || !func->isInfix())
- continue;
- func->addReference();
- status = func_get_func;
- break; /* 跳转到: 执行变量获取前的准备 */
- }
- if (status != func_get_func) {
- line = 0;
- down.pushMessage("ERROR", new ErrorMessage("SyntaxError", "Callback without code.", this));
- return as_end;
- }
- break;
- }
- default:
- errorLog(aFunCoreLogger, "Error FuncActivation block type");
- line = 0;
- down.pushMessage("ERROR", new ErrorMessage("RuntimeError", "Error FuncActivation block type.", this));
- return as_end;
- }
- }
- if (status == func_get_func) {
- if (func == nullptr) {
- auto *msg = down.getMessage<NormalMessage>("NORMAL");
- if (msg == nullptr)
- return as_end;
- else
- down.popMessage("NORMAL");
- func = dynamic_cast<Function *>(msg->getObject());
- delete msg;
- if (func == nullptr) {
- down.pushMessage("ERROR", new ErrorMessage("TypeError", "Callback without function.", this));
- return as_end;
- }
- func->addReference();
- }
- /* Label: 执行变量获取前的准备 */
- status = func_get_arg;
- try {
- call_func = func->getCallFunction(call, inter);
- acl = call_func->getArgCodeList(inter, *this, call);
- } catch (RuntimeError &e) {
- down.pushMessage("ERROR", new ErrorMessage(e.getType(), e.getMessage(), this));
- return as_end;
- }
- acl_begin = acl->begin();
- acl_end = acl->end();
- if (acl_begin != acl_end) { // 如果有参数需要计算
- code = acl_begin->code;
- line = code->getFileLine();
- path = code->getFilePath();
- return as_run;
- }
- }
- if (acl_begin != acl_end) { // 获取参数计算结果
- auto *msg = down.getMessage<NormalMessage>("NORMAL");
- if (msg == nullptr)
- return as_end;
- down.popMessage("NORMAL");
- acl_begin->setObject(msg->getObject());
- delete msg;
- acl_begin++;
- if (acl_begin != acl_end) {
- code = acl_begin->code;
- line = code->getFileLine();
- path = code->getFilePath();
- return as_run;
- }
- }
- on_tail = true;
- line = 0;
- return as_end_run;
- }
- void FuncActivation::endRun(){
- call_func->runFunction();
- }
- }
|