list.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. #include <lib9.h>
  2. #include <bio.h>
  3. #include <ctype.h>
  4. #include "mach.h"
  5. #define Extern extern
  6. #include "acid.h"
  7. static List **tail;
  8. List*
  9. construct(Node *l)
  10. {
  11. List *lh, **save;
  12. save = tail;
  13. lh = 0;
  14. tail = &lh;
  15. build(l);
  16. tail = save;
  17. return lh;
  18. }
  19. int
  20. listlen(List *l)
  21. {
  22. int len;
  23. len = 0;
  24. while(l) {
  25. len++;
  26. l = l->next;
  27. }
  28. return len;
  29. }
  30. void
  31. build(Node *n)
  32. {
  33. List *l;
  34. Node res;
  35. if(n == 0)
  36. return;
  37. switch(n->op) {
  38. case OLIST:
  39. build(n->left);
  40. build(n->right);
  41. return;
  42. default:
  43. expr(n, &res);
  44. l = al(res.type);
  45. l->lstore = res.nstore;
  46. *tail = l;
  47. tail = &l->next;
  48. }
  49. }
  50. List*
  51. addlist(List *l, List *r)
  52. {
  53. List *f;
  54. if(l == 0)
  55. return r;
  56. for(f = l; f->next; f = f->next)
  57. ;
  58. f->next = r;
  59. return l;
  60. }
  61. void
  62. append(Node *r, Node *list, Node *val)
  63. {
  64. List *l, *f;
  65. l = al(val->type);
  66. l->lstore = val->nstore;
  67. l->next = 0;
  68. r->op = OCONST;
  69. r->type = TLIST;
  70. if(list->nstore.u0.sl == 0) {
  71. list->nstore.u0.sl = l;
  72. r->nstore.u0.sl = l;
  73. return;
  74. }
  75. for(f = list->nstore.u0.sl; f->next; f = f->next)
  76. ;
  77. f->next = l;
  78. r->nstore.u0.sl = list->nstore.u0.sl;
  79. }
  80. int
  81. listcmp(List *l, List *r)
  82. {
  83. if(l == r)
  84. return 1;
  85. while(l) {
  86. if(r == 0)
  87. return 0;
  88. if(l->type != r->type)
  89. return 0;
  90. switch(l->type) {
  91. case TINT:
  92. if(l->lstore.u0.sival != r->lstore.u0.sival)
  93. return 0;
  94. break;
  95. case TFLOAT:
  96. if(l->lstore.u0.sfval != r->lstore.u0.sfval)
  97. return 0;
  98. break;
  99. case TSTRING:
  100. if(scmp(l->lstore.u0.sstring, r->lstore.u0.sstring) == 0)
  101. return 0;
  102. break;
  103. case TLIST:
  104. if(listcmp(l->lstore.u0.sl, r->lstore.u0.sl) == 0)
  105. return 0;
  106. break;
  107. }
  108. l = l->next;
  109. r = r->next;
  110. }
  111. if(l != r)
  112. return 0;
  113. return 1;
  114. }
  115. void
  116. nthelem(List *l, int n, Node *res)
  117. {
  118. if(n < 0)
  119. error("negative index in []");
  120. while(l && n--)
  121. l = l->next;
  122. res->op = OCONST;
  123. if(l == 0) {
  124. res->type = TLIST;
  125. res->nstore.u0.sl = 0;
  126. return;
  127. }
  128. res->type = l->type;
  129. res->nstore = l->lstore;
  130. }
  131. void
  132. delete(List *l, int n, Node *res)
  133. {
  134. List **tl;
  135. if(n < 0)
  136. error("negative index in delete");
  137. res->op = OCONST;
  138. res->type = TLIST;
  139. res->nstore.u0.sl = l;
  140. for(tl = &res->nstore.u0.sl; l && n--; l = l->next)
  141. tl = &l->next;
  142. if(l == 0)
  143. error("element beyond end of list");
  144. *tl = l->next;
  145. }
  146. List*
  147. listvar(char *s, long v)
  148. {
  149. List *l, *tl;
  150. tl = al(TLIST);
  151. l = al(TSTRING);
  152. tl->lstore.u0.sl = l;
  153. l->lstore.fmt = 's';
  154. l->lstore.u0.sstring = strnode(s);
  155. l->next = al(TINT);
  156. l = l->next;
  157. l->lstore.fmt = 'X';
  158. l->lstore.u0.sival = v;
  159. return tl;
  160. }
  161. static List*
  162. listlocals(Map *map, Symbol *fn, ulong fp)
  163. {
  164. int i;
  165. uvlong val;
  166. Symbol s;
  167. List **tail, *l2;
  168. l2 = 0;
  169. tail = &l2;
  170. s = *fn;
  171. for(i = 0; localsym(&s, i); i++) {
  172. if(s.class != CAUTO)
  173. continue;
  174. if(s.name[0] == '.')
  175. continue;
  176. if(geta(map, fp-s.value, &val) > 0) {
  177. *tail = listvar(s.name, val);
  178. tail = &(*tail)->next;
  179. }
  180. }
  181. return l2;
  182. }
  183. static List*
  184. listparams(Map *map, Symbol *fn, ulong fp)
  185. {
  186. int i;
  187. Symbol s;
  188. uvlong v;
  189. List **tail, *l2;
  190. l2 = 0;
  191. tail = &l2;
  192. fp += mach->szaddr; /* skip saved pc */
  193. s = *fn;
  194. for(i = 0; localsym(&s, i); i++) {
  195. if (s.class != CPARAM)
  196. continue;
  197. if(geta(map, fp+s.value, &v) > 0) {
  198. *tail = listvar(s.name, v);
  199. tail = &(*tail)->next;
  200. }
  201. }
  202. return l2;
  203. }
  204. void
  205. trlist(Map *map, uvlong pc, uvlong sp, Symbol *sym)
  206. {
  207. List *q, *l;
  208. static List **tail;
  209. if (tracelist == 0) { /* first time */
  210. tracelist = al(TLIST);
  211. tail = &tracelist;
  212. }
  213. q = al(TLIST);
  214. *tail = q;
  215. tail = &q->next;
  216. l = al(TINT); /* Function address */
  217. q->lstore.u0.sl = l;
  218. l->lstore.u0.sival = sym->value;
  219. l->lstore.fmt = 'X';
  220. l->next = al(TINT); /* called from address */
  221. l = l->next;
  222. l->lstore.u0.sival = pc;
  223. l->lstore.fmt = 'X';
  224. l->next = al(TLIST); /* make list of params */
  225. l = l->next;
  226. l->lstore.u0.sl = listparams(map, sym, sp);
  227. l->next = al(TLIST); /* make list of locals */
  228. l = l->next;
  229. l->lstore.u0.sl = listlocals(map, sym, sp);
  230. }