Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <bio.h>
4
#include <ctype.h>
5
#include <mach.h>
6
#define Extern extern
7
#include "acid.h"
8
 
9
static char *binop[] =
10
{
11
	[OMUL]	"*",
12
	[ODIV]	"/",
13
	[OMOD]	"%",
14
	[OADD]	"+",
15
	[OSUB]	"-",
16
	[ORSH]	">>",
17
	[OLSH]	"<<",
18
	[OLT]	"<",
19
	[OGT]	">",
20
	[OLEQ]	"<=",
21
	[OGEQ]	">=",
22
	[OEQ]	"==",
23
	[ONEQ]	"!=",
24
	[OLAND]	"&",
25
	[OXOR]	"^",
26
	[OLOR]	"|",
27
	[OCAND]	"&&",
28
	[OCOR]	"||",
29
	[OASGN]	" = ",
30
};
31
 
32
static char *tabs = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
33
char *typenames[] =
34
{
35
	[TINT]		"integer",
36
	[TFLOAT]	"float",
37
	[TSTRING]	"string",
38
	[TLIST]		"list",
39
	[TCODE]		"code",
40
};
41
 
42
int
43
cmp(void *va, void *vb)
44
{
45
	char **a = va;
46
	char **b = vb;
47
 
48
	return strcmp(*a, *b);
49
}
50
 
51
void
52
fundefs(void)
53
{
54
	Lsym *l;
55
	char **vec;
56
	int i, j, n, max, col, f, g, s;
57
 
58
	max = 0;
59
	f = 0;
60
	g = 100;
61
	vec = malloc(sizeof(char*)*g);
62
	if(vec == 0)
63
		fatal("out of memory");
64
 
65
	for(i = 0; i < Hashsize; i++) {
66
		for(l = hash[i]; l; l = l->hash) {
67
			if(l->proc == 0 && l->builtin == 0)
68
				continue;
69
			n = strlen(l->name);
70
			if(n > max)
71
				max = n;
72
			if(f >= g) {
73
				g *= 2;
74
				vec = realloc(vec, sizeof(char*)*g);
75
				if(vec == 0)
76
					fatal("out of memory");
77
			}
78
			vec[f++] = l->name;
79
		}
80
	}
81
        qsort(vec, f, sizeof(char*), cmp);
82
	max++;
83
	col = 60/max;
84
	s = (f+col-1)/col;
85
 
86
	for(i = 0; i < s; i++) {
87
		for(j = i; j < f; j += s)
88
			Bprint(bout, "%-*s", max, vec[j]);
89
		Bprint(bout, "\n");
90
	}
91
}
92
 
93
void
94
whatis(Lsym *l)
95
{
96
	int t;
97
	int def;
98
	Type *ti;
99
 
100
	if(l == 0) {
101
		fundefs();
102
		return;
103
	}
104
 
105
	def = 0;
106
	if(l->v->set) {
107
		t = l->v->type;
108
		Bprint(bout, "%s variable", typenames[t]);
109
		if(t == TINT || t == TFLOAT)
110
			Bprint(bout, " format %c", l->v->fmt);
111
		if(l->v->comt)
112
			Bprint(bout, " complex %s", l->v->comt->base->name);
113
		Bputc(bout, '\n');
114
		def = 1;
115
	}
116
	if(l->lt) {
117
		Bprint(bout, "complex %s {\n", l->name);
118
		for(ti = l->lt; ti; ti = ti->next) {
119
			if(ti->type) {
120
				if(ti->fmt == 'a') {
121
					Bprint(bout, "\t%s %d %s;\n",
122
					ti->type->name, ti->offset,
123
					ti->tag->name);
124
				}
125
				else {
126
					Bprint(bout, "\t'%c' %s %d %s;\n",
127
					ti->fmt, ti->type->name, ti->offset,
128
					ti->tag->name);
129
				}
130
			}
131
			else
132
				Bprint(bout, "\t'%c' %d %s;\n",
133
				ti->fmt, ti->offset, ti->tag->name);
134
		}
135
		Bprint(bout, "};\n");
136
		def = 1;
137
	}
138
	if(l->proc) {
139
		Bprint(bout, "defn %s(", l->name);
140
		pexpr(l->proc->left);
141
		Bprint(bout, ") {\n");
142
		pcode(l->proc->right, 1);
143
		Bprint(bout, "}\n");
144
		def = 1;
145
	}
146
	if(l->builtin) {
147
		Bprint(bout, "builtin function\n");
148
		def = 1;
149
	}
150
	if(def == 0)
151
		Bprint(bout, "%s is undefined\n", l->name);
152
}
153
 
