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

c01.c (5936B)


      1 build(op) {
      2 	extern cp[], cvtab, opdope[], maprel[];
      3 	auto p1[], t1, d1, p2[], t2, d2, p3[], t3, d3, t;
      4 	auto d, dope, leftc, cvn, pcvn;
      5 	char cvtab[];
      6 
      7 	if (op==4)  {		/* [] */
      8 		build(40);	/* + */
      9 		op = 36;	/* * */
     10 	}
     11 	dope = opdope[op];
     12 	if ((dope&01)!=0) {	/* binary */
     13 		p2 = disarray(*--cp);
     14 		t2 = p2[1];
     15 		chkfun(p2);
     16 		d2 = p2[2];
     17 		if (*p2==20)
     18 			d2 = 0;
     19 	}
     20 	p1 = disarray(*--cp);
     21 	if (op!=100 & op!=35)		/* call, * */
     22 		chkfun(p1);
     23 	t1 = p1[1];
     24 	d1 = p1[2];
     25 	if (*p1==20)
     26 		d1 = 0;
     27 	pcvn = 0;
     28 	switch (op) {
     29 
     30 	/* : */
     31 	case 8:
     32 		if (t1!=t2)
     33 			error("Type clash in conditional");
     34 		t = t1;
     35 		goto nocv;
     36 
     37 	/* , */
     38 	case 9:
     39 		*cp++ = block(2, 9, 0, 0, p1, p2);
     40 		return;
     41 
     42 	/* ? */
     43 	case 90:
     44 		if (*p2!=8)
     45 			error("Illegal conditional");
     46 		t = t2;
     47 		goto nocv;
     48 
     49 	/* call */
     50 	case 100:
     51 		if ((t1&030) != 020)
     52 			error("Call of non-function");
     53 		*cp++ = block(2,100,decref(t1),24,p1,p2);
     54 		return;
     55 
     56 	/* * */
     57 	case 36:
     58 		if (*p1==35 | *p1==29) {	/* & unary */
     59 			*cp++ = p1[3];
     60 			return;
     61 		}
     62 		if (*p1!=20 & d1==0)
     63 			d1 = 1;
     64 		if ((t1&030) == 020)		/* function */
     65 			error("Illegal indirection");
     66 		*cp++ = block(1,36,decref(t1),d1,p1);
     67 		return;
     68 
     69 	/* & unary */
     70 	case 35:
     71 		if (*p1==36) {			/* * */
     72 			*cp++ = p1[3];
     73 			return;
     74 		}
     75 		if (*p1==20) {
     76 			*cp++ = block(1,p1[3]==5?29:35,incref(t1),1,p1);
     77 			return;
     78 		}
     79 		error("Illegal lvalue");
     80 		break;
     81 
     82 	case 43:	/* / */
     83 	case 44:	/* % */
     84 	case 73:	/* =/ */
     85 	case 74:	/* =% */
     86 		d1++;
     87 		d2++;
     88 
     89 	case 42:	/* * */
     90 	case 72:	/* =* */
     91 		d1++;
     92 		d2++;
     93 		break;
     94 
     95 	case 30:	/* ++ -- pre and post */
     96 	case 31:
     97 	case 32:
     98 	case 33:
     99 		chklval(p1);
    100 		*cp++ = block(2,op,t1,max(d1,1),p1,plength(p1));
    101 		return;
    102 
    103 	case 39:	/* . (structure ref) */
    104 	case 50:	/* -> (indirect structure ref) */
    105 		if (p2[0]!=20 | p2[3]!=4)		/* not mos */
    106 			error("Illegal structure ref");
    107 		*cp++ = p1;
    108 		t = t2;
    109 		if ((t&030) == 030)	/* array */
    110 			t = decref(t);
    111 		setype(p1, t);
    112 		if (op==39)		/* is "." */
    113 			build(35);	/* unary & */
    114 		*cp++ = block(1,21,7,0,p2[5]);
    115 		build(40);		/* + */
    116 		if ((t2&030) != 030)	/* not array */
    117 			build(36);	/* unary * */
    118 		return;
    119 	}
    120 	if ((dope&02)!=0)		/* lvalue needed on left? */
    121 		chklval(p1);
    122 	if ((dope&020)!=0)		/* word operand on left? */
    123 		chkw(p1);
    124 	if ((dope&040)!=0)		/* word operand on right? */
    125 		chkw(p2);
    126 	if ((dope&01)==0) {		/* unary op? */
    127 		*cp++ = block(1,op,t1,max(d1,1),p1);
    128 		return;
    129 	}
    130 	if (t2==7) {
    131 		t = t1;
    132 		p2[1] = 0;	/* no int cv for struct */
    133 		t2 = 0;
    134 		goto nocv;
    135 	}
    136 	cvn = cvtab[11*lintyp(t1)+lintyp(t2)];
    137 	leftc = cvn&0100;
    138 	t = leftc? t2:t1;
    139 	if (op==80 & t1!=4 & t2!=4) {	/* = */
    140 		t = t1;
    141 		if (leftc | cvn!=1)
    142 			goto nocv;
    143 	}
    144 	if (cvn =& 077) {
    145 		if (cvn==077) {
    146 	illcv:
    147 			error("Illegal conversion");
    148 			goto nocv;
    149 		}
    150 		if (cvn>4 & cvn<10) {		/* ptr conv */
    151 			t = 0;			/* integer result */
    152 			cvn = 0;
    153 			if ((dope&04)!=0)	/* relational? */
    154 				goto nocv;
    155 			if (op!=41)	/* - */
    156 				goto illcv;
    157 			pcvn = cvn;
    158 			goto nocv;
    159 		}
    160 		if (leftc) {
    161 			if ((dope&010) != 0) {	/* =op */
    162 				if (cvn == 1) {
    163 					leftc = 0;
    164 					cvn = 8;
    165 					t = t1;
    166 					goto rcvt;
    167 				} else
    168 					goto illcv;
    169 			}
    170 			d1 = (p1=convert(p1, t, d1, cvn, plength(p2)))[2];
    171 		} else {
    172 		rcvt:
    173 			d2 = (p2=convert(p2, t, d2, cvn, plength(p1)))[2];
    174 		}
    175 nocv:;		}
    176 	if (d1==d2)
    177 		d = d1+1; else
    178 		d = max(d1,d2);
    179 	if ((dope&04)!=0) {		/* relational? */
    180 		if (op>61 & t>=010)
    181 			op =+ 4;	  /* ptr relation */
    182 		t = 0;		/* relational is integer */
    183 	}
    184 	*cp++ = optim(block(2,op,t,d,p1,p2));
    185 	if (pcvn) {
    186 		p1 = *--cp;
    187 		*cp++ = block(1,50+pcvn,0,d,p1);
    188 	}
    189 	return;
    190 	*cp++ = block(1,op,t1,d1==0?1:d1,p1);
    191 }
    192 
    193 setype(p, t)
    194 int p[];
    195 {
    196 	int p1[];
    197 
    198 	if ((p[1]&07) != 4)		/* not structure */
    199 		return;
    200 	p[1] = t;
    201 	switch(*p) {
    202 
    203 	case 29:		/* & */
    204 	case 35:
    205 		setype(p[3], decref(t));
    206 		return;
    207 
    208 	case 36:		/* * */
    209 		setype(p[3], incref(t));
    210 		return;
    211 
    212 	case 40:		/* + */
    213 		setype(p[4], t);
    214 	}
    215 }
    216 
    217 chkfun(p)
    218 int p[];
    219 {
    220 	if ((p[1]&030)==020)	/* func */
    221 		error("Illegal use of function");
    222 }
    223 
    224 optim(p)
    225 int p[];
    226 {
    227 	int p1[], p2[], t;
    228 
    229 	if (*p != 40)				/* + */
    230 		return(p);
    231 	p1 = p[3];
    232 	p2 = p[4];
    233 	if (*p1==21) {				/* const */
    234 		t = p1;
    235 		p1 = p2;
    236 		p2 = t;
    237 	}
    238 	if (*p2 != 21)				/* const */
    239 		return(p);
    240 	if ((t=p2[3]) == 0)			/* const 0 */
    241 		return(p1);
    242 	if (*p1!=35 & *p1!=29)			/* not & */
    243 		return(p);
    244 	p2 = p1[3];
    245 	if (*p2!=20) {				/* name? */
    246 		error("C error (optim)");
    247 		return(p);
    248 	}
    249 	p2[4] =+ t;
    250 	return(p1);
    251 }
    252 
    253 disarray(p)
    254 int p[];
    255 {
    256 	extern cp;
    257 	int t, cp[];
    258 
    259 	if (((t = p[1]) & 030)!=030 | p[0]==20&p[3]==4)	/* array & not MOS */
    260 		return(p);
    261 	p[1] = decref(t);
    262 	*cp++ = p;
    263 	build(35);				/* add & */
    264 	return(*--cp);
    265 }
    266 
    267 convert(p, t, d, cvn, len)
    268 int p[];
    269 {
    270 	int c, p1[];
    271 
    272 	if (*p==21) {		/* constant */
    273 		c = p[3];
    274 		switch(cvn) {
    275 
    276 		case 4:		/* int -> double[] */
    277 			c =<< 1;
    278 
    279 		case 3:		/* int -> float[] */
    280 			c =<< 1;
    281 
    282 		case 2:		/* int -> int[] */
    283 			c =<< 1;
    284 			p[3] = c;
    285 			return(p);
    286 
    287 		case 10:	/* i -> s[] */
    288 			p[3] = c*len;
    289 			return(p);
    290 		}
    291 	}
    292 	if (cvn==10)			/* i -> s[]; retrun i*len */
    293 		return(block(2,42,t,d+2,p,block(1,21,0,0,len)));
    294 	return(block(1, 50+cvn, t, max(1,d), p));
    295 }
    296 
    297 chkw(p)
    298 int p[]; {
    299 	extern error;
    300 	auto t;
    301 
    302 	if ((t=p[1])>1 & t<=07)
    303 		error("Integer operand required");
    304 	return;
    305 }
    306 
    307 lintyp(t)
    308 {
    309 	if (t<=07)
    310 		return(t);
    311 	if ((t&037)==t)
    312 		return((t&07)+5);
    313 	return(10);
    314 }
    315 
    316 error(s, p1, p2, p3, p4, p5, p6) {
    317 	extern line, fout, nerror;
    318 	int f;
    319 
    320 	nerror++;
    321 	flush();
    322 	f = fout;
    323 	fout = 1;
    324 	printf("%d: ", line);
    325 	printf(s, p1, p2, p3, p4, p5, p6);
    326 	putchar('\n');
    327 	fout = f;
    328 }
    329 
    330 block(n, op, t, d, p1,p2,p3)
    331 int p1[],p2[],p3[]; {
    332 	int p[], ap[], space[];
    333 	extern space;
    334 
    335 	ap = &op;
    336 	n =+ 3;
    337 	p = space;
    338 	while(n--)
    339 		pblock(*ap++);
    340 	return(p);
    341 }
    342 
    343 pblock(p)
    344 {
    345 	extern space, osleft;
    346 	int space[];
    347 
    348 	*space++ = p;
    349 	if (--osleft<=0) {
    350 		error("Expression overflow");
    351 		exit(1);
    352 	}
    353 }
    354 
    355 chklval(p)
    356 int p[]; {
    357 	extern error;
    358 
    359 	if (*p!=20 & *p !=36)
    360 		error("Lvalue required");
    361 }
    362 
    363 max(a, b)
    364 {
    365 	if (a>b)
    366 		return(a);
    367 	return(b);
    368 }
    369