activation.cpp 13 KB

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