home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 June
/
SIMTEL_0692.cdr
/
msdos
/
microcrn
/
issue_40.arc
/
DAIMS.ARC
/
SYMCLASS.CPP
< prev
next >
Wrap
Text File
|
1988-02-10
|
3KB
|
149 lines
#undef TEST
#include <stream.h>
#include <string.h>
#include "matrix.hxx"
#include "strings.hxx"
#include "symclass.hxx"
/*
-*++ sym_tab::sym_tab(): constructor for a symbol table
**
** (*++ history:
** 7 Dec 87 Bruce Eckel Creation date
** ++*)
**
** (*++ detailed:
** ++*)
*/
sym_tab::sym_tab() {
for (int i = 0; i < TBLSZ; tb[i++] = 0)
;
};
/*
-*++ sym_tab::~sym_tab(): Destructor for a symbol table
**
** (*++ history:
** 7 Dec 87 Bruce Eckel Creation date
** ++*)
**
** (*++ detailed:
** ++*)
*/
sym_tab::~sym_tab() { /* destructor */
for (int i = 0; i < TBLSZ; i++)
for (name* n = tb[i]; n; ) {
name * nxt = n->next;
delete n->label;
delete n;
n = nxt;
}
}
/*
-*++ sym_tab::dump(): dump a symbol table to cout
**
** (*++ history:
** 7 Dec 87 Bruce Eckel Creation date
** ++*)
**
** (*++ detailed:
** ++*)
*/
void sym_tab::dump() {
for (int i = 0; i < TBLSZ; i++)
for (name* n=tb[i]; n; n=n->next) {
cout << n->label << ":\n";
switch (n->type) {
case INTEGER : cout << "INTEGER : " << n->value.intval << "\n"; break;
case DOUBLE : cout << "DOUBLE : " << n->value.doubleval << "\n"; break;
// case MATRIX : cout << "MATRIX :\n" << n->value.matptr << "\n"; break;
case KEYWORD : cout << "KEYWORD"; break;
default: cout << "UNKNOWN TYPE";
}
}
}
/*
-*++ sym_tab::look(): look up or insert table names
**
** (*++ history:
** 7 Dec 87 Bruce Eckel Creation date
** ++*)
**
** (*++ detailed:
** ins == 0 means look up name in table, return 0 if name not found,
** pointer to name structure containing the string if found
** ins != 0 means insert a new name or a new keyword
** ins == NEWNAME means insert new name in table
** ins == NEWKEYWORD means insert new keyword in table
** ++*)
*/
name* sym_tab::look(char* p, int ins = 0) {
int ii = 0;
char* pp = p;
while (*pp) ii = ii<<1 ^ *pp++; /* hash function */
if (ii < 0) ii = -ii;
ii %= TBLSZ;
for (name* n=tb[ii]; n; n=n->next) /* search */
if (strcmp(p,n->label) == 0) return n;
if (ins == 0) return (name *)0; /* string not found */
name* nn = new name; /* insert a new name */
nn->label = new char[strlen(p) + 1];
strcpy(nn->label,p);
nn->type = INTEGER; /* defaults to int */
nn->value.doubleval = 1;
nn->value.intval = 1;
nn->next = tb[ii];
tb[ii] = nn;
return nn;
}
/*
-*++ sym_tab::remove(): removes label but leaves links in place
**
** (*++ history:
** 7 Dec 87 Bruce Eckel Creation date
** ++*)
**
** (*++ detailed: removes label but leaves links in place. look() won't find
** the name, so if the user wants to try re-defining the variable, s/he can.
** To do this "neatly", the list would have to be doubly-linked.
** ++*)
*/
void sym_tab::remove(name * nn)
{
*(nn->label) = 0;
}
#ifdef TEST
main()
{
sym_tab table;
table.keyword("if");
table.keyword("then");
table.keyword("else");
table.insert("pi")->doubleval = 3.14159;
table.insert("e")->doubleval = 2.71828;
table.insert("hello");
table.look("hello")->doubleval = 7.14;
table.dump();
}
#endif