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 (7185B)


      1 /*
      2 
      3 	    	C compiler, part 2
      4 
      5 	Copyright 1972 Bell Telephone Laboratories, Inc.
      6 
      7 */
      8 
      9 ospace() {}	/* fake */
     10 
     11 waste()		/* waste space */
     12 {
     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 	waste(waste(waste),waste(waste),waste(waste));
     20 	waste(waste(waste),waste(waste),waste(waste));
     21 }
     22 main(argc, argv)
     23 char argv[][];
     24 {
     25 	extern fout, fin, nerror, line;
     26 	extern getwrd, rcexpr, ospace, tmpfil;
     27 	extern cctab[], regtab[], efftab[], sptab[];
     28 	int sp[], c, table[], tabtab[3][], tree;
     29 
     30 	if (argc<4) {
     31 		error("Arg count");
     32 		exit(1);
     33 	}
     34 	if((fin=open(argv[1],0))<0) {
     35 		error("Cant't find %s", argv[1]);
     36 		exit(1);
     37 	}
     38 	if((fout=creat(argv[3],017))<0) {
     39 		error("Can't create %s", argv[3]);
     40 		exit(1);
     41 	}
     42 	tmpfil = argv[2];
     43 
     44 	tabtab[0] = regtab;
     45 	tabtab[1] = efftab;
     46 	tabtab[2] = cctab;
     47 	tabtab[3] = sptab;
     48 	while(c=getchar()) {
     49 		if(c=='#') {
     50 			sp = ospace;
     51 			c = getwrd();
     52 			tree = getwrd();
     53 			table = tabtab[getwrd()];
     54 			line = getwrd();
     55 			while(c--)
     56 				*sp++ = getwrd();
     57 			rcexpr(tree, table, 0);
     58 		} else
     59 			putchar(c);
     60 	}
     61 	flush();
     62 	exit(nerror!=0);
     63 }
     64 
     65 match(tree, table, nreg)
     66 int tree[], table[]; {
     67 	extern opdope[], dcalc, notcompat;
     68 	int op, d1, d2, t1, t2, p1[], p2[];
     69 	char mp[];
     70 
     71 	if (tree==0)
     72 		return(0);
     73 	op = *tree;
     74 	if (op>=29)			/* if not leaf */
     75 		p1 = tree[3];
     76 	else
     77 		p1 = tree;
     78 	t1 = p1[1];
     79 	d1 = dcalc(p1, nreg);
     80 	if ((opdope[op]&01)!=0) {	/* binary? */
     81 		p2 = tree[4];
     82 		t2 = p2[1];
     83 		d2 = dcalc(p2, nreg);
     84 	}
     85 	while(*table) {
     86 		if (*table++ == op) goto foundop;
     87 		table++;
     88 	}
     89 	return(0);
     90 foundop:
     91 	table = *table;
     92 nxtry:
     93 	mp = table;
     94 	if (*mp == 0)
     95 		return(0);
     96 	if (d1 > (*mp&077) | (*mp>=0100)&(*p1!=36))
     97 		goto notyet;
     98 	if (notcompat(t1, mp[1]))
     99 		goto notyet;
    100 	if ((opdope[op]&01)!=0 & p2!=0) {
    101 		if (d2 > (mp[2]&077) | (mp[2]>=0100)&(*p2!=36))
    102 			goto notyet;
    103 		if (notcompat(t2,mp[3]))
    104 			goto notyet;
    105 	}
    106 now:
    107 	return(table[2]);
    108 notyet:
    109 	table = table+3;
    110 	goto nxtry;
    111 }
    112 
    113 rcexpr(tree, table, reg)
    114 int tree[]; {
    115 	extern cexpr, regtab, cctab, sptab, printf, error;
    116 	extern jumpc, cbranch;
    117 
    118 	if(tree==0)
    119 		return;
    120 	if(*tree >= 103) {
    121 		(*tree==103?jumpc:cbranch)(tree[1],tree[2],tree[3],0);
    122 		return;
    123 	}
    124 	if (cexpr(tree, table, reg))
    125 		return;
    126 	if (table!=regtab) 
    127 		if(cexpr(tree, regtab, reg)) {
    128 			if (table==sptab)
    129 				printf("mov	r%d,-(sp)\n", reg);
    130 			if (table==cctab)
    131 				printf("tst	r%d\n", reg);
    132 			return;
    133 		}
    134 	error("No match for op %d", *tree);
    135 }
    136 
    137 cexpr(tree, table, reg)
    138 int tree[][], table[]; {
    139 	extern match, nreg, printf, pname, putchar, regtab;
    140 	extern sptab, cctab, rcexpr, prins, rlength, popstk;
    141 	extern collcon, isn, label, branch, cbranch, fltmod;
    142 	int p1[], p2[], c, r, p[], otable[], ctable[], regtab[], cctab[];
    143 	char string[], match[];
    144 
    145 	if ((c = *tree)==100) {		/* call */
    146 		p1 = tree[3];
    147 		p2 = tree[4];
    148 		r = 0;
    149 		if(p2) {
    150 			while (*p2==9) { /* comma */
    151 				rcexpr(p2[4], sptab, 0);
    152 				r =+ rlength((p=p2[4])[1]);
    153 				p2 = p2[3];
    154 			}
    155 			rcexpr(p2, sptab, 0);
    156 			r =+ rlength(p2[1]);
    157 		}
    158 		*tree = 101;
    159 		tree[2] = r;		/* save arg length */
    160 	}
    161 	if(c==90) {		/* ? */
    162 		cbranch(tree[3], c=isn++, 0, reg);
    163 		rcexpr(tree[4][3], table, reg);
    164 		branch(r=isn++, 0);
    165 		label(c);
    166 		rcexpr(tree[4][4], table, reg);
    167 		label(r);
    168 		return(1);
    169 	}
    170 	if ((string=match(tree, table, nreg-reg))==0) 
    171 		return(0);
    172 	p1 = tree[3];
    173 	p2 = tree[4];
    174 loop:
    175 	switch(c = *string++) {
    176 
    177 	case '\0':
    178 		p = tree;
    179 		if (*p==101 & p[2]>0) {
    180 			popstk(p[2]);
    181 		}
    182 		return(1);
    183 
    184 	/* A1 */
    185 	case 'A':
    186 		p = tree[3];
    187 		goto adr;
    188 
    189 	/* A2 */
    190 	case 'B':
    191 		p = tree[4];
    192 		goto adr;
    193 
    194 	/* A */
    195 	case 'O':
    196 		p = tree;
    197 	adr:
    198 		pname(p);
    199 		goto loop;
    200 
    201 	/* I */
    202 	case 'M':
    203 		if ((c = *string)=='\'')
    204 			string++; else
    205 			c = 0;
    206 		prins(*tree, c);
    207 		goto loop;
    208 
    209 	/* B1 */
    210 	case 'C':
    211 		p = tree[3];
    212 		goto pbyte;
    213 
    214 	/* BF */
    215 	case 'P':
    216 		p = tree;
    217 		goto pb1;
    218 
    219 	/* B2 */
    220 	case 'D':
    221 		p = tree[4];
    222 	pbyte:
    223 		if (p[1]==1)	/* char type? */
    224 			putchar('b');
    225 pb1:
    226 		if (isfloat(p))
    227 			putchar('f');
    228 		goto loop;
    229 
    230 	/* BE */
    231 	case 'L':
    232 		if (tree[3][1]==1 | tree[4][1]==1)
    233 			putchar('b');
    234 		goto loop;
    235 
    236 	/* C1 */
    237 	case 'E':
    238 		p = p1[3];
    239 		goto const;
    240 
    241 	/* C2 */
    242 	case 'F':
    243 		p = p2[3];
    244 	const:
    245 		printf("%o", p);
    246 		goto loop;
    247 
    248 	/* F */
    249 	case 'G':
    250 		p = p1;
    251 		goto subtre;
    252 
    253 	/* S */
    254 	case 'K':
    255 		p = p2;
    256 		goto subtre;
    257 
    258 	/* H */
    259 	case 'H':
    260 		p = tree;
    261 
    262 	subtre:
    263 		ctable = regtab;
    264 		r = reg;
    265 		c = *string++ - 'A';
    266 		if ((c&02)!=0)
    267 			ctable = sptab;
    268 		if ((c&04)!=0)
    269 			ctable = cctab;
    270 		if((c&010)!=0)
    271 			r = reg+1;
    272 		if((c&01)!=0)
    273 			if(*p==36) {
    274 				p = p[3];
    275 				if(collcon(p) & ctable!=sptab)
    276 					p = p[3];
    277 			}
    278 		rcexpr(p, ctable, r);
    279 		goto loop;
    280 
    281 	/* R */
    282 	case 'I':
    283 		r = reg;
    284 		goto preg;
    285 
    286 	/* R1 */
    287 	case 'J':
    288 		r = reg+1;
    289 	preg:
    290 		printf("r%d", r);
    291 		goto loop;
    292 
    293 	case '#':
    294 		p = p1[3];
    295 		goto nmbr;
    296 
    297 	case '"':
    298 		p = p2[3];
    299 		goto nmbr;
    300 	case '~':
    301 		p = tree[3];
    302 
    303 	nmbr:
    304 		if(collcon(p)) {
    305 			c = *p;
    306 			if(r = (p=p[4])[3])
    307 				printf("%o", c==40?r:-r);
    308 		}
    309 		goto loop;
    310 
    311 	/* M */
    312 	case 'N':
    313 		if ((c=isfloat(tree, &string))==fltmod)
    314 			goto loop;
    315 		printf((fltmod=c)==2?"setf\n":"setd\n");
    316 		goto loop;
    317 
    318 	/* Z */
    319 	case 'Z':
    320 		printf("$%o", p1[4]);
    321 		goto loop;
    322 	}
    323 	putchar(c);
    324 	goto loop;
    325 }
    326 
    327 pname(p)
    328 int p[][][]; {
    329 	extern putchar, printf, error;
    330 	char np[];
    331 	int i;
    332 
    333 loop:
    334 	switch(*p) {
    335 
    336 	case 21:		/* const */
    337 		printf("$%o", p[3]);
    338 		return;
    339 
    340 	case 22:		/* string */
    341 		printf("$l%d", p[3]);
    342 		return;
    343 
    344 	case 20:		/* name */
    345 		switch(p[3]) {
    346 
    347 		case 5:		/* auto, param */
    348 			printf("%o(r5)", p[4]);
    349 			return;
    350 
    351 		/* extern */
    352 		case 6:
    353 			printf("%p", &p[4]);
    354 			return;
    355 
    356 		}
    357 		printf("L%d", p[4]);
    358 		return;
    359 
    360 	case 35:		/* & */
    361 		putchar('$');
    362 		p = p[3];
    363 		goto loop;
    364 
    365 	case 36:		/* * */
    366 		putchar('*');
    367 		p = p[3];
    368 		goto loop;
    369 	}
    370 	error("pname called illegally");
    371 }
    372 
    373 dcalc(p, nreg)
    374 int p[]; {
    375 	int op, t;
    376 
    377 	if (p==0)
    378 		return(0);
    379 	op = *p;
    380 	switch (op) {
    381 
    382 	case 20:		/* name */
    383 	case 22:		/* string */
    384 	case 23:		/* float */
    385 	case 24:		/* double */
    386 		return(12);
    387 
    388 	case 21:		/* short constant */
    389 		return(p[3]==0? 4:8);
    390 
    391 	case 35:		/* & */
    392 		return(12);
    393 
    394 	case 36:		/* * */
    395 		if ((op=dcalc(p[3], nreg))<16)
    396 			return(16);
    397 	}
    398 
    399 def:
    400 	return(p[2]<=nreg? 20: 24);
    401 }
    402 
    403 notcompat(at, st) {
    404 
    405 	if (st==0)		/* word, byte */
    406 		return(at>1 & at<16);
    407 	if (st==1)		/* word */
    408 		return(at>0 & at<16);
    409 	st =- 2;
    410 	if (st==2 & at==3)
    411 		at = 2;
    412 	return(st != at);
    413 }
    414 
    415 prins(op, c) {
    416 	extern instab[], printf;
    417 	int insp[];
    418 
    419 	insp = instab;
    420 	while(*insp) {
    421 		if (*insp++ == op) {
    422 			if ((c = insp[c!=0])==0)
    423 				goto err;
    424 			printf("%s", c);
    425 			return;
    426 		} else
    427 			insp = insp + 2;
    428 	}
    429 err:
    430 	error("No match' for op %d", op);
    431 }
    432 
    433 collcon(p)
    434 int p[]; {
    435 	int p1[];
    436 
    437 	if(*p==40 | *p==41)
    438 		if(*(p1=p[4])==21)
    439 			return(1);
    440 	return(0);
    441 }
    442 
    443 isfloat(t, s)
    444 int t[];
    445 char s[][];
    446 {
    447 	extern opdope[];
    448 	int rt;
    449 
    450 	rt = **s - '0';
    451 	if (rt==2 | rt==4) {
    452 		(*s)++;
    453 		return(rt>2?3:2);
    454 	}
    455 	if ((opdope[t[0]]&010)!=0)	/* relational */
    456 		t = t[3];
    457 	if ((rt=t[1])>=2 & rt<=3)
    458 		return(rt);
    459 	return(0);
    460 }
    461 
    462 nreg 4;
    463 isn 10000;
    464 namsiz 8;
    465 line;
    466 tmpfil;
    467 nerror;
    468 fltmod;
    469