%{#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. Load more
%{ #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}; void btypeclean(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; } void settype(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; } } void setchantype(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 int tycleq(u32int t1, u32int t2) { if((t1^t2) & (BTYPE|BSIGN)) return 1; return 0; } static int sueeq(Sym*, Sym*) { return 0; } static int parameq(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 int dtypeeq(Dtype *d1, Dtype *d2)