activation.cpp 9.0 KB

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