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