1
0

activation.cpp 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  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. runCodeElement(code);
  58. } else switch (code->getBlockType()) {
  59. case block_p: // 顺序执行
  60. runCodeBlockP(code);
  61. break;
  62. case block_b:
  63. runCodeBlockB(code);
  64. break;
  65. case block_c:
  66. runCodeBlockC(code);
  67. break;
  68. default:
  69. errorLog(aFunCoreLogger, "Error block type.");
  70. break;
  71. }
  72. }
  73. }
  74. void Activation::runCodeElement(Code *code) {
  75. std::string literaler_name;
  76. bool in_protect = false;
  77. Object *obj = nullptr;
  78. if (inter.checkLiteral(code->getElement(), literaler_name, in_protect)) {
  79. if (in_protect)
  80. obj = inter.getProtectVarSpace()->findObject(literaler_name);
  81. else
  82. obj = varlist->findObject(literaler_name);
  83. auto literaler = dynamic_cast<Literaler *>(obj);
  84. if (literaler != nullptr)
  85. literaler->getObject(code->getElement(), code->getPrefix());
  86. else
  87. down->pushMessage(new ErrorMessage("TypeError", "Error type of literal.", this));
  88. } else {
  89. if (varlist != nullptr)
  90. obj = varlist->findObject(code->getElement());
  91. if (obj != nullptr) {
  92. auto cbv = dynamic_cast<CallBackVar *>(obj);
  93. if (cbv != nullptr && cbv->isCallBack())
  94. cbv->callBack();
  95. else
  96. down->pushMessage(new NormalMessage(obj));
  97. } else
  98. down->pushMessage(new ErrorMessage("NameError", std::string("Variable ") + code->getElement() + " not fount.", this));
  99. }
  100. }
  101. void Activation::runCodeBlockP(Code *code) {
  102. new ExeActivation(code->getSon(), inter);
  103. }
  104. void Activation::runCodeBlockC(Code *code) {
  105. new FuncActivation(code, inter);
  106. }
  107. void Activation::runCodeBlockB(Code *code) {
  108. new FuncActivation(code, inter);
  109. }
  110. ActivationStatus ExeActivation::getCode(Code *&code){
  111. code = next;
  112. if (code == nullptr)
  113. return as_end;
  114. if (!first) {
  115. auto msg = down->getMessage<NormalMessage>("NORMAL");
  116. if (msg == nullptr)
  117. return as_end;
  118. else
  119. down->popMessage("NORMAL");
  120. delete msg;
  121. }
  122. first = false;
  123. line = code->getFileLine();
  124. if (code->getFilePath() != nullptr)
  125. path = code->getFilePath();
  126. next = code->toNext();
  127. return as_run;
  128. }
  129. TopActivation::TopActivation(Code *code, Inter &inter_) : ExeActivation(code, inter_) {
  130. varlist->connect(inter_.getGlobalVarlist());
  131. }
  132. static void ActivationTopProgress(Message *msg, void *) {
  133. auto *t = dynamic_cast<TopMessage *>(msg);
  134. if (t)
  135. t->topProgress();
  136. };
  137. TopActivation::~TopActivation() {
  138. down->forEach(ActivationTopProgress, nullptr);
  139. }
  140. FuncActivation::~FuncActivation(){
  141. delete call_func;
  142. }
  143. ActivationStatus FuncActivation::getCode(Code *&code){
  144. if (on_tail)
  145. return as_end;
  146. if (status == func_first) {
  147. switch (call->getBlockType()) {
  148. case block_c:
  149. status = func_get_func;
  150. code = call->getSon();
  151. if (code == nullptr) {
  152. line = 0;
  153. down->pushMessage(new ErrorMessage("SyntaxError", "Callback without code.", this));
  154. return as_end;
  155. }
  156. line = code->getFileLine();
  157. if (code->getFilePath() != nullptr)
  158. path = code->getFilePath();
  159. return as_run;
  160. case block_b: {
  161. std::string prefix;
  162. if (!inter.getEnvVarSpace()->findString("sys:prefix", prefix) || prefix.size() != PREFIX_COUNT)
  163. prefix = "''";
  164. char quote = prefix[prefix_quote];
  165. for (Code *var = call->getSon(); var != nullptr; var = var->toNext()) {
  166. if (var->getType() != code_element || var->getPrefix() == quote || inter.checkLiteral(var->getElement()))
  167. continue;
  168. Object *obj = varlist->findObject(var->getElement());
  169. if (obj == nullptr || !dynamic_cast<Function *>(obj) || !dynamic_cast<Function *>(obj)->isInfix())
  170. continue;
  171. func = dynamic_cast<Function *>(obj);
  172. if (func == nullptr || !func->isInfix())
  173. continue;
  174. status = func_get_func;
  175. break; /* 跳转到: 执行变量获取前的准备 */
  176. }
  177. if (status != func_get_func) {
  178. line = 0;
  179. down->pushMessage(new ErrorMessage("SyntaxError", "Callback without code.", this));
  180. return as_end;
  181. }
  182. break;
  183. }
  184. default:
  185. errorLog(aFunCoreLogger, "Error FuncActivation block type");
  186. line = 0;
  187. down->pushMessage(new ErrorMessage("RuntimeError", "Error FuncActivation block type.", this));
  188. return as_end;
  189. }
  190. }
  191. if (status == func_get_func) {
  192. if (func == nullptr) {
  193. auto *msg = down->getMessage<NormalMessage>("NORMAL");
  194. if (msg == nullptr)
  195. return as_end;
  196. else
  197. down->popMessage("NORMAL");
  198. func = dynamic_cast<Function *>(msg->getObject());
  199. delete msg;
  200. if (func == nullptr) {
  201. down->pushMessage(new ErrorMessage("TypeError", "Callback without function.", this));
  202. return as_end;
  203. }
  204. }
  205. /* Label: 执行变量获取前的准备 */
  206. status = func_get_arg;
  207. call_func = func->getCallFunction(call, inter);
  208. acl = call_func->getArgCodeList();
  209. acl_begin = acl->begin();
  210. acl_end = acl->end();
  211. if (acl_begin != acl_end) { // 如果有参数需要计算
  212. code = acl_begin->code;
  213. line = code->getFileLine();
  214. if (code->getFilePath() != nullptr)
  215. path = code->getFilePath();
  216. return as_run;
  217. }
  218. }
  219. if (acl_begin != acl_end) { // 获取参数计算结果
  220. auto *msg = down->getMessage<NormalMessage>("NORMAL");
  221. if (msg == nullptr)
  222. return as_end;
  223. down->popMessage("NORMAL");
  224. acl_begin->ret = msg->getObject();
  225. delete msg;
  226. acl_begin++;
  227. if (acl_begin != acl_end) {
  228. code = acl_begin->code;
  229. line = code->getFileLine();
  230. if (code->getFilePath() != nullptr)
  231. path = code->getFilePath();
  232. return as_run;
  233. }
  234. }
  235. on_tail = true;
  236. line = 0;
  237. return as_end_run;
  238. }
  239. void FuncActivation::endRun(){
  240. call_func->runFunction();
  241. }