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

  1. /*****************************************************
  2. file: NODE.CPP       Copyright 1989 by John M. Dlugosz
  3.    dealings with nodes
  4. *****************************************************/
  5.  
  6. #include "usual.hpp"
  7. #include <stream.hpp>
  8. #include <assert.h>
  9. #include <string.h>
  10. #include <stdlib.h>
  11. #include "atom.hpp"
  12. #include "node.hpp"
  13.  
  14. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  15.  
  16. node::node()
  17. {
  18. flavor= nf_base;
  19. }
  20.  
  21. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  22.  
  23. node::~node()
  24. {
  25. }
  26.  
  27. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  28.  
  29. void node::print()
  30. {
  31. cout << "\nerror: base class node printed.\n";
  32. }
  33.  
  34. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  35. /*   type_node                              */
  36. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  37.  
  38. type_node::type_node ()
  39. {
  40. flavor= nf_type;
  41. tag= -1;
  42. to_what= NULL;
  43. aggr= NULL;
  44. flags= 0;
  45. primary= -1;  //not filled in yet
  46. }
  47.  
  48. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  49.  
  50. void type_node::print()
  51. {
  52. static char* typenames[]= {
  53.    "void", //0
  54.    "char", //1
  55.    "int",  //2
  56.    "long", //3
  57.    "float",  //4
  58.    "double", //5
  59.    "long double", //6
  60.       "enum ",  //7
  61.       "class ", //8
  62.       "union ", //9
  63.    "pointer to ",  //10
  64.    "reference to ",//11
  65.    "array of ",    //12
  66.    "function ",    //13
  67.    };
  68.  
  69. if (isConst()) cout << "const ";
  70. if (isVol()) cout << "volotile ";
  71. if (isNear()) cout << "near ";
  72. if (isFar()) cout << "far ";
  73. if (primary < 10) {  // a simple type
  74.    if (isUnsigned()) cout << "unsigned ";
  75.    cout << typenames[primary];
  76.    if (primary >= 7) {
  77.       cout << (tag > -1 ? atoms[tag] : "<no name>");
  78.       cout.put (' ');
  79.       }
  80.    }
  81. else {  //something fancy
  82.    cout << typenames[primary];
  83.    if (primary == 12) {
  84.       // >> print array dimention
  85.       }
  86.    else if (primary == 13) {
  87.       cout.put('(');
  88.       int max= aggr->size();
  89.       for (int loop= 0;  loop < max;  loop++) {
  90.          (*aggr)[loop]->type->print();
  91.          if (loop < max-1) cout << ", ";
  92.          }
  93.       cout << ") returning ";
  94.       }
  95.    if (secondary()) to_what->print();
  96.    else cout << "**unknown type**";
  97.    }
  98. }
  99.  
  100. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  101.  
  102. void type_node::stuff_primary (int x, atom tagname)
  103. {
  104. /* given the 'x' parameter from the grammer production, stick the right
  105.    values into the 'primary' and set the 'unsigned' flag if needed. */
  106.  
  107. static int lookup[15]= { 0,  1,1,1,2,2,3,3,4,5,6,0,7,8,9};
  108. assert (x >= 0 && x < 15);
  109. primary= lookup[x];
  110. tag= tagname;  //harmless if not needed
  111. if (x == 3 || x==5) flags|=16;  //mark as unsigned
  112. }
  113.    
  114. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  115.  
  116. bool strappend (char*& dest, char* source, int& length)
  117. {
  118. int len= strlen(source);
  119. if (len > length) return FALSE;
  120. memcpy (dest, source, len);
  121. length -= len;
  122. dest+=len;
  123. return TRUE;
  124. }
  125.  
  126. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  127.  
  128. bool ins_number (int value, char*& buf, int& length)
  129. {
  130. itoa (value, buf, 10);
  131. int len= strlen(buf);
  132. if (length < len) return FALSE;
  133. length -= len;
  134. buf += len;
  135. return TRUE;
  136. }
  137.  
  138. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  139.  
  140. bool type_node::mangled_name (unsigned flags, char*& buf, int& length)
  141. {
  142. /* the mangled type name is placed in the buffer.  The length parameter is
  143.    the size of buf.  flags are: 1- supply function return value
  144.    This function places type information in the buffer after the base
  145.    name.  */
  146.  
  147. static char typenames[]= {
  148.    'v', //0
  149.    'c', //1
  150.    'i',  //2
  151.    'l', //3
  152.    'f',  //4
  153.    'd', //5
  154.    'r', //6
  155.       'i',  //7  enum is coded as an int
  156.    };
  157. /* 
  158.       'N', //8   followed by name
  159.       'N', //9   union?  same as class, I guess.
  160.    "pointer to ",  //10
  161.    "reference to ",//11
  162.    "array of ",    //12
  163.    "function ",    //13
  164.    };
  165. */
  166.  
  167. while (this) {
  168.    if (isConst()) {
  169.       *buf++ = 'C';
  170.       if (!--length) return FALSE; }
  171.    if (isVol()) {
  172.       *buf++ = 'V';
  173.       if (!--length) return FALSE; }
  174.    if (isUnsigned()) {
  175.       *buf++ = 'U';
  176.       if (!--length) return FALSE; }
  177.    switch (primary) {
  178.       case type_pointer:
  179.          *buf++ = (isNear() ? 'p' : 'P');
  180.          if (!--length) return FALSE;
  181.          break;
  182.       case type_reference:
  183.          *buf++ = 'R';
  184.          if (!--length) return FALSE;
  185.          break;
  186.       case type_array:
  187.          *buf++ = 'A';
  188.          if (!--length) return FALSE;
  189.          // > do array dimention
  190.          break;
  191.       case type_class:
  192.       case type_union:
  193.          if (tag > -1) {
  194.             ins_number (strlen(atoms[tag]), buf, length);
  195.             strappend (buf, atoms[tag], length);
  196.             }
  197.          break;
  198.       case type_function:
  199.          // >> different letters for different types.  use 'F' for now
  200.          *buf++ = 'F';
  201.          if (!--length) return FALSE;
  202.          for (int loop= 0; loop < aggr->size(); loop++) {
  203.             //append each parameter
  204.             (*aggr)[loop]->type->mangled_name (1, buf, length);
  205.             }
  206.          if (flags & 1) {  //append function return type
  207.             *buf++ = '_';
  208.             if (!--length) return FALSE;
  209.             }
  210.          else {  //stop here.
  211.             *buf= '\0';
  212.             return TRUE;
  213.             }
  214.       default: // a simple type
  215.          *buf++ = typenames[primary];
  216.          if (!--length) return FALSE;
  217.          break;
  218.       }
  219.    this= secondary();
  220.    }
  221. *buf= '\0';
  222. return TRUE;
  223. }
  224.  
  225. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  226. /*    def_node                              */
  227. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  228.  
  229. def_node::def_node (atom n, int store, type_node* t)
  230. {
  231. flavor= nf_def;
  232. name= n;
  233. storage_class= store;
  234. type=t;
  235. flags= 0;
  236. }
  237.  
  238. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  239.  
  240. void def_node::print()
  241. {
  242. static char* names[]= {"", "static ", "extern ", "typedef ", "auto ", "register ", "inline " };
  243. cout << names[storage_class] << atoms[name] << " is ";
  244. type->print();
  245. }
  246.  
  247. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  248.  
  249. char* def_node::mangled_name()
  250. {
  251. static char static_buffer[256];
  252. char* buf= static_buffer;
  253. int length= 256;
  254. strappend (buf, atoms[name], length);
  255. strappend (buf, "__", length);
  256. // >> append class name
  257. type->mangled_name (0, buf, length);
  258. return static_buffer;
  259. }
  260.  
  261. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  262. /*   node list                              */
  263. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  264.  
  265. node_list::node_list()
  266. {
  267. count= 0;
  268. list= malloc ((capacity=8) * sizeof (node*));
  269. }
  270.  
  271. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  272.  
  273. node** node_list::access (int x)
  274. {
  275. if (x >= capacity) {
  276.    capacity += capacity/2;
  277.    list= realloc (list, capacity * sizeof (node*));
  278.    }
  279. return list+x;
  280. }
  281.  
  282. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  283. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  284. /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
  285.  
  286.