[BACK]Return to dic.c CVS log [TXT][DIR] Up to [local] / OpenXM / src / k097

Annotation of OpenXM/src/k097/dic.c, Revision 1.3

1.3     ! takayama    1: /* $OpenXM: OpenXM/src/k097/dic.c,v 1.2 2000/01/21 03:01:25 takayama Exp $ */
1.1       maekawa     2: #include <stdio.h>
                      3: #include "d.h"
                      4:
                      5:
                      6: static int K00debug0 = 0;  /* If it is set to 1, context will be printed. */
                      7:
                      8: static int K00Initialized = 0;
                      9:
                     10: struct context *K00CurrentContextp = NULL;
                     11: struct context *K00PrimitiveContextp = NULL;
                     12: /* It is initialize at K00InitDic() */
                     13:
                     14: objectp K00NullObject = NULL;
                     15: int K00Strict2 = 1;
                     16:
                     17:
                     18: static void myerror(char *s) {
                     19:   fprintf(stderr,"Error in dic.c : ");
1.3     ! takayama   20:   fprintf(stderr,"%s",s);
1.1       maekawa    21: }
                     22:
                     23: int K00putUserDictionary(str,h0,h1,ob,cp)
                     24: char *str;   /* key */
                     25: int h0,h1;   /* Hash values of the key */
                     26: objectp ob; /* value */
                     27: struct context *cp;
                     28: {
                     29:   int x,r;
                     30:   extern int K00Strict2;
                     31:   struct dictionary *dic;
                     32:   dic = cp->userDictionary;
                     33:   x = h0;
                     34:   if (str[0] == '\0') {
                     35:     K00errorDic("putUserDictionary(): You are defining a value with the null key.\n");
                     36:   }
                     37:   while (1) {
                     38:     if ((dic[x]).key == EMPTY) break;
                     39:     if (strcmp((dic[x]).key,str) == 0) break;
                     40:     x = (x+h1) % USER_DICTIONARY_SIZE;
                     41:     if (x == h0) {
                     42:       K00errorDic("User dictionary is full. loop hashing.\n");
                     43:     }
                     44:   }
                     45:   r = x;
                     46:   if (K00Strict2) {
                     47:     switch((dic[x]).attr) {
                     48:     case PROTECT:
                     49:       r = -PROTECT;   /* Protected, but we rewrite it. */
                     50:       break;
                     51:     case ABSOLUTE_PROTECT:
                     52:       r = -ABSOLUTE_PROTECT;  /* Protected and we do not rewrite it. */
                     53:       return(r);
                     54:     default:
                     55:       (dic[x]).attr = 0;
                     56:       break;
                     57:     }
                     58:   }
                     59:   (dic[x]).key = str;
                     60:   (dic[x]).obj = ob;
                     61:   (dic[x]).h0 = h0;
                     62:   (dic[x]).h1 = h1;
                     63:   return(r);
                     64: }
                     65:
                     66: objectp K00findUserDictionary(str,h0,h1,cp)
                     67: /* returns K00NullObject, if there is no item. */
                     68: char *str;    /* key */
                     69: int h0,h1;    /* The hashing values of the key. */
                     70: struct context *cp;
                     71: {
                     72:   int x;
                     73:   struct dictionary *dic;
                     74:   dic = cp->userDictionary;
                     75:   x = h0;
                     76:   while (1) {
                     77:     if ((dic[x]).key == EMPTY) { break; }
                     78:     if (strcmp((dic[x]).key,str) == 0) {
                     79:       return( (dic[x]).obj );
                     80:     }
                     81:     x = (x+h1) % USER_DICTIONARY_SIZE;
                     82:     if (x == h0) {
                     83:       K00errorDic("User dictionary is full. loop hashing in findUserDictionary.\n");
                     84:     }
                     85:   }
                     86:   if (cp->super == (struct context *)NULL) return(K00NullObject);
                     87:   else return(K00findUserDictionary(str,h0,h1,cp->super));
                     88:
                     89: }
                     90:
                     91: objectp K00findUserDictionary0(str,h0,h1,cp)
                     92: /* returns K00NullObject, if there is no item. */
                     93: /* This function does not look up the super class. */
                     94: char *str;    /* key */
                     95: int h0,h1;    /* The hashing values of the key. */
                     96: struct context *cp;
                     97: {
                     98:   int x;
                     99:   struct dictionary *dic;
                    100:   dic = cp->userDictionary;
                    101:   x = h0;
                    102:   while (1) {
                    103:     if ((dic[x]).key == EMPTY) { break; }
                    104:     if (strcmp((dic[x]).key,str) == 0) {
                    105:       return( (dic[x]).obj );
                    106:     }
                    107:     x = (x+h1) % USER_DICTIONARY_SIZE;
                    108:     if (x == h0) {
                    109:       K00errorDic("User dictionary is full. loop hashing in findUserDictionary.\n");
                    110:     }
                    111:   }
                    112:   return(K00NullObject);
                    113:
                    114: }
                    115:
                    116: int K00putUserDictionary2(str,h0,h1,attr,cp)
                    117: char *str;   /* key */
                    118: int h0,h1;   /* Hash values of the key */
                    119: int attr;    /* attribute field */
                    120: struct context *cp;
                    121: {
                    122:   int x;
                    123:   int i;
                    124:   struct dictionary *dic;
                    125:   dic = cp->userDictionary;
                    126:   if (SET_ATTR_FOR_ALL_WORDS & attr) {
                    127:     for (i=0; i<USER_DICTIONARY_SIZE; i++) {
                    128:       if ((dic[i]).key !=EMPTY) (dic[i]).attr = attr&(~SET_ATTR_FOR_ALL_WORDS);
                    129:     }
                    130:     return(0);
                    131:   }
                    132:   x = h0;
                    133:   if (str[0] == '\0') {
                    134:     K00errorDic("K00putUserDictionary2(): You are defining a value with the null key.\n");
                    135:   }
                    136:   while (1) {
                    137:     if ((dic[x]).key == EMPTY) return(-1);
                    138:     if (strcmp((dic[x]).key,str) == 0) break;
                    139:     x = (x+h1) % USER_DICTIONARY_SIZE;
                    140:     if (x == h0) {
                    141:       K00errorDic("User dictionary is full. loop hashing.\n");
                    142:     }
                    143:   }
                    144:   (dic[x]).attr = attr;
                    145:   return(x);
                    146: }
                    147:
                    148:
                    149:
                    150:
                    151: int K00hash0(str)
                    152: char *str;
                    153: {
                    154:   int h=0;
                    155:   while (*str != '\0') {
                    156:     h = ((h*128)+(*str)) % USER_DICTIONARY_SIZE;
                    157:     str++;
                    158:   }
                    159:   return(h);
                    160: }
                    161:
                    162: int K00hash1(str)
                    163: char *str;
                    164: {
                    165:   return(8-(str[0]%8));
                    166: }
                    167:
                    168: void K00hashInitialize(struct dictionary *dic)
                    169: {
                    170:   int i;
                    171:   for (i=0; i<USER_DICTIONARY_SIZE; i++) {
                    172:     (dic[i]).key = EMPTY; (dic[i]).attr = 0;
                    173:   }
                    174: }
                    175:
                    176: /* functions to handle contexts. */
                    177: void K00fprintContext(FILE *fp,struct context *cp) {
                    178:   if (cp == (struct context *)NULL) {
                    179:     fprintf(fp," Context=NIL \n");
                    180:     return;
                    181:   }
                    182:   fprintf(fp,"  ContextName = %s, ",cp->contextName);
                    183:   fprintf(fp,"Super = ");
                    184:   if (cp->super == (struct context *)NULL) fprintf(fp,"NIL");
                    185:   else {
                    186:     fprintf(fp,"%s",cp->super->contextName);
                    187:   }
                    188:   fprintf(fp,"\n");
                    189: }
                    190:
                    191: void K00fprintContextAndDictionary(FILE *fp,struct context *cp) {
                    192:   int i,j;
                    193:   int maxl;
                    194:   char format[1000];
                    195:   int nl;
                    196:   struct dictionary *dic;
                    197:
                    198:   if (cp == (struct context *)NULL) {
                    199:     fprintf(fp," Context=NIL \n");
                    200:     return;
                    201:   }
                    202:   fprintf(fp,"  ContextName = %s, ",cp->contextName);
                    203:   fprintf(fp,"Super = ");
                    204:   if (cp->super == (struct context *)NULL) fprintf(fp,"NIL");
                    205:   else {
                    206:     fprintf(fp,"%s",cp->super->contextName);
                    207:   }
                    208:   fprintf(fp,"\n");
                    209:
                    210:   dic = cp->userDictionary;
                    211:   maxl = 1;
                    212:   for (i=0; i<USER_DICTIONARY_SIZE; i++) {
                    213:     if ((dic[i]).key != EMPTY) {
                    214:       if (strlen((dic[i]).key) >maxl)
                    215:        maxl = strlen((dic[i]).key);
                    216:     }
                    217:   }
                    218:   maxl += 3;
                    219:   nl = 80/maxl;
                    220:   if (nl < 2) nl = 2;
                    221:   sprintf(format,"%%-%ds",maxl);
                    222:   for (i=0,j=0; i<USER_DICTIONARY_SIZE; i++) {
                    223:     if ((dic[i]).key != EMPTY) {
                    224:       fprintf(fp,format,(dic[i]).key);
                    225:       /*{ char *sss; int ii,h0,h1;
                    226:        sss = dic[i].key;
                    227:        h0 = dic[i].h0;
                    228:        h1 = dic[i].h1;
                    229:        for (ii=0; ii<strlen(sss); ii++) fprintf(fp,"%x ",sss[ii]);
                    230:        fprintf(fp,": h0=%d, h1=%d, %d\n",h0,h1,i);
                    231:       }*/
                    232:       if (j % nl == nl-1) fprintf(fp,"\n");
                    233:       j++;
                    234:     }
                    235:   }
                    236:   fprintf(fp,"\n");
                    237:   for (i=0; i<USER_DICTIONARY_SIZE; i++) {
                    238:     if ((dic[i]).key != EMPTY) {
                    239:       fprintf(fp,"%s ",(dic[i]).key);
                    240:       printObject_d(fp,(dic[i]).obj);
                    241:       fprintf(fp," \n");
                    242:     }
                    243:   }
                    244:   fprintf(fp,"\n");
                    245: }
                    246:
                    247: struct context *K00newContext0(struct context *super,char *name) {
                    248:   struct context *cp;
                    249:   cp = mymalloc(sizeof(struct context));
                    250:   if (cp == (struct context *)NULL) K00errorDic("No memory (newContext0)");
                    251:   cp->userDictionary=mymalloc(sizeof(struct dictionary)*USER_DICTIONARY_SIZE);
                    252:   if (cp->userDictionary==(struct dictionary *)NULL)
                    253:     K00errorDic("No memory (newContext0)");
                    254:   K00hashInitialize(cp->userDictionary);
                    255:   cp->contextName = name;
                    256:   cp->super = super;
                    257:   return(cp);
                    258: }
                    259:
                    260: void K00contextControl(actionOfContextControl ctl) {
                    261:   static struct context *cstack[CSTACK_SIZE];
                    262:   static int cstackp = 0;
                    263:   switch(ctl) {
                    264:   case CCRESTORE:
                    265:     if (cstackp == 0) return;
                    266:     else {
                    267:       K00CurrentContextp = cstack[0];
                    268:       cstackp = 0;
                    269:     }
                    270:     break;
                    271:   case CCPUSH:
                    272:     if (cstackp < CSTACK_SIZE) {
                    273:       cstack[cstackp] = K00CurrentContextp;
                    274:       cstackp++;
                    275:     }else{
                    276:       K00contextControl(CCRESTORE);
                    277:       K00errorDic("Context stack (cstack) is overflow. CurrentContext is restored.\n");
                    278:     }
                    279:     break;
                    280:   case CCPOP:
                    281:     if (cstackp > 0) {
                    282:       cstackp--;
                    283:       K00CurrentContextp = cstack[cstackp];
                    284:     }
                    285:     break;
                    286:   default:
                    287:     break;
                    288:   }
                    289:   return;
                    290: }
                    291:
                    292: void K00InitDic() {
                    293:   extern struct context *K00CurrentContextp;
                    294:   extern struct context *K00PrimitiveContextp;
                    295:   char *start = "K00start";
                    296:   char *size = "K00sizeof";
                    297:   char *primitiveObject = "PrimitiveObject";
                    298:   K00CurrentContextp = K00newContext0((struct context *)NULL,primitiveObject);
                    299:   K00PrimitiveContextp = K00CurrentContextp;
                    300:   K00putUserDictionary(start,K00hash0(start),K00hash1(start),
                    301:                       K00integerToObject(1),
                    302:                       K00CurrentContextp);
                    303:   K00putUserDictionary2(start,K00hash0(start),K00hash1(start),
                    304:                       ABSOLUTE_PROTECT,
                    305:                       K00CurrentContextp);
                    306:   K00putUserDictionary(size,K00hash0(size),K00hash1(size),
                    307:                       K00integerToObject(0),
                    308:                       K00CurrentContextp);
                    309:   K00putUserDictionary2(size,K00hash0(size),K00hash1(size),
                    310:                       ABSOLUTE_PROTECT,
                    311:                       K00CurrentContextp);
                    312:   K00putUserDictionary(primitiveObject,K00hash0(primitiveObject),
                    313:                       K00hash1("primitiveObject"),
                    314:                       K00contextToObject(K00CurrentContextp),
                    315:                       K00CurrentContextp);
                    316:   K00putUserDictionary2(primitiveObject,K00hash0(primitiveObject),
                    317:                       K00hash1("primitiveObject"),
                    318:                       ABSOLUTE_PROTECT,
                    319:                       K00CurrentContextp);
                    320:
                    321: }
                    322:
                    323:
                    324: void K00errorDic(char *s) {
                    325:   fprintf(stderr,"Error in dic.c: %s",s);
                    326:   exit(10);
                    327: }
                    328:
                    329: int K00objectToInteger(objectp op) {
                    330:   return(op->lc.ival);
                    331: }
                    332:
                    333: objectp K00integerToObject(int k) {
                    334:   objectp op;
                    335:   op = newObject_d();
                    336:   op->tag = Sinteger;
                    337:   op->lc.ival = k;
                    338:   return(op);
                    339: }
                    340:
                    341: objectp K00contextToObject(struct context *cp) {
                    342:   objectp op;
                    343:   op = newObject_d();
                    344:   op->tag = op->lc.ival = CLASSNAME_CONTEXT;
                    345:   op->rc.voidp = cp;
                    346:   return(op);
                    347: }
                    348:
                    349: struct context *K00objectToContext(objectp op) {
                    350:   return((struct context *)(op->rc.voidp));
                    351: }
                    352:
                    353: int K00putIncetanceVariable(actionOfPutIncetanceVariable action,char *s) {
                    354: /*  typedef enum {IRESET,IPUT,IEXIT} actionOfPutIncetanceVariable; */
                    355:   extern struct context *K00CurrentContextp;
                    356:   static int K00start;
                    357:   static int serial;
                    358:   static int initialized = 0;
                    359:   objectp op1;
                    360:   objectp op2;
                    361:   if (K00CurrentContextp == K00PrimitiveContextp) {
                    362:     myerror("You cannot define incetanceVariables in PrimitiveContext.\n");
                    363:     return(-1);
                    364:   }
                    365:   if (action == IRESET) {
                    366:     serial = 0;
                    367:     op1 = K00findUserDictionary0("K00start",K00hash0("K00start"),
                    368:                                 K00hash1("K00start"),
                    369:                                 K00CurrentContextp->super);
                    370:     if (op1 == K00NullObject) {
                    371:       myerror("K00start is not found.\n");
                    372:       return(-1);
                    373:     }
                    374:     op2 = K00findUserDictionary0("K00sizeof",K00hash0("K00sizeof"),
                    375:                              K00hash1("K00sizeof"),
                    376:                             K00CurrentContextp->super);
                    377:     if (op2 == K00NullObject) {
                    378:       myerror("K00sizeof is not found.\n");
                    379:       return(-1);
                    380:     }
                    381:     K00start = K00objectToInteger(op1)+K00objectToInteger(op2);
                    382:     initialized = 1;
                    383:     return(0);
                    384:   }else if (action == IEXIT) {
                    385:     if (initialized) {
                    386:       K00putUserDictionary("K00start",K00hash0("K00start"), K00hash1("K00start"),
                    387:                           K00integerToObject(K00start),
                    388:                           K00CurrentContextp);
                    389:       K00putUserDictionary("K00sizeof",K00hash0("K00sizeof"), K00hash1("K00sizeof"),
                    390:                           K00integerToObject(serial),
                    391:                           K00CurrentContextp);
                    392:     }
                    393:     initialized = 0;
                    394:     return(0);
                    395:
                    396:   }else if (action == IPUT) {
                    397:     if (initialized) {
                    398:       K00putUserDictionary(s,K00hash0(s),K00hash1(s),
                    399:                           K00integerToObject(K00start+serial),
                    400:                           K00CurrentContextp);
                    401:       serial++;
                    402:     }else{
                    403:       myerror("K00putIncetanceVariable() is not initialized.\n");
                    404:     }
                    405:     return(0);
                    406:   }
                    407:   return(-1);
                    408: }
                    409:
                    410: int K00getIncetanceVariable(char *s) {
                    411:   objectp op;
                    412:   extern struct context *K00CurrentContextp;
                    413:   extern int K00Initialized;
                    414:   if (!K00Initialized) {K00InitDic(); K00Initialized = 1;}
                    415:   op = K00findUserDictionary0(s,K00hash0(s),K00hash1(s),K00CurrentContextp);
                    416:   if (op == K00NullObject) {
                    417:     return(-1);
                    418:   }else if (op->tag != Sinteger) {
                    419:     return(-1);
                    420:   }else{
                    421:     return( K00objectToInteger(op) );
                    422:   }
                    423: }
                    424:
                    425: void K00recoverFromError() {
                    426:   K00toPrimitiveClass();
                    427: }
                    428:
                    429: int K00declareClass(char *name,char *supername) {
                    430:   extern struct context *K00CurrentContextp;
                    431:   extern struct context *K00PrimitiveContextp;
                    432:   struct context *sup;
                    433:   objectp op1;
                    434:   extern int K00Initialized;
                    435:   if (!K00Initialized) { K00InitDic(); K00Initialized = 1;}
                    436:   op1 = K00findUserDictionary0(supername,K00hash0(supername),K00hash1(supername),
                    437:                               K00PrimitiveContextp);
                    438:   if (op1 == K00NullObject) {
                    439:     myerror("Super class is not in the top dictionary.\n");
                    440:     /* debug */ K00fooPrimitive();
                    441:     return(-1);
                    442:   }
                    443:   if (op1->tag != CLASSNAME_CONTEXT) {
                    444:     myerror("It is not class.context.\n");
                    445:     /* debug */ K00fooPrimitive();
                    446:     return(-1);
                    447:   }
                    448:   K00CurrentContextp = K00newContext0(K00objectToContext(op1),name);
                    449:   K00putUserDictionary(name,K00hash0(name),K00hash1(name),
                    450:                       K00contextToObject(K00CurrentContextp),
                    451:                       K00PrimitiveContextp);
                    452:   K00putIncetanceVariable(IRESET," ");
                    453:   return(0);
                    454: }
                    455:
                    456: void K00toPrimitiveClass() {
                    457:   extern struct context *K00CurrentContextp;
                    458:   extern struct context *K00PrimitiveContextp;
                    459:   K00CurrentContextp = K00PrimitiveContextp;
                    460: }
                    461:
                    462: char *K00getCurrentContextName() {
                    463:   extern struct context *K00CurrentContextp;
                    464:   if (!K00Initialized) {
                    465:     K00InitDic(); K00Initialized = 1;
                    466:   }
                    467:   return(K00CurrentContextp->contextName);
                    468: }
                    469:
                    470: void pkkanInteger(int k) {
                    471:   char tmp[256]; /* pkkan creates a new memory area. */
                    472:   sprintf(tmp," %d ",k);
                    473:   pkkan(tmp);
                    474: }
                    475:
                    476:
1.3     ! takayama  477: void K00foo1() {
1.1       maekawa   478:   extern struct context *K00CurrentContextp;
                    479:   extern int K00debug0;
                    480:   if (K00debug0) K00fprintContextAndDictionary(stderr,K00CurrentContextp);
                    481: }
                    482:
1.3     ! takayama  483: void K00fooPrimitive() {
1.1       maekawa   484:   extern struct context *K00PrimitiveContextp;
                    485:   extern int K00debug0;
                    486:   if (K00debug0) {
                    487:     printf("--------- PrimitiveContext ------------\n");
                    488:     K00fprintContextAndDictionary(stderr,K00PrimitiveContextp);
                    489:   }
                    490: }
                    491:

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>