erplm.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. // memory allocation and freeing:
  2. // TODO improve memory usage tracing
  3. // TODO implement a garbage collector
  4. void* alloc_mem (int size) {
  5. void *ret = calloc(size, 4);
  6. if (!ret)
  7. _error("couldn't allocate memory");
  8. return ret;
  9. }
  10. void free_mem (void* pointer) {
  11. free(pointer);
  12. }
  13. // duplicating and freeing:
  14. Atom* duplicate_atom (Atom* at) {
  15. if (!at) return NULL;
  16. if (is_simple(at)) {
  17. if (at->type == SYMB)
  18. return create_symbol(duplicate_symbol(at->symb));
  19. return create_int(at->num);
  20. }
  21. Atom *na = create_atom(at->type);
  22. na->list = duplicate_list(at->list);
  23. return na;
  24. }
  25. List* duplicate_list (List* li) {
  26. if (!li) return NULL;
  27. List *nli = cons(NULL, NULL);
  28. List *np = nli;
  29. while (li) {
  30. if (li->head) np->head = duplicate_atom(li->head);
  31. if (li->tail) {
  32. np->tail = cons(NULL, NULL);
  33. np = np->tail;
  34. }
  35. li = li->tail;
  36. }
  37. return nli;
  38. }
  39. Table* duplicate_table (Table* ta) {
  40. if (!ta) return (Table*)_warning("DUPLICATE_TABLE" DUPLICATE_NULL);
  41. Table *nt = (Table*)ALLOC(sizeof(Table));
  42. Table *ntp = nt;
  43. while (ta) {
  44. ntp->key = duplicate_symbol(ta->key);
  45. ntp->value = duplicate_atom(ta->value);
  46. ntp->next = NULL;
  47. if (ta->next) {
  48. ntp->next = (Table*)ALLOC(sizeof(Table));
  49. ntp = ntp->next;
  50. }
  51. ta = ta->next;
  52. }
  53. return nt;
  54. }
  55. int* duplicate_symbol (int* symb) {
  56. if (symb == NULL)
  57. return NULL;
  58. int *ns = (int*)ALLOC(symb[0]+1);
  59. for (int a = 0; a <= symb[0]; a ++) {
  60. ns[a] = symb[a];
  61. }
  62. return ns;
  63. }
  64. void free_atom (Atom* at) {
  65. if (!at)
  66. return;
  67. if (is_simple(at)) {
  68. if (at->type == SYMB) FREE(at->symb);
  69. } else {
  70. free_list(at->list);
  71. }
  72. FREE(at);
  73. }
  74. void free_list (List* li) {
  75. if (!li) return;
  76. if (li->head) free_atom(li->head);
  77. if (li->tail)
  78. free_list(li->tail);
  79. FREE(li);
  80. }
  81. void free_table (Table* ta) {
  82. if (!ta) {
  83. _warning("FREE_TABLE" FREE_NULL);
  84. return;
  85. }
  86. FREE(ta->key);
  87. if (ta->value)
  88. free_atom(ta->value);
  89. if (ta->next)
  90. free_table(ta->next);
  91. FREE(ta);
  92. }
  93. // creating objects:
  94. List* cons (Atom* he, List* ta) {
  95. List *nl = (List*)ALLOC(sizeof(List));
  96. nl->head = he;
  97. nl->tail = ta;
  98. return nl;
  99. }
  100. Atom* create_atom (Type _type) {
  101. Atom *at = (Atom*)ALLOC(sizeof(Atom));
  102. at->type = _type;
  103. return at;
  104. }
  105. Atom* create_int (int in) {
  106. Atom *at = create_atom(NUM);
  107. at->num = in;
  108. return at;
  109. }
  110. Atom* create_symbol (int* symb) {
  111. Atom *at = create_atom(SYMB);
  112. at->symb = symb;
  113. return at;
  114. }
  115. Atom* create_list (List* li) {
  116. if (li == NULL)
  117. return NULL;
  118. Atom *at = create_atom(LIST);
  119. at->list = li;
  120. return at;
  121. }
  122. Atom* create_lambda (List* la) {
  123. if (la == NULL)
  124. return NULL;
  125. Atom *at = create_atom(LAMBDA);
  126. at->list = la;
  127. return at;
  128. }