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 # include "lclintMacros.nf"
00039 # include "llbasic.h"
00040 # include "llgrammar.h"
00041 # include "lclscan.h"
00042
00043
00044
00045 static lsymbol newStructTag (void) ;
00046 static lsymbol newEnumTag (void) ;
00047 static lsymbol newUnionTag (void) ;
00048
00049
00050 # define MAXBUFFLEN 1024
00051
00052
00053 # define DELTA 100
00054
00055
00056 # define NOSORTHANDLE 0
00057
00058
00059 # define HOFSORTHANDLE 1
00060
00061
00062
00063 static void sort_addTupleMembers (sort p_tupleSort, sort p_strSort)
00064 ;
00065
00066 static bool sort_isNewEntry (sortNode p_s) ;
00067
00068 static sort sort_enterNew ( sortNode p_s)
00069
00070
00071 ;
00072
00073 static sort sort_enterGlobal (sortNode p_s) ;
00074
00075 static sort sort_enterNewForce ( sortNode p_s)
00076
00077
00078 ;
00079
00080 static void genPtrOps (sort p_baseSort, sort p_ptrSort, sort p_arraySort);
00081 static void genArrOps (sort p_baseSort, sort p_arraySort, int p_dim,
00082 sort p_vecSort);
00083 static void genVecOps (sort p_baseSort, sort p_vecSort, int p_dim);
00084 static void genTupleOps (sort p_tupleSort);
00085 static void genUnionOps (sort p_tupleSort);
00086 static void genStrOps (sort p_strSort, sort p_tupleSort);
00087 static void genEnumOps (sort p_enumSort);
00088
00089 static void overloadPtrFcns (sort p_ptrSort);
00090 static void overloadIsSub (sort p_s, int p_dim);
00091 static void overloadSizeof (sort p_domainSort);
00092
00093 static cstring sort_unparseKind (sortKind p_k) ;
00094
00095 static cstring
00096 sort_unparseKindName (sortNode p_s) ;
00097
00098 static lsymbol
00099 sortTag_toSymbol (char *p_kind, ltoken p_tagid, bool *p_isNew);
00100
00101 static void
00102 overloadUnaryTok ( nameNode p_nn,
00103 sort p_domainSort, ltoken p_range);
00104 static void
00105 overloadUnary ( nameNode p_nn,
00106 sort p_domainSort, sort p_rangeSort);
00107 static void
00108 overloadBinary ( nameNode p_nn,
00109 sort p_s, ltoken p_dTok, sort p_rs);
00110 static nameNode makeFieldOp (lsymbol p_field);
00111 static nameNode makeArrowFieldOp (lsymbol p_field);
00112
00113 # undef sp
00114 static lsymbol sp (lsymbol p_s1, lsymbol p_s2);
00115 static void sortError (ltoken p_t, sort p_oldsort, sortNode p_newnode);
00116
00117
00118 sort sort_bool;
00119 sort sort_capBool;
00120 sort sort_int;
00121 sort sort_char;
00122 sort sort_float;
00123 sort sort_double;
00124 sort sort_cstring;
00125
00126
00127 static sort sort_void;
00128 static sort char_obj_ptrSort;
00129 static sort char_obj_ArrSort;
00130
00131
00132 static int sortUID = 1;
00133
00134 static sortNode *sortTable = (sortNode *) 0;
00135 static int sortTableSize = 0;
00136 static int sortTableAlloc = 0;
00137
00138
00139
00140
00141
00142 static bool exporting = TRUE;
00143
00144 static lsymbol underscoreSymbol;
00145 static ltoken intToken;
00146
00147 static nameNode arrayRefNameNode;
00148 static nameNode ptr2arrayNameNode;
00149 static nameNode deRefNameNode;
00150 static nameNode nilNameNode;
00151 static nameNode plusNameNode;
00152 static nameNode minusNameNode;
00153 static nameNode condNameNode;
00154 static nameNode eqNameNode;
00155 static nameNode neqNameNode;
00156
00157 static sortNode noSort;
00158
00159 static sortNode HOFSort =
00160 {
00161 SRT_HOF,
00162 HOFSORTHANDLE,
00163 lsymbol_undefined,
00164 lsymbol_undefined,
00165 FALSE,
00166 NOSORTHANDLE,
00167 NOSORTHANDLE,
00168 smemberInfo_undefined,
00169 FALSE,
00170 FALSE,
00171 FALSE,
00172 FALSE
00173 };
00174
00175 static ob_mstring sortKindName[] =
00176 {
00177 "FIRSTSORT", "NOSORT", "HOFSORT",
00178 "PRIMITIVE", "SYNONYM", "POINTER", "OBJ", "ARRAY", "VECTOR",
00179 "STRUCT", "TUPLE", "UNION", "UNIONVAL", "ENUM", "LASTSORT"
00180 } ;
00181
00182 static void smemberInfo_free ( smemberInfo *mem)
00183 {
00184 sfree (mem);
00185 }
00186
00187 static void sortNode_free ( sortNode sn)
00188
00189
00190 {
00191 smemberInfo_free (sn.members);
00192 }
00193
00194 void
00195 sort_destroyMod (void)
00196
00197
00198
00199
00200
00201 {
00202 if (sortTable != NULL)
00203 {
00204 int i;
00205
00206 for (i = 0; i < sortTableSize; i++)
00207 {
00208 sortNode_free (sortTable[i]);
00209 }
00210
00211 nameNode_free (arrayRefNameNode);
00212 nameNode_free (ptr2arrayNameNode);
00213 nameNode_free (deRefNameNode);
00214 nameNode_free (nilNameNode);
00215 nameNode_free (plusNameNode);
00216 nameNode_free (minusNameNode);
00217 nameNode_free (condNameNode);
00218 nameNode_free (eqNameNode);
00219 nameNode_free (neqNameNode);
00220
00221 sfree (sortTable);
00222
00223 }
00224 }
00225
00226 sort
00227 sort_makeNoSort (void)
00228 {
00229 return NOSORTHANDLE;
00230 }
00231
00232 sort
00233 sort_makeHOFSort (sort base)
00234 {
00235 sortNode outSort;
00236 sort handle;
00237
00238 outSort.kind = SRT_HOF;
00239 outSort.name = cstring_toSymbol (message ("_HOF_sort_%d", sortTableSize));
00240 outSort.tag = lsymbol_undefined;
00241 outSort.baseSort = base;
00242 outSort.objSort = NOSORTHANDLE;
00243 outSort.members = smemberInfo_undefined;
00244 outSort.export = exporting;
00245 outSort.imported = context_inImport ();
00246 outSort.mutable = FALSE;
00247 outSort.abstract = FALSE;
00248
00249 llassert (sortTable != NULL);
00250
00251 outSort.handle = handle = sortTableSize;
00252 sortTable[handle] = outSort;
00253
00254 sortTableSize++;
00255 return handle;
00256 }
00257
00258 static sort
00259 sort_construct (lsymbol name, sortKind kind, sort baseSort,
00260 lsymbol tagName,
00261 bool mut, sort objSort, smemberInfo *members)
00262 {
00263 sortNode outSort;
00264 sort handle;
00265
00266 handle = sort_lookupName (name);
00267
00268 outSort.kind = kind;
00269 outSort.name = name;
00270 outSort.tag = tagName;
00271 outSort.realtag = TRUE;
00272 outSort.baseSort = baseSort;
00273 outSort.objSort = objSort;
00274 outSort.members = members;
00275 outSort.mutable = mut;
00276 outSort.export = exporting;
00277 outSort.imported = context_inImport ();
00278 outSort.abstract = FALSE;
00279 outSort.handle = handle;
00280
00281 if (handle == NOSORTHANDLE)
00282 {
00283 outSort.handle = handle = sort_enterNew (outSort);
00284 return handle;
00285 }
00286 else
00287 {
00288 llassert (sortTable != NULL);
00289
00290 if (sortTable[handle].kind != kind)
00291 {
00292 sortError (ltoken_undefined, handle, outSort);
00293 smemberInfo_free (outSort.members);
00294
00295 return handle;
00296 }
00297 else
00298 {
00299
00300
00301
00302
00303
00304 sortTable[handle] = outSort;
00305 return handle;
00306 }
00307 }
00308 }
00309
00310 static sort
00311 sort_constructAbstract (lsymbol name, bool mut, sort baseSort)
00312 {
00313 sortNode outSort;
00314 sortKind kind;
00315 sort handle;
00316
00317 if (mut)
00318 kind = SRT_OBJ;
00319 else
00320 kind = SRT_PRIM;
00321
00322 handle = sort_lookupName (name);
00323 outSort.kind = kind;
00324 outSort.name = name;
00325 outSort.tag = lsymbol_undefined;
00326 outSort.baseSort = baseSort;
00327 outSort.objSort = NOSORTHANDLE;
00328 outSort.members = smemberInfo_undefined;
00329 outSort.mutable = mut;
00330 outSort.export = exporting;
00331 outSort.imported = context_inImport ();
00332 outSort.abstract = TRUE;
00333 outSort.handle = handle;
00334
00335 if (handle == NOSORTHANDLE)
00336 {
00337 outSort.handle = handle = sort_enterNew (outSort);
00338
00339 }
00340 else
00341 {
00342 llassert (sortTable != NULL);
00343
00344 if (sortTable[handle].kind != kind)
00345 {
00346 sortError (ltoken_undefined, handle, outSort);
00347 }
00348
00349 smemberInfo_free (outSort.members);
00350 }
00351
00352 return handle;
00353 }
00354
00355 sort
00356 sort_makeSort ( ltoken t, lsymbol n)
00357 {
00358
00359
00360
00361
00362
00363 sort handle = sort_lookupName (n);
00364
00365 if (handle == NOSORTHANDLE)
00366 {
00367 sortNode outSort;
00368
00369 outSort.handle = handle;
00370 outSort.kind = SRT_PRIM;
00371 outSort.name = n;
00372 outSort.tag = lsymbol_undefined;
00373 outSort.baseSort = NOSORTHANDLE;
00374 outSort.objSort = NOSORTHANDLE;
00375 outSort.members = smemberInfo_undefined;
00376 outSort.export = exporting;
00377 outSort.mutable = FALSE;
00378 outSort.imported = context_inImport ();
00379 outSort.abstract = FALSE;
00380
00381
00382 outSort.handle = handle = sort_enterNew (outSort);
00383 }
00384 else
00385 {
00386
00387 ;
00388 }
00389
00390 return handle;
00391 }
00392
00393 static sort
00394 sort_makeSortNoOps ( ltoken t, lsymbol n)
00395 {
00396 sort handle;
00397
00398 handle = sort_lookupName (n);
00399
00400 if (handle == NOSORTHANDLE)
00401 {
00402 sortNode outSort;
00403
00404 outSort.handle = handle;
00405 outSort.kind = SRT_PRIM;
00406 outSort.name = n;
00407 outSort.tag = lsymbol_undefined;
00408 outSort.baseSort = NOSORTHANDLE;
00409 outSort.objSort = NOSORTHANDLE;
00410 outSort.members = smemberInfo_undefined;
00411 outSort.export = exporting;
00412 outSort.mutable = FALSE;
00413 outSort.imported = context_inImport ();
00414 outSort.abstract = FALSE;
00415
00416 outSort.handle = handle = sort_enterNew (outSort);
00417 }
00418
00419 return handle;
00420 }
00421
00422 static sort
00423 sort_makeLiteralSort (ltoken t, lsymbol n)
00424
00425 {
00426
00427
00428
00429
00430
00431
00432 sort handle = sort_makeSort (t, n);
00433
00434 overloadSizeof (handle);
00435 return handle;
00436 }
00437
00438 sort
00439 sort_makeSyn (ltoken t, sort s, lsymbol n)
00440 {
00441
00442
00443 sortNode outSort;
00444 sort handle;
00445
00446 lsymbol newname = sp (underscoreSymbol, n);
00447
00448 if (n == lsymbol_undefined)
00449 {
00450 llbuglit ("sort_makeSyn: synonym must have name");
00451 }
00452
00453 handle = sort_lookupName (newname);
00454
00455 outSort.kind = SRT_SYN;
00456 outSort.name = newname;
00457 outSort.baseSort = s;
00458 outSort.objSort = NOSORTHANDLE;
00459
00460 outSort.tag = lsymbol_undefined;
00461 outSort.members = smemberInfo_undefined;
00462 outSort.export = exporting;
00463 outSort.mutable = FALSE;
00464 outSort.imported = context_inImport ();
00465 outSort.abstract = FALSE;
00466 outSort.handle = handle;
00467
00468 if (handle == NOSORTHANDLE)
00469 {
00470 outSort.handle = handle = sort_enterNew (outSort);
00471
00472 }
00473 else
00474 {
00475 llassert (sortTable != NULL);
00476
00477 if (sortTable[handle].kind != SRT_SYN)
00478 {
00479 sortError (t, handle, outSort);
00480 }
00481
00482 smemberInfo_free (outSort.members);
00483 }
00484
00485 return handle;
00486 }
00487
00488 sort
00489 sort_makeFormal (sort insort)
00490 {
00491 sortNode s;
00492 sort sor, handle;
00493
00494 sor = sort_getUnderlying (insort);
00495 handle = sor;
00496 s = sort_lookup (sor);
00497
00498 switch (s.kind)
00499 {
00500 case SRT_STRUCT:
00501 handle = sort_makeTuple (ltoken_undefined, sor);
00502 break;
00503 case SRT_UNION:
00504 handle = sort_makeUnionVal (ltoken_undefined, sor);
00505 break;
00506 default:
00507 break;
00508 }
00509
00510 return handle;
00511 }
00512
00513 sort
00514 sort_makeGlobal (sort insort)
00515 {
00516
00517 sortNode s;
00518 sort sor, handle;
00519 sor = sort_getUnderlying (insort);
00520 handle = sor;
00521 s = sort_lookup (sor);
00522
00523 switch (s.kind)
00524 {
00525 case SRT_ARRAY:
00526 case SRT_STRUCT:
00527 case SRT_UNION:
00528 case SRT_HOF:
00529 case SRT_NONE:
00530 break;
00531 case SRT_VECTOR:
00532 case SRT_TUPLE:
00533 case SRT_UNIONVAL:
00534 llcontbuglit ("sort_makeGlobal: can't make vectors, tuples, or unionvals global");
00535 break;
00536 default:
00537 handle = sort_makeObj (sor);
00538 break;
00539 }
00540 return handle;
00541 }
00542
00543 sort
00544 sort_makeObj (sort sor)
00545 {
00546 sortNode baseSortNode, outSort;
00547 sort baseSort, handle;
00548 lsymbol name;
00549
00550
00551 baseSort = sort_getUnderlying (sor);
00552 baseSortNode = sort_quietLookup (baseSort);
00553 switch (baseSortNode.kind)
00554 {
00555 case SRT_HOF:
00556 case SRT_NONE:
00557 return baseSort;
00558 case SRT_VECTOR:
00559 if (baseSortNode.objSort != 0)
00560 return baseSortNode.objSort;
00561 else
00562 {
00563 llcontbuglit ("sort_makeObj: Inconsistent vector reps:invalid objSort field");
00564 return baseSort;
00565 }
00566 case SRT_TUPLE:
00567 case SRT_UNIONVAL:
00568
00569
00570 if (baseSortNode.baseSort != NOSORTHANDLE)
00571
00572
00573 return baseSortNode.baseSort;
00574 else
00575 {
00576 llcontbuglit ("sort_makeObj: Inconsistent tuples or unionvals reps: invalid baseSort field");
00577 return baseSort;
00578 }
00579 default:
00580 name = sp (sp (underscoreSymbol, sort_getLsymbol (baseSort)),
00581 lsymbol_fromChars ("_Obj"));
00582 handle = sort_lookupName (name);
00583
00584 outSort.kind = SRT_OBJ;
00585
00586 outSort.name = name;
00587 outSort.tag = lsymbol_undefined;
00588 outSort.baseSort = baseSort;
00589 outSort.objSort = NOSORTHANDLE;
00590 outSort.members = smemberInfo_undefined;
00591 outSort.mutable = TRUE;
00592 outSort.export = exporting;
00593 outSort.abstract = FALSE;
00594 outSort.handle = handle;
00595 outSort.imported = TRUE;
00596
00597 if (handle == NOSORTHANDLE)
00598 {
00599 if (sort_isNewEntry (outSort))
00600 {
00601 outSort.handle = handle = sort_enterNew (outSort);
00602 }
00603 else
00604 {
00605 outSort.handle = handle = sort_enterNew (outSort);
00606 }
00607 }
00608 else
00609 {
00610 llassert (sortTable != NULL);
00611
00612 if (sortTable[handle].kind != SRT_OBJ)
00613 {
00614 sortError (ltoken_undefined, handle, outSort);
00615 }
00616
00617 smemberInfo_free (outSort.members);
00618 }
00619
00620 return handle;
00621 }
00622 }
00623
00624 sort
00625 sort_makePtr (ltoken t, sort baseSort)
00626 {
00627 sortNode s, outSort;
00628 sort handle, arrayHandle;
00629 lsymbol name;
00630
00631 s = sort_lookup (baseSort);
00632
00633 if (s.kind == SRT_HOF)
00634 {
00635 return baseSort;
00636 }
00637 if (s.kind == SRT_NONE)
00638 {
00639 return baseSort;
00640 }
00641
00642 if (s.kind != SRT_ARRAY && s.kind != SRT_STRUCT &&
00643 s.kind != SRT_UNION)
00644
00645
00646 baseSort = sort_makeObj (baseSort);
00647
00648 name = sp (sp (underscoreSymbol, sort_getLsymbol (baseSort)),
00649 lsymbol_fromChars ("_Ptr"));
00650 handle = sort_lookupName (name);
00651
00652 outSort.kind = SRT_PTR;
00653 outSort.name = name;
00654 outSort.tag = lsymbol_undefined;
00655 outSort.baseSort = baseSort;
00656 outSort.objSort = NOSORTHANDLE;
00657 outSort.members = smemberInfo_undefined;
00658 outSort.mutable = FALSE;
00659 outSort.export = exporting;
00660 outSort.imported = context_inImport ();
00661 outSort.abstract = FALSE;
00662 outSort.handle = handle;
00663
00664 if (handle == NOSORTHANDLE)
00665 {
00666 if (sort_isNewEntry (outSort))
00667 {
00668 outSort.handle = handle = sort_enterNew (outSort);
00669 arrayHandle = sort_makeArr (t, baseSort);
00670 genPtrOps (baseSort, handle, arrayHandle);
00671 }
00672 else
00673 {
00674 outSort.handle = handle = sort_enterNew (outSort);
00675 }
00676 }
00677 else
00678 {
00679 llassert (sortTable != NULL);
00680
00681 if (sortTable[handle].kind != SRT_PTR)
00682 {
00683 sortError (t, handle, outSort);
00684 }
00685 smemberInfo_free (outSort.members);
00686 }
00687 return handle;
00688 }
00689
00690 sort
00691 sort_makePtrN (sort s, int pointers)
00692 {
00693 llassert (pointers >= 0);
00694
00695 if (pointers == 0)
00696 {
00697 return s;
00698 }
00699 else
00700 {
00701 return sort_makePtrN (sort_makePtr (ltoken_undefined, s),
00702 pointers - 1);
00703 }
00704 }
00705
00706 sort
00707 sort_makeArr (ltoken t, sort baseSort)
00708 {
00709 sortNode s, outSort, old;
00710 sort handle, vecHandle;
00711 int dim;
00712 lsymbol name;
00713
00714 s = sort_lookup (baseSort);
00715
00716 if (s.kind == SRT_HOF)
00717 return baseSort;
00718 if (s.kind == SRT_NONE)
00719 return baseSort;
00720
00721 if (s.kind != SRT_ARRAY && s.kind != SRT_STRUCT &&
00722 s.kind != SRT_UNION && s.kind != SRT_OBJ)
00723
00724 baseSort = sort_makeObj (baseSort);
00725
00726 name = sp (sp (underscoreSymbol, sort_getLsymbol (baseSort)),
00727 lsymbol_fromChars ("_Arr"));
00728 handle = sort_lookupName (name);
00729
00730
00731 outSort.name = name;
00732 outSort.kind = SRT_ARRAY;
00733 outSort.baseSort = baseSort;
00734 outSort.objSort = NOSORTHANDLE;
00735 outSort.members = smemberInfo_undefined;
00736 outSort.mutable = TRUE;
00737 outSort.export = exporting;
00738 outSort.imported = context_inImport ();
00739 outSort.abstract = FALSE;
00740 outSort.handle = handle;
00741
00742 if (handle == NOSORTHANDLE)
00743 {
00744 if (sort_isNewEntry (outSort))
00745 {
00746 outSort.handle = handle = sort_enterNew (outSort);
00747
00748 for (old = outSort, dim = 0;
00749 old.kind == SRT_ARRAY;
00750 dim++, old = sort_lookup (old.baseSort))
00751 {
00752 ;
00753 }
00754
00755 vecHandle = sort_makeVec (t, handle);
00756 genArrOps (baseSort, handle, dim, vecHandle);
00757 }
00758 else
00759 {
00760 outSort.handle = handle = sort_enterNew (outSort);
00761 }
00762 }
00763 else
00764 {
00765 llassert (sortTable != NULL);
00766
00767 if (sortTable[handle].kind != SRT_ARRAY)
00768 {
00769 sortError (t, handle, outSort);
00770 }
00771
00772 smemberInfo_free (outSort.members);
00773 }
00774
00775 return handle;
00776 }
00777
00778 sort
00779 sort_makeVec (ltoken t, sort arraySort)
00780 {
00781 sortNode s, outSort, old;
00782 sort baseSort, handle, elementSort;
00783 int dim;
00784 lsymbol name;
00785
00786 s = sort_lookup (arraySort);
00787
00788 if (s.kind == SRT_HOF)
00789 return arraySort;
00790 if (s.kind == SRT_NONE)
00791 return arraySort;
00792
00793 if (s.kind != SRT_ARRAY)
00794 {
00795 llbug (message ("sort_makeVec: only arrays can become vectors: given sort is %s",
00796 sort_unparseKind (s.kind)));
00797 }
00798
00799 if (s.baseSort == NOSORTHANDLE)
00800 llbuglit ("sort_makeVec: arrays must have base (element) sort");
00801
00802
00803
00804 baseSort = s.baseSort;
00805 elementSort = sort_makeVal (baseSort);
00806
00807 name = sp (sp (underscoreSymbol, sort_getLsymbol (elementSort)),
00808 lsymbol_fromChars ("_Vec"));
00809 handle = sort_lookupName (name);
00810
00811 outSort.baseSort = elementSort;
00812 outSort.name = name;
00813 outSort.objSort = arraySort;
00814 outSort.kind = SRT_VECTOR;
00815 outSort.members = smemberInfo_undefined;
00816 outSort.mutable = FALSE;
00817 outSort.export = exporting;
00818 outSort.imported = context_inImport ();
00819 outSort.abstract = FALSE;
00820 outSort.handle = handle;
00821
00822 if (handle == NOSORTHANDLE)
00823 {
00824 if (sort_isNewEntry (outSort))
00825 {
00826 outSort.handle = handle = sort_enterNew (outSort);
00827
00828 for (old = outSort, dim = 0;
00829 old.kind == SRT_VECTOR;
00830 dim++, old = sort_lookup (old.baseSort))
00831 {
00832 ;
00833 }
00834
00835 genVecOps (elementSort, handle, dim);
00836 }
00837 else
00838 {
00839 outSort.handle = handle = sort_enterNew (outSort);
00840 }
00841 }
00842 else
00843 {
00844 llassert (sortTable != NULL);
00845
00846 if (sortTable[handle].kind != SRT_VECTOR)
00847 {
00848 sortError (t, handle, outSort);
00849 }
00850
00851 smemberInfo_free (outSort.members);
00852 }
00853
00854 return handle;
00855 }
00856
00857 sort
00858 sort_makeVal (sort sor)
00859 {
00860 sort retSort = sor;
00861 sortNode rsn, s;
00862
00863 llassert (sortTable != NULL);
00864 s = sort_quietLookup (sor);
00865
00866 switch (s.kind)
00867 {
00868 case SRT_PRIM:
00869 case SRT_ENUM:
00870 case SRT_PTR:
00871 case SRT_TUPLE:
00872 case SRT_UNIONVAL:
00873 case SRT_VECTOR:
00874 case SRT_HOF:
00875 case SRT_NONE:
00876
00877 retSort = sor;
00878 break;
00879 case SRT_SYN:
00880 return sort_makeVal (sortTable[sor].baseSort);
00881 case SRT_OBJ:
00882
00883 if (s.baseSort == NOSORTHANDLE)
00884 {
00885 llbuglit ("sort_makeVal: expecting a base sort for Obj");
00886 }
00887 retSort = s.baseSort;
00888 break;
00889 case SRT_ARRAY:
00890 retSort = sort_makeVec (ltoken_undefined, sor);
00891 break;
00892 case SRT_STRUCT:
00893 retSort = sort_makeTuple (ltoken_undefined, sor);
00894 break;
00895 case SRT_UNION:
00896 retSort = sort_makeUnionVal (ltoken_undefined, sor);
00897 break;
00898 default:
00899 llbuglit ("sort_makeVal: invalid sort kind");
00900 }
00901 rsn = sort_quietLookup (retSort);
00902 if (rsn.kind == SRT_NONE)
00903 {
00904 llfatalbug (message ("sort_makeVal: invalid return sort kind: %d", (int)rsn.kind));
00905 }
00906 return retSort;
00907 }
00908
00909 sort
00910 sort_makeImmutable (ltoken t, lsymbol name)
00911 {
00912 sortNode outSort;
00913 sort handle;
00914
00915 handle = sort_lookupName (name);
00916
00917 outSort.kind = SRT_PRIM;
00918 outSort.name = name;
00919 outSort.baseSort = NOSORTHANDLE;
00920 outSort.objSort = NOSORTHANDLE;
00921 outSort.members = smemberInfo_undefined;
00922 outSort.export = exporting;
00923 outSort.mutable = FALSE;
00924 outSort.imported = context_inImport ();
00925 outSort.abstract = TRUE;
00926 outSort.handle = handle;
00927
00928 if (handle == NOSORTHANDLE)
00929 {
00930 outSort.handle = handle = sort_enterNew (outSort);
00931 overloadSizeof (handle);
00932 }
00933 else
00934 {
00935 llassert (sortTable != NULL);
00936
00937 if ((sortTable[handle].kind != SRT_PRIM) &&
00938 (sortTable[handle].abstract) &&
00939 (!sortTable[handle].mutable))
00940 {
00941 sortError (t, handle, outSort);
00942 }
00943
00944 smemberInfo_free (outSort.members);
00945 }
00946
00947 return handle;
00948 }
00949
00950 sort
00951 sort_makeMutable (ltoken t, lsymbol name)
00952 {
00953 sort immutable_old, handle, baseSort;
00954 lsymbol objName;
00955
00956 immutable_old = sort_lookupName (name);
00957
00958
00959 baseSort = sort_makeImmutable (t, name);
00960
00961 llassert (sortTable != NULL);
00962
00963
00964 if (immutable_old != NOSORTHANDLE &&
00965 (sortTable[baseSort].kind != SRT_PRIM) &&
00966 (sortTable[baseSort].abstract) &&
00967 (!sortTable[baseSort].mutable))
00968 {
00969
00970 handle = NOSORTHANDLE;
00971 }
00972 else
00973 {
00974 sortNode outSort;
00975
00976
00977 objName = sp (sp (underscoreSymbol, name),
00978 lsymbol_fromChars ("_Obj"));
00979 handle = sort_lookupName (objName);
00980
00981 outSort.kind = SRT_OBJ;
00982 outSort.name = objName;
00983 outSort.tag = lsymbol_undefined;
00984 outSort.baseSort = baseSort;
00985 outSort.objSort = NOSORTHANDLE;
00986 outSort.members = smemberInfo_undefined;
00987 outSort.mutable = TRUE;
00988 outSort.export = exporting;
00989 outSort.imported = context_inImport ();
00990 outSort.abstract = TRUE;
00991 outSort.handle = handle;
00992
00993 if (handle == NOSORTHANDLE)
00994 {
00995 if (sort_isNewEntry (outSort))
00996 {
00997 outSort.handle = handle = sort_enterNew (outSort);
00998 }
00999 else
01000 {
01001 handle = sort_enterNew (outSort);
01002 }
01003 }
01004 else
01005 {
01006 llassert (sortTable != NULL);
01007
01008 if ((sortTable[handle].kind != SRT_OBJ)
01009 && sortTable[handle].abstract
01010 && sortTable[handle].mutable)
01011 {
01012 sortError (t, handle, outSort);
01013 }
01014
01015 smemberInfo_free (outSort.members);
01016 }
01017 }
01018 return handle;
01019 }
01020
01021 sort
01022 sort_makeStr (ltoken opttagid)
01023 {
01024 sortNode outSort;
01025 sort handle;
01026 bool isNewTag;
01027 lsymbol name;
01028
01029
01030
01031
01032 if (ltoken_isUndefined (opttagid))
01033 {
01034 opttagid = ltoken_create (simpleId, newStructTag ());
01035
01036 outSort.realtag = FALSE;
01037 }
01038 else
01039 {
01040 outSort.realtag = TRUE;
01041 }
01042
01043 name = sortTag_toSymbol ("Struct", opttagid, &isNewTag);
01044
01045 llassert (sortTable != NULL);
01046 handle = sort_lookupName (name);
01047 outSort.name = name;
01048 outSort.kind = SRT_STRUCT;
01049 outSort.tag = ltoken_getText (opttagid);
01050 outSort.baseSort = NOSORTHANDLE;
01051 outSort.objSort = NOSORTHANDLE;
01052 outSort.members = smemberInfo_undefined;
01053 outSort.export = exporting;
01054 outSort.mutable = TRUE;
01055 outSort.imported = context_inImport ();
01056 outSort.abstract = FALSE;
01057 outSort.handle = handle;
01058
01059 if (handle == NOSORTHANDLE)
01060 {
01061 if (sort_isNewEntry (outSort))
01062 {
01063 outSort.handle = handle = sort_enterNew (outSort);
01064 }
01065 else
01066 {
01067 outSort.handle = handle = sort_enterNewForce (outSort);
01068 }
01069 }
01070 else
01071 {
01072 if (sortTable[handle].kind != SRT_STRUCT)
01073 {
01074 sortError (opttagid, handle, outSort);
01075 }
01076
01077 smemberInfo_free (outSort.members);
01078 }
01079
01080 return handle;
01081 }
01082
01083 bool
01084 sort_updateStr (sort strSort, smemberInfo *info)
01085 {
01086
01087
01088 sort tupleSort;
01089 sortNode sn;
01090
01091 llassert (sortTable != NULL);
01092 sn = sort_lookup (strSort);
01093
01094 if (sn.members == (smemberInfo *) 0)
01095 {
01096 sortTable[strSort].members = info;
01097 tupleSort = sort_makeTuple (ltoken_undefined, strSort);
01098 genStrOps (strSort, tupleSort);
01099 return TRUE;
01100 }
01101 else
01102 {
01103 smemberInfo_free (info);
01104 return FALSE;
01105 }
01106 }
01107
01108 sort
01109 sort_makeTuple (ltoken t, sort strSort)
01110 {
01111 sort handle;
01112 sortNode outSort, s = sort_lookup (strSort);
01113 lsymbol name;
01114
01115 if (s.kind != SRT_STRUCT)
01116 {
01117 llfatalbug (message ("sort_makeTuple: Only structs can become tuples: given sort is %s",
01118 sort_unparseKind (s.kind)));
01119 }
01120
01121 name = sp (s.name, lsymbol_fromChars ("_Tuple"));
01122 llassert (sortTable != NULL);
01123 handle = sort_lookupName (name);
01124
01125 outSort.kind = SRT_TUPLE;
01126 outSort.name = name;
01127 outSort.tag = s.tag;
01128 outSort.realtag = s.realtag;
01129 outSort.baseSort = strSort;
01130 outSort.objSort = NOSORTHANDLE;
01131 outSort.members = smemberInfo_undefined;
01132 outSort.export = exporting;
01133 outSort.abstract = FALSE;
01134 outSort.imported = context_inImport ();
01135 outSort.mutable = FALSE;
01136 outSort.handle = handle;
01137
01138 if (handle == NOSORTHANDLE)
01139 {
01140 if (sort_isNewEntry (outSort))
01141 {
01142 outSort.handle = handle = sort_enterNew (outSort);
01143
01144 sort_addTupleMembers (handle, strSort);
01145 genTupleOps (handle);
01146 }
01147 else
01148 {
01149 outSort.handle = handle = sort_enterNew (outSort);
01150 }
01151 }
01152 else
01153 {
01154 if (sortTable[handle].kind != SRT_TUPLE)
01155 {
01156 sortError (t, handle, outSort);
01157 }
01158
01159 smemberInfo_free (outSort.members);
01160 }
01161
01162 return handle;
01163 }
01164
01165 static void
01166 sort_addTupleMembers (sort tupleSort, sort strSort)
01167 {
01168 smemberInfo *mem, *tail = smemberInfo_undefined;
01169 smemberInfo *top = smemberInfo_undefined;
01170 smemberInfo *newinfo;
01171
01172
01173
01174 llassert (sortTable != NULL);
01175
01176 for (mem = sortTable[strSort].members;
01177 mem != smemberInfo_undefined; mem = mem->next)
01178 {
01179 newinfo = (smemberInfo *) dmalloc (sizeof (*newinfo));
01180 newinfo->name = mem->name;
01181 newinfo->sort = sort_makeVal (mem->sort);
01182 newinfo->next = smemberInfo_undefined;
01183
01184 if (top == smemberInfo_undefined)
01185 {
01186 top = newinfo;
01187 tail = newinfo;
01188 }
01189 else
01190 {
01191 llassert (tail != smemberInfo_undefined);
01192
01193 tail->next = newinfo;
01194 tail = newinfo;
01195
01196 }
01197
01198 }
01199
01200 sortTable[tupleSort].members = top;
01201 }
01202
01203 static
01204 void genTupleOps (sort tupleSort)
01205 {
01206 ltoken range, dom;
01207 sort fieldsort;
01208 smemberInfo *m;
01209 unsigned int memCount;
01210 ltokenList domain = ltokenList_new ();
01211 sigNode signature;
01212 opFormUnion u;
01213 opFormNode opform;
01214 nameNode nn;
01215
01216 memCount = 0;
01217 range = ltoken_createType (simpleId, SID_SORT, sort_getLsymbol (tupleSort));
01218
01219 llassert (sortTable != NULL);
01220 for (m = sortTable[tupleSort].members;
01221 m != smemberInfo_undefined; m = m->next)
01222 {
01223 fieldsort = sort_makeVal (m->sort);
01224 overloadUnary (makeFieldOp (m->name), tupleSort, fieldsort);
01225
01226 dom = ltoken_createType (simpleId, SID_SORT,
01227 sort_getLsymbol (fieldsort));
01228 ltokenList_addh (domain, dom);
01229 memCount++;
01230 }
01231
01232
01233 signature = makesigNode (ltoken_undefined, domain, range);
01234 u.middle = memCount;
01235
01236 opform = makeOpFormNode (ltoken_copy (ltoken_lbracked),
01237 OPF_BMIDDLE, u, ltoken_copy (ltoken_rbracket));
01238
01239 nn = makeNameNodeForm (opform);
01240 symtable_enterOp (g_symtab, nn, signature);
01241
01242
01243
01244
01245 }
01246
01247 static
01248 void genUnionOps (sort tupleSort)
01249 {
01250
01251 smemberInfo *m;
01252 sort sort;
01253
01254 llassert (sortTable != NULL);
01255 for (m = sortTable[tupleSort].members;
01256 m != smemberInfo_undefined; m = m->next)
01257 {
01258
01259 overloadUnary (makeFieldOp (m->name), tupleSort, m->sort);
01260
01261
01262
01263 sort = sort_makePtr (ltoken_undefined, tupleSort);
01264 overloadUnary (makeArrowFieldOp (m->name), sort, m->sort);
01265
01266
01267 }
01268 }
01269
01270 static
01271 void genStrOps (sort strSort, sort tupleSort)
01272 {
01273 smemberInfo *m;
01274 sort sort;
01275
01276 llassert (sortTable != NULL);
01277 for (m = sortTable[strSort].members;
01278 m != smemberInfo_undefined; m = m->next)
01279 {
01280
01281 overloadUnary (makeFieldOp (m->name), strSort, m->sort);
01282
01283
01284
01285 sort = sort_makePtr (ltoken_undefined, strSort);
01286 overloadUnary (makeArrowFieldOp (m->name), sort, m->sort);
01287
01288
01289 }
01290
01291
01292
01293
01294 }
01295
01296 sort
01297 sort_makeUnion (ltoken opttagid)
01298 {
01299 sortNode outSort;
01300 sort handle;
01301 bool isNewTag;
01302 lsymbol name;
01303
01304
01305
01306
01307 if (ltoken_isUndefined (opttagid))
01308 {
01309 opttagid = ltoken_create (simpleId, newUnionTag ());
01310 outSort.realtag = FALSE;
01311 }
01312 else
01313 outSort.realtag = TRUE;
01314
01315 llassert (sortTable != NULL);
01316 name = sortTag_toSymbol ("Union", opttagid, &isNewTag);
01317 handle = sort_lookupName (name);
01318 outSort.name = name;
01319 outSort.kind = SRT_UNION;
01320 outSort.tag = ltoken_getText (opttagid);
01321 outSort.baseSort = NOSORTHANDLE;
01322 outSort.objSort = NOSORTHANDLE;
01323 outSort.members = smemberInfo_undefined;
01324 outSort.export = exporting;
01325 outSort.mutable = TRUE;
01326 outSort.imported = context_inImport ();
01327 outSort.abstract = FALSE;
01328 outSort.handle = handle;
01329
01330 if (handle == NOSORTHANDLE)
01331 {
01332 if (sort_isNewEntry (outSort))
01333 {
01334 outSort.handle = handle = sort_enterNew (outSort);
01335 }
01336 else
01337 {
01338 outSort.handle = handle = sort_enterNewForce (outSort);
01339 }
01340 }
01341 else
01342 {
01343 if (sortTable[handle].kind != SRT_UNION)
01344 {
01345 sortError (opttagid, handle, outSort);
01346 }
01347
01348 smemberInfo_free (outSort.members);
01349 }
01350
01351 return handle;
01352 }
01353
01354 bool
01355 sort_updateUnion (sort unionSort, smemberInfo *info)
01356 {
01357
01358
01359 sort uValSort;
01360 sortNode sn;
01361
01362 llassert (sortTable != NULL);
01363
01364 sn = sort_lookup (unionSort);
01365
01366 if (sn.members == (smemberInfo *) 0)
01367 {
01368 sortTable[unionSort].members = info;
01369 uValSort = sort_makeUnionVal (ltoken_undefined, unionSort);
01370
01371 genStrOps (unionSort, uValSort);
01372 return TRUE;
01373 }
01374 else
01375 {
01376 smemberInfo_free (info);
01377 return FALSE;
01378 }
01379 }
01380
01381 sort
01382 sort_makeUnionVal (ltoken t, sort unionSort)
01383 {
01384 sort handle;
01385 sortNode outSort, s = sort_lookup (unionSort);
01386 lsymbol name;
01387
01388 if (s.kind != SRT_UNION)
01389 {
01390 llfatalbug (message ("sort_makeUnion: only unions can become unionVals: given sort is: %s",
01391 sort_unparseKind (s.kind)));
01392 }
01393
01394 llassert (sortTable != NULL);
01395
01396 name = sp (s.name, lsymbol_fromChars ("_UnionVal"));
01397 handle = sort_lookupName (name);
01398
01399 outSort.kind = SRT_UNIONVAL;
01400 outSort.name = name;
01401 outSort.tag = s.tag;
01402 outSort.realtag = s.realtag;
01403 outSort.baseSort = unionSort;
01404 outSort.objSort = NOSORTHANDLE;
01405 outSort.members = smemberInfo_undefined;
01406 outSort.export = exporting;
01407 outSort.abstract = FALSE;
01408 outSort.imported = context_inImport ();
01409 outSort.mutable = FALSE;
01410 outSort.handle = handle;
01411
01412 if (handle == NOSORTHANDLE)
01413 {
01414 if (sort_isNewEntry (outSort))
01415 {
01416 outSort.handle = handle = sort_enterNew (outSort);
01417
01418
01419
01420
01421 sort_addTupleMembers (handle, unionSort);
01422 genUnionOps (handle);
01423 }
01424 else
01425 {
01426 outSort.handle = handle = sort_enterNew (outSort);
01427 }
01428 }
01429 else
01430 {
01431 if (sortTable[handle].kind != SRT_UNIONVAL)
01432 {
01433 sortError (t, handle, outSort);
01434 }
01435
01436 smemberInfo_free (outSort.members);
01437 }
01438
01439 return handle;
01440 }
01441
01442 static lsymbol
01443 newEnumTag ()
01444 {
01445 static int ecount = 0;
01446
01447 return (cstring_toSymbol (message ("e%s%de", context_moduleName (), ecount++)));
01448 }
01449
01450 static lsymbol
01451 newStructTag ()
01452 {
01453 static int ecount = 0;
01454
01455 return (cstring_toSymbol (message ("s%s%ds", context_moduleName (), ecount++)));
01456 }
01457
01458 static lsymbol
01459 newUnionTag ()
01460 {
01461 static int ecount = 0;
01462
01463 return (cstring_toSymbol (message ("u%s%du", context_moduleName (), ecount++)));
01464 }
01465
01466 sort
01467 sort_makeEnum (ltoken opttagid)
01468 {
01469 sortNode outSort;
01470 sort handle;
01471 bool isNew;
01472 lsymbol name;
01473
01474 llassert (sortTable != NULL);
01475
01476 if (ltoken_isUndefined (opttagid))
01477 {
01478 opttagid = ltoken_create (simpleId, newEnumTag ());
01479 outSort.realtag = FALSE;
01480 }
01481 else
01482 outSort.realtag = TRUE;
01483
01484
01485
01486 name = sortTag_toSymbol ("Enum", opttagid, &isNew);
01487 handle = sort_lookupName (name);
01488 outSort.name = name;
01489 outSort.kind = SRT_ENUM;
01490 outSort.tag = ltoken_getText (opttagid);
01491 outSort.baseSort = NOSORTHANDLE;
01492 outSort.objSort = NOSORTHANDLE;
01493 outSort.members = smemberInfo_undefined;
01494 outSort.export = exporting;
01495 outSort.mutable = FALSE;
01496 outSort.imported = context_inImport ();
01497 outSort.abstract = FALSE;
01498 outSort.handle = handle;
01499
01500 if (handle == NOSORTHANDLE)
01501 {
01502 if (sort_isNewEntry (outSort))
01503 {
01504 outSort.handle = handle = sort_enterNew (outSort);
01505 }
01506 else
01507 {
01508 outSort.handle = handle = sort_enterNewForce (outSort);
01509 }
01510 }
01511 else
01512 {
01513 if (sortTable[handle].kind != SRT_ENUM)
01514 {
01515 sortError (opttagid, handle, outSort);
01516 }
01517
01518 smemberInfo_free (outSort.members);
01519 }
01520
01521 return handle;
01522 }
01523
01524 bool
01525 sort_updateEnum (sort enumSort, smemberInfo *info)
01526 {
01527
01528
01529
01530
01531
01532 sortNode sn;
01533
01534 llassert (sortTable != NULL);
01535
01536 sn = sort_lookup (enumSort);
01537 if (sn.members == (smemberInfo *) 0)
01538 {
01539 sortTable[enumSort].members = info;
01540 genEnumOps (enumSort);
01541 return TRUE;
01542 }
01543 else
01544 {
01545 smemberInfo_free (info);
01546 return FALSE;
01547 }
01548 }
01549
01550 static
01551 void genEnumOps (sort enumSort)
01552 {
01553 smemberInfo *ei;
01554 ltokenList domain = ltokenList_new ();
01555 ltoken range, mem;
01556 nameNode nn;
01557 sigNode signature;
01558
01559 range = ltoken_createType (simpleId, SID_SORT, sort_getLsymbol (enumSort));
01560 signature = makesigNode (ltoken_undefined, domain, range);
01561
01562 llassert (sortTable != NULL);
01563
01564 for (ei = sortTable[enumSort].members;
01565 ei != (smemberInfo *) 0; ei = ei->next)
01566 {
01567 mem = ltoken_createType (simpleId, SID_OP, ei->name);
01568 nn = makeNameNodeId (mem);
01569 symtable_enterOp (g_symtab, nn, sigNode_copy (signature));
01570 }
01571
01572 sigNode_free (signature);
01573 overloadSizeof (enumSort);
01574 }
01575
01576 static void
01577 genPtrOps ( sort baseSort, sort ptrSort, sort arraySort)
01578 {
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588 overloadUnary (nameNode_copySafe (ptr2arrayNameNode), ptrSort, arraySort);
01589
01590
01591 overloadBinary (nameNode_copySafe (plusNameNode), ptrSort,
01592 ltoken_copy (intToken), ptrSort);
01593
01594 overloadBinary (nameNode_copySafe (minusNameNode), ptrSort,
01595 ltoken_copy (intToken), ptrSort);
01596
01597
01598
01599
01600 overloadPtrFcns (ptrSort);
01601 }
01602
01603 static void
01604 genArrOps (sort baseSort, sort arraySort, int dim, sort vecSort)
01605 {
01606
01607 overloadBinary (nameNode_copySafe (arrayRefNameNode), arraySort,
01608 ltoken_copy (intToken), baseSort);
01609
01610
01611
01612
01613
01614
01615 overloadIsSub (arraySort, dim);
01616
01617
01618
01619
01620
01621
01622 }
01623
01624
01625
01626
01627
01628
01629
01630 static void
01631 overloadPtrFcns (sort ptrSort)
01632 {
01633 ltokenList domain = ltokenList_new ();
01634 ltoken range;
01635 sigNode signature;
01636
01637
01638
01639 range = ltoken_createType (simpleId, SID_SORT, sort_getLsymbol (ptrSort));
01640 signature = makesigNode (ltoken_undefined, ltokenList_new (), ltoken_copy (range));
01641 symtable_enterOp (g_symtab, nameNode_copySafe (nilNameNode), signature);
01642
01643
01644
01645 ltokenList_addh (domain, ltoken_copy (intToken));
01646 ltokenList_addh (domain, ltoken_copy (range));
01647
01648 signature = makesigNode (ltoken_undefined, domain, ltoken_copy (range));
01649 symtable_enterOp (g_symtab, nameNode_copySafe (plusNameNode), signature);
01650
01651
01652
01653 domain = ltokenList_new ();
01654 ltokenList_addh (domain, ltoken_copy (range));
01655 ltokenList_addh (domain, range);
01656 range = ltoken_copy (intToken);
01657 signature = makesigNode (ltoken_undefined, domain, range);
01658 symtable_enterOp (g_symtab, nameNode_copySafe (minusNameNode), signature);
01659 }
01660
01661 static void
01662 genVecOps (sort baseSort, sort vecSort, int dim)
01663 {
01664
01665
01666 overloadBinary (nameNode_copySafe (arrayRefNameNode), vecSort,
01667 ltoken_copy (intToken), baseSort);
01668
01669
01670
01671
01672 overloadIsSub (vecSort, dim);
01673 }
01674
01675 static void
01676 overloadIsSub (sort s, int dim)
01677 {
01678
01679 int j, i;
01680 ltoken dom, nulltok = ltoken_undefined;
01681 ltokenList domain;
01682 sigNode signature;
01683
01684 for (j = 1; j <= dim; j++)
01685 {
01686 nameNode isSubNameNode = (nameNode) dmalloc (sizeof (*isSubNameNode));
01687
01688 isSubNameNode->isOpId = TRUE;
01689 isSubNameNode->content.opid = ltoken_createType (simpleId, SID_OP,
01690 lsymbol_fromChars ("isSub"));
01691 dom = ltoken_createType (simpleId, SID_SORT, sort_getLsymbol (s));
01692
01693 domain = ltokenList_singleton (dom);
01694
01695 for (i = 1; i <= j; i++)
01696 {
01697 ltokenList_addh (domain, ltoken_copy (intToken));
01698 }
01699
01700 signature = makesigNode (nulltok, domain, ltoken_copy (ltoken_bool));
01701 symtable_enterOp (g_symtab, isSubNameNode, signature);
01702 }
01703 }
01704
01705 static void
01706 overloadUnaryTok ( nameNode nn, sort domainSort, ltoken range)
01707 {
01708
01709 sigNode signature;
01710 ltoken dom;
01711 ltokenList domain;
01712
01713 dom = ltoken_createType (simpleId, SID_SORT, sort_getLsymbol (domainSort));
01714 domain = ltokenList_singleton (dom);
01715 signature = makesigNode (ltoken_undefined, domain, range);
01716 symtable_enterOp (g_symtab, nn, signature);
01717 }
01718
01719 static void
01720 overloadSizeof (sort domainSort)
01721 {
01722 nameNode sizeofNameNode = (nameNode) dmalloc (sizeof (*sizeofNameNode));
01723
01724 sizeofNameNode->isOpId = TRUE;
01725 sizeofNameNode->content.opid = ltoken_createType (simpleId, SID_OP,
01726 lsymbol_fromChars ("sizeof"));
01727
01728 overloadUnaryTok (sizeofNameNode, domainSort, ltoken_copy (intToken));
01729 }
01730
01731 static void
01732 overloadUnary ( nameNode nn, sort domainSort, sort rangeSort)
01733 {
01734 ltoken range = ltoken_createType (simpleId, SID_SORT, sort_getLsymbol (rangeSort));
01735
01736 overloadUnaryTok (nn, domainSort, range);
01737 }
01738
01739 static void
01740 overloadBinary ( nameNode nn, sort s, ltoken dTok, sort rs)
01741 {
01742
01743 sigNode signature;
01744 ltoken range, dom;
01745 ltokenList domain = ltokenList_new ();
01746
01747 range = ltoken_createType (simpleId, SID_SORT, sort_getLsymbol (rs));
01748 dom = ltoken_createType (simpleId, SID_SORT, sort_getLsymbol (s));
01749
01750 ltokenList_addh (domain, dom);
01751 ltokenList_addh (domain, dTok);
01752
01753 signature = makesigNode (ltoken_undefined, domain, range);
01754 symtable_enterOp (g_symtab, nn, signature);
01755 }
01756
01757 static nameNode
01758 makeFieldOp (lsymbol field)
01759 {
01760
01761 nameNode nn;
01762 opFormUnion u;
01763 opFormNode opform;
01764
01765 u.id = ltoken_createType (simpleId, SID_OP, field);
01766 opform = makeOpFormNode (ltoken_undefined, OPF_MSELECT, u, ltoken_undefined);
01767 nn = makeNameNodeForm (opform);
01768 return nn;
01769 }
01770
01771 static nameNode
01772 makeArrowFieldOp (lsymbol field)
01773 {
01774
01775 nameNode nn;
01776 opFormUnion u;
01777 opFormNode opform;
01778
01779 u.id = ltoken_createType (simpleId, SID_OP, field);
01780 opform = makeOpFormNode (ltoken_undefined, OPF_MMAP, u, ltoken_undefined);
01781 nn = makeNameNodeForm (opform);
01782 return nn;
01783 }
01784
01785 void
01786 sort_init (void)
01787
01788
01789
01790
01791
01792
01793
01794
01795
01796
01797
01798 {
01799
01800 opFormNode opform;
01801 opFormUnion u;
01802 underscoreSymbol = lsymbol_fromChars ("_");
01803
01804
01805
01806
01807
01808 lsymbol_setbool (lsymbol_fromChars ("bool"));
01809 intToken = ltoken_createType (simpleId, SID_SORT, lsymbol_fromChars ("int"));
01810
01811
01812
01813
01814
01815 u.anyop = ltoken_copy (ltoken_eq);
01816 opform = makeOpFormNode (ltoken_undefined, OPF_MANYOPM, u, ltoken_undefined);
01817 eqNameNode = makeNameNodeForm (opform);
01818
01819
01820
01821
01822
01823 u.anyop = ltoken_copy (ltoken_neq);
01824 opform = makeOpFormNode (ltoken_undefined, OPF_MANYOPM, u, ltoken_undefined);
01825 neqNameNode = makeNameNodeForm (opform);
01826
01827
01828
01829
01830
01831 opform = makeOpFormNode (ltoken_undefined, OPF_IF,
01832 opFormUnion_createMiddle (0), ltoken_undefined);
01833 condNameNode = makeNameNodeForm (opform);
01834
01835
01836 u.middle = 1;
01837 opform = makeOpFormNode (ltoken_copy (ltoken_lbracked), OPF_BMMIDDLE, u,
01838 ltoken_copy (ltoken_rbracket));
01839 arrayRefNameNode = makeNameNodeForm (opform);
01840
01841
01842 u.middle = 0;
01843 opform = makeOpFormNode (ltoken_copy (ltoken_lbracked),
01844 OPF_BMMIDDLE, u,
01845 ltoken_copy (ltoken_rbracket));
01846 ptr2arrayNameNode = makeNameNodeForm (opform);
01847
01848
01849 u.anyop = ltoken_create (LLT_MULOP, lsymbol_fromChars ("*"));
01850 opform = makeOpFormNode (ltoken_undefined, OPF_ANYOPM, u, ltoken_undefined);
01851 deRefNameNode = makeNameNodeForm (opform);
01852
01853
01854 u.anyop = ltoken_create (simpleOp, lsymbol_fromChars ("+"));
01855 opform = makeOpFormNode (ltoken_undefined, OPF_MANYOPM, u, ltoken_undefined);
01856 plusNameNode = makeNameNodeForm (opform);
01857
01858
01859 u.anyop = ltoken_create (simpleOp, lsymbol_fromChars ("-"));
01860 opform = makeOpFormNode (ltoken_undefined, OPF_MANYOPM, u, ltoken_undefined);
01861 minusNameNode = makeNameNodeForm (opform);
01862
01863
01864 nilNameNode = (nameNode) dmalloc (sizeof (*nilNameNode));
01865 nilNameNode->isOpId = TRUE;
01866 nilNameNode->content.opid = ltoken_createType (simpleId, SID_OP,
01867 lsymbol_fromChars ("NIL"));
01868
01869 noSort.kind = SRT_NONE;
01870 noSort.name = lsymbol_fromChars ("_unknown");;
01871 noSort.tag = lsymbol_undefined;
01872 noSort.baseSort = NOSORTHANDLE;
01873 noSort.objSort = NOSORTHANDLE;
01874 noSort.members = smemberInfo_undefined;
01875 noSort.export = FALSE;
01876 noSort.mutable = FALSE;
01877 noSort.abstract = FALSE;
01878 noSort.imported = FALSE;
01879 noSort.handle = NOSORTHANDLE;
01880
01881
01882
01883
01884
01885
01886
01887 noSort.handle = sort_enterGlobal (noSort);
01888 (void) sort_enterGlobal (HOFSort);
01889
01890
01891
01892 sort_bool = sort_makeImmutable (ltoken_undefined, lsymbol_fromChars ("bool"));
01893 sort_capBool = sort_makeSortNoOps (ltoken_undefined, lsymbol_fromChars ("Bool"));
01894
01895 llassert (sortTable != NULL);
01896
01897
01898 sortTable[sort_capBool].kind = SRT_SYN;
01899 sortTable[sort_capBool].baseSort = sort_bool;
01900 sortTable[sort_capBool].mutable = FALSE;
01901 sortTable[sort_capBool].abstract = TRUE;
01902
01903 sort_int = sort_makeLiteralSort (ltoken_undefined,
01904 lsymbol_fromChars ("int"));
01905 sort_char = sort_makeLiteralSort (ltoken_undefined,
01906 lsymbol_fromChars ("char"));
01907 sort_void = sort_makeLiteralSort (ltoken_undefined,
01908 lsymbol_fromChars ("void"));
01909
01910
01911 char_obj_ptrSort = sort_makePtr (ltoken_undefined, sort_char);
01912 char_obj_ArrSort = sort_makeArr (ltoken_undefined, sort_char);
01913
01914 sort_cstring = sort_makeVal (char_obj_ArrSort);
01915 sort_float = sort_makeLiteralSort (ltoken_undefined, lsymbol_fromChars ("float"));
01916 sort_double = sort_makeLiteralSort (ltoken_undefined, lsymbol_fromChars ("double"));
01917 }
01918
01919 sort
01920 sort_lookupName (lsymbol name)
01921 {
01922 long int i;
01923
01924 if (name == lsymbol_undefined)
01925 {
01926 return NOSORTHANDLE;
01927 }
01928
01929 llassert (sortTable != NULL);
01930
01931 for (i = 0; i < sortTableSize; i++)
01932 {
01933 if (sortTable[i].name == name)
01934 {
01935 return i;
01936 }
01937 }
01938
01939 return NOSORTHANDLE;
01940 }
01941
01942 static bool
01943 sort_isNewEntry (sortNode s)
01944 {
01945 int i;
01946
01947 for (i = 0; i < sortTableSize; i++)
01948 {
01949 llassert (sortTable != NULL);
01950
01951 if (sortTable[i].kind == s.kind && sortTable[i].name == s.name)
01952 {
01953 return FALSE;
01954 }
01955 }
01956 return TRUE;
01957 }
01958
01959 static sort
01960 sort_enterGlobal (sortNode s)
01961 {
01962 return (sort_enterNew (s));
01963 }
01964
01965 static sort
01966 sort_enterNew (sortNode s)
01967 {
01968
01969
01970
01971
01972 long int i;
01973
01974 for (i = 0; i < sortTableSize; i++)
01975 {
01976 llassert (sortTable != NULL);
01977
01978 if (sortTable[i].kind == s.kind && sortTable[i].name == s.name)
01979 {
01980 sortNode_free (s);
01981 return i;
01982 }
01983 }
01984
01985 if (sortTableSize >= sortTableAlloc)
01986 {
01987 sortNode *oldSortTable = sortTable;
01988
01989 sortTableAlloc += DELTA;
01990 sortTable = (sortNode *) dmalloc (sortTableAlloc * sizeof (*sortTable));
01991
01992 if (sortTableSize > 0)
01993 {
01994 llassert (oldSortTable != NULL);
01995 for (i = 0; i < sortTableSize; i++)
01996 {
01997 sortTable[i] = oldSortTable[i];
01998 }
01999 }
02000
02001 sfree (oldSortTable);
02002 }
02003
02004 llassert (sortTable != NULL);
02005
02006 s.handle = sortTableSize;
02007 sortTable[sortTableSize++] = s;
02008
02009
02010
02011 return s.handle;
02012 }
02013
02014 static sort sort_enterNewForce (sortNode s)
02015 {
02016 sort sor = sort_enterNew (s);
02017
02018 s.handle = sor;
02019 llassert (sortTable != NULL);
02020 sortTable[sor] = s;
02021
02022 return (sor);
02023 }
02024
02025 void
02026 sort_printStats (void)
02027 {
02028
02029 printf ("sortTableSize = %d; sortTableAlloc = %d\n", sortTableSize,
02030 sortTableAlloc);
02031 }
02032
02033 sortNode
02034 sort_lookup (sort sor)
02035 {
02036
02037
02038
02039 if (sor > 0U && sor < (unsigned) sortTableSize)
02040 {
02041 llassert (sortTable != NULL);
02042 return sortTable[sor];
02043 }
02044
02045 llassert (sor == 0);
02046 return noSort;
02047 }
02048
02049 sortNode
02050 sort_quietLookup (sort sor)
02051 {
02052
02053 if (sor > 0U && sor < (unsigned) sortTableSize)
02054 {
02055 llassert (sortTable != NULL);
02056 return (sortTable[sor]);
02057 }
02058 else
02059 {
02060 return noSort;
02061 }
02062 }
02063
02064 static cstring
02065 printEnumMembers ( smemberInfo *list)
02066 {
02067 cstring out = cstring_undefined;
02068 smemberInfo *m;
02069
02070 for (m = list; m != (smemberInfo *) 0; m = m->next)
02071 {
02072 out = cstring_concat (out, lsymbol_toString (m->name));
02073
02074 if (m->next != (smemberInfo *) 0)
02075 {
02076 out = cstring_concatChars (out, ", ");
02077 }
02078 }
02079 return out;
02080 }
02081
02082 static cstring
02083 printStructMembers ( smemberInfo *list)
02084 {
02085 cstring ret = cstring_undefined;
02086 smemberInfo *m;
02087
02088 for (m = list; m != (smemberInfo *) 0; m = m->next)
02089 {
02090 ret = message ("%q%q %s; ",
02091 ret, sort_unparse (m->sort),
02092 cstring_fromChars (lsymbol_toChars (m->name)));
02093 }
02094
02095 return ret;
02096 }
02097
02098 cstring
02099 sort_unparse (sort s)
02100 {
02101
02102 sortNode sn;
02103 lsymbol name;
02104
02105 sn = sort_quietLookup (s);
02106 name = sn.name;
02107
02108 switch (sn.kind)
02109 {
02110 case SRT_NONE:
02111 if (name == lsymbol_undefined)
02112 {
02113 return cstring_makeLiteral ("_unknown");
02114 }
02115
02116 return (cstring_fromCharsNew (lsymbol_toChars (name)));
02117 case SRT_HOF:
02118 return cstring_makeLiteral ("procedural");
02119 case SRT_PRIM:
02120 return (cstring_fromCharsNew (lsymbol_toChars (name)));
02121 case SRT_SYN:
02122 return (cstring_fromCharsNew (lsymbol_toChars (name)));
02123
02124 case SRT_PTR:
02125 return (message ("%q *", sort_unparse (sort_makeVal (sn.baseSort))));
02126 case SRT_OBJ:
02127 return (message ("obj %q", sort_unparse (sn.baseSort)));
02128 case SRT_ARRAY:
02129 return (message ("array of %q", sort_unparse (sort_makeVal (sn.baseSort))));
02130 case SRT_VECTOR:
02131 return (message ("vector of %q", sort_unparse (sn.baseSort)));
02132 case SRT_TUPLE:
02133 if (sn.tag != lsymbol_undefined && sn.realtag)
02134 {
02135 return (message ("struct %s", cstring_fromChars (lsymbol_toChars (sn.tag))));
02136 }
02137 else
02138 {
02139 return (message ("struct {%q}", printStructMembers (sn.members)));
02140 }
02141 case SRT_UNIONVAL:
02142 if (sn.tag != lsymbol_undefined && sn.realtag)
02143 {
02144 return (message ("union %s", cstring_fromChars (lsymbol_toChars (sn.tag))));
02145 }
02146 else
02147 {
02148 return (message ("union {%q}", printStructMembers (sn.members)));
02149 }
02150 case SRT_ENUM:
02151 if (sn.tag != lsymbol_undefined && sn.realtag)
02152 {
02153 return (message ("enum %s", cstring_fromChars (lsymbol_toChars (sn.tag))));
02154 }
02155 else
02156 {
02157 return (message ("enum {%q}", printEnumMembers (sn.members)));
02158 }
02159 case SRT_STRUCT:
02160 if (sn.tag != lsymbol_undefined && sn.realtag)
02161 {
02162 return (message ("obj struct %s", cstring_fromChars (lsymbol_toChars (sn.tag))));
02163 }
02164 else
02165 {
02166 return (message ("obj struct {%q}", printStructMembers (sn.members)));
02167 }
02168 case SRT_UNION:
02169 if (sn.tag != lsymbol_undefined && sn.realtag)
02170 {
02171 return (message ("obj union %s", cstring_fromChars (lsymbol_toChars (sn.tag))));
02172 }
02173 else
02174 {
02175 return (message ("obj union {%q}", printStructMembers (sn.members)));
02176 }
02177 default:
02178 return (cstring_makeLiteral ("illegal"));
02179 }
02180 }
02181
02182 static lsymbol
02183 sp (lsymbol s1, lsymbol s2)
02184 {
02185 char buff[MAXBUFFLEN];
02186 char *name1Ptr;
02187 char *name2Ptr;
02188 int temp_length;
02189
02190 name1Ptr = lsymbol_toCharsSafe (s1);
02191 name2Ptr = lsymbol_toCharsSafe (s2);
02192
02193 if (strlen (name1Ptr) + strlen (name2Ptr) + 1 > MAXBUFFLEN)
02194 {
02195 temp_length = strlen (name1Ptr) + strlen (name2Ptr) + 1;
02196 llfatalbug (message ("sp: name too long: %s%s",
02197 cstring_fromChars (name1Ptr),
02198 cstring_fromChars (name2Ptr)));
02199 }
02200
02201 strcpy (&buff[0], name1Ptr);
02202 strcat (&buff[0], name2Ptr);
02203
02204 return lsymbol_fromChars (&buff[0]);
02205 }
02206
02207 static lsymbol
02208 sortTag_toSymbol (char *kind, ltoken tagid, bool *isNew)
02209 {
02210
02211
02212
02213
02214
02215
02216 tagInfo to;
02217
02218 if (ltoken_isUndefined (tagid))
02219 {
02220 *isNew = TRUE;
02221 return (cstring_toSymbol (message ("_anon_%s%d", cstring_fromChars (kind), sortUID++)));
02222 }
02223 else
02224 {
02225 to = symtable_tagInfo (g_symtab, ltoken_getText (tagid));
02226
02227 if (tagInfo_exists (to))
02228 {
02229 *isNew = FALSE;
02230 }
02231 else
02232 {
02233 *isNew = TRUE;
02234 }
02235
02236 return (cstring_toSymbol (message ("_%s_%s",
02237 ltoken_unparse (tagid),
02238 cstring_fromChars (kind))));
02239 }
02240 }
02241
02242
02243 # define MAX_SORT_DEPTH 10
02244
02245 static sort
02246 sort_getUnderlyingAux (sort s, int depth)
02247 {
02248 sortNode sn = sort_quietLookup (s);
02249
02250 if (sn.kind == SRT_SYN)
02251 {
02252 if (depth > MAX_SORT_DEPTH)
02253 {
02254 llcontbug (message ("sort_getUnderlying: depth charge: %d", depth));
02255 return s;
02256 }
02257
02258 return sort_getUnderlyingAux (sn.baseSort, depth + 1);
02259 }
02260
02261 return s;
02262 }
02263
02264 sort
02265 sort_getUnderlying (sort s)
02266 {
02267 return sort_getUnderlyingAux (s, 0);
02268 }
02269
02270 static lsymbol
02271 underlyingSortName (sortNode sn)
02272 {
02273 if (sn.kind == SRT_SYN)
02274 return underlyingSortName (sort_quietLookup (sn.baseSort));
02275 return sn.name;
02276 }
02277
02278 static sortNode
02279 underlyingSortNode (sortNode sn)
02280 {
02281 if (sn.kind == SRT_SYN)
02282 {
02283 return underlyingSortNode (sort_quietLookup (sn.baseSort));
02284 }
02285
02286 return sn;
02287 }
02288
02289 bool
02290 sort_mutable (sort s)
02291 {
02292
02293 sortNode sn = sort_quietLookup (s);
02294 if (sn.mutable)
02295 return TRUE;
02296 return FALSE;
02297 }
02298
02299 bool
02300 sort_setExporting (bool flag)
02301 {
02302 bool old;
02303 old = exporting;
02304 exporting = flag;
02305 return old;
02306 }
02307
02308 static cstring
02309 sort_unparseKind (sortKind k)
02310 {
02311 if (k > SRT_FIRST && k < SRT_LAST)
02312 return (cstring_fromChars (sortKindName[(int)k]));
02313 else
02314 return (cstring_makeLiteralTemp ("<unknown sort kind>"));
02315 }
02316
02317 bool
02318 sort_isValidSort (sort s)
02319 {
02320 sortNode sn = sort_quietLookup (s);
02321 sortKind k = sn.kind;
02322 if (k != SRT_NONE && k > SRT_FIRST && k < SRT_LAST)
02323 return TRUE;
02324 else
02325 return FALSE;
02326 }
02327
02328 void
02329 sort_dump (FILE *f, bool lco)
02330 {
02331 int i;
02332 sortNode s;
02333 smemberInfo *mem;
02334
02335 fprintf (f, "%s\n", BEGINSORTTABLE);
02336 llassert (sortTable != NULL);
02337
02338 for (i = 2; i < sortTableSize; i++)
02339 {
02340
02341 s = sortTable[i];
02342
02343
02344
02345
02346
02347
02348
02349
02350 if (s.kind == SRT_NONE)
02351 continue;
02352
02353 if (lco)
02354 {
02355 fprintf (f, "%%LCL");
02356 }
02357
02358 if (lsymbol_isDefined (s.name))
02359 {
02360 fprintf (f, "sort %s ", lsymbol_toCharsSafe (s.name));
02361 }
02362 else
02363 {
02364 llcontbug (message ("Invalid sort in sort_dump: sort %d; sortname: %s. This may result from using .lcs files produced by an old version of LCLint. Remove the .lcs files, and rerun LCLint.",
02365 i, lsymbol_toString (s.name)));
02366 fprintf (f, "sort _error_ ");
02367 }
02368
02369 if (!lco && !s.export)
02370 fprintf (f, "private ");
02371
02372
02373 switch (s.kind)
02374 {
02375 case SRT_HOF:
02376 fprintf (f, "hof nil nil\n");
02377 break;
02378 case SRT_PRIM:
02379 if (s.abstract)
02380 fprintf (f, "immutable nil nil\n");
02381 else
02382 fprintf (f, "primitive nil nil\n");
02383 break;
02384 case SRT_OBJ:
02385 if (s.abstract)
02386 fprintf (f, "mutable %s nil\n",
02387 lsymbol_toCharsSafe (sortTable[s.baseSort].name));
02388 else
02389 fprintf (f, "obj %s nil\n",
02390 lsymbol_toCharsSafe (sortTable[s.baseSort].name));
02391 break;
02392 case SRT_SYN:
02393 fprintf (f, "synonym %s nil\n",
02394 lsymbol_toCharsSafe (sortTable[s.baseSort].name));
02395 break;
02396 case SRT_PTR:
02397 fprintf (f, "ptr %s nil\n", lsymbol_toCharsSafe (sortTable[s.baseSort].name));
02398 break;
02399 case SRT_ARRAY:
02400 fprintf (f, "arr %s nil\n",
02401 lsymbol_toCharsSafe (sortTable[s.baseSort].name));
02402 break;
02403 case SRT_VECTOR:
02404 fprintf (f, "vec %s %s\n",
02405 lsymbol_toCharsSafe (sortTable[s.baseSort].name),
02406 lsymbol_toCharsSafe (sortTable[s.objSort].name));
02407 break;
02408 case SRT_STRUCT:
02409 if (s.tag == lsymbol_undefined)
02410 {
02411
02412
02413
02414 llbuglit ("Struct has no tag");
02415 }
02416 else
02417 fprintf (f, "str %s nil\n", lsymbol_toCharsSafe (s.tag));
02418
02419 for (mem = s.members;
02420 mem != smemberInfo_undefined; mem = mem->next)
02421 {
02422 if (lco)
02423 fprintf (f, "%%LCL");
02424 fprintf (f, "sort %s strMem %s nil\n", lsymbol_toCharsSafe (mem->name),
02425 lsymbol_toCharsSafe (sortTable[mem->sort].name));
02426 }
02427 if (lco)
02428 fprintf (f, "%%LCL");
02429 fprintf (f, "sort strEnd nil nil nil\n");
02430 break;
02431 case SRT_UNION:
02432 if (s.tag == lsymbol_undefined)
02433 llbuglit ("Union has no tag");
02434 else
02435 fprintf (f, "union %s nil\n", lsymbol_toCharsSafe (s.tag));
02436 for (mem = s.members;
02437 mem != smemberInfo_undefined; mem = mem->next)
02438 {
02439 if (lco)
02440 fprintf (f, "%%LCL");
02441 fprintf (f, "sort %s unionMem %s nil\n", lsymbol_toCharsSafe (mem->name),
02442 lsymbol_toCharsSafe (sortTable[mem->sort].name));
02443 }
02444 if (lco)
02445 fprintf (f, "%%LCL");
02446 fprintf (f, "sort unionEnd nil nil nil\n");
02447 break;
02448 case SRT_ENUM:
02449 if (s.tag == lsymbol_undefined)
02450 {
02451 llbuglit ("Enum has no tag");
02452 }
02453
02454 fprintf (f, "enum %s nil\n", lsymbol_toCharsSafe (s.tag));
02455
02456 for (mem = s.members;
02457 mem != smemberInfo_undefined; mem = mem->next)
02458 {
02459 if (lco)
02460 fprintf (f, "%%LCL");
02461 fprintf (f, "sort %s enumMem nil nil\n", lsymbol_toCharsSafe (mem->name));
02462 }
02463 if (lco)
02464 fprintf (f, "%%LCL");
02465 fprintf (f, "sort enumEnd nil nil nil\n");
02466 break;
02467 case SRT_TUPLE:
02468 fprintf (f, "tup %s nil\n", lsymbol_toCharsSafe (sortTable[s.baseSort].name));
02469 break;
02470 case SRT_UNIONVAL:
02471 fprintf (f, "unionval %s nil\n",
02472 lsymbol_toCharsSafe (sortTable[s.baseSort].name));
02473 break;
02474 default:
02475 fprintf (f, "sort_dump: unexpected sort: %d", (int)s.kind);
02476 }
02477
02478 }
02479
02480 fprintf (f, "%s\n", SORTTABLEEND);
02481 }
02482
02483 static void
02484 sort_loadOther (char *kstr, lsymbol sname, sort bsort)
02485 {
02486 if (strcmp (kstr, "synonym") == 0)
02487 {
02488 (void) sort_construct (sname, SRT_SYN, bsort, lsymbol_undefined,
02489 FALSE, NOSORTHANDLE, smemberInfo_undefined);
02490 }
02491 else if (strcmp (kstr, "mutable") == 0)
02492 {
02493 (void) sort_constructAbstract (sname, TRUE, bsort);
02494 }
02495 else if (strcmp (kstr, "obj") == 0)
02496 {
02497 (void) sort_construct (sname, SRT_OBJ, bsort, lsymbol_undefined,
02498 TRUE, NOSORTHANDLE, smemberInfo_undefined);
02499 }
02500 else if (strcmp (kstr, "ptr") == 0)
02501 {
02502 (void) sort_construct (sname, SRT_PTR, bsort, lsymbol_undefined,
02503 FALSE, NOSORTHANDLE, smemberInfo_undefined);
02504 }
02505 else if (strcmp (kstr, "arr") == 0)
02506 {
02507 (void) sort_construct (sname, SRT_ARRAY, bsort, lsymbol_undefined,
02508 TRUE, NOSORTHANDLE, smemberInfo_undefined);
02509 }
02510 else if (strcmp (kstr, "tup") == 0)
02511 {
02512 (void) sort_construct (sname, SRT_TUPLE, bsort, lsymbol_undefined,
02513 FALSE, NOSORTHANDLE, smemberInfo_undefined);
02514 }
02515 else if (strcmp (kstr, "unionval") == 0)
02516 {
02517 (void) sort_construct (sname, SRT_UNIONVAL, bsort, lsymbol_undefined,
02518 FALSE, NOSORTHANDLE, smemberInfo_undefined);
02519 }
02520 else
02521 {
02522 llbug (message ("Unhandled: %s", cstring_fromChars (kstr)));
02523 }
02524 }
02525
02526 static void
02527 parseSortLine (char *line, ltoken t, tsource * s,
02528 mapping *map, lsymbolList slist)
02529 {
02530
02531
02532 static lsymbol strName = lsymbol_undefined;
02533 static smemberInfo *strMemList = NULL;
02534 static lsymbol unionName = lsymbol_undefined;
02535 static smemberInfo *unionMemList = NULL;
02536 static lsymbol enumName = lsymbol_undefined;
02537 static smemberInfo *enumMemList = NULL;
02538 static lsymbol tagName = lsymbol_undefined;
02539
02540 char *importfile = tsource_fileName (s);
02541 char sostr[MAXBUFFLEN], kstr[10], basedstr[MAXBUFFLEN], objstr[MAXBUFFLEN];
02542 bool tmp;
02543 tagInfo ti;
02544 lsymbol sname, bname, new_name, objName;
02545 sort objSort;
02546 char *lineptr;
02547 int col;
02548 ltoken tagid;
02549
02550 if (sscanf (line, "sort %s %s %s %s", &(sostr[0]), &(kstr[0]),
02551 &(basedstr[0]), &(objstr[0])) != 4)
02552 {
02553
02554
02555 lclplainerror
02556 (message ("%q: Imported file contains illegal sort declaration. "
02557 "Skipping this line: \n%s\n",
02558 fileloc_unparseRaw (cstring_fromChars (importfile),
02559 tsource_thisLineNumber (s)),
02560 cstring_fromChars (line)));
02561 return;
02562 }
02563
02564 sname = lsymbol_fromChars (sostr);
02565 if (sname == lsymbol_fromChars ("nil"))
02566 {
02567
02568
02569 sname = lsymbol_undefined;
02570 lclerror (t, message ("Illegal sort declaration in import file: %s:\n%s",
02571 cstring_fromChars (importfile),
02572 cstring_fromChars (line)));
02573 }
02574
02575
02576
02577
02578
02579 bname = lsymbol_fromChars (basedstr);
02580 if (strcmp (kstr, "primitive") == 0)
02581 {
02582 new_name = lsymbol_translateSort (map, sname);
02583 (void) sort_construct (new_name, SRT_PRIM, NOSORTHANDLE,
02584 lsymbol_undefined, FALSE,
02585 NOSORTHANDLE, smemberInfo_undefined);
02586 }
02587 else if (strcmp (kstr, "strMem") == 0)
02588 {
02589 smemberInfo *mem = (smemberInfo *) dmalloc (sizeof (*mem));
02590 mem->next = strMemList;
02591 mem->name = sname;
02592 mem->sortname = bname;
02593 mem->sort = NOSORTHANDLE;
02594 strMemList = mem;
02595 }
02596 else if (strcmp (sostr, "strEnd") == 0)
02597 {
02598 if (strName != lsymbol_undefined && strMemList != NULL)
02599 {
02600 sort asort = sort_construct (strName, SRT_STRUCT, NOSORTHANDLE, tagName,
02601 TRUE, NOSORTHANDLE, strMemList);
02602
02603 if (tagName != lsymbol_undefined)
02604 {
02605 tagid = ltoken_create (simpleId, tagName);
02606
02607 ti = (tagInfo) dmalloc (sizeof (*ti));
02608 ti->sort = asort;
02609 ti->kind = TAG_STRUCT;
02610 ti->id = tagid;
02611 ti->imported = FALSE;
02612
02613 (void) symtable_enterTagForce (g_symtab, ti);
02614 }
02615 }
02616 else
02617 {
02618 if (strName == lsymbol_undefined)
02619 {
02620 lclbug (message ("%q: Imported file contains unexpected null struct sort",
02621 fileloc_unparseRaw (cstring_fromChars (importfile), tsource_thisLineNumber (s))));
02622 }
02623 else
02624 {
02625
02626
02627
02628
02629 if (tagName != lsymbol_undefined)
02630 {
02631 tagid = ltoken_create (simpleId, tagName);
02632 (void) checkAndEnterTag (TAG_FWDSTRUCT, tagid);
02633 }
02634 }
02635 }
02636 strName = lsymbol_undefined;
02637 strMemList = NULL;
02638 tagName = lsymbol_undefined;
02639 }
02640 else if (strcmp (kstr, "str") == 0)
02641 {
02642 if (strName != lsymbol_undefined || strMemList != NULL)
02643 {
02644 lclbug (message ("%q: unexpected non-null struct sort or "
02645 "non-empty member list",
02646 fileloc_unparseRaw (cstring_fromChars (importfile),
02647 tsource_thisLineNumber (s))));
02648 }
02649
02650 if (strcmp (basedstr, "nil") == 0)
02651 {
02652 llfatalerror (message ("%s: Struct missing tag. Obsolete .lcs file, remove and rerun lcl.",
02653 cstring_fromChars (importfile)));
02654
02655
02656
02657
02658
02659 }
02660 else
02661 {
02662 tagName = bname;
02663 tagid = ltoken_create (simpleId, bname);
02664
02665 strName = sortTag_toSymbol ("Struct", tagid, &tmp);
02666 ti = symtable_tagInfo (g_symtab, tagName);
02667
02668
02669
02670
02671 }
02672
02673 lsymbolList_addh (slist, strName);
02674 }
02675 else if (strcmp (kstr, "enumMem") == 0)
02676 {
02677 smemberInfo *mem = (smemberInfo *) dmalloc (sizeof (*mem));
02678 mem->next = enumMemList;
02679 mem->sortname = enumName;
02680 mem->name = sname;
02681 mem->sort = NOSORTHANDLE;
02682 enumMemList = mem;
02683 }
02684 else if (strcmp (sostr, "enumEnd") == 0)
02685 {
02686 if (enumName != lsymbol_undefined && enumMemList != NULL)
02687 {
02688 sort asort = sort_construct (enumName, SRT_ENUM, NOSORTHANDLE, tagName,
02689 FALSE, NOSORTHANDLE, enumMemList);
02690
02691 if (tagName != lsymbol_undefined)
02692 {
02693 tagid = ltoken_create (simpleId, tagName);
02694
02695 ti = (tagInfo) dmalloc (sizeof (*ti));
02696 ti->sort = asort;
02697 ti->kind = TAG_ENUM;
02698 ti->id = tagid;
02699 ti->imported = FALSE;
02700
02701 (void) symtable_enterTagForce (g_symtab, ti);
02702 }
02703 }
02704 else
02705 {
02706 lclbug (message ("%q: unexpected null enum sort or empty member list",
02707 fileloc_unparseRaw (cstring_fromChars (importfile), tsource_thisLineNumber (s))));
02708 }
02709 enumName = lsymbol_undefined;
02710 enumMemList = NULL;
02711 tagName = lsymbol_undefined;
02712 }
02713 else if (strcmp (kstr, "enum") == 0)
02714 {
02715 if (enumName != lsymbol_undefined || enumMemList != NULL)
02716 {
02717 lclbug (message ("%q: Unexpected non-null enum sort or "
02718 "non-empty member list",
02719 fileloc_unparseRaw (cstring_fromChars (importfile),
02720 tsource_thisLineNumber (s))));
02721 }
02722
02723
02724 if (strcmp (basedstr, "nil") == 0)
02725 {
02726 llfatalerror (message ("%s: Enum missing tag. Obsolete .lcs file, "
02727 "remove and rerun lcl.",
02728 cstring_fromChars (importfile)));
02729 }
02730 else
02731 {
02732 tagName = bname;
02733 tagid = ltoken_create (simpleId, bname);
02734 enumName = sortTag_toSymbol ("Enum", tagid, &tmp);
02735 ti = symtable_tagInfo (g_symtab, bname);
02736 }
02737 }
02738 else if (strcmp (kstr, "unionMem") == 0)
02739 {
02740 smemberInfo *mem = (smemberInfo *) dmalloc (sizeof (*mem));
02741 mem->next = unionMemList;
02742 mem->sortname = bname;
02743 mem->name = sname;
02744 mem->sort = NOSORTHANDLE;
02745 unionMemList = mem;
02746 }
02747 else if (strcmp (sostr, "unionEnd") == 0)
02748 {
02749 if (unionName != lsymbol_undefined && unionMemList != NULL)
02750 {
02751 sort asort = sort_construct (unionName, SRT_UNION, NOSORTHANDLE, tagName,
02752 FALSE, NOSORTHANDLE, unionMemList);
02753
02754 if (tagName != lsymbol_undefined)
02755 {
02756 tagid = ltoken_create (simpleId, tagName);
02757
02758 ti = (tagInfo) dmalloc (sizeof (*ti));
02759 ti->sort = asort;
02760 ti->kind = TAG_UNION;
02761 ti->id = tagid;
02762 ti->imported = FALSE;
02763
02764 (void) symtable_enterTagForce (g_symtab, ti);
02765 }
02766 }
02767 else
02768 {
02769 if (unionName == lsymbol_undefined)
02770 {
02771 lclbug
02772 (message ("%q: Imported file contains unexpected null union sort",
02773 fileloc_unparseRaw (cstring_fromChars (importfile), tsource_thisLineNumber (s))));
02774 }
02775 else
02776 {
02777
02778
02779
02780
02781 if (tagName != lsymbol_undefined)
02782 {
02783 tagid = ltoken_create (simpleId, tagName);
02784
02785 (void) checkAndEnterTag (TAG_FWDUNION, tagid);
02786 }
02787 }
02788 }
02789
02790 unionName = lsymbol_undefined;
02791 unionMemList = NULL;
02792 tagName = lsymbol_undefined;
02793 }
02794 else if (strcmp (kstr, "union") == 0)
02795 {
02796 if (unionName != lsymbol_undefined || unionMemList != NULL)
02797 {
02798 lclbug
02799 (message
02800 ("%q: Unexpected non-null union sort or non-empty "
02801 "member list",
02802 fileloc_unparseRaw (cstring_fromChars (importfile), tsource_thisLineNumber (s))));
02803 }
02804
02805 if (strcmp (basedstr, "nil") == 0)
02806 {
02807 llfatalerror
02808 (message ("%s: Union missing tag. Obsolete .lcs file, "
02809 "remove and rerun lcl.",
02810 cstring_fromChars (importfile)));
02811 }
02812 else
02813 {
02814 tagName = bname;
02815 tagid = ltoken_create (simpleId, bname);
02816
02817 unionName = sortTag_toSymbol ("Union", tagid, &tmp);
02818 ti = symtable_tagInfo (g_symtab, bname);
02819 }
02820 lsymbolList_addh (slist, unionName);
02821 }
02822 else if (strcmp (kstr, "immutable") == 0)
02823 {
02824 (void) sort_constructAbstract (sname, FALSE, NOSORTHANDLE);
02825 }
02826 else if (strcmp (kstr, "hof") == 0)
02827 {
02828 (void) sort_construct (sname, SRT_HOF, NOSORTHANDLE, lsymbol_undefined,
02829 FALSE, NOSORTHANDLE, smemberInfo_undefined);
02830 }
02831 else
02832 {
02833 sort bsort = sort_lookupName (lsymbol_translateSort (map, bname));
02834
02835 if (sort_isNoSort (bsort))
02836 {
02837 lineptr = strchr (line, ' ');
02838 llassert (lineptr != NULL);
02839 lineptr = strchr (lineptr + 1, ' ');
02840 llassert (lineptr != NULL);
02841 lineptr = strchr (lineptr + 1, ' ');
02842 llassert (lineptr != NULL);
02843 col = 5 + lineptr - line;
02844
02845 llbug
02846 (message ("%q: Imported file contains unknown base sort: %s",
02847 fileloc_unparseRawCol (cstring_fromChars (importfile),
02848 tsource_thisLineNumber (s), col),
02849 cstring_fromChars (lsymbol_toCharsSafe (bname))));
02850 }
02851
02852 if (strcmp (kstr, "vec") == 0)
02853 {
02854 objName = lsymbol_fromChars (objstr);
02855 objSort = sort_lookupName (lsymbol_translateSort (map, objName));
02856 (void) sort_construct (sname, SRT_VECTOR, bsort, lsymbol_undefined,
02857 FALSE, objSort, smemberInfo_undefined);
02858 }
02859 else
02860 {
02861 sort_loadOther (kstr, sname, bsort);
02862 }
02863 }
02864 }
02865
02866 void
02867 sort_import (tsource *imported, ltoken tok, mapping * map)
02868 {
02869
02870 char *buf, *importfile;
02871 tsource *lclsource;
02872 sort bsort;
02873 lsymbolList slist = lsymbolList_new ();
02874
02875 buf = tsource_nextLine (imported);
02876
02877 llassert (buf != NULL);
02878
02879 importfile = tsource_fileName (imported);
02880
02881 if (!firstWord (buf, "%LCLSortTable"))
02882 {
02883 lclsource = LCLScanSource ();
02884
02885 lclfatalerror (tok, message ("Expecting \"%%LCLSortTable\" line "
02886 "in import file %s:\n%s",
02887 cstring_fromChars (importfile),
02888 cstring_fromChars (buf)));
02889
02890 }
02891
02892 for (;;)
02893 {
02894 buf = tsource_nextLine (imported);
02895
02896 llassert (buf != NULL);
02897
02898 if (firstWord (buf, "%LCLSortTableEnd"))
02899 {
02900 break;
02901 }
02902 else
02903 {
02904 if (firstWord (buf, "%LCL"))
02905 {
02906 parseSortLine (buf + 4, tok, imported, map, slist);
02907 }
02908 else
02909 {
02910 lclsource = LCLScanSource ();
02911 lclfatalerror
02912 (tok,
02913 message ("Expecting '%%LCL' prefix in import file %s:\n%s\n",
02914 cstring_fromChars (importfile),
02915 cstring_fromChars (buf)));
02916 }
02917 }
02918 }
02919
02920
02921 lsymbolList_elements (slist, s)
02922 {
02923 if (s != lsymbol_undefined)
02924 {
02925 sort sor;
02926 sortNode sn;
02927
02928 sor = sort_lookupName (s);
02929 sn = sort_quietLookup (sor);
02930
02931 switch (sn.kind)
02932 {
02933 case SRT_ENUM:
02934 {
02935 varInfo vi;
02936 smemberInfo *mlist = sn.members;
02937 for (; mlist != NULL; mlist = mlist->next)
02938 {
02939
02940 vi = symtable_varInfo (g_symtab, mlist->name);
02941 if (!varInfo_exists (vi))
02942 {
02943 vi = (varInfo) dmalloc (sizeof (*vi));
02944 vi->id = ltoken_create (NOTTOKEN, mlist->name);
02945 vi->kind = VRK_ENUM;
02946 vi->sort = sor;
02947 vi->export = TRUE;
02948
02949 (void) symtable_enterVar (g_symtab, vi);
02950 varInfo_free (vi);
02951 }
02952 else
02953 {
02954 lclplainerror
02955 (message ("%s: enum member %s of %s has already been declared",
02956 cstring_fromChars (importfile),
02957 lsymbol_toString (mlist->name),
02958 lsymbol_toString (sn.name)));
02959 }
02960 }
02961 break;
02962 }
02963 case SRT_STRUCT:
02964 case SRT_UNION:
02965 {
02966 smemberInfo *mlist = sn.members;
02967
02968 for (; mlist != NULL; mlist = mlist->next)
02969 {
02970 bsort = sort_lookupName (lsymbol_translateSort (map, mlist->sortname));
02971 if (sort_isNoSort (bsort))
02972 {
02973 lclbug (message ("%s: member %s of %s has unknown sort\n",
02974 cstring_fromChars (importfile),
02975 cstring_fromChars (lsymbol_toChars (mlist->name)),
02976 cstring_fromChars (lsymbol_toChars (sn.name))));
02977 }
02978 else
02979 {
02980 mlist->sort = bsort;
02981 }
02982 }
02983 break;
02984 }
02985 default:
02986 lclbug (message ("%s: %s has unexpected sort kind %s",
02987 cstring_fromChars (importfile),
02988 cstring_fromChars (lsymbol_toChars (sn.name)),
02989 sort_unparseKind (sn.kind)));
02990 }
02991 }
02992 } end_lsymbolList_elements;
02993
02994
02995 lsymbolList_free (slist);
02996 }
02997
02998 bool
02999 sort_equal (sort *s1, sort *s2)
03000 {
03001 sort syn1, syn2;
03002 if ((s1 != 0) && (s2 != 0))
03003 {
03004 if ((*s1) == (*s2))
03005 return TRUE;
03006
03007 syn1 = sort_getUnderlying (*s1);
03008 syn2 = sort_getUnderlying (*s2);
03009 if (syn1 == syn2)
03010 return TRUE;
03011
03012 }
03013 return FALSE;
03014 }
03015
03016 bool
03017 sort_compatible (sort s1, sort s2)
03018 {
03019 sort syn1, syn2;
03020
03021 if (s1 == s2)
03022 return TRUE;
03023
03024 syn1 = sort_getUnderlying (s1);
03025 syn2 = sort_getUnderlying (s2);
03026 if (syn1 == syn2)
03027 return TRUE;
03028
03029 return FALSE;
03030 }
03031
03032 bool
03033 sort_compatible_modulo_cstring (sort s1, sort s2)
03034 {
03035
03036
03037
03038
03039
03040
03041
03042 sort syn1, syn2;
03043 if (sort_compatible (s1, s2))
03044 return TRUE;
03045 syn1 = sort_getUnderlying (s1);
03046 syn2 = sort_getUnderlying (s2);
03047 if (sort_cstring == syn2 &&
03048 (syn1 == char_obj_ptrSort || syn1 == char_obj_ArrSort))
03049 return TRUE;
03050 return FALSE;
03051 }
03052
03053 lsymbol
03054 sort_getLsymbol (sort sor)
03055 {
03056
03057 sortNode sn = sort_quietLookup (sor);
03058 return sn.name;
03059 }
03060
03061
03062
03063 char *sort_getName (sort s)
03064 {
03065 return (lsymbol_toCharsSafe (sort_getLsymbol (s)));
03066 }
03067
03068 cstring
03069 sort_unparseName (sort s)
03070 {
03071 return (cstring_fromChars (sort_getName (s)));
03072 }
03073
03074 static void
03075 sortError (ltoken t, sort oldsort, sortNode newnode)
03076 {
03077 sortNode old = sort_quietLookup (oldsort);
03078
03079 if ((old.kind <= SRT_FIRST || old.kind >= SRT_LAST) ||
03080 (newnode.kind <= SRT_FIRST || newnode.kind >= SRT_LAST))
03081 {
03082 llbuglit ("sortError: illegal sort kind");
03083 }
03084
03085 llassert (sortTable != NULL);
03086
03087 lclerror (t, message ("Sort %s defined as %s cannot be redefined as %s",
03088 cstring_fromChars (lsymbol_toChars (newnode.name)),
03089 sort_unparseKindName (sortTable[oldsort]),
03090 sort_unparseKindName (newnode)));
03091 }
03092
03093 static cstring
03094 sort_unparseKindName (sortNode s)
03095 {
03096 switch (s.kind)
03097 {
03098 case SRT_NONE:
03099 return cstring_fromChars (sortKindName[(int)s.kind]);
03100 default:
03101 if (s.abstract)
03102 {
03103 if (s.mutable)
03104 {
03105 return cstring_makeLiteralTemp ("MUTABLE");
03106 }
03107 else
03108 {
03109 return cstring_makeLiteralTemp ("IMMUTABLE");
03110 }
03111 }
03112 else
03113 return cstring_fromChars (sortKindName[(int)s.kind]);
03114 }
03115
03116 BADEXIT;
03117 }
03118
03119 sort
03120 sort_fromLsymbol (lsymbol sortid)
03121 {
03122
03123 sort sort = sort_lookupName (sortid);
03124 if (sort == NOSORTHANDLE)
03125 sort = sort_makeSort (ltoken_undefined, sortid);
03126 return sort;
03127 }
03128
03129 bool
03130 sort_isHOFSortKind (sort s)
03131 {
03132 sortNode sn = sort_quietLookup (s);
03133 if (sn.kind == SRT_HOF)
03134 return TRUE;
03135 return FALSE;
03136 }
03137
03138
03139
03140
03141
03142 static bool
03143 sort_hasStateFcns (sort s)
03144 {
03145 sortNode sn = sort_quietLookup (s);
03146 sortKind kind = sn.kind;
03147
03148 if (kind == SRT_SYN)
03149 {
03150 return (sort_hasStateFcns (sn.baseSort));
03151 }
03152
03153 return ((kind == SRT_PTR) ||
03154 (kind == SRT_OBJ) ||
03155 (kind == SRT_ARRAY) ||
03156 (kind == SRT_STRUCT) ||
03157 (kind == SRT_UNION));
03158 }
03159
03160