00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 # include "lclintMacros.nf"
00044 # include "llbasic.h"
00045 # include "gram.h"
00046 # include "lclscan.h"
00047 # include "lclsyntable.h"
00048 # include "lslparse.h"
00049
00050
00051
00052 static bool isBlankLine (char *p_line);
00053 static bool inImport = FALSE;
00054
00055
00056 # define MAXBUFFLEN 512
00057
00058 # define DELTA 100
00059
00060 static void symHashTable_dump (symHashTable * p_t, FILE * p_f, bool p_lco);
00061
00062 static void tagInfo_free ( tagInfo p_tag);
00063 static scopeInfo symtable_scopeInfo (symtable p_stable);
00064
00065 static void symtable_dumpId (symtable p_stable, FILE *p_f, bool p_lco);
00066 static lsymbol nameNode2key (nameNode p_n);
00067
00068 typedef enum
00069 {
00070 SYMK_FCN, SYMK_SCOPE, SYMK_TYPE, SYMK_VAR
00071 } symKind;
00072
00073 typedef struct
00074 {
00075 symKind kind;
00076 union
00077 {
00078 fctInfo fct;
00079 scopeInfo scope;
00080 typeInfo type;
00081 varInfo var;
00082 } info;
00083 } idTableEntry;
00084
00085 typedef struct _idTable
00086 {
00087 unsigned int size;
00088 unsigned int allocated;
00089 idTableEntry *entries;
00090 bool exporting;
00091 } idTable;
00092
00093 struct _symtableStruct
00094 {
00095 idTable *idTable;
00096 symHashTable *hTable;
00097 mapping *type2sort;
00098 } ;
00099
00100 static ltoken idTableEntry_getId (idTableEntry *p_x);
00101 static idTableEntry *nextFree (idTable * p_st);
00102 static idTableEntry *symtable_lookup (idTable * p_st, lsymbol p_id);
00103 static idTableEntry *symtable_lookupInScope (idTable * p_st, lsymbol p_id);
00104
00105 static idTable *symtable_newIdTable (void);
00106 static void idTableEntry_free (idTableEntry p_x);
00107
00108
00109
00110 static bool allowed_redeclaration = FALSE;
00111 static symbolKey htData_key (htData *p_x);
00112
00113 static void symHashTable_free ( symHashTable *p_h);
00114 static symHashTable *symHashTable_create (unsigned int p_size);
00115 static htData *
00116 symHashTable_get (symHashTable * p_t, symbolKey p_key, infoKind p_kind,
00117 nameNode p_n);
00118 static bool symHashTable_put (symHashTable *p_t, htData *p_data);
00119 static htData *
00120 symHashTable_forcePut (symHashTable * p_t, htData *p_data);
00121
00122
00123 static void idTable_free ( idTable *p_st);
00124
00125 void varInfo_free ( varInfo v)
00126 {
00127 sfree (v);
00128 }
00129
00130 static varInfo varInfo_copy (varInfo v)
00131 {
00132 varInfo ret = (varInfo) dmalloc (sizeof (*ret));
00133
00134 ret->id = ltoken_copy (v->id);
00135 ret->sort = v->sort;
00136 ret->kind = v->kind;
00137 ret->export = v->export;
00138
00139 return ret;
00140 }
00141
00142 void symtable_free (symtable stable)
00143 {
00144
00145
00146 idTable_free (stable->idTable);
00147 symHashTable_free (stable->hTable);
00148 mapping_free (stable->type2sort);
00149 sfree (stable);
00150 }
00151
00152 static void idTable_free (idTable *st)
00153 {
00154 unsigned int i;
00155
00156 for (i = 0; i < st->size; i++)
00157 {
00158 idTableEntry_free (st->entries[i]);
00159 }
00160
00161 sfree (st->entries);
00162 sfree (st);
00163 }
00164
00165 static void fctInfo_free ( fctInfo f)
00166 {
00167 signNode_free (f->signature);
00168 pairNodeList_free (f->globals);
00169 ltoken_free (f->id);
00170 sfree (f);
00171 }
00172
00173 static void typeInfo_free ( typeInfo t)
00174 {
00175 sfree (t);
00176 }
00177
00178 static void scopeInfo_free ( scopeInfo s)
00179 {
00180 sfree (s);
00181 }
00182
00183 static void idTableEntry_free (idTableEntry x)
00184 {
00185 switch (x.kind)
00186 {
00187 case SYMK_FCN:
00188 fctInfo_free (x.info.fct);
00189 break;
00190 case SYMK_SCOPE:
00191 scopeInfo_free (x.info.scope);
00192 break;
00193 case SYMK_TYPE:
00194 typeInfo_free (x.info.type);
00195 break;
00196 case SYMK_VAR:
00197 varInfo_free (x.info.var);
00198 break;
00199 }
00200 }
00201
00202 static ltoken idTableEntry_getId (idTableEntry *x)
00203 {
00204 switch (x->kind)
00205 {
00206 case SYMK_FCN:
00207 return (x->info.fct->id);
00208 case SYMK_SCOPE:
00209 return ltoken_undefined;
00210 case SYMK_TYPE:
00211 return (x->info.type->id);
00212 case SYMK_VAR:
00213 return (x->info.var->id);
00214 }
00215
00216 BADBRANCH;
00217 }
00218
00219 symtable
00220 symtable_new (void)
00221 {
00222 symtable stable = (symtable) dmalloc (sizeof (*stable));
00223 idTableEntry *e;
00224
00225 stable->idTable = symtable_newIdTable ();
00226 stable->hTable = symHashTable_create (HT_MAXINDEX);
00227 stable->type2sort = mapping_create ();
00228
00229
00230
00231 mapping_bind (stable->type2sort, lsymbol_getBool (), lsymbol_getbool ());
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241 e = nextFree (stable->idTable);
00242 e->kind = SYMK_SCOPE;
00243 (e->info).scope = (scopeInfo) dmalloc (sizeof (*((e->info).scope)));
00244 (e->info).scope->kind = SPE_GLOBAL;
00245
00246 return stable;
00247 }
00248
00249 static idTable *symtable_newIdTable (void)
00250 {
00251 idTable *st = (idTable *) dmalloc (sizeof (*st));
00252
00253 st->size = 0;
00254 st->allocated = 0;
00255 st->entries = (idTableEntry *) 0;
00256 st->exporting = TRUE;
00257
00258
00259
00260
00261
00262
00263
00264 return st;
00265 }
00266
00267 static lsymbol
00268 nameNode2key (nameNode n)
00269 {
00270 unsigned int ret;
00271
00272 if (n->isOpId)
00273 {
00274 ret = ltoken_getText (n->content.opid);
00275 }
00276 else
00277 {
00278
00279 llassert (n->content.opform != NULL);
00280 ret = (n->content.opform)->key;
00281 }
00282
00283 return ret;
00284 }
00285
00286
00287
00288
00289
00290 static bool
00291 htData_insertSignature (htData *d, sigNode oi)
00292 {
00293 sigNodeSet set = d->content.op->signatures;
00294
00295
00296 if (oi != (sigNode) 0)
00297 {
00298 return (sigNodeSet_insert (set, oi));
00299 }
00300 return FALSE;
00301 }
00302
00303 void
00304 symtable_enterOp (symtable st, nameNode n,
00305 sigNode oi)
00306 {
00307
00308
00309
00310
00311
00312
00313
00314 symHashTable *ht = st->hTable;
00315 htData *d;
00316 lsymbol id;
00317
00318
00319
00320 id = nameNode2key (n);
00321
00322 d = symHashTable_get (ht, id, IK_OP, n);
00323
00324 if (d == (htData *) 0)
00325 {
00326 opInfo op = (opInfo) dmalloc (sizeof (*op));
00327 htData *nd = (htData *) dmalloc (sizeof (*nd));
00328
00329 op->name = n;
00330
00331 if (oi != (sigNode) 0)
00332 {
00333 op->signatures = sigNodeSet_singleton (oi);
00334 ht->count++;
00335 }
00336 else
00337 {
00338 op->signatures = sigNodeSet_new ();
00339 sigNode_markOwned (oi);
00340 }
00341
00342 nd->kind = IK_OP;
00343 nd->content.op = op;
00344 (void) symHashTable_put (ht, nd);
00345 }
00346 else
00347 {
00348
00349 nameNode_free (n);
00350
00351 if (htData_insertSignature (d, oi))
00352 {
00353 ht->count++;
00354 }
00355 }
00356 }
00357
00358 bool
00359 symtable_enterTag (symtable st, tagInfo ti)
00360 {
00361
00362 symHashTable *ht = st->hTable;
00363 htData *d;
00364 symbolKey key = ltoken_getText (ti->id);
00365
00366 d = symHashTable_get (ht, key, IK_TAG, (nameNode) 0);
00367 if (d == (htData *) 0)
00368 {
00369 d = (htData *) dmalloc (sizeof (*d));
00370 d->kind = IK_TAG;
00371 d->content.tag = ti;
00372 d->content.tag->imported = context_inImport ();
00373 (void) symHashTable_put (ht, d);
00374 return TRUE;
00375 }
00376 else
00377 {
00378 if (d->content.tag->imported)
00379 {
00380 d->content.tag = ti;
00381 d->content.tag->imported = context_inImport ();
00382 return TRUE;
00383 }
00384 else
00385 {
00386 tagInfo_free (ti);
00387 return FALSE;
00388 }
00389 }
00390 }
00391
00392 bool
00393 symtable_enterTagForce (symtable st, tagInfo ti)
00394 {
00395
00396 symHashTable *ht = st->hTable;
00397 htData *d;
00398 symbolKey key = ltoken_getText (ti->id);
00399
00400 d = symHashTable_get (ht, key, IK_TAG, (nameNode) 0);
00401
00402 if (d == (htData *) 0)
00403 {
00404 d = (htData *) dmalloc (sizeof (*d));
00405
00406 d->kind = IK_TAG;
00407 d->content.tag = ti;
00408 d->content.tag->imported = context_inImport ();
00409 (void) symHashTable_put (ht, d);
00410 return TRUE;
00411 }
00412 else
00413 {
00414
00415 d->kind = IK_TAG;
00416 d->content.tag = ti;
00417 d->content.tag->imported = context_inImport ();
00418
00419 (void) symHashTable_forcePut (ht, d);
00420 return FALSE;
00421 }
00422 }
00423
00424 opInfo
00425 symtable_opInfo (symtable st, nameNode n)
00426 {
00427 symHashTable *ht = st->hTable;
00428 lsymbol i = nameNode2key (n);
00429
00430 htData *d;
00431 d = symHashTable_get (ht, i, IK_OP, n);
00432 if (d == (htData *) 0)
00433 {
00434 return (opInfo)NULL;
00435 }
00436
00437 return (d->content.op);
00438 }
00439
00440 tagInfo
00441 symtable_tagInfo (symtable st, lsymbol i)
00442 {
00443 symHashTable *ht = st->hTable;
00444 htData *d;
00445 d = symHashTable_get (ht, i, IK_TAG, 0);
00446
00447 if (d == (htData *) 0)
00448 {
00449 return (tagInfo) NULL;
00450 }
00451
00452 return (d->content.tag);
00453 }
00454
00455 void
00456 symtable_enterScope (symtable stable, scopeInfo si)
00457 {
00458 idTable *st = stable->idTable;
00459 idTableEntry *e = nextFree (st);
00460 if (si->kind == SPE_GLOBAL)
00461 llbuglit ("symtable_enterScope: SPE_GLOBAL");
00462 e->kind = SYMK_SCOPE;
00463 (e->info).scope = si;
00464 }
00465
00466 void
00467 symtable_exitScope (symtable stable)
00468 {
00469 idTable *st = stable->idTable;
00470 int n;
00471
00472 if (st->entries != NULL)
00473 {
00474 for (n = st->size - 1; (st->entries[n]).kind != SYMK_SCOPE; n--)
00475 {
00476 ;
00477 }
00478 }
00479 else
00480 {
00481 llcontbuglit ("symtable_exitScope: no scope to exit");
00482 n = 0;
00483 }
00484
00485 st->size = n;
00486 }
00487
00488 bool
00489 symtable_enterFct (symtable stable, fctInfo fi)
00490 {
00491 idTable *st = stable->idTable;
00492 idTableEntry *e;
00493 bool redecl = FALSE;
00494
00495 if (!allowed_redeclaration &&
00496 symtable_lookup (st, ltoken_getText (fi->id)) != (idTableEntry *) 0)
00497 {
00498 lclRedeclarationError (fi->id);
00499 redecl = TRUE;
00500 }
00501
00502 e = nextFree (st);
00503 e->kind = SYMK_FCN;
00504 fi->export = st->exporting;
00505 (e->info).fct = fi;
00506
00507 return redecl;
00508 }
00509
00510 void
00511 symtable_enterType (symtable stable, typeInfo ti)
00512 {
00513 idTable *st = stable->idTable;
00514 idTableEntry *e;
00515 bool insertp = TRUE;
00516 scopeKind k = (symtable_scopeInfo (stable))->kind;
00517
00518
00519
00520 if (k != SPE_GLOBAL && k != SPE_INVALID)
00521 {
00522 llbug (message ("%q: symtable_enterType: expect global scope. (type: %s)",
00523 ltoken_unparseLoc (ti->id),
00524 ltoken_getRawString (ti->id)));
00525 }
00526
00527 if (!allowed_redeclaration &&
00528 symtable_lookup (st, ltoken_getText (ti->id)) != (idTableEntry *) 0)
00529 {
00530
00531 if (ltoken_getText (ti->id) == lsymbol_getBool () ||
00532 ltoken_getText (ti->id) == lsymbol_getbool ())
00533 {
00534 insertp = FALSE;
00535 }
00536 else
00537 {
00538 lclRedeclarationError (ti->id);
00539 }
00540 }
00541 if (insertp)
00542 {
00543
00544
00545 if (ltoken_getCode (ti->id) != LLT_TYPEDEF_NAME)
00546 {
00547 lclbug (message ("symtable_enterType: gets a simpleId, expect a type: %s",
00548 ltoken_getRawString (ti->id)));
00549 }
00550
00551 e = nextFree (st);
00552 e->kind = SYMK_TYPE;
00553 ti->export = st->exporting;
00554 (e->info).type = ti;
00555 mapping_bind (stable->type2sort, ltoken_getText (ti->id),
00556 sort_getLsymbol (sort_makeVal (sort_getUnderlying (ti->basedOn))));
00557 }
00558 else
00559 {
00560 typeInfo_free (ti);
00561 }
00562 }
00563
00564 lsymbol
00565 lsymbol_sortFromType (symtable s, lsymbol typename)
00566 {
00567 lsymbol inter;
00568 lsymbol out;
00569 ltoken tok;
00570
00571 if (LCLIsSyn (typename))
00572 {
00573 tok = LCLGetTokenForSyn (typename);
00574 inter = ltoken_getText (tok);
00575
00576
00577 }
00578 else
00579 {
00580 inter = typename;
00581 }
00582
00583
00584 out = mapping_find (s->type2sort, inter);
00585
00586 if (out == lsymbol_undefined)
00587 {
00588 return inter;
00589 }
00590
00591 return out;
00592 }
00593
00594
00595
00596
00597
00598
00599
00600 bool
00601 symtable_enterVar (symtable stable, varInfo vi)
00602 {
00603 idTable *st = stable->idTable;
00604 bool insertp = TRUE;
00605 bool redecl = FALSE;
00606
00607
00608
00609
00610 if (!allowed_redeclaration &&
00611 (symtable_lookupInScope (st, ltoken_getText (vi->id)) != (idTableEntry *) 0))
00612 {
00613 if (ltoken_getText (vi->id) == lsymbol_getTRUE () ||
00614 ltoken_getText (vi->id) == lsymbol_getFALSE ())
00615 {
00616 insertp = FALSE;
00617 }
00618 else
00619 {
00620 if (usymtab_existsEither (ltoken_getRawString (vi->id)))
00621 {
00622 lclRedeclarationError (vi->id);
00623 redecl = TRUE;
00624 }
00625 else
00626 {
00627 llbuglit ("redeclared somethingerother?!");
00628 }
00629 }
00630 }
00631
00632 if (insertp)
00633 {
00634 idTableEntry *e = nextFree (st);
00635
00636 e->kind = SYMK_VAR;
00637 vi->export = st->exporting &&
00638 (vi->kind == VRK_VAR || vi->kind == VRK_CONST || vi->kind == VRK_ENUM);
00639 (e->info).var = varInfo_copy (vi);
00640 }
00641
00642 return (redecl);
00643 }
00644
00645 bool
00646 symtable_exists (symtable stable, lsymbol i)
00647 {
00648 idTable *st = stable->idTable;
00649 return symtable_lookup (st, i) != (idTableEntry *) 0;
00650 }
00651
00652 typeInfo
00653 symtable_typeInfo (symtable stable, lsymbol i)
00654 {
00655 idTable *st;
00656 idTableEntry *e;
00657
00658 st = stable->idTable;
00659 e = symtable_lookup (st, i);
00660
00661 if (e == (idTableEntry *) 0 || e->kind != SYMK_TYPE)
00662 {
00663 return (typeInfo) NULL;
00664 }
00665
00666 return (e->info).type;
00667 }
00668
00669 varInfo
00670 symtable_varInfo (symtable stable, lsymbol i)
00671 {
00672 idTable *st = stable->idTable;
00673 idTableEntry *e;
00674
00675 e = symtable_lookup (st, i);
00676
00677 if (e == (idTableEntry *) 0 || e->kind != SYMK_VAR)
00678 {
00679 return (varInfo) NULL;
00680 }
00681
00682 return (e->info).var;
00683 }
00684
00685 varInfo
00686 symtable_varInfoInScope (symtable stable, lsymbol id)
00687 {
00688
00689 idTable *st = stable->idTable;
00690 idTableEntry *e2 = (idTableEntry *) 0;
00691 int n;
00692
00693 for (n = st->size - 1; n >= 0; n--)
00694 {
00695 ltoken tok;
00696
00697 e2 = &(st->entries[n]);
00698
00699 if (e2->kind == SYMK_SCOPE && e2->info.scope->kind != SPE_QUANT)
00700 {
00701 return (varInfo) NULL;
00702 }
00703
00704 tok = idTableEntry_getId (e2);
00705
00706 if (e2->kind == SYMK_VAR && ltoken_getText (tok) == id)
00707 {
00708 return (e2->info).var;
00709 }
00710 }
00711
00712 return (varInfo) NULL;
00713 }
00714
00715 scopeInfo
00716 symtable_scopeInfo (symtable stable)
00717 {
00718 idTable *st = stable->idTable;
00719 int n;
00720 idTableEntry *e;
00721
00722 for (n = st->size - 1; n >= 0; n--)
00723 {
00724 e = &(st->entries[n]);
00725 if (e->kind == SYMK_SCOPE)
00726 return (e->info).scope;
00727 }
00728
00729 lclfatalbug ("symtable_scopeInfo: not found");
00730 BADEXIT;
00731 }
00732
00733 void
00734 symtable_export (symtable stable, bool yesNo)
00735 {
00736 idTable *st = stable->idTable;
00737 st->exporting = yesNo;
00738 (void) sort_setExporting (yesNo);
00739 }
00740
00741 static void
00742 symHashTable_dump (symHashTable * t, FILE * f, bool lco)
00743 {
00744
00745 int i, size;
00746 bucket *b;
00747 htEntry *entry;
00748 htData *d;
00749 ltoken tok;
00750 sigNodeSet sigs;
00751
00752 for (i = 0; i <= HT_MAXINDEX; i++)
00753 {
00754 b = t->buckets[i];
00755
00756 for (entry = b; entry != NULL; entry = entry->next)
00757 {
00758 d = entry->data;
00759
00760 switch (d->kind)
00761 {
00762 case IK_SORT:
00763 break;
00764 case IK_OP:
00765 {
00766 char *name = cstring_toCharsSafe (nameNode_unparse (d->content.op->name));
00767 sigs = d->content.op->signatures;
00768 size = sigNodeSet_size (sigs);
00769
00770
00771 sigNodeSet_elements (sigs, x)
00772 {
00773 cstring s = sigNode_unparse (x);
00774
00775 if (lco)
00776 {
00777 fprintf (f, "%%LCL");
00778 }
00779
00780 fprintf (f, "op %s %s\n", name, cstring_toCharsSafe (s));
00781 cstring_free (s);
00782 } end_sigNodeSet_elements;
00783
00784 sfree (name);
00785 break;
00786 }
00787 case IK_TAG:
00788 tok = d->content.tag->id;
00789
00790 if (!ltoken_isUndefined (tok))
00791 {
00792 cstring s = tagKind_unparse (d->content.tag->kind);
00793
00794 if (lco)
00795 {
00796 fprintf (f, "%%LCL");
00797 }
00798
00799 fprintf (f, "tag %s %s\n", ltoken_getTextChars (tok),
00800 cstring_toCharsSafe (s));
00801 cstring_free (s);
00802 }
00803 break;
00804 }
00805 }
00806 }
00807 }
00808
00809 void
00810 symtable_dump (symtable stable, FILE * f, bool lco)
00811 {
00812 symHashTable *ht = stable->hTable;
00813
00814
00815 fprintf (f, "%s\n", BEGINSYMTABLE);
00816
00817 symHashTable_dump (ht, f, lco);
00818
00819 symtable_dumpId (stable, f, lco);
00820
00821 fprintf (f, "%s\n", SYMTABLEEND);
00822 }
00823
00824 lsymbol
00825 lsymbol_translateSort (mapping * m, lsymbol s)
00826 {
00827 lsymbol res = mapping_find (m, s);
00828 if (res == lsymbol_undefined)
00829 return s;
00830 return res;
00831 }
00832
00833 static lslOp
00834 lslOp_renameSorts (mapping *map, lslOp op)
00835 {
00836 sigNode sign;
00837
00838 if (op != (lslOp) 0)
00839 {
00840 ltokenList domain;
00841 ltoken range;
00842
00843 sign = op->signature;
00844 range = sign->range;
00845 domain = sign->domain;
00846
00847 ltokenList_elements (domain, dt)
00848 {
00849 ltoken_setText (dt,
00850 lsymbol_translateSort (map, ltoken_getText (dt)));
00851 } end_ltokenList_elements;
00852
00853
00854 op->signature = makesigNode (sign->tok, domain, range);
00855
00856 }
00857
00858 return op;
00859 }
00860
00861 static signNode
00862 signNode_fromsigNode (sigNode s)
00863 {
00864 signNode sign;
00865 sortList slist;
00866
00867 if (s == (sigNode) 0)
00868 {
00869 return (signNode) 0;
00870 }
00871
00872 sign = (signNode) dmalloc (sizeof (*sign));
00873 slist = sortList_new ();
00874 sign->tok = ltoken_copy (s->tok);
00875 sign->key = s->key;
00876 sign->range = sort_makeSort (ltoken_undefined, ltoken_getText (s->range));
00877
00878 ltokenList_elements (s->domain, dt)
00879 {
00880 sortList_addh (slist, sort_makeSort (ltoken_undefined, ltoken_getText (dt)));
00881 } end_ltokenList_elements;
00882
00883 sign->domain = slist;
00884 return sign;
00885 }
00886
00887
00892 static pairNodeList
00893 parseGlobals (char *line, tsource *srce)
00894 {
00895 pairNodeList plist = pairNodeList_new ();
00896 pairNode p;
00897 int semi_index;
00898 char *lineptr, sostr[MAXBUFFLEN], gstr[MAXBUFFLEN];
00899
00900
00901
00902 lineptr = line;
00903
00904 while (!isBlankLine (lineptr))
00905 {
00906 if (sscanf (lineptr, "%s %s", &(sostr[0]), gstr) != 2)
00907 {
00908 lclplainerror
00909 (message
00910 ("%q: Imported file contains illegal function global declaration.\n"
00911 "Skipping rest of the line: %s (%s)",
00912 fileloc_unparseRaw (cstring_fromChars (tsource_fileName (srce)),
00913 tsource_thisLineNumber (srce)),
00914 cstring_fromChars (line),
00915 cstring_fromChars (lineptr)));
00916 return plist;
00917 }
00918
00919 p = (pairNode) dmalloc (sizeof (*p));
00920
00921
00922 semi_index = size_toInt (strlen (gstr));
00923 gstr[semi_index - 1] = '\0';
00924
00925 p->tok = ltoken_create (NOTTOKEN, lsymbol_fromChars (gstr));
00926 p->sort = sort_makeSort (ltoken_undefined, lsymbol_fromChars (sostr));
00927
00928 pairNodeList_addh (plist, p);
00929 lineptr = strchr (lineptr, ';');
00930
00931 llassert (lineptr != NULL);
00932 lineptr = lineptr + 1;
00933 }
00934
00935 return plist;
00936 }
00937
00938 static bool
00939 isBlankLine (char *line)
00940 {
00941 int i;
00942
00943 if (line == NULL) return TRUE;
00944
00945 for (i = 0; line[i] != '\0'; i++)
00946 {
00947 if (line[i] == ' ')
00948 continue;
00949 if (line[i] == '\t')
00950 continue;
00951 if (line[i] == '\n')
00952 return TRUE;
00953 return FALSE;
00954 }
00955 return TRUE;
00956 }
00957
00958 typedef fctInfo o_fctInfo;
00959
00960 static void
00961 parseLine (char *line, tsource *srce, mapping * map)
00962 {
00963 static o_fctInfo *savedFcn = NULL;
00964 char *lineptr, *lineptr2, *cimportfile = tsource_fileName (srce);
00965 cstring importfile = cstring_fromChars (cimportfile);
00966 char namestr[MAXBUFFLEN], kstr[20], sostr[MAXBUFFLEN];
00967 sort bsort, nullSort = sort_makeNoSort ();
00968 int col = 0;
00969 fileloc imploc = fileloc_undefined;
00970
00971
00972 if (inImport)
00973 {
00974 imploc = fileloc_createImport (importfile, tsource_thisLineNumber (srce));
00975 }
00976
00977 if (firstWord (line, "op"))
00978 {
00979 lslOp op;
00980
00981 lineptr = strchr (line, 'o');
00982 llassert (lineptr != NULL);
00983 lineptr = strchr (lineptr, ' ');
00984 llassert (lineptr != NULL);
00985
00986
00987 lineptr2 = strchr (lineptr, '\0');
00988
00989 if (lineptr2 != 0)
00990 {
00991 *lineptr2 = '\n';
00992 *(lineptr2 + 1) = '\0';
00993 }
00994
00995 llassert (cimportfile != NULL);
00996 op = parseOpLine (cimportfile, lineptr + 1);
00997
00998 if (op == (lslOp) 0)
00999 {
01000 lclplainerror
01001 (message
01002 ("%q: Imported file contains illegal operator declaration:\n "
01003 "skipping this line: %s",
01004 fileloc_unparseRaw (importfile, tsource_thisLineNumber (srce)),
01005 cstring_fromChars (line)));
01006 fileloc_free (imploc);
01007 return;
01008 }
01009
01010 op = lslOp_renameSorts (map, op);
01011
01012 llassert (op != NULL);
01013 llassert (op->name != NULL);
01014
01015 symtable_enterOp (g_symtab, op->name,
01016 sigNode_copy (op->signature));
01017 }
01018 else if (firstWord (line, "type"))
01019 {
01020 typeInfo ti;
01021
01022 if (sscanf (line, "type %s %s %s", namestr, sostr, kstr) != 3)
01023 {
01024 lclplainerror
01025 (message ("%q: illegal type declaration:\n skipping this line: %s",
01026 fileloc_unparseRaw (importfile, tsource_thisLineNumber (srce)),
01027 cstring_fromChars (line)));
01028 fileloc_free (imploc);
01029 return;
01030 }
01031
01032 ti = (typeInfo) dmalloc (sizeof (*ti));
01033 ti->id = ltoken_createFull (LLT_TYPEDEF_NAME, lsymbol_fromChars (namestr),
01034 importfile, tsource_thisLineNumber (srce), col);
01035
01036 bsort = sort_lookupName (lsymbol_translateSort (map, lsymbol_fromChars (sostr)));
01037
01038 if (sort_isNoSort (bsort))
01039 {
01040 lineptr = strchr (line, ' ');
01041 llassert (lineptr != NULL);
01042 lineptr = strchr (lineptr + 1, ' ');
01043 llassert (lineptr != NULL);
01044 col = 5 + lineptr - line;
01045
01046 lclbug (message ("%q: Imported files contains unknown base sort",
01047 fileloc_unparseRawCol (importfile, tsource_thisLineNumber (srce), col)));
01048
01049 bsort = nullSort;
01050 }
01051 ti->basedOn = bsort;
01052
01053 if (strcmp (kstr, "exposed") == 0)
01054 {
01055 ti->abstract = FALSE;
01056 ti->modifiable = TRUE;
01057 }
01058 else
01059 {
01060 ti->abstract = TRUE;
01061 if (strcmp (kstr, "mutable") == 0)
01062 ti->modifiable = TRUE;
01063 else
01064 ti->modifiable = FALSE;
01065 }
01066 ti->export = TRUE;
01067
01068
01069
01070
01071
01072 if (inImport)
01073 {
01074 cstring cnamestr = cstring_fromChars (namestr);
01075
01076 if (!usymtab_existsGlobEither (cnamestr))
01077 {
01078 (void) usymtab_addEntry
01079 (uentry_makeDatatype (cnamestr, ctype_unknown,
01080 ti->abstract ? ynm_fromBool (ti->modifiable) : MAYBE,
01081 ti->abstract ? YES : NO,
01082 fileloc_copy (imploc)));
01083 }
01084 }
01085
01086 symtable_enterType (g_symtab, ti);
01087 }
01088 else if (firstWord (line, "var"))
01089 {
01090 varInfo vi;
01091
01092 if (sscanf (line, "var %s %s", namestr, sostr) != 2)
01093 {
01094 lclplainerror
01095 (message ("%q: Imported file contains illegal variable declaration. "
01096 "Skipping this line.",
01097 fileloc_unparseRaw (importfile, tsource_thisLineNumber (srce))));
01098 fileloc_free (imploc);
01099 return;
01100 }
01101
01102 vi = (varInfo) dmalloc (sizeof (*vi));
01103 bsort = sort_lookupName (lsymbol_translateSort (map, lsymbol_fromChars (sostr)));
01104 lineptr = strchr (line, ' ');
01105 llassert (lineptr != NULL);
01106 lineptr = strchr (lineptr + 1, ' ');
01107 llassert (lineptr != NULL);
01108 col = 5 + lineptr - line;
01109
01110 if (sort_isNoSort (bsort))
01111 {
01112 lclplainerror (message ("%q: Imported file contains unknown base sort",
01113 fileloc_unparseRawCol (importfile, tsource_thisLineNumber (srce), col)));
01114 bsort = nullSort;
01115 }
01116
01117 vi->id = ltoken_createFull (simpleId, lsymbol_fromChars (namestr),
01118 importfile, tsource_thisLineNumber (srce), col);
01119 vi->sort = bsort;
01120 vi->kind = VRK_VAR;
01121 vi->export = TRUE;
01122 (void) symtable_enterVar (g_symtab, vi);
01123 varInfo_free (vi);
01124
01125 if (inImport)
01126 {
01127 cstring cnamestr = cstring_fromChars (namestr);
01128
01129 if (!usymtab_existsGlobEither (cnamestr))
01130 {
01131
01132 (void) usymtab_supEntrySref
01133 (uentry_makeVariable (cnamestr, ctype_unknown,
01134 fileloc_copy (imploc),
01135 FALSE));
01136 }
01137 }
01138 }
01139 else if (firstWord (line, "const"))
01140 {
01141 varInfo vi;
01142
01143 if (sscanf (line, "const %s %s", namestr, sostr) != 2)
01144 {
01145 lclbug (message ("%q: Imported file contains illegal constant declaration: %s",
01146 fileloc_unparseRaw (importfile, tsource_thisLineNumber (srce)),
01147 cstring_fromChars (line)));
01148 fileloc_free (imploc);
01149 return;
01150 }
01151
01152 vi = (varInfo) dmalloc (sizeof (*vi));
01153 bsort = sort_lookupName (lsymbol_translateSort (map, lsymbol_fromChars (sostr)));
01154 lineptr = strchr (line, ' ');
01155 llassert (lineptr != NULL);
01156 lineptr = strchr (lineptr + 1, ' ');
01157 llassert (lineptr != NULL);
01158
01159 col = 5 + lineptr - line;
01160
01161 if (sort_isNoSort (bsort))
01162 {
01163 lclplainerror (message ("%q: Imported file contains unknown base sort",
01164 fileloc_unparseRawCol (importfile, tsource_thisLineNumber (srce), col)));
01165 bsort = nullSort;
01166 }
01167
01168 vi->id = ltoken_createFull (simpleId, lsymbol_fromChars (namestr),
01169 importfile, tsource_thisLineNumber (srce), col);
01170 vi->sort = bsort;
01171 vi->kind = VRK_CONST;
01172 vi->export = TRUE;
01173 (void) symtable_enterVar (g_symtab, vi);
01174 varInfo_free (vi);
01175
01176 if (inImport)
01177 {
01178 cstring cnamestr = cstring_fromChars (namestr);
01179
01180 if (!usymtab_existsGlobEither (cnamestr))
01181 {
01182
01183 (void) usymtab_addEntry (uentry_makeConstant (cnamestr,
01184 ctype_unknown,
01185 fileloc_copy (imploc)));
01186 }
01187 }
01188
01189 }
01190 else if (firstWord (line, "fcnGlobals"))
01191 {
01192 pairNodeList globals;
01193 lineptr = strchr (line, 'f');
01194 llassert (lineptr != NULL);
01195 lineptr = strchr (lineptr, ' ');
01196 llassert (lineptr != NULL);
01197
01198
01199 if (!isBlankLine (lineptr))
01200 {
01201 globals = parseGlobals (lineptr, srce);
01202
01203
01204
01205
01206 }
01207 else
01208 {
01209 globals = pairNodeList_new ();
01210 }
01211
01212
01213
01214 if (savedFcn != NULL)
01215 {
01216 pairNodeList_free ((*savedFcn)->globals);
01217 (*savedFcn)->globals = globals;
01218
01219 (void) symtable_enterFct (g_symtab, *savedFcn);
01220 savedFcn = NULL;
01221 }
01222 else
01223 {
01224 lclplainerror
01225 (message ("%q: Unexpected function globals. "
01226 "Skipping this line: \n%s",
01227 fileloc_unparseRaw (importfile, tsource_thisLineNumber (srce)),
01228 cstring_fromChars (line)));
01229 savedFcn = NULL;
01230 pairNodeList_free (globals);
01231 }
01232 }
01233 else if (firstWord (line, "fcn"))
01234 {
01235 lslOp op;
01236 lslOp op2;
01237
01238 if (savedFcn != (fctInfo *) 0)
01239 {
01240 lclplainerror
01241 (message ("%q: illegal function declaration. Skipping this line:\n%s",
01242 fileloc_unparseRaw (importfile, tsource_thisLineNumber (srce)),
01243 cstring_fromChars (line)));
01244 fileloc_free (imploc);
01245 return;
01246 }
01247
01248 savedFcn = (fctInfo *) dmalloc (sizeof (*savedFcn));
01249
01250 lineptr = strchr (line, 'f');
01251 llassert (lineptr != NULL);
01252 lineptr = strchr (lineptr, ' ');
01253 llassert (lineptr != NULL);
01254
01255
01256
01257 lineptr2 = strchr (lineptr, '\0');
01258
01259 if (lineptr2 != 0)
01260 {
01261 *lineptr2 = '\n';
01262 *(lineptr2 + 1) = '\0';
01263 }
01264
01265 op = parseOpLine (cimportfile, lineptr + 1);
01266
01267 if (op == (lslOp) 0)
01268 {
01269 lclplainerror (message ("%q: illegal function declaration: %s",
01270 fileloc_unparseRaw (importfile, tsource_thisLineNumber (srce)),
01271 cstring_fromChars (line)));
01272 fileloc_free (imploc);
01273 return;
01274 }
01275
01276 op2 = lslOp_renameSorts (map, op);
01277
01278 llassert (op2 != NULL);
01279
01280 if ((op->name != NULL) && op->name->isOpId)
01281 {
01282 (*savedFcn) = (fctInfo) dmalloc (sizeof (**savedFcn));
01283 (*savedFcn)->id = op->name->content.opid;
01284 (*savedFcn)->signature = signNode_fromsigNode (op2->signature);
01285 (*savedFcn)->globals = pairNodeList_new ();
01286 (*savedFcn)->export = TRUE;
01287
01288 if (inImport)
01289 {
01290
01291 cstring fname = ltoken_unparse ((*savedFcn)->id);
01292
01293 if (!usymtab_existsGlobEither (fname))
01294 {
01295 (void) usymtab_addEntry (uentry_makeFunction
01296 (fname, ctype_unknown,
01297 typeId_invalid, globSet_new (),
01298 sRefSet_undefined,
01299 fileloc_copy (imploc)));
01300 }
01301 }
01302 }
01303 else
01304 {
01305 lclplainerror (message ("%q: unexpected function name: %s",
01306 fileloc_unparseRaw (importfile, tsource_thisLineNumber (srce)),
01307 cstring_fromChars (line)));
01308 }
01309 }
01310 else if (firstWord (line, "enumConst"))
01311 {
01312 varInfo vi;
01313
01314 if (sscanf (line, "enumConst %s %s", namestr, sostr) != 2)
01315 {
01316 lclplainerror
01317 (message ("%q: Illegal enum constant declaration. "
01318 "Skipping this line:\n%s",
01319 fileloc_unparseRaw (importfile, tsource_thisLineNumber (srce)),
01320 cstring_fromChars (line)));
01321 fileloc_free (imploc);
01322 return;
01323 }
01324
01325 vi = (varInfo) dmalloc (sizeof (*vi));
01326 bsort = sort_lookupName (lsymbol_translateSort (map, lsymbol_fromChars (sostr)));
01327 lineptr = strchr (line, ' ');
01328 llassert (lineptr != NULL);
01329 lineptr = strchr (lineptr + 1, ' ');
01330 llassert (lineptr != NULL);
01331
01332 col = 5 + lineptr - line;
01333 if (sort_isNoSort (bsort))
01334 {
01335 lclplainerror (message ("%q: unknown base sort\n",
01336 fileloc_unparseRawCol (importfile, tsource_thisLineNumber (srce), col)));
01337 bsort = nullSort;
01338 }
01339
01340 vi->id = ltoken_createFull (simpleId, lsymbol_fromChars (namestr),
01341 importfile, tsource_thisLineNumber (srce), col);
01342
01343 vi->sort = bsort;
01344 vi->kind = VRK_ENUM;
01345 vi->export = TRUE;
01346 (void) symtable_enterVar (g_symtab, vi);
01347 varInfo_free (vi);
01348
01349 if (inImport)
01350 {
01351 cstring cnamestr = cstring_fromChars (namestr);
01352 if (!usymtab_existsEither (cnamestr))
01353 {
01354 (void) usymtab_addEntry (uentry_makeConstant (cnamestr, ctype_unknown,
01355 fileloc_copy (imploc)));
01356 }
01357 }
01358 }
01359 else if (firstWord (line, "tag"))
01360 {
01361
01362 }
01363 else
01364 {
01365 lclplainerror
01366 (message ("%q: Unknown symbol declaration. Skipping this line:\n%s",
01367 fileloc_unparseRaw (importfile, tsource_thisLineNumber (srce)),
01368 cstring_fromChars (line)));
01369 }
01370
01371 fileloc_free (imploc);
01372 }
01373
01374 void
01375 symtable_import (tsource *imported, ltoken tok, mapping * map)
01376 {
01377 char *buf, *importfile;
01378 tsource *lclsource;
01379 int old_lsldebug;
01380 bool old_inImport = inImport;
01381
01382 buf = tsource_nextLine (imported);
01383 importfile = tsource_fileName (imported);
01384
01385 llassert (buf != NULL);
01386
01387 if (!firstWord (buf, "%LCLSymbolTable"))
01388 {
01389 lclsource = LCLScanSource ();
01390 lclfatalerror (tok,
01391 message ("Expecting '%%LCLSymbolTable' line in import file %s:\n%s\n",
01392 cstring_fromChars (importfile),
01393 cstring_fromChars (buf)));
01394 }
01395
01396 old_lsldebug = lsldebug;
01397 lsldebug = 0;
01398 allowed_redeclaration = TRUE;
01399 inImport = TRUE;
01400
01401 for (;;)
01402 {
01403 buf = tsource_nextLine (imported);
01404 llassert (buf != NULL);
01405
01406
01407 if (firstWord (buf, "%LCLSymbolTableEnd"))
01408 {
01409 break;
01410 }
01411 else
01412 {
01413 if (firstWord (buf, "%LCL"))
01414 {
01415 parseLine (buf + 4, imported, map);
01416 }
01417 else
01418 {
01419 lclsource = LCLScanSource ();
01420 lclfatalerror
01421 (tok,
01422 message ("Expecting '%%LCL' prefix in import file %s:\n%s\n",
01423 cstring_fromChars (importfile),
01424 cstring_fromChars (buf)));
01425 }
01426 }
01427 }
01428
01429
01430 inImport = old_inImport;
01431 lsldebug = old_lsldebug;
01432 allowed_redeclaration = FALSE;
01433 }
01434
01435 static void
01436 symtable_dumpId (symtable stable, FILE *f, bool lco)
01437 {
01438 idTable *st = stable->idTable;
01439 unsigned int i;
01440 idTableEntry *se;
01441 fctInfo fi;
01442 typeInfo ti;
01443 varInfo vi;
01444
01445 for (i = 1; i < st->size; i++)
01446 {
01447
01448 se = st->entries + i;
01449 llassert (se != NULL);
01450
01451
01452
01453 switch (se->kind)
01454 {
01455 case SYMK_FCN:
01456 {
01457 cstring tmp;
01458
01459 fi = (se->info).fct;
01460
01461 if (lco)
01462 {
01463 fprintf (f, "%%LCL");
01464 }
01465
01466 if (!lco && !fi->export)
01467 {
01468 fprintf (f, "spec ");
01469 }
01470
01471 tmp = signNode_unparse (fi->signature);
01472 fprintf (f, "fcn %s %s \n", ltoken_getTextChars (fi->id),
01473 cstring_toCharsSafe (tmp));
01474 cstring_free (tmp);
01475
01476 tmp = pairNodeList_unparse (fi->globals);
01477 fprintf (f, "%%LCLfcnGlobals %s\n", cstring_toCharsSafe (tmp));
01478 cstring_free (tmp);
01479 break;
01480 }
01481 case SYMK_SCOPE:
01482 if (lco)
01483 {
01484 break;
01485 }
01486
01487
01488 switch ((se->info).scope->kind)
01489 {
01490 case SPE_GLOBAL:
01491 fprintf (f, "Global scope\n");
01492 break;
01493 case SPE_ABSTRACT:
01494 fprintf (f, "Abstract type scope\n");
01495 break;
01496 case SPE_FCN:
01497 fprintf (f, "Function scope\n");
01498 break;
01499
01500
01501
01502
01503
01504 case SPE_QUANT:
01505 fprintf (f, "Quantifier scope\n");
01506 break;
01507 case SPE_CLAIM:
01508 fprintf (f, "Claim scope\n");
01509 break;
01510 case SPE_INVALID:
01511 break;
01512 }
01513 break;
01514 case SYMK_TYPE:
01515 ti = (se->info).type;
01516 if (lco)
01517 fprintf (f, "%%LCL");
01518 if (!lco && !ti->export)
01519 fprintf (f, "spec ");
01520 fprintf (f, "type %s %s",
01521 ltoken_getTextChars (ti->id), sort_getName (ti->basedOn));
01522 if (ti->abstract)
01523 {
01524 if (ti->modifiable)
01525 fprintf (f, " mutable\n");
01526 else
01527 fprintf (f, " immutable\n");
01528 }
01529 else
01530 fprintf (f, " exposed\n");
01531 break;
01532 case SYMK_VAR:
01533
01534 vi = (se->info).var;
01535 if (lco)
01536 {
01537 fprintf (f, "%%LCL");
01538 }
01539
01540 if (!lco && !vi->export)
01541 {
01542 fprintf (f, "spec ");
01543 }
01544 switch (vi->kind)
01545 {
01546 case VRK_CONST:
01547 fprintf (f, "const %s %s\n",
01548 ltoken_getTextChars (vi->id), sort_getName (vi->sort));
01549 break;
01550 case VRK_VAR:
01551 fprintf (f, "var %s %s\n",
01552 ltoken_getTextChars (vi->id), sort_getName (vi->sort));
01553 break;
01554 case VRK_ENUM:
01555 fprintf (f, "enumConst %s %s\n",
01556 ltoken_getTextChars (vi->id), sort_getName (vi->sort));
01557 break;
01558 default:
01559 if (lco)
01560 {
01561 switch (vi->kind)
01562 {
01563 case VRK_GLOBAL:
01564 fprintf (f, "global %s %s\n", ltoken_getTextChars (vi->id), sort_getName (vi->sort));
01565 break;
01566 case VRK_PRIVATE:
01567 fprintf (f, "local %s %s\n",
01568 ltoken_getTextChars (vi->id), sort_getName (vi->sort));
01569 break;
01570 case VRK_LET:
01571 fprintf (f, "let %s %s\n",
01572 ltoken_getTextChars (vi->id), sort_getName (vi->sort));
01573 break;
01574 case VRK_PARAM:
01575 fprintf (f, "param %s %s\n",
01576 ltoken_getTextChars (vi->id), sort_getName (vi->sort));
01577 break;
01578 case VRK_QUANT:
01579 fprintf (f, "quant %s %s\n",
01580 ltoken_getTextChars (vi->id), sort_getName (vi->sort));
01581 break;
01582 BADDEFAULT;
01583 }
01584
01585
01586 }
01587 }
01588 }
01589 }
01590 }
01591
01592 static idTableEntry *
01593 nextFree (idTable * st)
01594 {
01595 idTableEntry *ret;
01596 unsigned int n = st->size;
01597
01598 if (n >= st->allocated)
01599 {
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610 idTableEntry *oldentries = st->entries;
01611 unsigned int i;
01612
01613 st->entries = dmalloc ((n+DELTA) * sizeof (*st->entries));
01614
01615 for (i = 0; i < n; i++)
01616 {
01617 st->entries[i] = oldentries[i];
01618 }
01619
01620 sfree (oldentries);
01621
01622 st->allocated = n + DELTA;
01623 }
01624
01625 ret = &(st->entries[st->size]);
01626 st->size++;
01627 return ret;
01628 }
01629
01630
01631 static idTableEntry *
01632 symtable_lookup (idTable *st, lsymbol id)
01633 {
01634 int n;
01635 idTableEntry *e;
01636
01637 for (n = st->size - 1; n >= 0; n--)
01638 {
01639 e = &(st->entries[n]);
01640
01641
01642 switch (e->kind)
01643 {
01644 case SYMK_SCOPE:
01645 break;
01646 case SYMK_FCN:
01647 if (ltoken_getText (e->info.fct->id) == id) return e;
01648 break;
01649 case SYMK_TYPE:
01650 if (ltoken_getText (e->info.type->id) == id) return e;
01651 break;
01652 case SYMK_VAR:
01653 if (ltoken_getText (e->info.var->id) == id) return e;
01654 break;
01655 BADDEFAULT;
01656 }
01657
01658 }
01659
01660 return (idTableEntry *) 0;
01661 }
01662
01663
01664 static idTableEntry *
01665 symtable_lookupInScope (idTable *st, lsymbol id)
01666 {
01667 int n;
01668 idTableEntry *e;
01669 for (n = st->size - 1; n >= 0; n--)
01670 {
01671 e = &(st->entries[n]);
01672 if (e->kind == SYMK_SCOPE)
01673 break;
01674 if (ltoken_getText (e->info.fct->id) == id)
01675 {
01676 return e;
01677 }
01678 }
01679 return (idTableEntry *) 0;
01680 }
01681
01682
01683
01684 static symbolKey
01685 htData_key (htData * x)
01686 {
01687
01688 switch (x->kind)
01689 {
01690 case IK_SORT:
01691 return x->content.sort;
01692 case IK_OP:
01693 {
01694 nameNode n = (x->content.op)->name;
01695
01696 if (n->isOpId)
01697 {
01698 return ltoken_getText (n->content.opid);
01699 }
01700 else
01701 {
01702 llassert (n->content.opform != NULL);
01703 return (n->content.opform)->key;
01704 }
01705 }
01706 case IK_TAG:
01707 return ltoken_getText ((x->content).tag->id);
01708 }
01709 BADEXIT;
01710 }
01711
01712 static void htData_free ( htData *d)
01713 {
01714 if (d != NULL)
01715 {
01716 switch (d->kind)
01717 {
01718 case IK_SORT:
01719 break;
01720 case IK_OP:
01721
01722 sigNodeSet_free (d->content.op->signatures);
01723 break;
01724 case IK_TAG:
01725 {
01726 switch (d->content.tag->kind)
01727 {
01728 case TAG_STRUCT:
01729 case TAG_UNION:
01730 case TAG_FWDSTRUCT:
01731 case TAG_FWDUNION:
01732
01733
01734
01735
01736 break;
01737 case TAG_ENUM:
01738
01739
01740
01741
01742
01743 break;
01744 }
01745 }
01746 }
01747
01748 sfree (d);
01749 }
01750 }
01751
01752 static void bucket_free ( bucket *b)
01753 {
01754 if (b != NULL)
01755 {
01756 bucket_free (b->next);
01757 htData_free (b->data);
01758 sfree (b);
01759 }
01760 }
01761
01762 static void symHashTable_free ( symHashTable *h)
01763 {
01764 unsigned int i;
01765
01766 for (i = 0; i < h->size; i++)
01767 {
01768 bucket_free (h->buckets[i]);
01769 }
01770
01771 sfree (h->buckets);
01772 sfree (h);
01773 }
01774
01775 static symHashTable *
01776 symHashTable_create (unsigned int size)
01777 {
01778 unsigned int i;
01779 symHashTable *t = (symHashTable *) dmalloc (sizeof (*t));
01780
01781 t->buckets = (bucket **) dmalloc ((size + 1) * sizeof (*t->buckets));
01782 t->count = 0;
01783 t->size = size;
01784
01785 for (i = 0; i <= size; i++)
01786 {
01787 t->buckets[i] = (bucket *) NULL;
01788 }
01789
01790 return t;
01791 }
01792
01793 static htData *
01794 symHashTable_get (symHashTable *t, symbolKey key, infoKind kind, nameNode n)
01795 {
01796 bucket *b;
01797 htEntry *entry;
01798 htData *d;
01799
01800 b = t->buckets[MASH (key, kind)];
01801 if (b == (bucket *) 0)
01802 {
01803 return ((htData *) 0);
01804 }
01805
01806 for (entry = (htEntry *) b; entry != NULL; entry = entry->next)
01807 {
01808 d = entry->data;
01809
01810 if (d->kind == kind && htData_key (d) == key)
01811 if (kind != IK_OP || sameNameNode (n, d->content.op->name))
01812 {
01813 return d;
01814 }
01815 }
01816 return ((htData *) 0);
01817 }
01818
01819 static bool
01820 symHashTable_put (symHashTable *t, htData *data)
01821 {
01822
01823
01824 symbolKey key;
01825 htData *oldd;
01826 infoKind kind;
01827 nameNode name;
01828
01829 key = htData_key (data);
01830 kind = data->kind;
01831
01832 if (kind == IK_OP && (!data->content.op->name->isOpId))
01833 {
01834 name = data->content.op->name;
01835 }
01836 else
01837 {
01838 name = (nameNode) 0;
01839 }
01840
01841 oldd = symHashTable_get (t, key, kind, name);
01842
01843 if (oldd == (htData *) 0)
01844 {
01845
01846 bucket *new_entry = (bucket *) dmalloc (sizeof (*new_entry));
01847 bucket *b = (t->buckets[MASH (key, kind)]);
01848 htEntry *entry = (htEntry *) b;
01849
01850
01851 new_entry->data = data;
01852 new_entry->next = entry;
01853 t->buckets[MASH (key, kind)] = new_entry;
01854 t->count++;
01855
01856 return TRUE;
01857 }
01858 else
01859 {
01860 htData_free (data);
01861 }
01862
01863 return FALSE;
01864 }
01865
01866 static htData *
01867 symHashTable_forcePut (symHashTable *t, htData *data)
01868 {
01869
01870 symbolKey key;
01871 bucket *b;
01872 htData *oldd;
01873 htEntry *entry, *new_entry;
01874 infoKind kind;
01875 nameNode name;
01876
01877 key = htData_key (data);
01878 kind = data->kind;
01879
01880 if (kind == IK_OP && (!data->content.op->name->isOpId))
01881 {
01882 name = data->content.op->name;
01883 }
01884 else
01885 {
01886 name = (nameNode) 0;
01887 }
01888
01889 oldd = symHashTable_get (t, key, kind, name);
01890
01891 if (oldd == (htData *) 0)
01892 {
01893 new_entry = (htEntry *) dmalloc (sizeof (*new_entry));
01894
01895
01896 b = t->buckets[MASH (key, kind)];
01897
01898
01899 entry = b;
01900 new_entry->data = data;
01901 new_entry->next = entry;
01902 t->buckets[MASH (key, kind)] = new_entry;
01903 t->count++;
01904
01905 return NULL;
01906 }
01907 else
01908 {
01909 *oldd = *data;
01910
01911
01912 if (data != oldd)
01913 {
01914 sfree (data);
01915
01916 }
01917
01918
01919 return oldd;
01920 }
01921 }
01922
01923 #if 0
01924 static unsigned int
01925 symHashTable_count (symHashTable * t)
01926 {
01927 return (t->count);
01928 }
01929
01930 #endif
01931
01932 static void
01933 symHashTable_printStats (symHashTable * t)
01934 {
01935 int i, bucketCount, setsize, sortCount, opCount, tagCount;
01936 int sortTotal, opTotal, tagTotal;
01937 bucket *b;
01938 htEntry *entry;
01939 htData *d;
01940
01941 sortTotal = 0;
01942 opTotal = 0;
01943 tagTotal = 0;
01944 sortCount = 0;
01945 opCount = 0;
01946 tagCount = 0;
01947
01948
01949 printf ("\n Printing symHashTable stats ... \n");
01950 for (i = 0; i <= HT_MAXINDEX; i++)
01951 {
01952 b = t->buckets[i];
01953 bucketCount = 0;
01954 for (entry = b; entry != NULL; entry = entry->next)
01955 {
01956 d = entry->data;
01957 bucketCount++;
01958 switch (d->kind)
01959 {
01960 case IK_SORT:
01961 sortCount++;
01962 break;
01963 case IK_OP:
01964 {
01965 cstring name = nameNode_unparse (d->content.op->name);
01966 cstring sigs = sigNodeSet_unparse (d->content.op->signatures);
01967 opCount++;
01968
01969 setsize = sigNodeSet_size (d->content.op->signatures);
01970 printf (" Op (%d): %s %s\n", setsize,
01971 cstring_toCharsSafe (name),
01972 cstring_toCharsSafe (sigs));
01973 cstring_free (name);
01974 cstring_free (sigs);
01975 break;
01976 }
01977 case IK_TAG:
01978 tagCount++;
01979 break;
01980 }
01981 }
01982 if (bucketCount > 0)
01983 {
01984 printf (" Bucket %d has count = %d; opCount = %d; sortCount = %d; tagCount = %d\n", i, bucketCount, opCount, sortCount, tagCount);
01985 sortTotal += sortCount;
01986 tagTotal += tagCount;
01987 opTotal += opCount;
01988 }
01989 }
01990 printf ("SymHashTable has total count = %d, opTotal = %d, sortTotal = %d, tagTotal = %d :\n", t->count, opTotal, sortTotal, tagTotal);
01991
01992 }
01993
01994 void
01995 symtable_printStats (symtable s)
01996 {
01997 symHashTable_printStats (s->hTable);
01998
01999 printf ("idTable size = %d; allocated = %d\n",
02000 s->idTable->size, s->idTable->allocated);
02001 }
02002
02003 cstring
02004 tagKind_unparse (tagKind k)
02005 {
02006 switch (k)
02007 {
02008 case TAG_STRUCT:
02009 case TAG_FWDSTRUCT:
02010 return cstring_makeLiteral ("struct");
02011 case TAG_UNION:
02012 case TAG_FWDUNION:
02013 return cstring_makeLiteral ("union");
02014 case TAG_ENUM:
02015 return cstring_makeLiteral ("enum");
02016 }
02017 BADEXIT;
02018 }
02019
02020 static void tagInfo_free ( tagInfo tag)
02021 {
02022 sfree (tag);
02023 }
02024
02025 sigNodeSet
02026 symtable_possibleOps (symtable tab, nameNode n)
02027 {
02028 opInfo oi = symtable_opInfo (tab, n);
02029
02030 if (opInfo_exists (oi))
02031 {
02032 return (oi->signatures);
02033 }
02034
02035 return sigNodeSet_undefined;
02036 }
02037
02038 bool
02039 symtable_opExistsWithArity (symtable tab, nameNode n, int arity)
02040 {
02041 opInfo oi = symtable_opInfo (tab, n);
02042
02043 if (opInfo_exists (oi))
02044 {
02045 sigNodeSet sigs = oi->signatures;
02046 sigNodeSet_elements (sigs, sig)
02047 {
02048 if (ltokenList_size (sig->domain) == arity)
02049 return TRUE;
02050 } end_sigNodeSet_elements;
02051 }
02052 return FALSE;
02053 }
02054
02055 static bool
02056 domainMatches (ltokenList domain, sortSetList argSorts)
02057 {
02058
02059
02060
02061 bool matched = TRUE;
02062 sort s;
02063
02064 sortSetList_reset (argSorts);
02065 ltokenList_elements (domain, dom)
02066 {
02067 s = sort_fromLsymbol (ltoken_getText (dom));
02068 if (!(sortSet_member (sortSetList_current (argSorts), s)))
02069 {
02070
02071
02072 matched = FALSE;
02073 break;
02074 }
02075 sortSetList_advance (argSorts);
02076 } end_ltokenList_elements;
02077
02078 return matched;
02079 }
02080
02081 lslOpSet
02082 symtable_opsWithLegalDomain (symtable tab, nameNode n,
02083 sortSetList argSorts, sort qual)
02084 {
02085
02086 lslOpSet ops = lslOpSet_new ();
02087 lslOp op;
02088 sort rangeSort;
02089 opInfo oi;
02090
02091 llassert (n != NULL);
02092 oi = symtable_opInfo (tab, n);
02093
02094 if (opInfo_exists (oi))
02095 {
02096 sigNodeSet sigs = oi->signatures;
02097
02098 sigNodeSet_elements (sigs, sig)
02099 {
02100 if (ltokenList_size (sig->domain) == sortSetList_size (argSorts))
02101 {
02102 rangeSort = sigNode_rangeSort (sig);
02103
02104 if ((qual == 0) || (sort_equal (&rangeSort, &qual)))
02105 {
02106 if (domainMatches (sig->domain, argSorts))
02107 {
02108 op = (lslOp) dmalloc (sizeof (*op));
02109
02110
02111
02112 op->signature = sig;
02113 op->name = nameNode_copy (n);
02114 (void) lslOpSet_insert (ops, op);
02115 }
02116 }
02117 }
02118 } end_sigNodeSet_elements;
02119 }
02120 return ops;
02121 }