home *** CD-ROM | disk | FTP | other *** search
/ Total Destruction / Total_Destruction.iso / addons / Lccwin32.exe / Lccwin32 / lccpub / src / Sym.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-11-11  |  7.3 KB  |  343 lines

  1. #include "c.h"
  2.  
  3. #define equalp(x) v.x == p->sym.u.c.v.x
  4.  
  5. struct table {
  6.     int level;
  7.     Table previous;
  8.     struct entry {
  9.         struct symbol sym;
  10.         struct entry *link;
  11.     } *buckets[1024];
  12.     Symbol all;
  13. };
  14. #define HASHSIZE NELEMS(((Table)0)->buckets)
  15. static struct table
  16.     cns = { CONSTANTS },
  17.     ext = { GLOBAL },
  18.     ids = { GLOBAL },
  19.     tys = { GLOBAL };
  20. Table constants   = &cns;
  21. Table externals   = &ext;
  22. Table identifiers = &ids;
  23. Table globals     = &ids;
  24. Table types       = &tys;
  25. Table labels;
  26. int level = GLOBAL;
  27. List loci, symbols;
  28.  
  29. Table table(tp, level) Table tp; int level; {
  30.     Table new;
  31.  
  32.     NEW0(new, FUNC);
  33.     new->previous = tp;
  34.     new->level = level;
  35.     if (tp)
  36.         new->all = tp->all;
  37.     return new;
  38. }
  39. void foreach(tp, lev, apply, cl) Table tp; int lev;
  40. void (*apply) ARGS((Symbol, void *)); void *cl; {
  41.     assert(tp);
  42.     while (tp && tp->level > lev)
  43.         tp = tp->previous;
  44.     if (tp && tp->level == lev) {
  45.         Symbol p;
  46.         Coordinate sav;
  47.         sav = src;
  48.         for (p = tp->all; p && p->scope == lev; p = p->up) {
  49.             src = p->src;
  50.             (*apply)(p, cl);
  51.         }
  52.         src = sav;
  53.     }
  54. }
  55.  
  56. void ExtendDomain(int lev,int start)
  57. {
  58.     Table tp = identifiers;
  59.     Symbol p;
  60.  
  61.     do {
  62.         if (tp) {
  63.             for (p = tp->all; p && (p->scope <= lev && p->scope >= PARAM); p = p->up) {
  64.                 if (p->lastuse >= start) {
  65. #if 0
  66.                     printf("Extending %s to %d\n",p->name,StatementCount);
  67. #endif
  68.                     p->lastuse = StatementCount;
  69.                 }
  70.             }
  71.         }
  72.         lev--;
  73.         tp = tp->previous;
  74.     } while (tp && lev >= PARAM);
  75. }
  76.  
  77.  
  78. void enterscope() {
  79.     ++level;
  80. }
  81. void exitscope() {
  82.     rmtypes(level);
  83.     if (types->level == level)
  84.         types = types->previous;
  85.     if (identifiers->level == level) {
  86.         if (Aflag >= 2) {
  87.             int n = 0;
  88.             Symbol p;
  89.             for (p = identifiers->all; p && p->scope == level; p = p->up)
  90.                 if (++n > 127) {
  91.                     warning("more than 127 identifiers declared in a block\n");
  92.                     break;
  93.                 }
  94.         }
  95.         identifiers = identifiers->previous;
  96.     }
  97.     assert(level >= GLOBAL);
  98.     --level;
  99. }
  100. Symbol install(name, tpp, level, arena)
  101. char *name; Table *tpp; int level, arena; {
  102.     Table tp = *tpp;
  103.     struct entry *p;
  104.     unsigned h = (unsigned)name&(HASHSIZE-1);
  105.  
  106.     assert(level == 0 || level >= tp->level);
  107.     if (level > 0 && tp->level < level)
  108.         tp = *tpp = table(tp, level);
  109.     NEW0(p, arena);
  110.     p->sym.name = name;
  111.     p->sym.scope = level;
  112.     p->sym.up = tp->all;
  113.     tp->all = &p->sym;
  114.     p->link = tp->buckets[h];
  115.     tp->buckets[h] = p;
  116.     return &p->sym;
  117. }
  118. Symbol lookup(name, tp) char *name; Table tp; {
  119.     struct entry *p;
  120.     unsigned h = (unsigned)name&(HASHSIZE-1);
  121.  
  122.     assert(tp);
  123.     do
  124.         for (p = tp->buckets[h]; p; p = p->link)
  125.             if (name == p->sym.name)
  126.                 return &p->sym;
  127.     while ((tp = tp->previous) != NULL);
  128.     return NULL;
  129. }
  130. int genlabel(int n)
  131. {
  132.     static int label = 1;
  133.  
  134.     label += n;
  135.     return label - n;
  136. }
  137. Symbol findlabel(int lab)
  138. {
  139.     struct entry *p;
  140.     unsigned h = lab&(HASHSIZE-1);
  141.  
  142.     for (p = labels->buckets[h]; p; p = p->link)
  143.         if (lab == p->sym.u.l.label)
  144.             return &p->sym;
  145.     NEW0(p, FUNC);
  146.     p->sym.name = stringd(lab);
  147.     p->sym.scope = LABELS;
  148.     p->sym.up = labels->all;
  149.     labels->all = &p->sym;
  150.     p->link = labels->buckets[h];
  151.     labels->buckets[h] = p;
  152.     p->sym.generated = 1;
  153.     p->sym.u.l.label = lab;
  154.     p->sym.islabel = 1;
  155.     (*IR->defsymbol)(&p->sym);
  156.     return &p->sym;
  157. }
  158. Symbol constant(ty, v) Type ty; Value v; {
  159.     struct entry *p;
  160.     unsigned h = v.u&(HASHSIZE-1);
  161.  
  162.     ty = unqual(ty);
  163.     for (p = constants->buckets[h]; p; p = p->link)
  164.         if (eqtype(ty, p->sym.type, 1))
  165.             switch (ty->op) {
  166.             case CHAR:     if (equalp(uc)) return &p->sym; break;
  167.             case SHORT:    if (equalp(ss)) return &p->sym; break;
  168.             case INT:      if (equalp(i))  return &p->sym; break;
  169.             case UNSIGNED: if (equalp(u))  return &p->sym; break;
  170.             case FLOAT:    if (equalp(f))  return &p->sym; break;
  171.             case DOUBLE:   if (equalp(d))  return &p->sym; break;
  172.             case ARRAY: case FUNCTION:
  173.             case POINTER:  if (equalp(p))  return &p->sym; break;
  174.             case LONGLONG: if (equalp(d)) return &p->sym; break;
  175.             default: assert(0);
  176.             }
  177.     NEW0(p, PERM);
  178.     p->sym.name = vtoa(ty, v);
  179.     p->sym.scope = CONSTANTS;
  180.     p->sym.type = ty;
  181.     p->sym.sclass = STATIC;
  182.     p->sym.isconstant = 1;
  183.     p->sym.u.c.v = v;
  184.     p->link = constants->buckets[h];
  185.     p->sym.up = constants->all;
  186.     constants->all = &p->sym;
  187.     constants->buckets[h] = p;
  188.     if (ty->u.sym && !ty->u.sym->addressed)
  189.         (*IR->defsymbol)(&p->sym);
  190.     p->sym.defined = 1;
  191.     p->sym.isconstant = 1;
  192.     return &p->sym;
  193. }
  194. Symbol intconst(int n)
  195. {
  196.     Value v;
  197.  
  198.     v.i = n;
  199.     return constant(inttype, v);
  200. }
  201. Symbol genident(int scls,Type ty,int lev)
  202. {
  203.     Symbol p;
  204.  
  205.     NEW0(p, lev >= LOCAL ? FUNC : PERM);
  206.     p->name = stringd(genlabel(1));
  207.     p->scope = lev;
  208.     p->sclass = scls;
  209.     p->type = ty;
  210.     p->generated = 1;
  211.     if (lev == GLOBAL)
  212.         (*IR->defsymbol)(p);
  213.     return p;
  214. }
  215.  
  216. Symbol temporary(int scls,Type ty,int lev)
  217. {
  218.     Symbol p = genident(scls, ty, lev);
  219.  
  220.     p->temporary = 1;
  221.     return p;
  222. }
  223. Symbol newtemp(sclass, tc) int sclass, tc; {
  224.     Symbol p = temporary(sclass, btot(tc), LOCAL);
  225.  
  226.     (*IR->local)(p);
  227.     p->defined = 1;
  228.     return p;
  229. }
  230.  
  231. void locus(Table tp,Coordinate *cp)
  232. {
  233.     loci    = append(cp, loci);
  234.     symbols = append(tp->all, symbols);
  235. }
  236.  
  237. void use(Symbol p,Coordinate src)
  238. {
  239.     Coordinate *cp;
  240.  
  241.     NEW(cp, PERM);
  242.     *cp = src;
  243.     p->uses = append(cp, p->uses);
  244. }
  245. /* findtype - find type ty in identifiers */
  246. Symbol findtype(Type ty)
  247. {
  248.     Table tp = identifiers;
  249.     int i;
  250.     struct entry *p;
  251.  
  252.     assert(tp);
  253.     do
  254.         for (i = 0; i < HASHSIZE; i++)
  255.             for (p = tp->buckets[i]; p; p = p->link)
  256.                 if (p->sym.type == ty && p->sym.sclass == TYPEDEF)
  257.                     return &p->sym;
  258.     while ((tp = tp->previous) != NULL);
  259.     return NULL;
  260. }
  261.  
  262. /* mkstr - make a string constant */
  263. Symbol mkstr(str) char *str; {
  264.     Value v;
  265.     Symbol p;
  266.  
  267.     v.p = str;
  268.     p = constant(array(chartype, strlen(v.p) + 1, 0), v);
  269.     if (p->u.c.loc == NULL)
  270.         p->u.c.loc = genident(STATIC, p->type, GLOBAL);
  271.     return p;
  272. }
  273.  
  274. /* mksymbol - make a symbol for name, install in &globals if sclass==EXTERN */
  275. Symbol mksymbol(sclass, name, ty) int sclass; char *name; Type ty; {
  276.     Symbol p;
  277.  
  278.     if (sclass == EXTERN)
  279.         p = install(string(name), &globals, GLOBAL, PERM);
  280.     else {
  281.         NEW0(p, PERM);
  282.         p->name = string(name);
  283.         p->scope = GLOBAL;
  284.     }
  285.     p->sclass = sclass;
  286.     p->type = ty;
  287.     (*IR->defsymbol)(p);
  288.     p->defined = 1;
  289.     return p;
  290. }
  291.  
  292. /* vtoa - return string for the constant v of type ty */
  293. char *vtoa(ty, v) Type ty; Value v; {
  294.     char buf[50];
  295.  
  296.     ty = unqual(ty);
  297.     switch (ty->op) {
  298.     case CHAR:
  299.         return stringd(v.uc);
  300.     case SHORT:
  301.         return stringd(v.ss);
  302.     case INT:
  303.         return stringd(v.i);
  304.     case UNSIGNED:
  305.         if ((v.u&~0x7fff) == 0)
  306.             return stringd(v.u);
  307.         else if (v.u)
  308.             return stringf("0x%x", v.u);
  309.         else
  310.             return stringf("%d", v.u);
  311.     case FLOAT:
  312.         sprintf(buf, "%.8g", v.f);
  313.         return string(buf);
  314.     case DOUBLE:
  315.     case LONGLONG:
  316.         sprintf(buf, "%.18g", v.d);
  317.         return string(buf);
  318.     case ARRAY:
  319.         if (ty->type->op == CHAR)
  320.             return v.p;
  321.         /* else fall thru */
  322.     case POINTER: case FUNCTION:
  323.         if (v.p)
  324.         return stringf("0x%x", v.p);
  325.         else
  326.         return stringf("%d", v.p);
  327.  
  328.     default:assert(0);
  329.     }
  330.     return NULL;
  331. }
  332. void IncrementReferences(Symbol sym)
  333. {
  334.     sym->ref++;
  335.     sym->lastuse = StatementCount;
  336.     if (sym->firstuse == 0)
  337.         sym->firstuse = sym->lastuse;
  338. }
  339.  
  340. void Initreferences(Symbol sym)
  341. {
  342.     sym->firstuse = sym->lastuse = StatementCount;
  343. }