xref: /csrg-svn/usr.bin/pascal/pdx/tree/build.c (revision 22558)
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.1 (Berkeley) 06/06/85";
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 	NODE *p1, *p2;
42 	register ARGLIST ap;
43 	SYM *s;
44 
45 	p = alloc(1, NODE);
46 	p->op = op;
47 	ap = (ARGLIST) &args;
48 	switch(degree(op)) {
49 		case BINARY:
50 			p->left = p1 = nextarg(ap, NODE *);
51 			p->right = p2 = nextarg(ap, NODE *);
52 			break;
53 
54 		case UNARY:
55 			p->left = p1 = 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