activation.cpp 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  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_}, line{0},
  15. up{inter_.activation == nullptr ? nullptr : &inter_.activation->up}, down{}{
  16. if (inter_.activation != nullptr) {
  17. varlist = new VarList(inter_.activation->varlist);
  18. line = inter_.activation->line;
  19. path = inter_.activation->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 (inter.activation != nullptr)
  33. down.joinMsg(inter.activation->down);
  34. delete varlist;
  35. }
  36. /**
  37. * 运行代码
  38. * @param code
  39. */
  40. void Activation::runCode(const Code::ByteCode *code){
  41. auto code_type = code->getType();
  42. if (code_type == Code::ByteCode::code_start) { // start 不处理 msg
  43. auto *none = new Object("None", inter);
  44. down.pushMessage("NORMAL", new NormalMessage(none));
  45. } else {
  46. if (code_type == Code::ByteCode::code_element) {
  47. runCodeElement(code);
  48. } else
  49. switch (code->getBlockType()) {
  50. case Code::ByteCode::block_p: // 顺序执行
  51. runCodeBlockP(code);
  52. break;
  53. case Code::ByteCode::block_b:
  54. runCodeBlockB(code);
  55. break;
  56. case Code::ByteCode::block_c:
  57. runCodeBlockC(code);
  58. break;
  59. default:
  60. errorLog(aFunCoreLogger, "Error block type.");
  61. break;
  62. }
  63. }
  64. }
  65. void Activation::runCodeElement(const Code::ByteCode *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, *this);
  77. else
  78. down.pushMessage("ERROR", 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(inter, *this))
  85. cbv->callBack(inter, *this);
  86. else
  87. down.pushMessage("NORMAL", new NormalMessage(obj));
  88. } else
  89. down.pushMessage("ERROR",
  90. new ErrorMessage("NameError", std::string("Variable ") + code->getElement() + " not fount.",
  91. this));
  92. }
  93. }
  94. void Activation::runCodeBlockP(const Code::ByteCode *code){
  95. new ExeActivation(code->getSon(), inter);
  96. }
  97. void Activation::runCodeBlockC(const Code::ByteCode *code){
  98. new FuncActivation(code, inter);
  99. }
  100. void Activation::runCodeBlockB(const Code::ByteCode *code){
  101. new FuncActivation(code, inter);
  102. }
  103. Activation::ActivationStatus ExeActivation::getCode(const Code::ByteCode *&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. path = code->getFilePath();
  118. next = code->toNext();
  119. return as_run;
  120. }
  121. TopActivation::TopActivation(const Code &code, Inter &inter_) : ExeActivation(code, inter_), base{code} {
  122. varlist->connect(inter_.getGlobalVarlist());
  123. }
  124. static void ActivationTopProgress(Message *msg, Inter &inter, Activation &activation){
  125. auto *t = dynamic_cast<TopMessage *>(msg);
  126. if (t)
  127. t->topProgress(inter, activation);
  128. };
  129. TopActivation::~TopActivation(){
  130. down.forEach(ActivationTopProgress, std::ref(inter), std::ref(*this));
  131. }
  132. FuncActivation::~FuncActivation(){
  133. delete call_func;
  134. }
  135. FuncActivation::FuncActivation(Function *func_, Inter &inter_) : Activation(inter_), call{nullptr} {
  136. on_tail = false; // 跳过所有阶段
  137. status = func_get_func;
  138. func = func_;
  139. if (inter_.getActivation() == nullptr)
  140. varlist->connect(inter_.getGlobalVarlist());
  141. }
  142. Activation::ActivationStatus FuncActivation::getCode(const Code::ByteCode *&code) {
  143. if (on_tail)
  144. return as_end;
  145. if (status == func_first) {
  146. switch (call->getBlockType()) {
  147. case Code::ByteCode::block_c:
  148. status = func_get_func;
  149. code = call->getSon();
  150. if (code == nullptr) {
  151. line = 0;
  152. down.pushMessage("ERROR", new ErrorMessage("SyntaxError", "Callback without code.", this));
  153. return as_end;
  154. }
  155. line = code->getFileLine();
  156. if (!code->getFilePath().empty())
  157. path = code->getFilePath();
  158. return as_run;
  159. case Code::ByteCode::block_b: {
  160. std::string prefix;
  161. if (!inter.getEnvVarSpace().findString("sys:prefix", prefix) ||
  162. prefix.size() != Inter::PREFIX_COUNT)
  163. prefix = "''";
  164. char quote = prefix[Inter::prefix_quote];
  165. for (Code::ByteCode *var = call->getSon(); var != nullptr; var = var->toNext()) {
  166. if (var->getType() != Code::ByteCode::code_element || var->getPrefix() == quote ||
  167. inter.checkLiteral(var->getElement()))
  168. continue;
  169. Object *obj = varlist->findObject(var->getElement());
  170. if (obj == nullptr || !dynamic_cast<Function *>(obj) ||
  171. !dynamic_cast<Function *>(obj)->isInfix())
  172. continue;
  173. func = dynamic_cast<Function *>(obj);
  174. if (func == nullptr || !func->isInfix())
  175. continue;
  176. status = func_get_func;
  177. break; /* 跳转到: 执行变量获取前的准备 */
  178. }
  179. if (status != func_get_func) {
  180. line = 0;
  181. down.pushMessage("ERROR", new ErrorMessage("SyntaxError", "Callback without code.", this));
  182. return as_end;
  183. }
  184. break;
  185. }
  186. default:
  187. errorLog(aFunCoreLogger, "Error FuncActivation block type");
  188. line = 0;
  189. down.pushMessage("ERROR", new ErrorMessage("RuntimeError", "Error FuncActivation block type.", this));
  190. return as_end;
  191. }
  192. }
  193. if (status == func_get_func) {
  194. if (func == nullptr) {
  195. auto *msg = down.getMessage<NormalMessage>("NORMAL");
  196. if (msg == nullptr)
  197. return as_end;
  198. else
  199. down.popMessage("NORMAL");
  200. func = dynamic_cast<Function *>(msg->getObject());
  201. delete msg;
  202. if (func == nullptr) {
  203. down.pushMessage("ERROR", new ErrorMessage("TypeError", "Callback without function.", this));
  204. return as_end;
  205. }
  206. }
  207. /* Label: 执行变量获取前的准备 */
  208. status = func_get_arg;
  209. call_func = func->getCallFunction(call, inter);
  210. acl = call_func->getArgCodeList(inter, *this, call);
  211. acl_begin = acl->begin();
  212. acl_end = acl->end();
  213. if (acl_begin != acl_end) { // 如果有参数需要计算
  214. code = acl_begin->code;
  215. line = code->getFileLine();
  216. path = code->getFilePath();
  217. return as_run;
  218. }
  219. }
  220. if (acl_begin != acl_end) { // 获取参数计算结果
  221. auto *msg = down.getMessage<NormalMessage>("NORMAL");
  222. if (msg == nullptr)
  223. return as_end;
  224. down.popMessage("NORMAL");
  225. acl_begin->ret = msg->getObject();
  226. delete msg;
  227. acl_begin++;
  228. if (acl_begin != acl_end) {
  229. code = acl_begin->code;
  230. line = code->getFileLine();
  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. }
  242. }