📄 node.cpp
字号:
/*****************************************************
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;
}
/* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
/* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
/* /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -