xref: /csrg-svn/usr.bin/pascal/pdx/tree/build.c (revision 5542)
1*5542Slinton /* Copyright (c) 1982 Regents of the University of California */
2*5542Slinton 
3*5542Slinton static char sccsid[] = "@(#)build.c 1.1 01/18/82";
4*5542Slinton 
5*5542Slinton /*
6*5542Slinton  * parse tree building routines
7*5542Slinton  *
8*5542Slinton  * Semantics is not checked here, this is done by the "treetype" routine
9*5542Slinton  * in the SYM directory which returns the type of the newly built tree.
10*5542Slinton  */
11*5542Slinton 
12*5542Slinton #include "defs.h"
13*5542Slinton #include "tree.h"
14*5542Slinton #include "sym.h"
15*5542Slinton #include "source.h"
16*5542Slinton #include "tree.rep"
17*5542Slinton 
18*5542Slinton /*
19*5542Slinton  * header for using routines with unknown number and types of arguments
20*5542Slinton  * I didn't like the looks of the standard varargs.h.
21*5542Slinton  */
22*5542Slinton 
23*5542Slinton typedef char *ARGLIST;
24*5542Slinton 
25*5542Slinton #define nextarg(arglist, type)	((type *) (arglist += sizeof(type)))[-1]
26*5542Slinton 
27*5542Slinton /*
28*5542Slinton  * build a tree
29*5542Slinton  */
30*5542Slinton 
31*5542Slinton /*VARARGS1*/
32*5542Slinton NODE *build(op, args)
33*5542Slinton OP op;
34*5542Slinton {
35*5542Slinton 	register NODE *p;
36*5542Slinton 	NODE *p1, *p2;
37*5542Slinton 	register ARGLIST ap;
38*5542Slinton 	SYM *s;
39*5542Slinton 
40*5542Slinton 	p = alloc(1, NODE);
41*5542Slinton 	p->op = op;
42*5542Slinton 	ap = (ARGLIST) &args;
43*5542Slinton 	switch(degree(op)) {
44*5542Slinton 		case BINARY:
45*5542Slinton 			p->left = p1 = nextarg(ap, NODE *);
46*5542Slinton 			p->right = p2 = nextarg(ap, NODE *);
47*5542Slinton 			break;
48*5542Slinton 
49*5542Slinton 		case UNARY:
50*5542Slinton 			p->left = p1 = nextarg(ap, NODE *);
51*5542Slinton 			p->right = NIL;
52*5542Slinton 			break;
53*5542Slinton 
54*5542Slinton 	}
55*5542Slinton 	switch(op) {
56*5542Slinton 		case O_NAME:
57*5542Slinton 		case O_WHICH:
58*5542Slinton 			p->nameval = nextarg(ap, SYM *);
59*5542Slinton 			break;
60*5542Slinton 
61*5542Slinton 		case O_LCON:
62*5542Slinton 			p->lconval = nextarg(ap, long);
63*5542Slinton 			break;
64*5542Slinton 
65*5542Slinton 		case O_FCON:
66*5542Slinton 			p->fconval = nextarg(ap, double);
67*5542Slinton 			break;
68*5542Slinton 
69*5542Slinton 		case O_SCON:
70*5542Slinton 			p->sconval = nextarg(ap, char *);
71*5542Slinton 			break;
72*5542Slinton 
73*5542Slinton 		case O_CALL:
74*5542Slinton 			p->left = nextarg(ap, NODE *);
75*5542Slinton 			p->right = nextarg(ap, NODE *);
76*5542Slinton 			break;
77*5542Slinton 
78*5542Slinton 		case O_CHFILE:
79*5542Slinton 			p->sconval = nextarg(ap, char *);
80*5542Slinton 			break;
81*5542Slinton 
82*5542Slinton 		case O_EDIT:
83*5542Slinton 			p->sconval = nextarg(ap, char *);
84*5542Slinton 			if (p->sconval == NIL) {
85*5542Slinton 				p->sconval = cursource;
86*5542Slinton 			}
87*5542Slinton 			break;
88*5542Slinton 
89*5542Slinton 		case O_SOURCE:
90*5542Slinton 			p->sconval = nextarg(ap, char *);
91*5542Slinton 			break;
92*5542Slinton 
93*5542Slinton 		case O_PRINT:
94*5542Slinton 		case O_WHATIS:
95*5542Slinton 		case O_LIST:
96*5542Slinton 		case O_XI:
97*5542Slinton 		case O_XD:
98*5542Slinton 			p->left = nextarg(ap, NODE *);
99*5542Slinton 			break;
100*5542Slinton 
101*5542Slinton 		case O_TRACE:
102*5542Slinton 		case O_TRACEI:
103*5542Slinton 		case O_STOP:
104*5542Slinton 		case O_STOPI:
105*5542Slinton 			p->what = nextarg(ap, NODE *);
106*5542Slinton 			p->where = nextarg(ap, NODE *);
107*5542Slinton 			p->cond = nextarg(ap, NODE *);
108*5542Slinton 			break;
109*5542Slinton 
110*5542Slinton 		case O_DELETE:
111*5542Slinton 			p->left = build(O_LCON, nextarg(ap, long));
112*5542Slinton 			break;
113*5542Slinton 
114*5542Slinton 		case O_QLINE: {
115*5542Slinton 			char *s;
116*5542Slinton 
117*5542Slinton 			s = nextarg(ap, char *);
118*5542Slinton 			p->left = alloc(1, NODE);
119*5542Slinton 			p->left->op = O_SCON;
120*5542Slinton 			if (s != cursource) {
121*5542Slinton 				p->left->sconval = s;
122*5542Slinton 				s[strlen(s) - 1] = '\0';
123*5542Slinton 			} else {
124*5542Slinton 				p->left->sconval = strdup(s);
125*5542Slinton 			}
126*5542Slinton 			p->right = nextarg(ap, NODE *);
127*5542Slinton 			break;
128*5542Slinton 		}
129*5542Slinton 
130*5542Slinton 		case O_ALIAS:
131*5542Slinton 			p->left = alloc(1, NODE);
132*5542Slinton 			p->left->op = O_SCON;
133*5542Slinton 			p->left->sconval = nextarg(ap, char *);
134*5542Slinton 			p->right = alloc(1, NODE);
135*5542Slinton 			p->right->op = O_SCON;
136*5542Slinton 			p->right->sconval = nextarg(ap, char *);
137*5542Slinton 			break;
138*5542Slinton 
139*5542Slinton 		default:
140*5542Slinton 			if (op < O_NOP || op > O_LASTOP) {
141*5542Slinton 				panic("build: bad op %d", op);
142*5542Slinton 			}
143*5542Slinton 			break;
144*5542Slinton 	}
145*5542Slinton 	p->nodetype = treetype(p, (ARGLIST) &args);
146*5542Slinton 	return(p);
147*5542Slinton }
148