legacy-cc

The earliest versions of the very first c compiler known to exist in the wild written by the late legend himself dmr. https://github.com/mortdeus/legacy-cc
git clone http://git.hanabi.in/repos/legacy-cc.git
Log | Files | Refs | README

c10.c (9261B)


      1 /*
      2 
      3 	    	C compiler, part 2
      4 
      5 	Copyright 1972 Bell Telephone Laboratories, Inc.
      6 
      7 */
      8 
      9 waste()		/* waste space */
     10 {
     11 	waste(waste(waste),waste(waste),waste(waste));
     12 	waste(waste(waste),waste(waste),waste(waste));
     13 	waste(waste(waste),waste(waste),waste(waste));
     14 	waste(waste(waste),waste(waste),waste(waste));
     15 	waste(waste(waste),waste(waste),waste(waste));
     16 	waste(waste(waste),waste(waste),waste(waste));
     17 	waste(waste(waste),waste(waste),waste(waste));
     18 	waste(waste(waste),waste(waste),waste(waste));
     19 }
     20 main(argc, argv)
     21 char argv[][];
     22 {
     23 	extern fout, fin, nerror, line;
     24 	extern getwrd, rcexpr, tmpfil;
     25 	extern cctab[], regtab[], efftab[], sptab[];
     26 	int sp[], c, table[], tabtab[3][], tree;
     27 
     28 	if (argc<4) {
     29 		error("Arg count");
     30 		exit(1);
     31 	}
     32 	if((fin=open(argv[1],0))<0) {
     33 		error("Cant't find %s", argv[1]);
     34 		exit(1);
     35 	}
     36 	if((fout=creat(argv[3],017))<0) {
     37 		error("Can't create %s", argv[3]);
     38 		exit(1);
     39 	}
     40 	tmpfil = argv[2];
     41 
     42 	tabtab[0] = regtab;
     43 	tabtab[1] = efftab;
     44 	tabtab[2] = cctab;
     45 	tabtab[3] = sptab;
     46 	while(c=getchar()) {
     47 		if(c=='#') {
     48 			sp = 0;
     49 			c = getwrd();
     50 			tree = getwrd();
     51 			table = tabtab[getwrd()];
     52 			line = getwrd();
     53 			while(c--)
     54 				*sp++ = getwrd();
     55 			rcexpr(tree, table, 0);
     56 		} else
     57 			putchar(c);
     58 	}
     59 	flush();
     60 	exit(nerror!=0);
     61 }
     62 
     63 match(tree, table, nreg)
     64 int tree[], table[]; {
     65 	extern opdope[], cctab, maprel;
     66 	int op, d1, d2, t1, t2, p1[], p2[], dope, cctab[];
     67 	int maprel[];
     68 	char mp[];
     69 
     70 	if (tree==0)
     71 		return(0);
     72 	op = *tree;
     73 	if (op>=29)			/* if not leaf */
     74 		p1 = tree[3];
     75 	else
     76 		p1 = tree;
     77 	t1 = p1[1];
     78 	d1 = dcalc(p1, nreg);
     79 	if (((dope=opdope[op])&01)!=0) {	/* binary? */
     80 		p2 = tree[4];
     81 		t2 = p2[1];
     82 		d2 = dcalc(p2, nreg);
     83 		if (d2>d1 & (dope&0100)!=0)	/* commute? */
     84 		    if (table!=cctab | (op!=47&op!=48)) { /* commute? */
     85 			if ((dope&04)!=0)	/* relation? */
     86 				*tree = op = maprel[op-60];
     87 			dope = t1;
     88 			t1 = t2;
     89 			t2 = dope;
     90 			dope = p1;
     91 			tree[3] = p1 = p2;
     92 			tree[4] = p2 = dope;
     93 			dope = d1;
     94 			d1 = d2;
     95 			d2 = dope;
     96 			dope = t1;
     97 			t1 = t2;
     98 			t2 = dope;
     99 		}
    100 	}
    101 	while(*table) {
    102 		if (*table++ == op) goto foundop;
    103 		table++;
    104 	}
    105 	return(0);
    106 foundop:
    107 	table = *table;
    108 nxtry:
    109 	mp = table;
    110 	if (*mp == 0)
    111 		return(0);
    112 	if (d1 > (*mp&077) | (*mp>=0100)&(*p1!=36))
    113 		goto notyet;
    114 	if (notcompat(t1, mp[1]))
    115 		goto notyet;
    116 	if ((opdope[op]&01)!=0 & p2!=0) {
    117 		if (d2 > (mp[2]&077) | (mp[2]>=0100)&(*p2!=36))
    118 			goto notyet;
    119 		if (notcompat(t2,mp[3]))
    120 			goto notyet;
    121 	}
    122 now:
    123 	return(table[2]);
    124 notyet:
    125 	table = table+3;
    126 	goto nxtry;
    127 }
    128 
    129 rcexpr(tree, table, reg)
    130 int tree[]; {
    131 	extern cexpr, regtab, cctab, sptab, printf, error;
    132 	extern jumpc, cbranch;
    133 	int r, modf;
    134 
    135 	if(tree==0)
    136 		return(0);
    137 	if(*tree == 103 | *tree==104) {
    138 		(*tree==103?jumpc:cbranch)(tree[1],tree[2],tree[3],0);
    139 		return(0);
    140 	}
    141 	modf = isfloat(tree)? 'f':0;
    142 	if (*tree == 110) {			/* force r0 */
    143 		if((r=rcexpr(tree[3], table, reg)) != 0)
    144 			printf("mov%c	r%d,r0\n", modf, r);
    145 		return(0);
    146 	}
    147 	if ((r=cexpr(tree, table, reg))>=0)
    148 		return(r);
    149 	if (table!=regtab) 
    150 		if((r=cexpr(tree, regtab, reg))>=0) {
    151 			if (table==sptab)
    152 				printf("mov%c	r%d,-(sp)\n", modf, r);
    153 			if (table==cctab) {
    154 				if (modf=='f')
    155 					printf("cfcc\n");
    156 				printf("tst%c	r%d\n", modf, r);
    157 			}
    158 			return(0);
    159 		}
    160 	error("No match for op %d", *tree);
    161 }
    162 
    163 cexpr(tree, table, reg)
    164 int tree[][], table[]; {
    165 	extern match, nreg, printf, pname, putchar, regtab;
    166 	extern sptab, cctab, rcexpr, prins, rlength, popstk;
    167 	extern collcon, isn, label, branch, cbranch;
    168 	extern maprel[];
    169 	int p1[], p2[], c, r, p[], otable[], ctable[], regtab[], cctab[];
    170 	int sptab[];
    171 	char string[], match[];
    172 	int reg1, rreg;
    173 
    174 	if ((c = *tree)==100) {		/* call */
    175 		p1 = tree[3];
    176 		p2 = tree[4];
    177 		r = 0;
    178 		if(*p2) {
    179 			while (*p2==9) { /* comma */
    180 				rcexpr(p2[4], sptab, 0);
    181 				r =+ arlength((p=p2[4])[1]);
    182 				p2 = p2[3];
    183 			}
    184 			rcexpr(p2, sptab, 0);
    185 			r =+ arlength(p2[1]);
    186 		}
    187 		*tree = 101;
    188 		tree[2] = r;		/* save arg length */
    189 	}
    190 	if(c==90) {		/* ? */
    191 		cbranch(tree[3], c=isn++, 0, reg);
    192 		rcexpr(tree[4][3], table, reg);
    193 		branch(r=isn++, 0);
    194 		label(c);
    195 		reg = rcexpr(tree[4][4], table, reg);
    196 		label(r);
    197 		goto retrn;
    198 	}
    199 	reg = oddreg(tree, reg);
    200 	reg1 = reg+1;
    201 	if ((string=match(tree, table, nreg-reg))==0) 
    202 		return(-1);
    203 	p1 = tree[3];
    204 	p2 = tree[4];
    205 loop:
    206 	switch(c = *string++) {
    207 
    208 	case '\0':
    209 		p = tree;
    210 		if (*p==101) {
    211 			if (p[2]>0)
    212 				popstk(p[2]);
    213 			reg = 0;
    214 		}
    215 retrn:
    216 		c = isfloat(tree);
    217 		if (table==cctab & c)
    218 			printf("cfcc\n");
    219 		if (!c)
    220 			if ((c = *tree)==43 | c==73)
    221 				reg--;
    222 		return(reg);
    223 
    224 	/* A1 */
    225 	case 'A':
    226 		p = tree[3];
    227 		goto adr;
    228 
    229 	/* A2 */
    230 	case 'B':
    231 		p = tree[4];
    232 		goto adr;
    233 
    234 	/* A */
    235 	case 'O':
    236 		p = tree;
    237 	adr:
    238 		pname(p);
    239 		goto loop;
    240 
    241 	/* I */
    242 	case 'M':
    243 		if ((c = *string)=='\'')
    244 			string++; else
    245 			c = 0;
    246 		prins(*tree, c);
    247 		goto loop;
    248 
    249 	/* B1 */
    250 	case 'C':
    251 		if ((c = *tree)<28)
    252 			p = tree;
    253 		else
    254 			p = tree[3];
    255 		goto pbyte;
    256 
    257 	/* BF */
    258 	case 'P':
    259 		p = tree;
    260 		goto pb1;
    261 
    262 	/* B2 */
    263 	case 'D':
    264 		p = tree[4];
    265 	pbyte:
    266 		if (p[1]==1)	/* char type? */
    267 			putchar('b');
    268 	pb1:
    269 		if (isfloat(p))
    270 			putchar('f');
    271 		goto loop;
    272 
    273 	/* BE */
    274 	case 'L':
    275 		if (tree[3][1]==1 | tree[4][1]==1)
    276 			putchar('b');
    277 		p = tree;
    278 		goto pb1;
    279 
    280 	/* C1 */
    281 	case 'E':
    282 		p = p1[3];
    283 		goto const;
    284 
    285 	/* C2 */
    286 	case 'F':
    287 		p = p2[3];
    288 	const:
    289 		printf("%o", p);
    290 		goto loop;
    291 
    292 	/* F */
    293 	case 'G':
    294 		p = p1;
    295 		goto subtre;
    296 
    297 	/* S */
    298 	case 'K':
    299 		p = p2;
    300 		goto subtre;
    301 
    302 	/* H */
    303 	case 'H':
    304 		p = tree;
    305 
    306 	subtre:
    307 		ctable = regtab;
    308 		r = reg;
    309 		c = *string++ - 'A';
    310 		if ((c&02)!=0)
    311 			ctable = sptab;
    312 		if ((c&04)!=0)
    313 			ctable = cctab;
    314 		if((c&010)!=0)
    315 			r = reg1;
    316 		if((c&01)!=0)
    317 			if(*p==36) {
    318 				p = p[3];
    319 				if(collcon(p) & ctable!=sptab)
    320 					p = p[3];
    321 			}
    322 		rreg = rcexpr(p, ctable, r);
    323 		if (rreg==r | ctable!=regtab)
    324 			goto loop;
    325 		if (string[-2]=='G')	/* left operand */
    326 			if (oddreg(tree, 0)==1) {
    327 				printf("mov	r%d,r%d\n", rreg, r);
    328 				goto loop;
    329 			}
    330 		if (r==reg) {
    331 			reg = rreg;
    332 			reg1 = rreg+1;
    333 		} else
    334 			reg1 = rreg;
    335 		goto loop;
    336 
    337 	/* R */
    338 	case 'I':
    339 		r = reg;
    340 		if (*string=='-') {
    341 			string++;
    342 			r--;
    343 		}
    344 		goto preg;
    345 
    346 	/* R1 */
    347 	case 'J':
    348 		r = reg1;
    349 	preg:
    350 		if (r>=5)
    351 			error("Register overflow: simplify expression");
    352 		printf("r%d", r);
    353 		goto loop;
    354 
    355 	case '#':
    356 		p = p1[3];
    357 		goto nmbr;
    358 
    359 	case '"':
    360 		p = p2[3];
    361 		goto nmbr;
    362 
    363 	case '~':
    364 		p = tree[3];
    365 
    366 	nmbr:
    367 		if(collcon(p)) {
    368 			if (*p==41)			/* - */
    369 				putchar('-');
    370 			switch (*(p = p[4])) {
    371 
    372 			case 21:		/* number */
    373 				if (p[3])
    374 					printf("%d.", p[3]);
    375 				break;
    376 
    377 			case 35:		/* & name */
    378 				pname(p[3]);
    379 				break;
    380 
    381 			}
    382 	}
    383 		goto loop;
    384 
    385 	/* V */
    386 	case 'V':
    387 		tree[0] = maprel[(c=tree[0])-60];
    388 		goto loop;
    389 
    390 	/* Z */
    391 	case 'Z':
    392 		printf("$%o", p1[5]+p1[4]);
    393 		goto loop;
    394 
    395 	case '^':		/* for ++ -- */
    396 		printf("%o", tree[4]);
    397 		goto loop;
    398 	}
    399 	putchar(c);
    400 	goto loop;
    401 }
    402 
    403 pname(p)
    404 int p[][]; {
    405 	char np[];
    406 	int i;
    407 
    408 loop:
    409 	switch(*p) {
    410 
    411 	case 21:		/* const */
    412 		printf("$%o", p[3]);
    413 		return;
    414 
    415 	case 23:		/* float const */
    416 		printf("L%d", p[3]);
    417 		return;
    418 
    419 	casename:
    420 	case 20:		/* name */
    421 		if (i=p[4])
    422 			printf("%d.+", i);
    423 		switch(p[3]) {
    424 
    425 		case 5:		/* auto, param */
    426 			printf("%d.(r5)", p[5]);
    427 			return;
    428 
    429 		/* extern */
    430 		case 6:
    431 			printf("%p", &p[5]);
    432 			return;
    433 
    434 		case 4:
    435 			error("Illegal structure reference");
    436 			printf("$0");
    437 			return;
    438 
    439 		}
    440 		printf("L%d", p[5]);
    441 		return;
    442 
    443 	case 35:		/* & */
    444 		putchar('$');
    445 		p = p[3];
    446 		goto loop;
    447 
    448 	case 36:		/* * */
    449 		putchar('*');
    450 		p = p[3];
    451 		goto loop;
    452 
    453 	}
    454 	error("pname called illegally");
    455 }
    456 
    457 dcalc(p, nreg)
    458 int p[]; {
    459 	int op, t, p1[], p2[];
    460 
    461 	if (p==0)
    462 		return(0);
    463 	op = *p;
    464 	switch (op) {
    465 
    466 	case 20:		/* name */
    467 	case 35:		/* & (non-automatic) */
    468 		return(12);
    469 
    470 	case 21:		/* short constant */
    471 		return(p[3]==0? 4:8);
    472 
    473 	case 23:		/* float const */
    474 		return(p[3]==0? 4:12);
    475 
    476 	case 36:		/* * */
    477 		p1 = p[3];
    478 		if (*p1==20)		/* name or offset name */
    479 			return(12);
    480 	}
    481 
    482 def:
    483 	return(p[2]<=nreg? 20: 24);
    484 }
    485 
    486 notcompat(at, st) {
    487 
    488 	if (st==0)		/* word, byte */
    489 		return(at>1 & at<=07);
    490 	if (st==1)		/* word */
    491 		return(at>0 & at<=07);
    492 	st =- 2;
    493 	if ((at&077740) != 0)
    494 		at = 020;		/* *int for **stuff */
    495 	if ((at&077770) != 0)
    496 		at = at&07 | 020;
    497 	if (st==2 & at==3)
    498 		at = 2;
    499 	return(st != at);
    500 }
    501 
    502 prins(op, c) {
    503 	extern instab[], printf;
    504 	int insp[];
    505 
    506 	insp = instab;
    507 	while(*insp) {
    508 		if (*insp++ == op) {
    509 			if ((c = insp[c!=0])==0)
    510 				goto err;
    511 			printf("%s", c);
    512 			return;
    513 		} else
    514 			insp = insp + 2;
    515 	}
    516 err:
    517 	error("No match' for op %d", op);
    518 }
    519 
    520 collcon(p)
    521 int p[]; {
    522 	int p1[], t[];
    523 
    524 	if(*p==40 | *p==41) {
    525 		if(*(p1=p[4])==21) {	/* number */
    526 			return(1);
    527 		}
    528 		if (*p1==35)
    529 			return(1);
    530 		if (*(p1=p[3])==35) {
    531 			p1 = p[3];
    532 			p[3] = p[4];
    533 			p[4] = p1;
    534 			return(1);
    535 		}
    536 	}
    537 	return(0);
    538 }
    539 
    540 isfloat(t)
    541 int t[];
    542 {
    543 	extern opdope[];
    544 	int rt;
    545 
    546 	if ((opdope[t[0]]&04)!=0)	/* relational */
    547 		t = t[3];
    548 	if ((rt=t[1])>=2 & rt<=3)
    549 		return(rt);
    550 	return(0);
    551 }
    552 
    553 nreg 3;
    554 isn 10000;
    555 namsiz 8;
    556 line;
    557 tmpfil;
    558 nerror;
    559 
    560 oddreg(t, reg)
    561 int t[];
    562 {
    563 	if (!isfloat(t))
    564 		switch(*t) {
    565 		case 43:	/* / */
    566 		case 44:	/* % */
    567 		case 73:	/* =/ */
    568 		case 74:	/* =% */
    569 			reg++;
    570 
    571 		case 42:	/* * */
    572 		case 72:	/* =* */
    573 			return(reg|1);
    574 		}
    575 	return(reg);
    576 }
    577 
    578 arlength(t)
    579 {
    580 	int arl;
    581 
    582 	if ((arl=rlength(t)) == 4)
    583 		return(8);
    584 	return(arl);
    585 }
    586 
    587 maprel[] 60, 61, 64, 65, 62, 63, 68, 69, 66, 67;
    588