1 /*	File const.c: 2.1 (00/07/17,16:02:19) */
2 /*% cc -O -c %
3  *
4  */
5 
6 #include <stdio.h>
7 #include "defs.h"
8 #include "data.h"
9 #include "code.h"
10 #include "const.h"
11 #include "error.h"
12 #include "io.h"
13 #include "lex.h"
14 #include "primary.h"
15 #include "sym.h"
16 
17 /* protos */
18 void add_buffer (char *p, char c);
19 
20 
21 /*
22  *	setup a new const array
23  *
24  */
new_const(void)25 void new_const(void )
26 {
27 	const_ptr = &const_var[const_nb];
28 	const_val_idx  = const_val_start;
29 	const_data_idx = const_data_start;
30 }
31 
32 
33 /*
34  *	add a const array
35  *
36  */
add_const(int typ)37 void add_const(int typ)
38 {
39 	if((const_data_idx >= MAX_CONST_DATA) || (const_val_idx >= MAX_CONST_VALUE))
40 		error("too much constant data (> 8KB)");
41 	if (const_nb >= MAX_CONST)
42 		error("too much constant arrays");
43 	else {
44 		const_ptr->sym   = cptr;
45 		const_ptr->typ   = typ;
46 		const_ptr->size  = const_val_idx - const_val_start;
47 		const_ptr->data  = const_val_start;
48 		const_val_start  = const_val_idx;
49 		const_data_start = const_data_idx;
50 		const_nb++;
51 	}
52 }
53 
54 
55 /*
56  *	array initializer
57  *
58  */
array_initializer(int typ,int id,int stor)59 int array_initializer(int typ, int id, int stor)
60 {
61 	int nb;
62 	int k;
63 	int i;
64 
65 	nb = 0;
66 	k  = needsub ();
67 
68 	if (stor == CONST)
69 		new_const();
70 	if (match ("=")) {
71 		if (stor != CONST)
72 			error ("can't initialize non-const arrays");
73 		if(!match ("{")) {
74 			error ("syntax error");
75 			return (-1);
76 		}
77 		if(!match ("}")) {
78 			for (;;) {
79 				if (match ("}")) {
80 					error ("value missing");
81 					break;
82 				}
83 				if (match (",")) {
84 					error ("value missing");
85 					continue;
86 				}
87 				if ((ch() == '\"') && (id == POINTER))
88 					i = get_string_ptr(typ);
89 				else
90 					i = get_raw_value();
91 				nb++;
92 				blanks();
93 				if (const_val_idx < MAX_CONST_VALUE)
94 					const_val[const_val_idx++] = i;
95 				if ((ch() != ',') && (ch() != '}')) {
96 					error("syntax error");
97 					return (-1);
98 				}
99 				if (match ("}"))
100 					break;
101 				gch();
102 			}
103 		}
104 		if (k == 0)
105 			k = nb;
106 		if (nb > k) {
107 			nb = k;
108 			error ("excess elements in array initializer");
109 		}
110 	}
111 	if (stor == CONST) {
112 		while (nb < k) {
113 			nb++;
114 			if (const_val_idx < MAX_CONST_VALUE)
115 				const_val[const_val_idx++] = -1;
116 		}
117 	}
118 	return (k);
119 }
120 
121 
122 /*
123  *  add a string to the literal pool and return a pointer (index) to it
124  *
125  */
get_string_ptr(int typ)126 int get_string_ptr(int typ)
127 {
128 	int  num[1];
129 
130 	if (typ == CINT)
131 		error("incompatible pointer type");
132 	if (qstr(num))
133 		return (-(num[0] + 1024));
134 	else
135 		return (-1);
136 }
137 
138 
139 /*
140  *  get value raw text
141  *
142  */
get_raw_value(void)143 int get_raw_value(void )
144 {
145 	char  c;
146 	char  tmp[LINESIZE+1];
147 	char *ptr;
148 	int   level;
149 	int   flag;
150 	int   start;
151 
152 	flag  = 0;
153 	level = 0;
154 	start = const_data_idx;
155 	ptr   = tmp;
156 
157 	for (;;) {
158 		c = ch();
159 
160 		/* discard blanks */
161 		if ((c == ' ') || (c == '\t')) {
162 			gch();
163 			continue;
164 		}
165 		/* string */
166 		if (c == '\"') {
167 			for (;;) {
168 				gch();
169 
170 				/* add char */
171 				if (const_data_idx < MAX_CONST_DATA)
172 					const_data[const_data_idx++] = c;
173 
174 				/* next */
175 				c = ch();
176 
177 				if((c == 0) || (c == '\"'))
178 					break;
179 			}
180 		}
181 		/* paranthesis */
182 		if (c == '(')
183 			level++;
184 		else if (c == ')')
185 			level--;
186 		/* comma separator */
187 		else if (c == ',') {
188 			if (level == 0)
189 				break;
190 		}
191 		/* end */
192 		else if ((c == 0) || (c == '}')) {
193 			if (level)
194 				error("syntax error");
195 			break;
196 		}
197 
198 		/* parse */
199 		if (an(c)) {
200 			flag  = 1;
201 		   *ptr++ = c;
202 		}
203 		else {
204 			/* add buffer */
205 			if (flag) {
206 				flag = 0;
207 			   *ptr  = '\0';
208 				ptr  = tmp;
209 				add_buffer(tmp, c);
210 			}
211 
212 			/* add char */
213 			if (const_data_idx < MAX_CONST_DATA)
214 				const_data[const_data_idx++] = c;
215 		}
216 		gch();
217 	}
218 	/* add buffer */
219 	if (flag) {
220 	   *ptr = '\0';
221 		add_buffer(tmp, c);
222 	}
223 	/* close string */
224 	if (const_data_idx < MAX_CONST_DATA)
225 		const_data[const_data_idx++] = '\0';
226 
227 	return (start);
228 }
229 
230 
231 /*
232  *	add a string to the constant pool
233  *  handle underscore
234  *
235  */
add_buffer(char * p,char c)236 void add_buffer (char *p, char c)
237 {
238 	/* underscore */
239 	if (alpha(*p)) {
240 		if (c != '(') {
241 			if (const_data_idx < MAX_CONST_DATA)
242 				const_data[const_data_idx++] = '_';
243 		}
244 	}
245 
246 	/* string */
247 	while (*p) {
248 		if (const_data_idx < MAX_CONST_DATA)
249 			const_data[const_data_idx++] = *p;
250 		p++;
251 	}
252 }
253 
254 
255 /*
256  *	dump the constant pool
257  *
258  */
dump_const(void)259 void dump_const (void )
260 {
261 	int	i, j, k;
262 	int size;
263 /*	int c; */
264 
265 	if (const_nb) {
266 		const_ptr = const_var;
267 
268 		for (i = 0; i < const_nb; i++) {
269 			size = const_ptr->size;
270 			cptr = const_ptr->sym;
271 			cptr[STORAGE] = EXTERN;
272 			prefix ();
273 			outstr (cptr);
274 			outstr (":");
275 			nl();
276 			j = const_ptr->data;
277 
278 			while (size) {
279 				k = const_val[j++];
280 
281 				if (cptr[TYPE] == CCHAR) {
282 					defbyte ();
283 					const_size += 1;
284 				} else {
285 					defword ();
286 					const_size += 2;
287 				}
288 				if ((k == -1) || (k >= MAX_CONST_DATA))
289 					outstr("0");
290 				else if (k <= -1024) {
291 					k = (-k) - 1024;
292 					outlabel(litlab);
293 					outbyte('+');
294 					outdec(k);
295 				}
296 				else
297 					outstr(&const_data[k]);
298 				nl();
299 				size--;
300 			}
301 			const_ptr++;
302 		}
303 	}
304 }
305 
306