home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c100 / 3.ddi / PARSE.ZIP / DEFINE.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1989-05-03  |  4.9 KB  |  205 lines

  1. /*****************************************************
  2. File: DEFINE.CPP     Copyright 1989 by John M. Dlugosz
  3.    deal with definitions once they are parsed
  4. *****************************************************/
  5.  
  6. #include "usual.hpp"
  7. #include <stream.hpp>
  8. #include "atom.hpp"
  9. #include "node.hpp"
  10. #include "define.hpp"
  11.  
  12. static type_node_list unnamed_types;
  13. local_type_list* named_type_list;
  14.  
  15. bool local_level= FALSE;
  16. unsigned memory_model= 0; //small model
  17.  
  18. def_node_list global_stuff;
  19. struct p_list_struct {
  20.    def_node_list* l;
  21.    p_list_struct* next;
  22.    };
  23. static p_list_struct *p_list;
  24. def_node_list* completed_def_list;
  25.  
  26. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  27.  
  28. local_type_list::local_type_list (local_type_list* old)
  29. {
  30. prev= old;
  31. }
  32.  
  33. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  34.  
  35. type_node* local_type_list::search (atom s)
  36. {
  37. while (this) {
  38.    for (int loop= 0;  loop < list.size();  loop++) {
  39.       type_node* p= list[loop];
  40.       if (p->tag == s) return p;
  41.       }
  42.    this= prev;  //try next outer scope
  43.    }
  44. return NULL;
  45. }
  46.  
  47. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  48.  
  49. bool local_type_list::add (type_node* n)
  50. {
  51. list.add (n);
  52. return TRUE;
  53. }
  54.  
  55. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  56. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  57.  
  58. bool types_match (type_node *a, type_node *b)
  59. {
  60. return (a->secondary() == b->secondary() &&
  61.         a->primary == b->primary &&
  62.         a->flags == b->flags);
  63. }
  64.  
  65. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  66.  
  67. static type_node* normalize_type (type_node* n)
  68. {
  69.  
  70. return n;  //short out for testing
  71.  
  72. if (n->secondary()) n->to_what= normalize_type (n->to_what);
  73. if (n->tag == -1) {  //unnamed type
  74.    if (n->aggr == NULL) {
  75.       // an unnamed class is always a unique type
  76.          for (int loop= 0;  loop < unnamed_types.size();  loop++) {
  77.             if (types_match (n, unnamed_types[loop])) {  //found it!
  78.                delete n;
  79.                return unnamed_types[loop];
  80.                }
  81.             }
  82.       // drop out of loop.  no match
  83.       unnamed_types.add (n);  //add to list
  84.    }
  85.    return n;
  86.    }
  87. else {  //type has a name.
  88.    return n;
  89.    }
  90. }
  91.  
  92. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  93.  
  94. static check_over (type_node* n)
  95. {
  96. while (n) {
  97.    type_node* p= n->secondary();
  98.    switch (n->primary) {
  99.       case type_pointer:
  100.       case type_reference:
  101.          if (!n->isNear() && !n->isFar()) {  //fill in default
  102.             if (p->primary == type_function)
  103.                n->flags |= (memory_model & 1) ? 8 : 4;
  104.             else //data pointer
  105.                n->flags |= (memory_model & 2) ? 8 : 4;
  106.             }
  107.          break;
  108.       }
  109.    n= p;
  110.    }
  111. }
  112.  
  113. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  114.  
  115. static void check_over_1 (def_node* n)
  116. {
  117. if (n->storage_class == 0) {
  118.    n->storage_class == (local_level) ? 4 /* auto */ : 2 /* extern */;
  119.    }
  120. }
  121.  
  122. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  123.  
  124. void store_thing (type_node* t, atom name, int storage_class, int param, bool isfriend, int protect_mode)
  125. {
  126. /* 'param' is passed through from the grammar.  If 1, this is a declaration
  127.    for a local or global object.  If 2, this is part of a parameter list */
  128. check_over (t);
  129. def_node* n= new def_node (name, storage_class, normalize_type(t));
  130.  
  131. // file it away somewhere
  132. switch (param) {
  133.    case 1:   // top level definition
  134.       if (name == -1) {
  135.          // >> I need to get a standard error reporter
  136.          cout << "abstract declarator ignored\n";
  137.          }
  138.       check_over_1 (n);
  139.       global_stuff.add (n);
  140.       break;
  141.    case 2:   // a parameter list
  142.       // >> check it over
  143.       p_list->l->add(n);
  144.       break;
  145.    case 3:  // a class definition list
  146.       if (isfriend) {
  147.          // >> do something with it
  148.          }
  149.       else {  //a member
  150.          // >> check it over
  151.          n->flags |= protect_mode;
  152.          p_list->l->add(n);
  153.          }
  154.       break;
  155.    }
  156. }
  157.  
  158. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  159.  
  160. void parameter_list (int x)
  161. {
  162. p_list_struct* p;
  163. if (x) {
  164.    p= new p_list_struct;
  165.    p->next= p_list;
  166.    p->l= new def_node_list;
  167.    p_list= p;
  168.    }
  169. else {
  170.    p= p_list;
  171.    p_list= p_list->next;
  172.    completed_def_list= p->l;
  173.    delete p;
  174.    }
  175. }
  176.  
  177. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  178. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  179. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  180.  
  181. void dump_types()
  182. {
  183. cout << "-----unnamed types-----\n";
  184. for (int loop= 0;  loop < unnamed_types.size();  loop++) {
  185.    unnamed_types[loop]->print();
  186.    cout.put ('\n');
  187.    }
  188. cout << "-----named types-----\n";
  189. for (loop= 0;  loop < named_type_list->list.size();  loop++) {
  190.    named_type_list->list[loop]->print();
  191.    cout.put ('\n');
  192.    }
  193.  
  194. }
  195.  
  196. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  197.  
  198. extern "C" void cpp_setup();
  199. void cpp_setup()
  200. {
  201. named_type_list= new local_type_list;
  202. }
  203.  
  204. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  205.