home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************
- file: NODE.CPP Copyright 1989 by John M. Dlugosz
- dealings with nodes
- *****************************************************/
-
- #include "usual.hpp"
- #include <stream.hpp>
- #include <assert.h>
- #include <string.h>
- #include <stdlib.h>
- #include "atom.hpp"
- #include "node.hpp"
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- node::node()
- {
- flavor= nf_base;
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- node::~node()
- {
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- void node::print()
- {
- cout << "\nerror: base class node printed.\n";
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
- /* type_node */
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- type_node::type_node ()
- {
- flavor= nf_type;
- tag= -1;
- to_what= NULL;
- aggr= NULL;
- flags= 0;
- primary= -1; //not filled in yet
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- void type_node::print()
- {
- static char* typenames[]= {
- "void", //0
- "char", //1
- "int", //2
- "long", //3
- "float", //4
- "double", //5
- "long double", //6
- "enum ", //7
- "class ", //8
- "union ", //9
- "pointer to ", //10
- "reference to ",//11
- "array of ", //12
- "function ", //13
- };
-
- if (isConst()) cout << "const ";
- if (isVol()) cout << "volotile ";
- if (isNear()) cout << "near ";
- if (isFar()) cout << "far ";
- if (primary < 10) { // a simple type
- if (isUnsigned()) cout << "unsigned ";
- cout << typenames[primary];
- if (primary >= 7) {
- cout << (tag > -1 ? atoms[tag] : "<no name>");
- cout.put (' ');
- }
- }
- else { //something fancy
- cout << typenames[primary];
- if (primary == 12) {
- // >> print array dimention
- }
- else if (primary == 13) {
- cout.put('(');
- int max= aggr->size();
- for (int loop= 0; loop < max; loop++) {
- (*aggr)[loop]->type->print();
- if (loop < max-1) cout << ", ";
- }
- cout << ") returning ";
- }
- if (secondary()) to_what->print();
- else cout << "**unknown type**";
- }
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- void type_node::stuff_primary (int x, atom tagname)
- {
- /* given the 'x' parameter from the grammer production, stick the right
- values into the 'primary' and set the 'unsigned' flag if needed. */
-
- static int lookup[15]= { 0, 1,1,1,2,2,3,3,4,5,6,0,7,8,9};
- assert (x >= 0 && x < 15);
- primary= lookup[x];
- tag= tagname; //harmless if not needed
- if (x == 3 || x==5) flags|=16; //mark as unsigned
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- bool strappend (char*& dest, char* source, int& length)
- {
- int len= strlen(source);
- if (len > length) return FALSE;
- memcpy (dest, source, len);
- length -= len;
- dest+=len;
- return TRUE;
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- bool ins_number (int value, char*& buf, int& length)
- {
- itoa (value, buf, 10);
- int len= strlen(buf);
- if (length < len) return FALSE;
- length -= len;
- buf += len;
- return TRUE;
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- bool type_node::mangled_name (unsigned flags, char*& buf, int& length)
- {
- /* the mangled type name is placed in the buffer. The length parameter is
- the size of buf. flags are: 1- supply function return value
- This function places type information in the buffer after the base
- name. */
-
- static char typenames[]= {
- 'v', //0
- 'c', //1
- 'i', //2
- 'l', //3
- 'f', //4
- 'd', //5
- 'r', //6
- 'i', //7 enum is coded as an int
- };
- /*
- 'N', //8 followed by name
- 'N', //9 union? same as class, I guess.
- "pointer to ", //10
- "reference to ",//11
- "array of ", //12
- "function ", //13
- };
- */
-
- while (this) {
- if (isConst()) {
- *buf++ = 'C';
- if (!--length) return FALSE; }
- if (isVol()) {
- *buf++ = 'V';
- if (!--length) return FALSE; }
- if (isUnsigned()) {
- *buf++ = 'U';
- if (!--length) return FALSE; }
- switch (primary) {
- case type_pointer:
- *buf++ = (isNear() ? 'p' : 'P');
- if (!--length) return FALSE;
- break;
- case type_reference:
- *buf++ = 'R';
- if (!--length) return FALSE;
- break;
- case type_array:
- *buf++ = 'A';
- if (!--length) return FALSE;
- // > do array dimention
- break;
- case type_class:
- case type_union:
- if (tag > -1) {
- ins_number (strlen(atoms[tag]), buf, length);
- strappend (buf, atoms[tag], length);
- }
- break;
- case type_function:
- // >> different letters for different types. use 'F' for now
- *buf++ = 'F';
- if (!--length) return FALSE;
- for (int loop= 0; loop < aggr->size(); loop++) {
- //append each parameter
- (*aggr)[loop]->type->mangled_name (1, buf, length);
- }
- if (flags & 1) { //append function return type
- *buf++ = '_';
- if (!--length) return FALSE;
- }
- else { //stop here.
- *buf= '\0';
- return TRUE;
- }
- default: // a simple type
- *buf++ = typenames[primary];
- if (!--length) return FALSE;
- break;
- }
- this= secondary();
- }
- *buf= '\0';
- return TRUE;
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
- /* def_node */
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- def_node::def_node (atom n, int store, type_node* t)
- {
- flavor= nf_def;
- name= n;
- storage_class= store;
- type=t;
- flags= 0;
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- void def_node::print()
- {
- static char* names[]= {"", "static ", "extern ", "typedef ", "auto ", "register ", "inline " };
- cout << names[storage_class] << atoms[name] << " is ";
- type->print();
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- char* def_node::mangled_name()
- {
- static char static_buffer[256];
- char* buf= static_buffer;
- int length= 256;
- strappend (buf, atoms[name], length);
- strappend (buf, "__", length);
- // >> append class name
- type->mangled_name (0, buf, length);
- return static_buffer;
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
- /* node list */
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- node_list::node_list()
- {
- count= 0;
- list= malloc ((capacity=8) * sizeof (node*));
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
- node** node_list::access (int x)
- {
- if (x >= capacity) {
- capacity += capacity/2;
- list= realloc (list, capacity * sizeof (node*));
- }
- return list+x;
- }
-
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
- /* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
-
-