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