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


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