154
void
155
slist(Node *n, int d)
156
{
157
	if(n == 0)
158
		return;
159
	if(n->op == OLIST)
160
		Bprint(bout, "%.*s{\n", d-1, tabs);
161
	pcode(n, d);
162
	if(n->op == OLIST)
163
		Bprint(bout, "%.*s}\n", d-1, tabs);
164
}
165
 
166
void
167
pcode(Node *n, int d)
168
{
169
	Node *r, *l;
170
 
171
	if(n == 0)
172
		return;
173
 
174
	r = n->right;
175
	l = n->left;
176
 
177
	switch(n->op) {
178
	default:
179
		Bprint(bout, "%.*s", d, tabs);
180
		pexpr(n);
181
		Bprint(bout, ";\n");
182
		break;
183
	case OLIST:
184
		pcode(n->left, d);
185
		pcode(n->right, d);
186
		break;
187
	case OLOCAL:
188
		Bprint(bout, "%.*slocal", d, tabs);
189
		while(l) {
190
			Bprint(bout, " %s", l->sym->name);
191
			l = l->left;
192
			if(l == 0)
193
				Bprint(bout, ";\n");
194
			else
195
				Bprint(bout, ",");
196
		}
197
		break;
198
	case OCOMPLEX:
199
		Bprint(bout, "%.*scomplex %s %s;\n", d, tabs, n->sym->name, l->sym->name);
200
		break;
201
	case OIF:
202
		Bprint(bout, "%.*sif ", d, tabs);
203
		pexpr(l);
204
		d++;
205
		Bprint(bout, " then\n");
206
		if(r && r->op == OELSE) {
207
			slist(r->left, d);
208
			Bprint(bout, "%.*selse\n", d-1, tabs);
209
			slist(r->right, d);
210
		}
211
		else
212
			slist(r, d);
213
		break;
214
	case OWHILE:
215
		Bprint(bout, "%.*swhile ", d, tabs);
216
		pexpr(l);
217
		d++;
218
		Bprint(bout, " do\n");
219
		slist(r, d);
220
		break;
221
	case ORET:
222
		Bprint(bout, "%.*sreturn ", d, tabs);
223
		pexpr(l);
224
		Bprint(bout, ";\n");
225
		break;
226
	case ODO:
227
		Bprint(bout, "%.*sloop ", d, tabs);
228
		pexpr(l->left);
229
		Bprint(bout, ", ");
230
		pexpr(l->right);
231
		Bprint(bout, " do\n");
232
		slist(r, d+1);
233
	}
234
}
235
 
