activation.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. #include "core-activation.h"
  2. #include "inter.h"
  3. #include "core-init.h"
  4. #include "msg.h"
  5. #include "code.h"
  6. #include "core-exception.h"
  7. namespace aFuncore {
  8. /**
  9. * 创建基本Activation
  10. * 自动继承上层VarList和UpMessage
  11. * 自动压入inter
  12. * @param inter_
  13. */
  14. Activation::Activation(Inter &inter_)
  15. : inter{inter_}, line{0},
  16. up{inter_.activation == nullptr ? nullptr : &inter_.activation->up}, down{}{
  17. if (inter_.activation != nullptr) {
  18. varlist.connect(inter_.activation->varlist);
  19. line = inter_.activation->line;
  20. path = inter_.activation->path;
  21. } else {
  22. auto global = new VarSpace(inter);
  23. varlist.push(inter_.getProtectVarSpace());
  24. varlist.push(global);
  25. global->delReference();
  26. path = "";
  27. }
  28. inter.pushActivation(this);
  29. }
  30. static void ActivationTopProgress(Message *msg, Inter &inter, Activation &activation){
  31. auto *t = dynamic_cast<TopMessage *>(msg);
  32. if (t)
  33. t->topProgress(inter, activation);
  34. };
  35. /**
  36. * 析构Activation
  37. * 注意: 不会自动从inter中弹出
  38. * 释放Varlist并且将DownMessage压入上层
  39. */
  40. Activation::~Activation(){
  41. if (inter.activation != nullptr)
  42. down.joinMsg(inter.activation->down);
  43. else
  44. down.forEach(ActivationTopProgress, std::ref(inter), std::ref(*this));
  45. }
  46. void Activation::endRun() {
  47. }
  48. /**
  49. * 运行代码
  50. * @param code
  51. */
  52. void Activation::runCode(const Code::ByteCode *code){
  53. auto code_type = code->getType();
  54. if (code_type == Code::ByteCode::code_start) { // start 不处理 msg
  55. auto *none = new Object("None", inter);
  56. down.pushMessage("NORMAL", new NormalMessage(none));
  57. none->delReference();
  58. } else {
  59. if (code_type == Code::ByteCode::code_element) {
  60. runCodeElement(code);
  61. } else
  62. switch (code->getBlockType()) {
  63. case Code::ByteCode::block_p: // 顺序执行
  64. runCodeBlockP(code);
  65. break;
  66. case Code::ByteCode::block_b:
  67. runCodeBlockB(code);
  68. break;
  69. case Code::ByteCode::block_c:
  70. runCodeBlockC(code);
  71. break;
  72. default:
  73. errorLog(aFunCoreLogger, "Error block type.");
  74. break;
  75. }
  76. }
  77. }
  78. void Activation::runCodeElement(const Code::ByteCode *code){
  79. std::string literaler_name;
  80. bool in_protect = false;
  81. Object *obj = nullptr;
  82. if (inter.checkLiteral(code->getElement(), literaler_name, in_protect)) {
  83. if (in_protect)
  84. obj = inter.getProtectVarSpace()->findObject(literaler_name);
  85. else
  86. obj = varlist.findObject(literaler_name);
  87. auto literaler = dynamic_cast<Literaler *>(obj);
  88. if (literaler != nullptr)
  89. literaler->getObject(code->getElement(), code->getPrefix(), inter, *this);
  90. else
  91. down.pushMessage("ERROR", new ErrorMessage("TypeError", "Error type of literal.", this));
  92. } else {
  93. obj = varlist.findObject(code->getElement());
  94. if (obj != nullptr) {
  95. auto cbv = dynamic_cast<CallBackVar *>(obj);
  96. if (cbv != nullptr && cbv->isCallBack(inter, *this))
  97. cbv->callBack(inter, *this);
  98. else
  99. down.pushMessage("NORMAL", new NormalMessage(obj));
  100. } else
  101. down.pushMessage("ERROR",
  102. new ErrorMessage("NameError", std::string("Variable ") + code->getElement() + " not fount.",
  103. this));
  104. }
  105. }
  106. void Activation::runCodeBlockP(const Code::ByteCode *code){
  107. new ExeActivation(code->getSon(), inter);
  108. }
  109. void Activation::runCodeBlockC(const Code::ByteCode *code){
  110. new FuncActivation(code, inter);
  111. }
  112. void Activation::runCodeBlockB(const Code::ByteCode *code){
  113. new FuncActivation(code, inter);
  114. }
  115. Activation::ActivationStatus ExeActivation::getCode(const Code::ByteCode *&code){
  116. code = next;
  117. if (code == nullptr)
  118. return as_end;
  119. if (!first) {
  120. auto msg = down.getMessage<NormalMessage>("NORMAL");
  121. if (msg == nullptr)
  122. return as_end;
  123. else
  124. down.popMessage("NORMAL");
  125. delete msg;
  126. }
  127. first = false;
  128. line = code->getFileLine();
  129. path = code->getFilePath();
  130. next = code->toNext();
  131. return as_run;
  132. }
  133. Activation::VarList::~VarList() {
  134. for (auto &t : varspace)
  135. t->delReference();
  136. }
  137. /**
  138. * 访问变量
  139. * @param name 变量名
  140. * @return
  141. */
  142. Var *Activation::VarList::findVar(const std::string &name){
  143. Var *ret = nullptr;
  144. for (auto tmp = varspace.begin(), end = varspace.end(); tmp != end && ret == nullptr; tmp++)
  145. ret = (*tmp)->findVar(name);
  146. return ret;
  147. }
  148. /**
  149. * 定义变量
  150. * 若定义出现redefine则退出报错
  151. * 若出现fail则跳到下一个变量空间尝试定义
  152. * @param name 变量名
  153. * @param data 变量(Object)
  154. * @return
  155. */
  156. bool Activation::VarList::defineVar(const std::string &name, Object *data){
  157. VarSpace::VarOperationFlat ret = VarSpace::vof_fail;
  158. for (auto tmp = varspace.begin(), end = varspace.end(); tmp != end && ret == VarSpace::vof_fail; tmp++)
  159. ret = (*tmp)->defineVar(name, data);
  160. return ret == VarSpace::vof_success;
  161. }
  162. /**
  163. * 定义变量
  164. * 若定义出现redefine则退出报错
  165. * 若出现fail则跳到下一个变量空间尝试定义
  166. * @param name 变量名
  167. * @param data 变量(Var)
  168. * @return
  169. */
  170. bool Activation::VarList::defineVar(const std::string &name, Var *data){
  171. VarSpace::VarOperationFlat ret = VarSpace::vof_fail;
  172. for (auto tmp = varspace.begin(), end = varspace.end(); tmp != end && ret == VarSpace::vof_fail; tmp++)
  173. ret = (*tmp)->defineVar(name, data);
  174. return ret == VarSpace::vof_success;
  175. }
  176. /**
  177. * 设置变量的值
  178. * 若not_var则跳到下一个变量空间
  179. * 若fail则结束
  180. * @param name 变量名
  181. * @param data 数据
  182. * @return
  183. */
  184. bool Activation::VarList::setVar(const std::string &name, Object *data){
  185. VarSpace::VarOperationFlat ret = VarSpace::vof_not_var;
  186. for (auto tmp = varspace.begin(), end = varspace.end(); tmp != end && ret == VarSpace::vof_not_var; tmp++)
  187. ret = (*tmp)->setVar(name, data);
  188. return ret == VarSpace::vof_success;
  189. }
  190. /**
  191. * 删除变量
  192. * 若not_var则跳到下一个变量空间
  193. * 若fail则结束
  194. * @param name
  195. * @return
  196. */
  197. bool Activation::VarList::delVar(const std::string &name){
  198. VarSpace::VarOperationFlat ret = VarSpace::vof_not_var;
  199. for (auto tmp = varspace.begin(), end = varspace.end(); tmp != end && ret == VarSpace::vof_not_var; tmp++)
  200. ret = (*tmp)->delVar(name);
  201. return ret == VarSpace::vof_success;
  202. }
  203. void Activation::VarList::clear(){
  204. for (auto &t: varspace)
  205. t->delReference();
  206. varspace.clear();
  207. }
  208. void Activation::VarList::connect(VarList &new_varlist){
  209. for (auto &t: new_varlist.varspace) {
  210. t->addReference();
  211. this->varspace.push_back(t);
  212. }
  213. }
  214. TopActivation::TopActivation(const Code &code, Inter &inter_) : ExeActivation(code, inter_), base{code} {
  215. }
  216. FuncActivation::FuncActivation(Function *func_, Inter &inter_) : Activation(inter_), call{nullptr}, acl_begin{}, acl_end{} {
  217. on_tail = false; // 跳过所有阶段
  218. status = func_get_func;
  219. func = func_;
  220. func->addReference();
  221. }
  222. FuncActivation::~FuncActivation(){
  223. if (func != nullptr)
  224. func->delReference();
  225. delete call_func;
  226. }
  227. Activation::ActivationStatus FuncActivation::getCode(const Code::ByteCode *&code) {
  228. if (on_tail)
  229. return as_end;
  230. if (status == func_first) {
  231. switch (call->getBlockType()) {
  232. case Code::ByteCode::block_c:
  233. status = func_get_func;
  234. code = call->getSon();
  235. if (code == nullptr) {
  236. line = 0;
  237. down.pushMessage("ERROR", new ErrorMessage("SyntaxError", "Callback without code.", this));
  238. return as_end;
  239. }
  240. line = code->getFileLine();
  241. if (!code->getFilePath().empty())
  242. path = code->getFilePath();
  243. return as_run;
  244. case Code::ByteCode::block_b: {
  245. std::string prefix;
  246. if (!inter.getEnvVarSpace().findString("sys:prefix", prefix) ||
  247. prefix.size() != Inter::PREFIX_COUNT)
  248. prefix = "''";
  249. char quote = prefix[Inter::prefix_quote];
  250. for (Code::ByteCode *var = call->getSon(); var != nullptr; var = var->toNext()) {
  251. if (var->getType() != Code::ByteCode::code_element || var->getPrefix() == quote ||
  252. inter.checkLiteral(var->getElement()))
  253. continue;
  254. Object *obj = varlist.findObject(var->getElement());
  255. if (obj == nullptr || !dynamic_cast<Function *>(obj) ||
  256. !dynamic_cast<Function *>(obj)->isInfix())
  257. continue;
  258. func = dynamic_cast<Function *>(obj);
  259. if (func == nullptr || !func->isInfix())
  260. continue;
  261. func->addReference();
  262. status = func_get_func;
  263. break; /* 跳转到: 执行变量获取前的准备 */
  264. }
  265. if (status != func_get_func) {
  266. line = 0;
  267. down.pushMessage("ERROR", new ErrorMessage("SyntaxError", "Callback without code.", this));
  268. return as_end;
  269. }
  270. break;
  271. }
  272. default:
  273. errorLog(aFunCoreLogger, "Error FuncActivation block type");
  274. line = 0;
  275. down.pushMessage("ERROR", new ErrorMessage("RuntimeError", "Error FuncActivation block type.", this));
  276. return as_end;
  277. }
  278. }
  279. if (status == func_get_func) {
  280. if (func == nullptr) {
  281. auto *msg = down.getMessage<NormalMessage>("NORMAL");
  282. if (msg == nullptr)
  283. return as_end;
  284. else
  285. down.popMessage("NORMAL");
  286. func = dynamic_cast<Function *>(msg->getObject());
  287. delete msg;
  288. if (func == nullptr) {
  289. down.pushMessage("ERROR", new ErrorMessage("TypeError", "Callback without function.", this));
  290. return as_end;
  291. }
  292. func->addReference();
  293. }
  294. /* Label: 执行变量获取前的准备 */
  295. status = func_get_arg;
  296. try {
  297. call_func = func->getCallFunction(call, inter);
  298. acl = call_func->getArgCodeList(inter, *this, call);
  299. } catch (RuntimeError &e) {
  300. down.pushMessage("ERROR", new ErrorMessage(e.getType(), e.getMessage(), this));
  301. return as_end;
  302. }
  303. acl_begin = acl->begin();
  304. acl_end = acl->end();
  305. if (acl_begin != acl_end) { // 如果有参数需要计算
  306. code = acl_begin->code;
  307. line = code->getFileLine();
  308. path = code->getFilePath();
  309. return as_run;
  310. }
  311. }
  312. if (acl_begin != acl_end) { // 获取参数计算结果
  313. auto *msg = down.getMessage<NormalMessage>("NORMAL");
  314. if (msg == nullptr)
  315. return as_end;
  316. down.popMessage("NORMAL");
  317. acl_begin->setObject(msg->getObject());
  318. delete msg;
  319. acl_begin++;
  320. if (acl_begin != acl_end) {
  321. code = acl_begin->code;
  322. line = code->getFileLine();
  323. path = code->getFilePath();
  324. return as_run;
  325. }
  326. }
  327. on_tail = true;
  328. line = 0;
  329. return as_end_run;
  330. }
  331. void FuncActivation::endRun(){
  332. call_func->runFunction();
  333. }
  334. }