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>