plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

print.c (7127B)


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