home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.cs.arizona.edu
/
ftp.cs.arizona.edu.tar
/
ftp.cs.arizona.edu
/
icon
/
historic
/
v92.tgz
/
v92.tar
/
v92
/
src
/
rtt
/
rttnode.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-03-22
|
6KB
|
265 lines
#include "rtt.h"
/*
* node0 - create a syntax tree leaf node.
*/
struct node *node0(id, tok)
int id;
struct token *tok;
{
struct node *n;
n = NewNode(0);
n->nd_id = id;
n->tok = tok;
return n;
}
/*
* node1 - create a syntax tree node with one child.
*/
struct node *node1(id, tok, n1)
int id;
struct token *tok;
struct node *n1;
{
struct node *n;
n = NewNode(1);
n->nd_id = id;
n->tok = tok;
n->u[0].child = n1;
return n;
}
/*
* node2 - create a syntax tree node with two children.
*/
struct node *node2(id, tok, n1, n2)
int id;
struct token *tok;
struct node *n1;
struct node *n2;
{
struct node *n;
n = NewNode(2);
n->nd_id = id;
n->tok = tok;
n->u[0].child = n1;
n->u[1].child = n2;
return n;
}
/*
* node3 - create a syntax tree node with three children.
*/
struct node *node3(id, tok, n1, n2, n3)
int id;
struct token *tok;
struct node *n1;
struct node *n2;
struct node *n3;
{
struct node *n;
n = NewNode(3);
n->nd_id = id;
n->tok = tok;
n->u[0].child = n1;
n->u[1].child = n2;
n->u[2].child = n3;
return n;
}
/*
* node4 - create a syntax tree node with four children.
*/
struct node *node4(id, tok, n1, n2, n3, n4)
int id;
struct token *tok;
struct node *n1;
struct node *n2;
struct node *n3;
struct node *n4;
{
struct node *n;
n = NewNode(4);
n->nd_id = id;
n->tok = tok;
n->u[0].child = n1;
n->u[1].child = n2;
n->u[2].child = n3;
n->u[3].child = n4;
return n;
}
/*
* sym_node - create a syntax tree node for a variable. If the identifier
* is in the symbol table, create a node that references the entry,
* otherwise create a simple leaf node.
*/
struct node *sym_node(tok)
struct token *tok;
{
struct sym_entry *sym;
struct node *n;
sym = sym_lkup(tok->image);
if (sym != NULL) {
n = NewNode(1);
n->nd_id = SymNd;
n->tok = tok;
n->u[0].sym = sym;
++sym->ref_cnt;
/*
* If this is the result location of an operation, note that it
* is explicitly referenced.
*/
if (sym->id_type == RsltLoc)
sym->u.referenced = 1;
return n;
}
else
return node0(PrimryNd, tok);
}
/*
* comp_nd - create a node for a compound statement.
*/
struct node *comp_nd(tok, dcls, stmts)
struct token *tok;
struct node *dcls;
struct node *stmts;
{
struct node *n;
n = NewNode(3);
n->nd_id = CompNd;
n->tok = tok;
n->u[0].child = dcls;
n->u[1].sym = dcl_stk->tended; /* tended declarations are not in dcls */
n->u[2].child = stmts;
return n;
}
/*
* arith_nd - create a node for an arith_case statement.
*/
struct node *arith_nd(tok, p1, p2, c_int, ci_act, intgr, i_act, dbl, d_act)
struct token *tok;
struct node *p1;
struct node *p2;
struct node *c_int;
struct node *ci_act;
struct node *intgr;
struct node *i_act;
struct node *dbl;
struct node *d_act;
{
struct node *n;
/*
* Insure the cases are what we expect.
*/
if (c_int->tok->tok_id != C_Integer)
errt3(c_int->tok, "expected \"C_integer\", found \"", c_int->tok->image,
"\"");
if (intgr->tok->image != icontypes[int_typ].id)
errt3(intgr->tok, "expected \"integer\", found \"", intgr->tok->image,
"\"");
if (dbl->tok->tok_id != C_Double)
errt3(dbl->tok, "expected \"C_double\", found \"", dbl->tok->image,
"\"");
/*
* Indicate in the symbol table that the arguments are converted to C
* values.
*/
dst_alloc(c_int, p1);
dst_alloc(c_int, p2);
dst_alloc(dbl, p1);
dst_alloc(dbl, p2);
free_tree(c_int);
free_tree(intgr);
free_tree(dbl);
n = node3(TrnryNd, NULL, ci_act, i_act, d_act);
return node3(TrnryNd, tok, p1, p2, n);
}
struct node *dest_node(tok)
struct token *tok;
{
struct node *n;
int typcd;
n = sym_node(tok);
typcd = n->u[0].sym->u.typ_indx;
if (typcd != int_typ && typcd != str_typ && typcd != cset_typ &&
typcd != real_typ)
errt2(tok, "cannot convert to ", tok->image);
return n;
}
/*
* free_tree - free storage for a syntax tree.
*/
novalue free_tree(n)
struct node *n;
{
struct sym_entry *sym, *sym1;
if (n == NULL)
return;
/*
* Free any subtrees and other referenced storage.
*/
switch (n->nd_id) {
case SymNd:
free_sym(n->u[0].sym); /* Indicate one less reference to symbol */
break;
case CompNd:
/*
* Compound node. Free ordinary declarations, tended declarations,
* and executable code.
*/
free_tree(n->u[0].child);
sym = n->u[1].sym;
while (sym != NULL) {
sym1 = sym;
sym = sym->u.tnd_var.next;
free_sym(sym1);
}
free_tree(n->u[2].child);
break;
case QuadNd:
free_tree(n->u[3].child);
/* fall thru to next case */
case TrnryNd:
free_tree(n->u[2].child);
/* fall thru to next case */
case AbstrNd: case BinryNd: case CommaNd: case ConCatNd: case LstNd:
case StrDclNd:
free_tree(n->u[1].child);
/* fall thru to next case */
case IcnTypNd: case PstfxNd: case PreSpcNd: case PrefxNd:
free_tree(n->u[0].child);
/* fall thru to next case */
case ExactCnv: case PrimryNd:
break;
default:
fprintf(stdout, "rtt internal error: unknown node type\n");
exit(ErrorExit);
}
free_t(n->tok); /* free token */
free((char *)n);
}