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*/
build(op,args)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