618 lines · 8.5 KB · Text
RawDownload
%{#include <u.h>#include <libc.h>#include <thread.h>#include <llrb.h>#include "ccc.h"%} %union {	Sym *sym;	Symlist *symlist;	Type *type;	Typelist *typelist;	struct Tspec {		Btype;		Dtype *dtype;	} tspec;	struct Decl {		Btype btype;		Dtype *dtype;		Symlist *slist;		Type *chantype;	} decl;	struct Sumembs {		Names *names;		Symlist *slist;	} sumembs;	int ival;	double dval;} %type	<decl>	xasdecl%type	<symlist>	declors%type	<typelist>	paramlist paramlist1%type	<sym>	declor declor1 name tycl sue%type	<type>	abdeclor abdeclor1 abdeclor2 abdeclor3 param%type	<tspec>	tcqspec%type	<sumembs>	sdecls%type	<ival>	zival su %token	<sym>	LNAME LVOID LCHAR LSHORT LINT LLONG LFLOAT%token	<sym>	LDOUBLE LSIGNED LUNSIGNED LCONST LVOLATILE%token	<sym>	LAUTO LREGISTER LSTATIC LEXTERN LTYPEDEF%token	<sym>	LUNION LENUM LSTRUCT LTYPE%token	<ival>	LIVAL%token	<dval>	LDVAL%token	LCHAN %% unit:|	unit xadecl xadecl:	xasdecl	{		if($1.chantype != nil) {			setchantype($1.slist, $1.chantype);			printchandecls($1.slist);			nocopyout();		} else {			settype($1.slist, &$1.btype, $1.dtype);			copyout();		}		symlistfree($1.slist);	} xasdecl:	tcqspec ';'	{		btypeclean(&$1); 		$$.btype = $1;		$$.dtype = $1.dtype;		$$.slist = nil;		$$.chantype = nil;	}|	tcqspec declors ';'	{		btypeclean(&$1); 		$$.btype = $1;		$$.dtype = $1.dtype;		$$.slist = $2;		$$.chantype = nil;	}|	LCHAN '(' param ')' declors ';'	{		$$.btype = BZ;		$$.dtype = nil;		$$.slist = $5;		$$.chantype = $3;	} tcqspec:	{		$$ = (struct Tspec){BZ, nil};	}|	tcqspec tycl	{		$$.tycl = addspec($1.tycl, $2->tycl);	}|	tcqspec sue	{		$$.sue = addsue(&$1, $2);	}|	tcqspec LTYPE	{		$$ = *addtypedef(&$1, $2->type);	} declors:	declor	{		$$ = addsym(symlist(), $1);	}|	declors ',' declor	{		$$ = addsym($1, $3);	} declor:	declor1|	'*' declor	{		dtype($2->newtype, TPTR);		$$ = $2;	} declor1:	LNAME	{		$1->newtype = type();		$$ = $1;	}|	'(' declor ')'	{		$$ = $2;	}|	declor1 '[' zival ']'	{		Dtype *d; 		d = dtype($1->newtype, TARR);		d->alen = $3;		$$ = $1;	}|	declor1 '(' paramlist ')'	{		Dtype *d; 		d = dtype($1->newtype, TFUNC);		d->param = $3;		$$ = $1;	} paramlist:	paramlist1|	paramlist1 ',' '.' '.' '.'	{		Type *t; 		t = type();		t->tycl = 1<<TDOTS;		addtype($1, t);		$$ = $1;	} paramlist1:	param	{		$$ = addtype(typelist(), paramconv($1));	}|	paramlist1 ',' param	{		$$ = addtype($1, paramconv($3));	} param:	tcqspec declor	{		$$ = $2->newtype;		$2->newtype = nil;		btypeclean(&$1);		*(Btype*)$$ = $1;	}|	tcqspec abdeclor	{		$$ = $2;		btypeclean(&$1);		*(Btype*)$$ = $1;	}	 abdeclor:	{		$$ = type();	}|	abdeclor1 abdeclor1:	abdeclor2|	'*'	{		$$ = type();		dtype($$, TPTR);	}|	'*' abdeclor1	{		dtype($2, TPTR);		$$ = $2;	} abdeclor2:	abdeclor3|	abdeclor2 '(' paramlist ')'	{		Dtype *d; 		d = dtype($1, TFUNC);		d->param = $3;		$$ = $1;	}|	abdeclor2 '[' zival ']'	{		Dtype *d; 		d = dtype($1, TARR);		d->alen = $3;		$$ = $1;	} abdeclor3:	'[' zival ']'	{		Dtype *d; 		$$ = type();		d = dtype($$, TARR);		d->alen = $2;	}|	'(' abdeclor1 ')'	{		$$ = $2;	} sue:	su name	{		$2->suetype = $1;		$$ = $2;	}|	su name '{' sdecls '}'	{		$2->sunames = $4.names;		$2->sulist = $4.slist;		$2->suetype = $1;		$$ = $2;	}|	su '{' sdecls '}'	{		$$ = sym(nil, nil);		$$->sunames = $3.names;		$$->sulist = $3.slist;		$$->suetype = $1;	}|	e name	{		$2->suetype = TENUM;		$$ = $2;	} su:	LSTRUCT	{		suelookup = 1;		$$ = TSTRUCT;	}|	LUNION	{		suelookup = 1;		$$ = TUNION;	} e:	LENUM	{		suelookup = 1;	} sdecls:	{		$$.names = pushnames(nil);		$$.slist = symlist();	}|	sdecls xasdecl	{		if($2.slist == nil)			anonmemb(&$1, $2.btype.sue);		else			addsumembs(&$1, &$2);		symlistfree($2.slist);		$$ = $1;	} zival:	{		$$ = -1;	}|	LIVAL name:	LNAME|	LTYPE tycl:	LVOID|	LCHAR|	LSHORT|	LINT|	LLONG|	LFLOAT|	LDOUBLE|	LSIGNED|	LUNSIGNED|	LCONST|	LVOLATILE|	LAUTO|	LREGISTER|	LSTATIC|	LEXTERN|	LTYPEDEF %% Btype BZ = {0}; voidbtypeclean(Btype *btype){	int i, t;	u32int tycl;	Sym *sue; 	tycl = btype->tycl;	sue = btype->sue; 	if(sue != nil) {		if(tycl & (BTYPE|BSIGN))			error("Cannot be a basic type and a structure type.");		return;	} 	for(i = TVOID; i < NTYPE; i++) {		if(tycl & 1<<i)			break;	} 	switch(i) {	case NTYPE:		t = TINT;		break;	case TLONG:		if(tycl & 1<<TDOUBLE) {			tycl &= ~(1<<TLONG);			t = TDOUBLE;			break;		}	case TVLONG:	case TSHORT:		tycl &= ~(1<<TINT);	default:		t = i;		break;	} 	for(i = t+1; i < NTYPE; i++) {		if(tycl & 1<<i)			error("Overspecified type %d and %d.", t, i);	} 	if(tycl & BSIGN) switch(t) {	case TVOID:	case TFLOAT:	case TDOUBLE:		error("%d cannot be signed or unsigned.", t);	}		btype->tycl = tycl;} voidsettype(Symlist *symlist, Btype *btype, Dtype *dtype){	Sym **s, *sym;	Type *type, *newtype; 	if(symlist == nil)		return; 	for(s = symlist->sp; s < symlist->ep; s++) {		sym = *s;		type = sym->type;		newtype = sym->newtype; 		*(Btype*)newtype = *btype;		*newtype->dtail = dtype; 		if(type != nil) {			if(typeeq(type, newtype) != 0)				error("Types do not match %S: %D, %D", sym->name, type, newtype);			typefree(type);		}		sym->type = newtype;		sym->newtype = nil;		if(btype->tycl & 1<<TTYPEDEF)			sym->lex = LTYPE;	}} voidsetchantype(Symlist *symlist, Type *t){	Sym **s, *sym;	Type *type, *newtype; 	if(symlist == nil)		return; 	for(s = symlist->sp; s < symlist->ep; s++) {		sym = *s;		type = sym->type;		newtype = sym->newtype; 		newtype->chantype = t; 		if(type != nil) {			if(typeeq(type, newtype) != 0)				error("Chan types do not match %S: %D, %D", sym->name, type, newtype);			typefree(type);		}		sym->type = newtype;	}} Type*paramconv(Type *t){	Dtype *d; 	if((d = t->dtype) != nil) switch(d->t) {	case TARR:		d->alen = 0;		d->t = TPTR;		break;	case TFUNC:		t->dtype = dtype(nil, TPTR);		t->dtype->link = d;		break;	}	return t;} static inttycleq(u32int t1, u32int t2){	if((t1^t2) & (BTYPE|BSIGN))		return 1;	return 0;} static intsueeq(Sym*, Sym*){	return 0;} static intparameq(Typelist *l1, Typelist *l2){	Type **ti1, **ti2; 	if(l1 !=nil && l2 != nil)		goto check;	if(l1 == nil && l2 == nil)		return 0;	return 1; check:	for(ti1 = l1->sp, ti2 = l2->sp; ti1 < l1->ep; ti1++, ti2++) {		if(ti2 == l2->ep)			return 1;		if(typeeq(*ti1, *ti2) != 0)			return 1;	}	return 0;}  static intdtypeeq(Dtype *d1, Dtype *d2)

Lines 1–500 of 618.