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