activation.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. #include "activation.h"
  2. #include "value.h"
  3. #include "inter.h"
  4. #include "init.h"
  5. #include "msg.h"
  6. #include "var.h"
  7. #include "code.h"
  8. #include "env-var.h"
  9. using namespace aFuncore;
  10. using namespace aFuntool;
  11. /**
  12. * 创建基本Activation
  13. * 自动继承上层VarList和UpMessage
  14. * 自动压入inter
  15. * @param inter_
  16. */
  17. Activation::Activation(Inter *inter_) : inter{inter_}, line{0} {
  18. Activation *prev_ = inter->getActivation();
  19. prev = prev_;
  20. down = new DownMessage();
  21. if (prev != nullptr) {
  22. varlist = new VarList(prev->varlist);
  23. up = new UpMessage(prev->up);
  24. line = prev->line;
  25. path = prev->path;
  26. } else {
  27. varlist = new VarList();
  28. up = new UpMessage();
  29. line = 0;
  30. path = "";
  31. }
  32. inter->pushActivation(this);
  33. }
  34. /**
  35. * 析构Activation
  36. * 注意: 不会自动从inter中弹出
  37. * 释放Varlist并且将DownMessage压入上层
  38. */
  39. Activation::~Activation(){
  40. if (prev != nullptr && down != nullptr)
  41. down->joinMsg(prev->down);
  42. delete up;
  43. delete down;
  44. delete varlist;
  45. }
  46. /**
  47. * 运行代码
  48. * @param code
  49. */
  50. void Activation::runCode(Code *code){
  51. auto code_type = code->getType();
  52. if (code_type == code_start) { // start 不处理 msg
  53. auto *none = new Object("None", inter);
  54. down->pushMessage(new NormalMessage(none));
  55. } else {
  56. if (code_type == code_element) {
  57. std::string literaler_name;
  58. bool in_protect = false;
  59. Object *obj = nullptr;
  60. if (inter->checkLiteral(code->getElement(), literaler_name, in_protect)) {
  61. if (in_protect)
  62. obj = inter->getProtectVarSpace()->findObject(literaler_name);
  63. else
  64. obj = varlist->findObject(literaler_name);
  65. auto literaler = dynamic_cast<Literaler *>(obj);
  66. if (literaler != nullptr)
  67. literaler->getObject(code->getElement(), code->getPrefix());
  68. else
  69. down->pushMessage(new ErrorMessage("TypeError", "Error type of literal.", this));
  70. } else {
  71. if (varlist != nullptr)
  72. obj = varlist->findObject(code->getElement());
  73. if (obj != nullptr) {
  74. auto cbv = dynamic_cast<CallBackVar *>(obj);
  75. if (cbv != nullptr && cbv->isCallBack())
  76. cbv->callBack();
  77. else
  78. down->pushMessage(new NormalMessage(obj));
  79. } else
  80. down->pushMessage(new ErrorMessage("NameError", std::string("Variable ") + code->getElement() + " not fount.", this));
  81. }
  82. } else switch (code->getBlockType()) {
  83. case block_p: // 顺序执行
  84. new ExeActivation(code->getSon(), inter);
  85. break;
  86. case block_b:
  87. case block_c:
  88. new FuncActivation(code, inter);
  89. break;
  90. default:
  91. errorLog(aFunCoreLogger, "Error block type.");
  92. break;
  93. }
  94. }
  95. }
  96. ActivationStatus ExeActivation::getCode(Code *&code){
  97. code = next;
  98. if (code == nullptr)
  99. return as_end;
  100. if (!first) {
  101. auto msg = down->getMessage<NormalMessage>("NORMAL");
  102. if (msg == nullptr)
  103. return as_end;
  104. else
  105. down->popMessage("NORMAL");
  106. delete msg;
  107. }
  108. first = false;
  109. line = code->getFileLine();
  110. if (code->getFilePath() != nullptr)
  111. path = code->getFilePath();
  112. next = code->toNext();
  113. return as_run;
  114. }
  115. TopActivation::TopActivation(Code *code, Inter *inter_) : ExeActivation(code, inter_) {
  116. varlist->connect(inter_->getGlobalVarlist());
  117. }
  118. static void ActivationTopProgress(Message *msg, void *) {
  119. auto *t = dynamic_cast<TopMessage *>(msg);
  120. if (t)
  121. t->topProgress();
  122. };
  123. TopActivation::~TopActivation() {
  124. down->forEach<void *>(ActivationTopProgress, nullptr);
  125. }
  126. FuncActivation::~FuncActivation(){
  127. delete call_func;
  128. }
  129. ActivationStatus FuncActivation::getCode(Code *&code){
  130. if (on_tail)
  131. return as_end;
  132. if (status == func_first) {
  133. switch (call->getBlockType()) {
  134. case block_c:
  135. status = func_get_func;
  136. code = call->getSon();
  137. if (code == nullptr) {
  138. line = 0;
  139. down->pushMessage(new ErrorMessage("SyntaxError", "Callback without code.", this));
  140. return as_end;
  141. }
  142. line = code->getFileLine();
  143. if (code->getFilePath() != nullptr)
  144. path = code->getFilePath();
  145. return as_run;
  146. case block_b: {
  147. std::string prefix;
  148. if (!inter->getEnvVarSpace()->findString("sys:prefix", prefix) || prefix.size() != PREFIX_COUNT)
  149. prefix = "''";
  150. char quote = prefix[prefix_quote];
  151. for (Code *var = call->getSon(); var != nullptr; var = var->toNext()) {
  152. if (var->getType() != code_element || var->getPrefix() == quote || inter->checkLiteral(var->getElement()))
  153. continue;
  154. Object *obj = varlist->findObject(var->getElement());
  155. if (obj == nullptr || !dynamic_cast<Function *>(obj) || !dynamic_cast<Function *>(obj)->isInfix())
  156. continue;
  157. func = dynamic_cast<Function *>(obj);
  158. if (func == nullptr || !func->isInfix())
  159. continue;
  160. status = func_get_func;
  161. break; /* 跳转到: 执行变量获取前的准备 */
  162. }
  163. if (status != func_get_func) {
  164. line = 0;
  165. down->pushMessage(new ErrorMessage("SyntaxError", "Callback without code.", this));
  166. return as_end;
  167. }
  168. break;
  169. }
  170. default:
  171. errorLog(aFunCoreLogger, "Error FuncActivation block type");
  172. line = 0;
  173. down->pushMessage(new ErrorMessage("RuntimeError", "Error FuncActivation block type.", this));
  174. return as_end;
  175. }
  176. }
  177. if (status == func_get_func) {
  178. if (func == nullptr) {
  179. auto *msg = down->getMessage<NormalMessage>("NORMAL");
  180. if (msg == nullptr)
  181. return as_end;
  182. else
  183. down->popMessage("NORMAL");
  184. func = dynamic_cast<Function *>(msg->getObject());
  185. delete msg;
  186. if (func == nullptr) {
  187. down->pushMessage(new ErrorMessage("TypeError", "Callback without function.", this));
  188. return as_end;
  189. }
  190. }
  191. /* Label: 执行变量获取前的准备 */
  192. status = func_get_arg;
  193. call_func = func->getCallFunction(call, inter);
  194. acl = call_func->getArgCodeList();
  195. acl_begin = acl->begin();
  196. acl_end = acl->end();
  197. if (acl_begin != acl_end) { // 如果有参数需要计算
  198. code = acl_begin->code;
  199. line = code->getFileLine();
  200. if (code->getFilePath() != nullptr)
  201. path = code->getFilePath();
  202. return as_run;
  203. }
  204. }
  205. if (acl_begin != acl_end) { // 获取参数计算结果
  206. auto *msg = down->getMessage<NormalMessage>("NORMAL");
  207. if (msg == nullptr)
  208. return as_end;
  209. down->popMessage("NORMAL");
  210. acl_begin->ret = msg->getObject();
  211. delete msg;
  212. acl_begin++;
  213. if (acl_begin != acl_end) {
  214. code = acl_begin->code;
  215. line = code->getFileLine();
  216. if (code->getFilePath() != nullptr)
  217. path = code->getFilePath();
  218. return as_run;
  219. }
  220. }
  221. on_tail = true;
  222. line = 0;
  223. return as_end_run;
  224. }
  225. void FuncActivation::endRun(){
  226. call_func->runFunction();
  227. }