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

c02.c (8422B)


      1 extdef() {
      2 	extern eof, cval, defsym;
      3 	extern csym, strflg, xdflg, peeksym, fcval;
      4 	int o, c, cs[], type, csym[], width, nel, ninit, defsym[];
      5 	char s[];
      6 	float sf;
      7 	double fcval;
      8 
      9 	if(((o=symbol())==0) | o==1)	/* EOF */
     10 		return;
     11 	type = 0;
     12 	if (o==19) {			/* keyword */
     13 		if ((type=cval)>4)
     14 			goto syntax;	/* not type */
     15 	} else {
     16 		if (o==20)
     17 			csym[4] =| 0200;	/* remember name */
     18 		peeksym = o;
     19 	}
     20 	defsym = 0;
     21 	xdflg++;
     22 	tdeclare(type, 0, 0);
     23 	if (defsym==0)
     24 		return;
     25 	*defsym = 6;
     26 	cs = &defsym[4];
     27 	printf(".globl	%p\n", cs);
     28 	strflg = 1;
     29 	xdflg = 0;
     30 	type = defsym[1];
     31 	if ((type&030)==020) {		/* a function */
     32 		printf(".text\n%p:\nmov r5,-(sp); mov sp,r5\n", cs);
     33 		declist(0);
     34 		strflg = 0;
     35 		c = 0;
     36 		if ((peeksym=symbol())!=2) {	/* { */
     37 			blkhed();
     38 			c++;
     39 		}
     40 		statement(1);
     41 		retseq();
     42 		if (c)
     43 			blkend();
     44 		return;
     45 	}
     46 	width = length(defsym);
     47 	if ((type&030)==030)	/* array */
     48 		width = plength(defsym);
     49 	nel = defsym[8];
     50 	ninit = 0;
     51 	if ((peeksym=symbol()) == 1) {	/* ; */
     52 		printf(".comm	%p,%o\n", &defsym[4], nel*width);
     53 		peeksym = -1;
     54 		return;
     55 	}
     56 	printf(".data\n%p:", &defsym[4]);
     57 loop:	{
     58 		ninit++;
     59 		switch(o=symbol()) {
     60 	
     61 		case 22:			/* string */
     62 			if (width!=2)
     63 				bxdec();
     64 			printf("L%d\n", cval);
     65 			break;
     66 	
     67 		case 41:			/* - const */
     68 			if ((o=symbol())==23) {	/* float */
     69 				fcval = -fcval;
     70 				goto case23;
     71 			}
     72 			if (o!=21)
     73 				goto syntax;
     74 			cval = -cval;
     75 	
     76 		case 21:			/* const */
     77 			if (width==1)
     78 				printf(".byte ");
     79 			if (width>2) {
     80 				fcval = cval;
     81 				goto case23;
     82 			}
     83 			printf("%o\n", cval);
     84 			break;
     85 	
     86 		case 20:			/* name */
     87 			if (width!=2)
     88 				bxdec();
     89 			printf("%p\n", &csym[4]);
     90 			break;
     91 	
     92 		case 23:
     93 		case23:
     94 			if (width==4) {
     95 				sf = fcval;
     96 				printf("%o;%o\n", sf);
     97 				break;
     98 			}
     99 			if (width==8) {
    100 				printf("%o;%o;%o;%o\n", fcval);
    101 				break;
    102 			}
    103 			bxdec();
    104 			break;
    105 	
    106 		default:
    107 			goto syntax;
    108 	
    109 		}
    110 	} if ((o=symbol())==9) goto loop;	/* , */
    111 	if (o==1) {			/* ; */
    112 	done:
    113 		if (ninit<nel)
    114 			printf(".=.+%d.\n", (nel-ninit)*width);
    115 		return;
    116 	}
    117 syntax:
    118 	error("External definition syntax");
    119 	errflush(o);
    120 	statement(0);
    121 }
    122 
    123 bxdec()
    124 {
    125 	error("Inconsistent external initialization");
    126 }
    127 
    128 statement(d) {
    129 	extern symbol, error, blkhed, eof, peeksym;
    130 	extern blkend, csym[], rcexpr, block[], tree[], regtab[];
    131 	extern retseq, jumpc, jump, label, contlab, brklab, cval;
    132 	extern swp[], isn, pswitch, peekc;
    133 	extern efftab[], deflab, errflush, swtab[], swsiz, branch;
    134 
    135 	int o, o1, o2, o3, np[];
    136 
    137 stmt:
    138 	switch(o=symbol()) {
    139 
    140 	/* EOF */
    141 	case 0:
    142 		error("Unexpected EOF");
    143 	/* ; */
    144 	case 1:
    145 	/* } */
    146 	case 3:
    147 		return;
    148 
    149 	/* { */
    150 	case 2: {
    151 		if(d)
    152 			blkhed();
    153 		while (!eof) {
    154 			if ((o=symbol())==3)	/* } */
    155 				goto bend;
    156 			peeksym = o;
    157 			statement(0);
    158 		}
    159 		error("Missing '}'");
    160 	bend:
    161 		return;
    162 	}
    163 
    164 	/* keyword */
    165 	case 19:
    166 		switch(cval) {
    167 
    168 		/* goto */
    169 		case 10:
    170 			np = tree();
    171 			if ((np[1]&030)!=030)	/* not array */
    172 				np = block(1, 36, 1, np[2]+1, np);
    173 			rcexpr(block(1,102,0,0,np), regtab);
    174 			goto semi;
    175 
    176 		/* return */
    177 		case 11:
    178 			if((peeksym=symbol())==6)	/* ( */
    179 				rcexpr(block(1,110,0,0,pexpr()), regtab);
    180 			retseq();
    181 			goto semi;
    182 
    183 		/* if */
    184 		case 12:
    185 			jumpc(pexpr(), o1=isn++, 0);
    186 			statement(0);
    187 			if ((o=symbol())==19 & cval==14) {  /* else */
    188 				o2 = isn++;
    189 				(easystmt()?branch:jump)(o2);
    190 				label(o1);
    191 				statement(0);
    192 				label(o2);
    193 				return;
    194 			}
    195 			peeksym = o;
    196 			label(o1);
    197 			return;
    198 
    199 		/* while */
    200 		case 13:
    201 			o1 = contlab;
    202 			o2 = brklab;
    203 			label(contlab = isn++);
    204 			jumpc(pexpr(), brklab=isn++, 0);
    205 			o3 = easystmt();
    206 			statement(0);
    207 			(o3?branch:jump)(contlab);
    208 			label(brklab);
    209 			contlab = o1;
    210 			brklab = o2;
    211 			return;
    212 
    213 		/* break */
    214 		case 17:
    215 			if(brklab==0)
    216 				error("Nothing to break from");
    217 			jump(brklab);
    218 			goto semi;
    219 
    220 		/* continue */
    221 		case 18:
    222 			if(contlab==0)
    223 				error("Nothing to continue");
    224 			jump(contlab);
    225 			goto semi;
    226 
    227 		/* do */
    228 		case 19:
    229 			o1 = contlab;
    230 			o2 = brklab;
    231 			contlab = isn++;
    232 			brklab = isn++;
    233 			label(o3 = isn++);
    234 			statement(0);
    235 			label(contlab);
    236 			contlab = o1;
    237 			if ((o=symbol())==19 & cval==13) { /* while */
    238 				jumpc(tree(), o3, 1);
    239 				label(brklab);
    240 				brklab = o2;
    241 				goto semi;
    242 			}
    243 			goto syntax;
    244 
    245 		/* case */
    246 		case 16:
    247 			if ((o=symbol())!=21) {	/* constant */
    248 				if (o!=41)	/* - */
    249 					goto syntax;
    250 				if ((o=symbol())!=21)
    251 					goto syntax;
    252 				cval = - cval;
    253 			}
    254 			if ((o=symbol())!=8)	/* : */
    255 				goto syntax;
    256 			if (swp==0) {
    257 				error("Case not in switch");
    258 				goto stmt;
    259 			}
    260 			if(swp>=swtab+swsiz) {
    261 				error("Switch table overflow");
    262 			} else {
    263 				*swp++ = isn;
    264 				*swp++ = cval;
    265 				label(isn++);
    266 			}
    267 			goto stmt;
    268 
    269 		/* switch */
    270 		case 15:
    271 			o1 = brklab;
    272 			brklab = isn++;
    273 			np = pexpr();
    274 			if (np[1]>1 & np[1]<07)
    275 				error("Integer required");
    276 			rcexpr(block(1,110,0,0,np), regtab);
    277 			pswitch();
    278 			brklab = o1;
    279 			return;
    280 
    281 		/* default */
    282 		case 20:
    283 			if (swp==0)
    284 				error("Default not in switch");
    285 			if ((o=symbol())!=8)	/* : */
    286 				goto syntax;
    287 			deflab = isn++;
    288 			label(deflab);
    289 			goto stmt;
    290 		}
    291 
    292 		error("Unknown keyword");
    293 		goto syntax;
    294 
    295 	/* name */
    296 	case 20:
    297 		if (peekc==':') {
    298 			peekc = 0;
    299 			if (csym[0]>0) {
    300 				error("Redefinition");
    301 				goto stmt;
    302 			}
    303 			csym[0] = 7;
    304 			csym[1] = 030;	/* int[] */
    305 			if (csym[2]==0)
    306 				csym[2] = isn++;
    307 			label(csym[2]);
    308 			goto stmt;
    309 		}
    310 	}
    311 
    312 	peeksym = o;
    313 	rcexpr(tree(), efftab);
    314 	goto semi;
    315 
    316 semi:
    317 	if ((o=symbol())!=1)		/* ; */
    318 		goto syntax;
    319 	return;
    320 
    321 syntax:
    322 	error("Statement syntax");
    323 	errflush(o);
    324 	goto stmt;
    325 }
    326 
    327 pexpr()
    328 {
    329 	auto o, t;
    330 
    331 	if ((o=symbol())!=6)	/* ( */
    332 		goto syntax;
    333 	t = tree();
    334 	if ((o=symbol())!=7)	/* ) */
    335 		goto syntax;
    336 	return(t);
    337 syntax:
    338 	error("Statement syntax");
    339 	errflush(o);
    340 	return(0);
    341 }
    342 
    343 pswitch() {
    344 	extern swp[], isn, swtab[], printf, deflab, statement, brklab;
    345 	extern label;
    346 	int sswp[], dl, cv, swlab;
    347 
    348 	sswp = swp;
    349 	if (swp==0)
    350 		swp = swtab;
    351 	swlab = isn++;
    352 	printf("jsr	pc,bswitch; l%d\n", swlab);
    353 	dl = deflab;
    354 	deflab = 0;
    355 	statement(0);
    356 	if (!deflab) {
    357 		deflab = isn++;
    358 		label(deflab);
    359 	}
    360 	printf("L%d:.data;L%d:", brklab, swlab);
    361 	while(swp>sswp & swp>swtab) {
    362 		cv = *--swp;
    363 		printf("%o; l%d\n", cv, *--swp);
    364 	}
    365 	printf("L%d; 0\n.text\n", deflab);
    366 	deflab = dl;
    367 	swp = sswp;
    368 }
    369 
    370 blkhed()
    371 {
    372 	extern symbol, cval, peeksym, paraml[], parame[];
    373 	extern error, rlength, setstk, defvec, isn, defstat;
    374 	extern stack, hshtab[], hshsiz, pssiz;
    375 	int al, pl, cs[], hl, t[];
    376 
    377 	declist(0);
    378 	stack = al = 0;
    379 	pl = 4;
    380 	while(paraml) {
    381 		*parame = 0;
    382 		paraml = *(cs = paraml);
    383 		if (cs[1]==2)		/* float args -> double */
    384 			cs[1] = 3;
    385 		cs[2] = pl;
    386 		*cs = 10;
    387 		if ((cs[1]&030) == 030)		/* array */
    388 			cs[1] =- 020;		/* set ref */
    389 		pl =+ rlength(cs);
    390 	}
    391 	cs = hshtab;
    392 	hl = hshsiz;
    393 	while(hl--) {
    394 	    if (cs[4]) {
    395 		if (cs[0]>1 & (cs[1]&07)==05) {  /* referred structure */
    396 			t = cs[3];
    397 			cs[3] = t[3];
    398 			cs[1] = cs[1]&077770 | 04;
    399 		}
    400 		switch(cs[0]) {
    401 
    402 		/* sort unmentioned */
    403 		case -2:
    404 			cs[0] = 5;		/* auto */
    405 
    406 		/* auto */
    407 		case 5:
    408 			al =- trlength(cs);
    409 			cs[2] = al;
    410 			break;
    411 
    412 		/* parameter */
    413 		case 10:
    414 			cs[0] = 5;
    415 			break;
    416 
    417 		/* static */
    418 		case 7:
    419 			cs[2] = isn;
    420 			printf(".bss; L%d: .=.+%o; .text\n",
    421 				isn++, trlength(cs));
    422 			break;
    423 
    424 		}
    425 	    }
    426 	    cs = cs+pssiz;
    427 	}
    428 	setstk(al);
    429 }
    430 
    431 blkend() {
    432 	extern hshtab[], hshsiz, pssiz, hshused, debug;
    433 	auto i, hl;
    434 
    435 	i = 0;
    436 	hl = hshsiz;
    437 	while(hl--) {
    438 		if(hshtab[i+4]) {
    439 if (debug)
    440 if (hshtab[i]!=1)
    441 error("%p	%o	%o	%o	%o	%o",
    442 	&hshtab[i+4],
    443 	hshtab[i],
    444 	hshtab[i+1],
    445 	hshtab[i+2],
    446 	hshtab[i+3],
    447 	hshtab[i+8]);
    448 			if (hshtab[i]==0)
    449 				error("%p undefined", &hshtab[i+4]);
    450 			if((hshtab[i+4]&0200)==0) {	/* not top-level */
    451 				hshtab[i+4] = 0;
    452 				hshused--;
    453 			}
    454 		}
    455 		i =+ pssiz;
    456 	}
    457 }
    458 
    459 errflush(o) {
    460 	extern symbol, peeksym, eof;
    461 
    462 	while(o>3)	/* ; { } */
    463 		o = symbol();
    464 	peeksym  = o;
    465 }
    466 
    467 declist(mosflg)
    468 {
    469 	extern peeksym, csym[], cval;
    470 	auto o, offset;
    471 
    472 	offset = 0;
    473 	while((o=symbol())==19 & cval<10)
    474 		if (cval<=4)
    475 			offset = tdeclare(cval, offset, mosflg);
    476 		else
    477 			scdeclare(cval);
    478 	peeksym = o;
    479 	return(offset);
    480 }
    481 
    482 easystmt()
    483 {
    484 	extern peeksym, peekc, cval;
    485 
    486 	if((peeksym=symbol())==20)	/* name */
    487 		return(peekc!=':');	 /* not label */
    488 	if (peeksym==19) {		/* keyword */
    489 		switch(cval)
    490 
    491 		case 10:	/* goto */
    492 		case 11:	/* return */
    493 		case 17:	/* break */
    494 		case 18:	/* continue */
    495 			return(1);
    496 		return(0);
    497 	}
    498 	return(peeksym!=2);		/* { */
    499 }
    500 
    501 branch(lab)
    502 {
    503 	printf("br	L%d\n", lab);
    504 }
    505