sptr<SymFunc> Parser::ParseFunc(bool program) { Types t = currToken->type; if (program) { Expect(PROGRAM, -1); } else Expect(FUNCTION, PROCEDURE, -1); string name = currToken->lexeme; sptr<FuncSymType> functype(new FuncSymType(NextTable())); NextToken(); Expect(OPENBRAC, -1); if (!MatchSkip(CLOSEBRAC, -1)) { do { functype->PushArgs(ParseVarList(functype->symTable)); } while (MatchSkip(SEMICOLON, -1)); Expect(CLOSEBRAC, -1); } if (t == FUNCTION) { Expect(COLON, -1); functype->SetType(currSymTable->GetType(currToken->lexeme)); NextToken(); } else { functype->SetType(SymType::voidType); } Expect(SEMICOLON, -1); sptr<SymFunc> func(new SymFunc(name, functype, ParseBodyBlock())); LastTable()->Push(func); return func; }
void typeinit(void) { int i, etype, sameas; Type *t; Sym *s, *s1; if(widthptr == 0) fatal("typeinit before betypeinit"); for(i=0; i<NTYPE; i++) simtype[i] = i; types[TPTR32] = typ(TPTR32); dowidth(types[TPTR32]); types[TPTR64] = typ(TPTR64); dowidth(types[TPTR64]); t = typ(TUNSAFEPTR); types[TUNSAFEPTR] = t; t->sym = pkglookup("Pointer", unsafepkg); t->sym->def = typenod(t); dowidth(types[TUNSAFEPTR]); tptr = TPTR32; if(widthptr == 8) tptr = TPTR64; for(i=TINT8; i<=TUINT64; i++) isint[i] = 1; isint[TINT] = 1; isint[TUINT] = 1; isint[TUINTPTR] = 1; isfloat[TFLOAT32] = 1; isfloat[TFLOAT64] = 1; iscomplex[TCOMPLEX64] = 1; iscomplex[TCOMPLEX128] = 1; isptr[TPTR32] = 1; isptr[TPTR64] = 1; isforw[TFORW] = 1; issigned[TINT] = 1; issigned[TINT8] = 1; issigned[TINT16] = 1; issigned[TINT32] = 1; issigned[TINT64] = 1; /* * initialize okfor */ for(i=0; i<NTYPE; i++) { if(isint[i] || i == TIDEAL) { okforeq[i] = 1; okforcmp[i] = 1; okforarith[i] = 1; okforadd[i] = 1; okforand[i] = 1; okforconst[i] = 1; issimple[i] = 1; minintval[i] = mal(sizeof(*minintval[i])); maxintval[i] = mal(sizeof(*maxintval[i])); } if(isfloat[i]) { okforeq[i] = 1; okforcmp[i] = 1; okforadd[i] = 1; okforarith[i] = 1; okforconst[i] = 1; issimple[i] = 1; minfltval[i] = mal(sizeof(*minfltval[i])); maxfltval[i] = mal(sizeof(*maxfltval[i])); } if(iscomplex[i]) { okforeq[i] = 1; okforadd[i] = 1; okforarith[i] = 1; okforconst[i] = 1; issimple[i] = 1; } } issimple[TBOOL] = 1; okforadd[TSTRING] = 1; okforbool[TBOOL] = 1; okforcap[TARRAY] = 1; okforcap[TCHAN] = 1; okforconst[TBOOL] = 1; okforconst[TSTRING] = 1; okforlen[TARRAY] = 1; okforlen[TCHAN] = 1; okforlen[TMAP] = 1; okforlen[TSTRING] = 1; okforeq[TPTR32] = 1; okforeq[TPTR64] = 1; okforeq[TUNSAFEPTR] = 1; okforeq[TINTER] = 1; okforeq[TCHAN] = 1; okforeq[TSTRING] = 1; okforeq[TBOOL] = 1; okforeq[TMAP] = 1; // nil only; refined in typecheck okforeq[TFUNC] = 1; // nil only; refined in typecheck okforeq[TARRAY] = 1; // nil slice only; refined in typecheck okforeq[TSTRUCT] = 1; // it's complicated; refined in typecheck okforcmp[TSTRING] = 1; for(i=0; i<nelem(okfor); i++) okfor[i] = okfornone; // binary okfor[OADD] = okforadd; okfor[OAND] = okforand; okfor[OANDAND] = okforbool; okfor[OANDNOT] = okforand; okfor[ODIV] = okforarith; okfor[OEQ] = okforeq; okfor[OGE] = okforcmp; okfor[OGT] = okforcmp; okfor[OLE] = okforcmp; okfor[OLT] = okforcmp; okfor[OMOD] = okforand; okfor[OMUL] = okforarith; okfor[ONE] = okforeq; okfor[OOR] = okforand; okfor[OOROR] = okforbool; okfor[OSUB] = okforarith; okfor[OXOR] = okforand; okfor[OLSH] = okforand; okfor[ORSH] = okforand; // unary okfor[OCOM] = okforand; okfor[OMINUS] = okforarith; okfor[ONOT] = okforbool; okfor[OPLUS] = okforarith; // special okfor[OCAP] = okforcap; okfor[OLEN] = okforlen; // comparison iscmp[OLT] = 1; iscmp[OGT] = 1; iscmp[OGE] = 1; iscmp[OLE] = 1; iscmp[OEQ] = 1; iscmp[ONE] = 1; mpatofix(maxintval[TINT8], "0x7f"); mpatofix(minintval[TINT8], "-0x80"); mpatofix(maxintval[TINT16], "0x7fff"); mpatofix(minintval[TINT16], "-0x8000"); mpatofix(maxintval[TINT32], "0x7fffffff"); mpatofix(minintval[TINT32], "-0x80000000"); mpatofix(maxintval[TINT64], "0x7fffffffffffffff"); mpatofix(minintval[TINT64], "-0x8000000000000000"); mpatofix(maxintval[TUINT8], "0xff"); mpatofix(maxintval[TUINT16], "0xffff"); mpatofix(maxintval[TUINT32], "0xffffffff"); mpatofix(maxintval[TUINT64], "0xffffffffffffffff"); /* f is valid float if min < f < max. (min and max are not themselves valid.) */ mpatoflt(maxfltval[TFLOAT32], "33554431p103"); /* 2^24-1 p (127-23) + 1/2 ulp*/ mpatoflt(minfltval[TFLOAT32], "-33554431p103"); mpatoflt(maxfltval[TFLOAT64], "18014398509481983p970"); /* 2^53-1 p (1023-52) + 1/2 ulp */ mpatoflt(minfltval[TFLOAT64], "-18014398509481983p970"); maxfltval[TCOMPLEX64] = maxfltval[TFLOAT32]; minfltval[TCOMPLEX64] = minfltval[TFLOAT32]; maxfltval[TCOMPLEX128] = maxfltval[TFLOAT64]; minfltval[TCOMPLEX128] = minfltval[TFLOAT64]; /* for walk to use in error messages */ types[TFUNC] = functype(N, nil, nil); /* types used in front end */ // types[TNIL] got set early in lexinit types[TIDEAL] = typ(TIDEAL); types[TINTER] = typ(TINTER); /* simple aliases */ simtype[TMAP] = tptr; simtype[TCHAN] = tptr; simtype[TFUNC] = tptr; simtype[TUNSAFEPTR] = tptr; /* pick up the backend typedefs */ for(i=0; typedefs[i].name; i++) { s = lookup(typedefs[i].name); s1 = pkglookup(typedefs[i].name, builtinpkg); etype = typedefs[i].etype; if(etype < 0 || etype >= nelem(types)) fatal("typeinit: %s bad etype", s->name); sameas = typedefs[i].sameas; if(sameas < 0 || sameas >= nelem(types)) fatal("typeinit: %s bad sameas", s->name); simtype[etype] = sameas; minfltval[etype] = minfltval[sameas]; maxfltval[etype] = maxfltval[sameas]; minintval[etype] = minintval[sameas]; maxintval[etype] = maxintval[sameas]; t = types[etype]; if(t != T) fatal("typeinit: %s already defined", s->name); t = typ(etype); t->sym = s1; dowidth(t); types[etype] = t; s1->def = typenod(t); } Array_array = rnd(0, widthptr); Array_nel = rnd(Array_array+widthptr, widthint); Array_cap = rnd(Array_nel+widthint, widthint); sizeof_Array = rnd(Array_cap+widthint, widthptr); // string is same as slice wo the cap sizeof_String = rnd(Array_nel+widthint, widthptr); dowidth(types[TSTRING]); dowidth(idealstring); }
void typeinit(void) { int i, etype, sameas; Type *t; Sym *s, *s1; if(widthptr == 0) fatal("typeinit before betypeinit"); for(i=0; i<NTYPE; i++) simtype[i] = i; types[TPTR32] = typ(TPTR32); dowidth(types[TPTR32]); types[TPTR64] = typ(TPTR64); dowidth(types[TPTR64]); tptr = TPTR32; if(widthptr == 8) tptr = TPTR64; for(i=TINT8; i<=TUINT64; i++) isint[i] = 1; isint[TINT] = 1; isint[TUINT] = 1; isint[TUINTPTR] = 1; for(i=TFLOAT32; i<=TFLOAT64; i++) isfloat[i] = 1; isfloat[TFLOAT] = 1; isptr[TPTR32] = 1; isptr[TPTR64] = 1; isforw[TFORW] = 1; issigned[TINT] = 1; issigned[TINT8] = 1; issigned[TINT16] = 1; issigned[TINT32] = 1; issigned[TINT64] = 1; /* * initialize okfor */ for(i=0; i<NTYPE; i++) { if(isint[i] || i == TIDEAL) { okforeq[i] = 1; okforcmp[i] = 1; okforarith[i] = 1; okforadd[i] = 1; okforand[i] = 1; issimple[i] = 1; minintval[i] = mal(sizeof(*minintval[i])); maxintval[i] = mal(sizeof(*maxintval[i])); } if(isfloat[i]) { okforeq[i] = 1; okforcmp[i] = 1; okforadd[i] = 1; okforarith[i] = 1; issimple[i] = 1; minfltval[i] = mal(sizeof(*minfltval[i])); maxfltval[i] = mal(sizeof(*maxfltval[i])); } } issimple[TBOOL] = 1; okforadd[TSTRING] = 1; okforbool[TBOOL] = 1; okforcap[TARRAY] = 1; okforcap[TCHAN] = 1; okforlen[TARRAY] = 1; okforlen[TCHAN] = 1; okforlen[TMAP] = 1; okforlen[TSTRING] = 1; okforeq[TPTR32] = 1; okforeq[TPTR64] = 1; okforeq[TINTER] = 1; okforeq[TMAP] = 1; okforeq[TCHAN] = 1; okforeq[TFUNC] = 1; okforeq[TSTRING] = 1; okforeq[TBOOL] = 1; okforeq[TARRAY] = 1; // refined in typecheck okforcmp[TSTRING] = 1; for(i=0; i<nelem(okfor); i++) okfor[i] = okfornone; // binary okfor[OADD] = okforadd; okfor[OAND] = okforand; okfor[OANDAND] = okforbool; okfor[OANDNOT] = okforand; okfor[ODIV] = okforarith; okfor[OEQ] = okforeq; okfor[OGE] = okforcmp; okfor[OGT] = okforcmp; okfor[OLE] = okforcmp; okfor[OLT] = okforcmp; okfor[OMOD] = okforarith; okfor[OMUL] = okforarith; okfor[ONE] = okforeq; okfor[OOR] = okforand; okfor[OOROR] = okforbool; okfor[OSUB] = okforarith; okfor[OXOR] = okforand; okfor[OLSH] = okforand; okfor[ORSH] = okforand; // unary okfor[OCOM] = okforand; okfor[OMINUS] = okforarith; okfor[ONOT] = okforbool; okfor[OPLUS] = okforadd; // special okfor[OCAP] = okforcap; okfor[OLEN] = okforlen; // comparison iscmp[OLT] = 1; iscmp[OGT] = 1; iscmp[OGE] = 1; iscmp[OLE] = 1; iscmp[OEQ] = 1; iscmp[ONE] = 1; mpatofix(maxintval[TINT8], "0x7f"); mpatofix(minintval[TINT8], "-0x80"); mpatofix(maxintval[TINT16], "0x7fff"); mpatofix(minintval[TINT16], "-0x8000"); mpatofix(maxintval[TINT32], "0x7fffffff"); mpatofix(minintval[TINT32], "-0x80000000"); mpatofix(maxintval[TINT64], "0x7fffffffffffffff"); mpatofix(minintval[TINT64], "-0x8000000000000000"); mpatofix(maxintval[TUINT8], "0xff"); mpatofix(maxintval[TUINT16], "0xffff"); mpatofix(maxintval[TUINT32], "0xffffffff"); mpatofix(maxintval[TUINT64], "0xffffffffffffffff"); mpatoflt(maxfltval[TFLOAT32], "3.40282347e+38"); mpatoflt(minfltval[TFLOAT32], "-3.40282347e+38"); mpatoflt(maxfltval[TFLOAT64], "1.7976931348623157e+308"); mpatoflt(minfltval[TFLOAT64], "-1.7976931348623157e+308"); /* for walk to use in error messages */ types[TFUNC] = functype(N, nil, nil); /* types used in front end */ // types[TNIL] got set early in lexinit types[TIDEAL] = typ(TIDEAL); /* simple aliases */ simtype[TMAP] = tptr; simtype[TCHAN] = tptr; simtype[TFUNC] = tptr; /* pick up the backend typedefs */ for(i=0; typedefs[i].name; i++) { s = lookup(typedefs[i].name); s1 = pkglookup(typedefs[i].name, "/builtin/"); etype = typedefs[i].etype; if(etype < 0 || etype >= nelem(types)) fatal("typeinit: %s bad etype", s->name); sameas = typedefs[i].sameas; if(sameas < 0 || sameas >= nelem(types)) fatal("typeinit: %s bad sameas", s->name); simtype[etype] = sameas; minfltval[etype] = minfltval[sameas]; maxfltval[etype] = maxfltval[sameas]; minintval[etype] = minintval[sameas]; maxintval[etype] = maxintval[sameas]; t = types[etype]; if(t != T) fatal("typeinit: %s already defined", s->name); t = typ(etype); t->sym = s; dowidth(t); types[etype] = t; s1->def = typenod(t); } Array_array = rnd(0, widthptr); Array_nel = rnd(Array_array+widthptr, types[TUINT32]->width); Array_cap = rnd(Array_nel+types[TUINT32]->width, types[TUINT32]->width); sizeof_Array = rnd(Array_cap+types[TUINT32]->width, maxround); // string is same as slice wo the cap sizeof_String = rnd(Array_nel+types[TUINT32]->width, maxround); dowidth(types[TSTRING]); dowidth(idealstring); }