var.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. #include "__var.h"
  2. #include "tool.h"
  3. /* VarNode 创建与释放 */
  4. static af_VarNode *makeVarNode(af_Object *obj, char *id);
  5. static af_VarNode *freeVarNode(af_VarNode *vn);
  6. static void freeAllVarNode(af_VarNode *vn);
  7. /* VarNode 相关操作 */
  8. static af_VarNode *findVarNode_(af_Var *var, char *id);
  9. /* VarCup 创建与释放 */
  10. static af_VarCup *makeVarCup(af_Var *var);
  11. static af_VarCup *freeVarCup(af_VarCup *vp);
  12. static void freeAllVarCup(af_VarCup *vp);
  13. /* VarSpace 寻值函数 */
  14. static af_Var *findVarFromVarSpaceByIndex(time33_t index, char *name, af_VarSpace *vs);
  15. /* 变量权限函数 */
  16. static bool checkVarReadPermissions(af_Var *var, af_Object *visitor, af_VarSpace *vs);
  17. static bool checkVarWritePermissions(af_Var *var, af_Object *visitor, af_VarSpace *vs);
  18. static af_VarNode *makeVarNode(af_Object *obj, char *id) {
  19. af_VarNode *vn = calloc(1, sizeof(af_VarNode));
  20. if (id != NULL)
  21. vn->id = strCopy(id);
  22. vn->obj = obj;
  23. return vn;
  24. }
  25. static af_VarNode *freeVarNode(af_VarNode *vn) {
  26. af_VarNode *next = vn->next;
  27. free(vn->id);
  28. free(vn);
  29. return next;
  30. }
  31. static void freeAllVarNode(af_VarNode *vn) {
  32. while (vn != NULL)
  33. vn = freeVarNode(vn);
  34. }
  35. af_Var *makeVar(char *name, char p_self, char p_posterity, char p_external, af_Object *obj, af_Environment *env){
  36. af_VarNode *vn = makeVarNode(obj, NULL);
  37. af_Var *var = calloc(1, sizeof(af_Var));
  38. var->name = strCopy(name);
  39. var->vn = vn;
  40. var->permissions[0] = p_self;
  41. var->permissions[1] = p_posterity;
  42. var->permissions[2] = p_external;
  43. gc_addVar(var, env);
  44. return var;
  45. }
  46. void freeVar(af_Var *var, af_Environment *env){
  47. freeAllVarNode(var->vn);
  48. free(var->name);
  49. GC_FREE_EXCHANGE(var, Var, env);
  50. free(var);
  51. }
  52. static af_VarNode *findVarNode_(af_Var *var, char *id) {
  53. af_VarNode *vn = var->vn->next;
  54. if (id == NULL)
  55. return var->vn;
  56. for (NULL; vn != NULL; vn = vn->next) {
  57. if (EQ_STR(vn->id, id))
  58. return vn;
  59. }
  60. return NULL;
  61. }
  62. void addVarNode(af_Var *var, af_Object *obj, char *id) {
  63. af_VarNode *vn = makeVarNode(obj, id);
  64. vn->next = var->vn->next; // 第一个 vn 必须表示返回值
  65. var->vn->next = vn;
  66. }
  67. af_Object *findVarNode(af_Var *var, char *id) {
  68. af_VarNode *vn = findVarNode_(var, id);
  69. if (vn != NULL)
  70. return vn->obj;
  71. return NULL;
  72. }
  73. static af_VarCup *makeVarCup(af_Var *var) {
  74. af_VarCup *vp = calloc(1, sizeof(af_VarCup));
  75. vp->var = var;
  76. return vp;
  77. }
  78. static af_VarCup *freeVarCup(af_VarCup *vp) {
  79. af_VarCup *next = vp->next;
  80. free(vp);
  81. return next;
  82. }
  83. static void freeAllVarCup(af_VarCup *vp) {
  84. while (vp != NULL)
  85. vp = freeVarCup(vp);
  86. }
  87. af_VarSpace *makeVarSpace(af_Object *belong, char p_self, char p_posterity, char p_external, af_Environment *env){
  88. if (env->status != core_creat && belong == NULL)
  89. return NULL;
  90. af_VarSpace *vs = calloc(1, sizeof(af_VarSpace));
  91. vs->belong = belong;
  92. vs->permissions[0] = p_self;
  93. vs->permissions[1] = p_posterity;
  94. vs->permissions[2] = p_external;
  95. gc_addVarSpace(vs, env);
  96. return vs;
  97. }
  98. void freeVarSpace(af_VarSpace *vs, af_Environment *env) {
  99. for (int i = 0; i < VAR_HASHTABLE_SIZE; i++)
  100. freeAllVarCup(vs->var[i]);
  101. GC_FREE_EXCHANGE(vs, VarSpace, env);
  102. free(vs);
  103. }
  104. af_VarSpaceListNode *makeVarSpaceList(af_VarSpace *vs) {
  105. af_VarSpaceListNode *vsl = calloc(1, sizeof(af_VarSpaceListNode));
  106. vsl->vs = vs;
  107. return vsl;
  108. }
  109. af_VarSpaceListNode *copyVarSpaceList(af_VarSpaceListNode *vsl) {
  110. af_VarSpaceListNode *base = NULL;
  111. af_VarSpaceListNode **pvsl = &base;
  112. for (NULL; vsl != NULL; vsl = vsl->next, pvsl = &((*pvsl)->next))
  113. *pvsl = makeVarSpaceList(vsl->vs);
  114. return base;
  115. }
  116. static af_VarSpaceListNode *freeVarSpaceList(af_VarSpaceListNode *vsl){
  117. af_VarSpaceListNode *next = vsl->next;
  118. free(vsl);
  119. return next;
  120. }
  121. void freeAllVarSpaceList(af_VarSpaceListNode *vsl){
  122. while (vsl != NULL)
  123. vsl = freeVarSpaceList(vsl);
  124. }
  125. af_VarSpace *getVarSpaceFromList(af_VarSpaceListNode *vsl) {
  126. if (vsl != NULL)
  127. return vsl->vs;
  128. return NULL;
  129. }
  130. bool freeVarSpaceListCount(size_t count, af_VarSpaceListNode *vsl) {
  131. for (size_t i = count; i > 0; i--) {
  132. if (vsl == NULL) // 发生了错误
  133. return false;
  134. vsl = freeVarSpaceList(vsl);
  135. }
  136. return true;
  137. }
  138. static bool checkVarSpaceDefinePermissions(af_Object *visitor, af_VarSpace *vs){
  139. char p = vs->permissions[2]; // 默认外部权限
  140. if (vs->belong == NULL || (visitor != NULL && vs->belong->data == visitor->data)) // (无权限设定或ObjectData匹配) 应用自身权限
  141. p = vs->permissions[0];
  142. else if (visitor != NULL && checkPosterity(vs->belong, visitor)) // 应用后代权限
  143. p = vs->permissions[1];
  144. return p == 2 || p == 3;
  145. }
  146. /*
  147. * 函数名: addVarToVarSpace
  148. * 目标: 把var添加到VarSpace中
  149. * 若空间被保护, 权限错误或已存在同名Var则返回false不作修改
  150. * 否则返回true
  151. */
  152. bool addVarToVarSpace(af_Var *var, af_Object *visitor, af_VarSpace *vs) {
  153. time33_t index = time33(var->name) % VAR_HASHTABLE_SIZE;
  154. af_VarCup **pCup = &vs->var[index];
  155. if (vs->is_protect)
  156. return false;
  157. if (!checkVarSpaceDefinePermissions(visitor, vs))
  158. return false;
  159. for (NULL; *pCup != NULL; pCup = &((*pCup)->next)) {
  160. if (EQ_STR((*pCup)->var->name, var->name))
  161. return false;
  162. }
  163. *pCup = makeVarCup(var);
  164. return true;
  165. }
  166. /*
  167. * 函数名: makeVarToVarSpace
  168. * 目标: 创建一个新的var添加到VarSpace中
  169. * 若已存在同名Var则返回false不作修改
  170. * 否则返回true
  171. * 调用 addVarToVarSpace
  172. */
  173. bool makeVarToVarSpace(char *name, char p_self, char p_posterity, char p_external, af_Object *obj, af_VarSpace *vs,
  174. af_Object *visitor, af_Environment *env){
  175. return addVarToVarSpace(makeVar(name, p_self, p_posterity, p_external, obj, env), visitor, vs);
  176. }
  177. /*
  178. * 函数名: makeVarToVarSpace
  179. * 目标: 添加一个Var到VarSpaceList
  180. * 自动跳过保护空间
  181. * 调用 addVarToVarSpace
  182. */
  183. bool addVarToVarSpaceList(af_Var *var, af_Object *visitor, af_VarSpaceListNode *vsl) {
  184. for (NULL; vsl != NULL; vsl = vsl->next) {
  185. if (!vsl->vs->is_protect)
  186. return addVarToVarSpace(var, visitor, vsl->vs);
  187. }
  188. return false;
  189. }
  190. /*
  191. * 函数名: makeVarToVarSpace
  192. * 目标: 创建一个新的var到VarSpaceList
  193. * 自动跳过保护空间
  194. * 调用 addVarToVarSpaceList -> addVarToVarSpace
  195. */
  196. bool makeVarToVarSpaceList(char *name, char p_self, char p_posterity, char p_external, af_Object *obj,
  197. af_VarSpaceListNode *vsl, af_Object *visitor, af_Environment *env){
  198. return addVarToVarSpaceList(makeVar(name, p_self, p_posterity, p_external, obj, env), visitor, vsl);
  199. }
  200. /*
  201. * 函数名: makeVarToProtectVarSpace
  202. * 目标: 创建一个新的var变量添加到保护空间中
  203. * 若已存在同名Var则返回false不作修改
  204. * 否则返回true
  205. * 调用 addVarToVarSpace
  206. */
  207. bool makeVarToProtectVarSpace(char *name, char p_self, char p_posterity, char p_external, af_Object *obj, af_Environment *env){
  208. env->protect->is_protect = false;
  209. bool re = addVarToVarSpace(makeVar(name, p_self, p_posterity, p_external, obj, env), env->activity->belong, env->protect);
  210. env->protect->is_protect = true;
  211. return re;
  212. }
  213. /*
  214. * 函数名: addVarToProtectVarSpace
  215. * 目标: 添加一个var变量添加到保护空间中
  216. * 若已存在同名Var则返回false不作修改
  217. * 否则返回true
  218. * 调用 addVarToVarSpace
  219. */
  220. bool addVarToProtectVarSpace(af_Var *var, af_Environment *env) {
  221. bool is_protect = env->protect->is_protect;
  222. env->protect->is_protect = false;
  223. bool re = addVarToVarSpace(var, NULL, env->protect);
  224. env->protect->is_protect = is_protect;
  225. return re;
  226. }
  227. static bool checkVarSpaceDelPermissions(af_Object *visitor, af_VarSpace *vs) {
  228. char p = vs->permissions[2]; // 默认外部权限
  229. if (vs->belong == NULL || (visitor != NULL && vs->belong->data == visitor->data)) // (无权限设定或ObjectData匹配) 应用自身权限
  230. p = vs->permissions[0];
  231. else if (visitor != NULL && checkPosterity(vs->belong, visitor)) // 应用后代权限
  232. p = vs->permissions[1];
  233. return p == 1 || p == 3;
  234. }
  235. /*
  236. * 函数名: delVarFromVarSpace
  237. * 目标: 从VarSpace中删除指定的变量
  238. * 若空间被保护, 权限错误或已存在同名Var则返回false不作修改
  239. * 否则返回true
  240. */
  241. bool delVarFromVarSpace(char *name, af_Object *visitor, af_VarSpace *vs) {
  242. time33_t index = time33(name) % VAR_HASHTABLE_SIZE;
  243. af_VarCup **pCup = &vs->var[index];
  244. if (vs->is_protect)
  245. return false;
  246. if (!checkVarSpaceDelPermissions(visitor, vs))
  247. return false;
  248. for (NULL; *pCup != NULL; pCup = &((*pCup)->next)) {
  249. if (EQ_STR((*pCup)->var->name, name)) {
  250. *pCup = freeVarCup(*pCup);
  251. return true;
  252. }
  253. }
  254. return false;
  255. }
  256. /*
  257. * 函数名: delVarFromVarList
  258. * 目标: 从VarSpaceList中第一层的VarSpace中删除指定的变量
  259. * 若空间被保护, 权限错误或已存在同名Var则返回false不作修改
  260. * 否则返回true
  261. * 调用delVarFromVarSpace
  262. */
  263. bool delVarFromVarList(char *name, af_Object *visitor, af_VarSpaceListNode *vsl) {
  264. return delVarFromVarSpace(name, visitor, vsl->vs);
  265. }
  266. /*
  267. * 函数名: findVarFromVarSpaceByIndex
  268. * 目标: 根据指定的index, 在VarSpace中搜索var
  269. * 权限检查交给 findVarFromVarSpace 和 findVarFromVarList
  270. */
  271. static af_Var *findVarFromVarSpaceByIndex(time33_t index, char *name, af_VarSpace *vs) {
  272. for (af_VarCup *cup = vs->var[index]; cup != NULL; cup = cup->next) {
  273. if (EQ_STR(cup->var->name, name))
  274. return cup->var;
  275. }
  276. return NULL;
  277. }
  278. static bool checkVarReadPermissions(af_Var *var, af_Object *visitor, af_VarSpace *vs){
  279. char p = var->permissions[2]; // 默认外部权限
  280. if (vs->belong == NULL || (visitor != NULL && vs->belong->data == visitor->data)) // (无权限设定或ObjectData匹配) 应用自身权限
  281. p = var->permissions[0];
  282. else if (visitor != NULL && checkPosterity(vs->belong, visitor)) // 应用后代权限
  283. p = var->permissions[1];
  284. return p == 1 || p == 3;
  285. }
  286. /*
  287. * 函数名: findVarFromVarSpace
  288. * 目标: 在VarSpace中搜索var
  289. * 调用: findVarFromVarSpaceByIndex
  290. */
  291. af_Var *findVarFromVarSpace(char *name, af_Object *visitor, af_VarSpace *vs){
  292. af_Var *var = findVarFromVarSpaceByIndex(time33(name) % VAR_HASHTABLE_SIZE, name, vs);
  293. if (var == NULL)
  294. return NULL;
  295. if (checkVarReadPermissions(var, visitor, vs))
  296. return var;
  297. return NULL;
  298. }
  299. /*
  300. * 函数名: findVarFromVarList
  301. * 目标: 在VarSpaceListNode中搜索var
  302. * 调用: findVarFromVarSpaceByIndex
  303. */
  304. af_Var *findVarFromVarList(char *name, af_Object *visitor, af_VarSpaceListNode *vsl) {
  305. time33_t index = time33(name) % VAR_HASHTABLE_SIZE;
  306. af_Var *var = NULL;
  307. for (NULL; vsl != NULL; vsl = vsl->next) {
  308. var = findVarFromVarSpaceByIndex(index, name, vsl->vs);
  309. if (var != NULL) {
  310. if (checkVarReadPermissions(var, visitor, vsl->vs))
  311. return var;
  312. return NULL;
  313. }
  314. }
  315. return NULL;
  316. }
  317. static bool checkVarWritePermissions(af_Var *var, af_Object *visitor, af_VarSpace *vs){
  318. char p = var->permissions[2]; // 默认外部权限
  319. if (vs->belong == NULL || (visitor != NULL && vs->belong->data == visitor->data)) // (无权限设定或ObjectData匹配) 应用自身权限
  320. p = var->permissions[0];
  321. else if (visitor != NULL && checkPosterity(vs->belong, visitor)) // 应用后代权限
  322. p = var->permissions[1];
  323. return p == 2 || p == 3;
  324. }
  325. /*
  326. * 函数名: setVarToVarSpace
  327. * 目标: 在VarSpace中搜索var并修改其值
  328. * 调用: findVarFromVarSpaceByIndex
  329. */
  330. bool setVarToVarSpace(char *name, af_Object *obj, af_Object *visitor, af_VarSpace *vs){
  331. af_Var *var = findVarFromVarSpaceByIndex(time33(name) % VAR_HASHTABLE_SIZE, name, vs);
  332. if (var == NULL)
  333. return false;
  334. if (checkVarWritePermissions(var, visitor, vs)) {
  335. var->vn->obj = obj;
  336. return true;
  337. }
  338. return false;
  339. }
  340. /*
  341. * 函数名: setVarToVarList
  342. * 目标: 在VarSpaceListNode中搜索var并修改其值
  343. * 调用: findVarFromVarSpaceByIndex
  344. */
  345. bool setVarToVarList(char *name, af_Object *obj, af_Object *visitor, af_VarSpaceListNode *vsl) {
  346. time33_t index = time33(name) % VAR_HASHTABLE_SIZE;
  347. af_Var *var = NULL;
  348. for (NULL; vsl != NULL; vsl = vsl->next) {
  349. var = findVarFromVarSpaceByIndex(index, name, vsl->vs);
  350. if (var != NULL) {
  351. if (checkVarWritePermissions(var, visitor, vsl->vs)) {
  352. var->vn->obj = obj;
  353. return true;
  354. }
  355. return false;
  356. }
  357. }
  358. return false;
  359. }
  360. af_VarSpaceListNode *pushNewVarList(af_Object *belong, af_VarSpaceListNode *base, af_Environment *env){
  361. af_VarSpaceListNode *new = makeVarSpaceList(makeVarSpace(belong, 3, 2, 0, env));
  362. new->next = base;
  363. return new;
  364. }
  365. void setVarPermissions(af_Var *var, af_Object *visitor, af_VarSpace *vs, char p_self, char p_posterity, char p_external) {
  366. if (vs->belong->data != visitor->data)
  367. return;
  368. var->permissions[0] = p_self;
  369. var->permissions[1] = p_posterity;
  370. var->permissions[2] = p_external;
  371. }
  372. void setVarSpacePermissions(af_Object *visitor, af_VarSpace *vs, char p_self, char p_posterity, char p_external) {
  373. if (vs->belong->data != visitor->data)
  374. return;
  375. vs->permissions[0] = p_self;
  376. vs->permissions[1] = p_posterity;
  377. vs->permissions[2] = p_external;
  378. }
  379. bool isProtectVarSpace(af_VarSpace *vs) {
  380. return vs->is_protect;
  381. }
  382. bool setVarSpaceProtect(af_Object *visitor, af_VarSpace *vs, char protect) {
  383. bool re = vs->is_protect;
  384. if (vs->belong->data != visitor->data)
  385. return re;
  386. vs->is_protect = protect;
  387. return re;
  388. }