var.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. #include "__virtualmath.h"
  2. Var *makeVar(char *name, LinkValue *value){
  3. Var *tmp;
  4. tmp = memCalloc(1, sizeof(Var));
  5. tmp->name = memStrcpy(name, 0, false, false);
  6. tmp->value = value;
  7. tmp->next = NULL;
  8. return tmp;
  9. }
  10. Var *freeVar(Var *var, bool self){
  11. freeBase(var, return_);
  12. memFree(var->name);
  13. if (self){
  14. Var *next_var = var->next;
  15. memFree(var);
  16. return next_var;
  17. }
  18. return_:
  19. return var;
  20. }
  21. HashTable *makeHashTable(Inter *inter) {
  22. HashTable *tmp, *list_tmp = inter->hash_base;
  23. tmp = memCalloc(1, sizeof(Value));
  24. tmp->hashtable = (Var **)calloc(MAX_SIZE, sizeof(Var *));
  25. tmp->next = NULL;
  26. if (list_tmp == NULL){
  27. inter->hash_base = tmp;
  28. tmp->last = NULL;
  29. goto return_;
  30. }
  31. while (list_tmp->next != NULL){
  32. list_tmp = list_tmp->next;
  33. }
  34. list_tmp->next = tmp;
  35. tmp->last = list_tmp->next;
  36. return_:
  37. return tmp;
  38. }
  39. void freeHashTable(HashTable *ht, Inter *inter){
  40. freeBase(ht, return_);
  41. if (ht->last == NULL){
  42. inter->hash_base = ht->next;
  43. }
  44. else{
  45. ht->last->next = ht->next;
  46. }
  47. if (ht->next != NULL){
  48. ht->next->last = ht->last;
  49. }
  50. for (int i=0; i < MAX_SIZE; i++){
  51. Var *tmp = ht->hashtable[i];
  52. while (tmp != NULL){
  53. tmp = freeVar(tmp, true);
  54. }
  55. }
  56. memFree(ht->hashtable);
  57. memFree(ht);
  58. return_:
  59. return;
  60. }
  61. VarList *makeVarList(Inter *inter) {
  62. VarList *tmp = calloc(1, sizeof(VarList));
  63. tmp->next = NULL;
  64. tmp->hashtable = makeHashTable(inter);
  65. return tmp;
  66. }
  67. VarList *freeVarList(VarList *vl, bool self){
  68. freeBase(vl, return_);
  69. if (self){
  70. VarList *next_var = vl->next;
  71. memFree(vl);
  72. return next_var;
  73. }
  74. return_:
  75. return vl;
  76. }
  77. /**
  78. * hashTable使用time33算法
  79. * @param key
  80. * @return
  81. */
  82. HASH_INDEX time33(char *key){ // hash function
  83. HASH_INDEX hash = 5381;
  84. while(*key){
  85. hash += (hash << (HASH_INDEX)5) + (*key++);
  86. }
  87. return (hash & (HASH_INDEX)0x7FFFFFFF) % MAX_SIZE;
  88. }
  89. void addVar(char *name, LinkValue *value, VarList *var_list){
  90. HASH_INDEX index = time33(name);
  91. Var *base = var_list->hashtable->hashtable[index];
  92. if (base == NULL){
  93. var_list->hashtable->hashtable[index] = makeVar(name, value);
  94. goto return_;
  95. }
  96. while (true){
  97. if (base->next != NULL)
  98. goto new_one;
  99. if (eqString(base->name, name))
  100. goto change;
  101. base = base->next;
  102. }
  103. new_one:
  104. base->next = makeVar(name, value);
  105. goto return_;
  106. change:
  107. base->value = value;
  108. goto return_;
  109. return_:
  110. return;
  111. }
  112. LinkValue *findVar(char *name, VarList *var_list){
  113. LinkValue *tmp = NULL;
  114. HASH_INDEX index = time33(name);
  115. Var *base = var_list->hashtable->hashtable[index];
  116. if (base == NULL){
  117. goto return_;
  118. }
  119. while (base != NULL){
  120. if (eqString(base->name, name)){
  121. tmp = base->value;
  122. goto return_;
  123. }
  124. base = base->next;
  125. }
  126. return_:
  127. return tmp;
  128. }
  129. LinkValue *findFromVarList(char *name, VarList *var_list, NUMBER_TYPE times){
  130. LinkValue *tmp = NULL;
  131. for (NUMBER_TYPE i=0; i < times && var_list->next != NULL; i++){
  132. var_list = var_list->next;
  133. }
  134. while (var_list != NULL){
  135. tmp = findVar(name, var_list);
  136. if (tmp != NULL){
  137. goto return_;
  138. }
  139. var_list = var_list->next;
  140. }
  141. return_:
  142. return tmp;
  143. }
  144. void addFromVarList(char *name, VarList *var_list, NUMBER_TYPE times, LinkValue *value){
  145. for (NUMBER_TYPE i=0; i < times && var_list->next != NULL; i++){
  146. var_list = var_list->next;
  147. }
  148. addVar(name, value, var_list);
  149. }
  150. VarList *pushVarList(VarList *base, Inter *inter){
  151. VarList *new = makeVarList(inter);
  152. new->next = base;
  153. return new;
  154. }
  155. VarList *popVarList(VarList *base, Inter *inter){
  156. if (base->next == NULL)
  157. return base;
  158. return freeVarList(base, true);
  159. }
  160. VarList *copyVarListCore(VarList *base, Inter *inter){
  161. VarList *tmp = makeVarList(inter);
  162. tmp->hashtable = base->hashtable;
  163. return tmp;
  164. }
  165. VarList *copyVarList(VarList *base, bool n_new, Inter *inter){
  166. VarList *new, *tmp;
  167. new = tmp = copyVarListCore(base, inter);
  168. while (base->next != NULL){
  169. tmp->next = copyVarListCore(base->next, inter);
  170. tmp = tmp->next;
  171. base = base->next;
  172. }
  173. if (n_new)
  174. new = pushVarList(new, inter);
  175. return new;
  176. }