axe_labels.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /*
  2. * Andrea Di Biagio
  3. * Politecnico di Milano, 2007
  4. *
  5. * axe_labels.c
  6. * Formal Languages & Compilers Machine, 2007/2008
  7. *
  8. */
  9. #include "axe_errors.h"
  10. #include "axe_labels.h"
  11. #include "collections.h"
  12. struct t_axe_label_manager
  13. {
  14. t_list *labels;
  15. int current_label_ID;
  16. t_axe_label *label_to_assign;
  17. };
  18. int isAssignedLabel(t_axe_label_manager *lmanager)
  19. {
  20. /* preconditions: lmanager must be different from NULL */
  21. if (lmanager == NULL)
  22. notifyError(AXE_INVALID_LABEL_MANAGER);
  23. if ( (lmanager->label_to_assign != NULL)
  24. && ((lmanager->label_to_assign)->labelID != LABEL_UNSPECIFIED) )
  25. {
  26. return 1;
  27. }
  28. return 0;
  29. }
  30. int compareLabels(t_axe_label *labelA, t_axe_label *labelB)
  31. {
  32. if ( (labelA == NULL) || (labelB == NULL) )
  33. return 0;
  34. if (labelA->labelID == labelB->labelID)
  35. return 1;
  36. return 0;
  37. }
  38. /* reserve a new label identifier and return the identifier to the caller */
  39. t_axe_label * newLabelID(t_axe_label_manager *lmanager)
  40. {
  41. t_axe_label *result;
  42. /* preconditions: lmanager must be different from NULL */
  43. assert(lmanager != NULL);
  44. /* initialize a new label */
  45. result = alloc_label(lmanager->current_label_ID);
  46. /* update the value of `current_label_ID' */
  47. lmanager->current_label_ID++;
  48. /* tests if an out of memory occurred */
  49. if (result == NULL)
  50. return NULL;
  51. /* add the new label to the list of labels */
  52. lmanager->labels = addElement(lmanager->labels, result, -1);
  53. /* return the new label */
  54. return result;
  55. }
  56. /* assign the given label identifier to the next instruction. Returns
  57. * NULL if an error occurred; otherwise the assigned label */
  58. t_axe_label * assignLabelID(t_axe_label_manager *lmanager, t_axe_label *label)
  59. {
  60. /* precondition: lmanager must be different from NULL */
  61. assert(lmanager != NULL);
  62. /* precondition: label must be different from NULL and
  63. * must always carry a valid identifier */
  64. if ( (label == NULL)
  65. || (label->labelID == LABEL_UNSPECIFIED)
  66. || (label->labelID >= lmanager->current_label_ID))
  67. {
  68. notifyError(AXE_INVALID_LABEL);
  69. }
  70. /* test if the next instruction has already a label */
  71. if ( (lmanager->label_to_assign != NULL)
  72. && ((lmanager->label_to_assign)->labelID != LABEL_UNSPECIFIED) )
  73. {
  74. label->labelID = (lmanager->label_to_assign)->labelID;
  75. }
  76. else
  77. lmanager->label_to_assign = label;
  78. /* all went good */
  79. return label;
  80. }
  81. /* initialize the memory structures for the label manager */
  82. t_axe_label_manager * initialize_label_manager()
  83. {
  84. t_axe_label_manager *result;
  85. /* create an instance of `t_axe_label_manager' */
  86. result = (t_axe_label_manager *)
  87. _AXE_ALLOC_FUNCTION (sizeof(t_axe_label_manager));
  88. if (result == NULL)
  89. notifyError(AXE_OUT_OF_MEMORY);
  90. /* initialize the new instance */
  91. result->labels = NULL;
  92. result->current_label_ID = 0;
  93. result->label_to_assign = NULL;
  94. return result;
  95. }
  96. /* finalize an instance of `t_axe_label_manager' */
  97. void finalize_label_manager(t_axe_label_manager *lmanager)
  98. {
  99. t_list *current_element;
  100. t_axe_label *current_label;
  101. /* preconditions */
  102. if (lmanager == NULL)
  103. return;
  104. /* initialize `current_element' to the head of the list
  105. * of labels */
  106. current_element = lmanager->labels;
  107. while (current_element != NULL)
  108. {
  109. /* retrieve the current label */
  110. current_label = (t_axe_label *) LDATA(current_element);
  111. assert(current_label != NULL);
  112. /* free the memory associated with the current label */
  113. _AXE_FREE_FUNCTION(current_label);
  114. /* fetch the next label */
  115. current_element = LNEXT(current_element);
  116. }
  117. /* free the memory associated to the list of labels */
  118. freeList(lmanager->labels);
  119. _AXE_FREE_FUNCTION(lmanager);
  120. }
  121. t_axe_label * assign_label(t_axe_label_manager *lmanager)
  122. {
  123. t_axe_label *result;
  124. /* precondition: lmanager must be different from NULL */
  125. if (lmanager == NULL)
  126. notifyError(AXE_INVALID_LABEL_MANAGER);
  127. /* the label that must be returned (can be a NULL pointer) */
  128. result = lmanager->label_to_assign;
  129. /* update the value of `lmanager->label_to_assign' */
  130. lmanager->label_to_assign = NULL;
  131. /* return the label */
  132. return result;
  133. }
  134. int get_number_of_labels(t_axe_label_manager *lmanager)
  135. {
  136. if (lmanager == NULL)
  137. return 0;
  138. if (lmanager->labels == NULL)
  139. return 0;
  140. /* postconditions */
  141. return getLength(lmanager->labels);
  142. }