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