236
void
237
pexpr(Node *n)
238
{
239
	Node *r, *l;
240
 
241
	if(n == 0)
242
		return;
243
 
244
	r = n->right;
245
	l = n->left;
246
 
247
	switch(n->op) {
248
	case ONAME:
249
		Bprint(bout, "%s", n->sym->name);
250
		break;
251
	case OCONST:
252
		switch(n->type) {
253
		case TINT:
254
			Bprint(bout, "%lld", n->ival);
255
			break;
256
		case TFLOAT:
257
			Bprint(bout, "%g", n->fval);
258
			break;
259
		case TSTRING:
260
			pstr(n->string);
261
			break;
262
		case TLIST:
263
			break;
264
		}
265
		break;
266
	case OMUL:
267
	case ODIV:
268
	case OMOD:
269
	case OADD:
270
	case OSUB:
271
	case ORSH:
272
	case OLSH:
273
	case OLT:
274
	case OGT:
275
	case OLEQ:
276
	case OGEQ:
277
	case OEQ:
278
	case ONEQ:
279
	case OLAND:
280
	case OXOR:
281
	case OLOR:
282
	case OCAND:
283
	case OCOR:
284
		Bputc(bout, '(');
285
		pexpr(l);
286
		Bprint(bout, binop[n->op]);
287
		pexpr(r);
288
		Bputc(bout, ')');
289
		break;
290
	case OASGN:
291
		pexpr(l);
292
		Bprint(bout, binop[n->op]);
293
		pexpr(r);
294
		break;
295
	case OINDM:
296
		Bprint(bout, "*");
297
		pexpr(l);
298
		break;
299
	case OEDEC:
300
		Bprint(bout, "--");
301
		pexpr(l);
302
		break;
303
	case OEINC:
304
		Bprint(bout, "++");
305
		pexpr(l);
306
		break;
307
	case OPINC:
308
		pexpr(l);
309
		Bprint(bout, "++");
310
		break;
311
	case OPDEC:
312
		pexpr(l);
313
		Bprint(bout, "--");
314
		break;
315
	case ONOT:
316
		Bprint(bout, "!");
317
		pexpr(l);
318
		break;
319
	case OLIST:
320
		pexpr(l);
321
		if(r) {
322
			Bprint(bout, ",");
323
			pexpr(r);
324
		}
325
		break;
326
	case OCALL:
327
		pexpr(l);
328
		Bprint(bout, "(");
329
		pexpr(r);
330
		Bprint(bout, ")");
331
		break;
332
	case OCTRUCT:
333
		Bprint(bout, "{");
334
		pexpr(l);
335
		Bprint(bout, "}");
336
		break;
337
	case OHEAD:
338
		Bprint(bout, "head ");
339
		pexpr(l);
340
		break;
341
	case OTAIL:
342
		Bprint(bout, "tail ");
343
		pexpr(l);
344
		break;
345
	case OAPPEND:
346
		Bprint(bout, "append ");
347
		pexpr(l);
348
		Bprint(bout, ",");
349
		pexpr(r);
350
		break;
351
	case ODELETE:
352
		Bprint(bout, "delete ");
353
		pexpr(l);
354
		Bprint(bout, ",");
355
		pexpr(r);
356
		break;
357
	case ORET:
358
		Bprint(bout, "return ");
359
		pexpr(l);
360
		break;
361
	case OINDEX:
362
		pexpr(l);
363
		Bprint(bout, "[");
364
		pexpr(r);
365
		Bprint(bout, "]");
366
		break;
367
	case OINDC:
368
		Bprint(bout, "@");
369
		pexpr(l);
370
		break;
371
	case ODOT:
372
		pexpr(l);
373
		Bprint(bout, ".%s", n->sym->name);
374
		break;
375
	case OFRAME:
376
		Bprint(bout, "%s:%s", n->sym->name, l->sym->name);
377
		break;
378
	case OCAST:
379
		Bprint(bout, "(%s)", n->sym->name);
380
		pexpr(l);
381
		break;
382
	case OFMT:
383
		pexpr(l);
384
		Bprint(bout, "\\%c", (int)r->ival);
385
		break;
386
	case OEVAL:
387
		Bprint(bout, "eval ");
388
		pexpr(l);
389
		break;
390
	case OWHAT:
391
		Bprint(bout, "whatis");
392
		if(n->sym)
393
			Bprint(bout, " %s", n->sym->name);
394
		break;
395
	}
396
}
397
 
398
void
399
pstr(String *s)
400
{
401
	int i, c;
402
 
403
	Bputc(bout, '"');
404
	for(i = 0; i < s->len; i++) {
405
		c = s->string[i];
406
		switch(c) {
407
		case '\0':
408
			c = '0';
409
			break;
410
		case '\n':
411
			c = 'n';
412
			break;
413
		case '\r':
414
			c = 'r';
415
			break;
416
		case '\t':
417
			c = 't';
418
			break;
419
		case '\b':
420
			c = 'b';
421
			break;
422
		case '\f':
423
			c = 'f';
424
			break;
425
		case '\a':
426
			c = 'a';
427
			break;
428
		case '\v':
429
			c = 'v';
430
			break;
431
		case '\\':
432
			c = '\\';
433
			break;
434
		case '"':
435
			c = '"';
436
			break;
437
		default:
438
			Bputc(bout, c);
439
			continue;
440
		}
441
		Bputc(bout, '\\');
442
		Bputc(bout, c);
443
	}
444
	Bputc(bout, '"');
445
}