BSD 4 release
[unix-history] / usr / src / cmd / struct / tree.c
CommitLineData
aaa7ced1
BJ
1# include "y.tab.h"
2#include "b.h"
3#include <stdio.h>
4
5
6addroot(string,type,n1,n2)
7char *string;
8int type;
9struct node *n1, *n2;
10 {
11 struct node *p;
12 p = malloc(sizeof(*p));
13 p->left = n1;
14 p->right = n2;
15 p->op = type;
16 p->lit = malloc(slength(string) + 1);
17 str_copy(string,p->lit,slength(string) + 1);
18 return(p);
19 }
20
21
22freetree(tree)
23struct node *tree;
24 {
25 if (tree)
26 {freetree(tree->left);
27 freetree(tree->right);
28 freenode(tree);
29 }
30 }
31
32freenode(treenode)
33struct node *treenode;
34 {
35 free(treenode->lit);
36 free(treenode);
37 }
38
39int compop[] { '&', '|', '<', '>', xxeq, xxle, xxne, xxge};
40int notop[] { '|', '&', xxge, xxle, xxne, '>', xxeq, '<'};
41char *opstring[] { "||", "&&", ">=", "<=", "!=", ">", "==", "<"};
42
43checkneg(tree,neg) /* eliminate nots if possible */
44struct node *tree;
45int neg;
46 {
47 int i;
48 struct node *t;
49 if (!tree) return(0);
50 for (i = 0; i < 8; ++i)
51 if (tree->op == compop[i]) break;
52 if (i > 1 && i < 8 && tree ->left ->op == '-' && str_eq(tree->right->lit,"0"))
53 {
54 t = tree->right;
55 tree->right = tree->left->right;
56 freenode(t);
57 t = tree->left;
58 tree->left = tree->left->left;
59 freenode(t);
60 }
61
62
63 if (neg)
64 {
65 if (tree ->op == '!')
66 {
67 t = tree->left;
68 freenode(tree);
69 return(checkneg(t,0));
70 }
71 if (i < 8)
72 {
73 tree->op = notop[i];
74 free(tree->lit);
75 tree->lit = malloc(slength(opstring[i])+1);
76 str_copy(opstring[i],tree->lit, slength(opstring[i])+1);
77 if (tree->op == '&' || tree->op == '|')
78 {
79 tree->left = checkneg(tree->left,1);
80 tree->right = checkneg(tree->right,1);
81 }
82 return(tree);
83 }
84 if (tree->op == xxident && str_eq(tree->lit,".false."))
85 str_copy(".true.",tree->lit, slength(".true.")+1);
86 else if (tree->op == xxident && str_eq(tree->lit,".true."))
87 {
88 free(tree->lit);
89 tree->lit = malloc(slength(".false.")+1);
90 str_copy(".false.",tree->lit, slength(".false.")+1);
91 }
92 else
93 {
94 tree = addroot("!",'!',tree,0);
95 tree->lit = malloc(2);
96 str_copy("!",tree->lit, slength("!")+1);
97 }
98 return(tree);
99 }
100 else
101 if (tree->op == '!')
102 {
103 t = tree;
104 tree = tree->left;
105 freenode(t);
106 return(checkneg(tree,1));
107 }
108 else
109 {tree->left = checkneg(tree->left,0);
110 tree->right = checkneg(tree->right,0);
111 return(tree);
112 }
113 }
114
115yield(tree,fprec)
116struct node *tree;
117int fprec; /* fprec is precedence of father of this node */
118 {
119 int paren,p;
120 static int oplast; /* oplast = 1 iff last char printed was operator */
121 if (!tree) return;
122 p = prec(tree ->op);
123 paren = (p < fprec || (oplast && tree->op == xxuminus)) ? 1 : 0;
124
125 if (paren)
126 {
127 putout('(',"(");
128 oplast = 0;
129 }
130
131 switch(tree->op)
132 {
133 case xxuminus:
134 tree->op = '-';
135 case '!':
136 putout(tree->op,tree->lit);
137 oplast = 1;
138 yield(tree->left,p);
139 break;
140 case '&':
141 case '|':
142 case '<':
143 case '>':
144 case xxeq:
145 case xxle:
146 case xxge:
147 case '+':
148 case '-':
149 case '*':
150 case '/':
151 case '^':
152 yield(tree->left,p);
153 putout(tree->op, tree->lit);
154 oplast = 1;
155 yield(tree->right,p);
156 break;
157 case xxidpar:
158 yield(tree->left,0);
159 putout('(',"(");
160 oplast = 0;
161 yield(tree->right,0);
162 putout('(',")");
163 oplast = 0;
164 break;
165 default:
166 yield(tree->left,p);
167 putout(tree->op, tree->lit);
168 oplast = 0;
169 yield(tree->right,p);
170 break;
171 }
172 if (paren)
173 {
174 putout(')',")");
175 oplast = 0;
176 }
177 }
178
179puttree(tree)
180struct node *tree;
181 {
182 yield(tree,0);
183 freetree(tree);
184 }
185
186
187prec(oper)
188int oper;
189 {
190 switch(oper)
191 {
192 case ',': return(0);
193 case '|': return(1);
194 case '&': return(2);
195 case '!': return(3);
196
197 case '<': case '>': case xxeq:
198 case xxne: case xxle: case xxge:
199 return(4);
200 case '+':
201 case '-': return(5);
202 case '*':
203 case '/': return(6);
204 case xxuminus: return(7);
205 case '^': return(8);
206 default: return(9);
207 }
208 }
209str_copy(s,ptr,length) /* copy s at ptr, return length of s */
210char *s, *ptr;
211int length;
212 {int i;
213 for (i = 0; i < length; i++)
214 {
215 ptr[i] = s[i];
216 if (ptr[i] == '\0')
217 return(i + 1);
218 }
219 fprintf(2,"string %s too long to be copied by str_copy at address %d\n",
220 *s,ptr);
221 exit(1);
222 }
223str_eq(s,t)
224char s[],t[];
225 {int j;
226 for (j = 0; s[j] == t[j]; j++)
227 {if (s[j] == '\0') return(1);}
228 return(0);
229 }
230
231slength(s) /* return number of chars in s, not counting '\0' */
232char *s;
233 {
234 int i;
235 if (!s) return(-1);
236 for (i = 0; s[i] != '\0'; i++);
237 return(i);
238 }