home *** CD-ROM | disk | FTP | other *** search
- /*
- Little Smalltalk, version 3
- Written by Tim Budd, Oregon State University, June 1988
-
- routines used in reading in textual descriptions of classes
- */
-
- # include <stdio.h>
- # include "env.h"
- # include "memory.h"
- # include "names.h"
- # include "lex.h"
- # ifdef STRING
- # include <string.h>
- # endif
- # ifdef STRINGS
- # include <strings.h>
- # endif
-
- # define MethodTableSize 39
-
- /*
- the following are switch settings, with default values
- */
- boolean savetext = true;
-
- /*
- we read the input a line at a time, putting lines into the following
- buffer. In addition, all methods must also fit into this buffer.
- */
- # define TextBufferSize 1024
- static char textBuffer[TextBufferSize];
-
- /*
- findClass gets a class object,
- either by finding it already or making it
- in addition, it makes sure it has a size, by setting
- the size to zero if it is nil.
- */
- static object findClass(name)
- char *name;
- { object newobj;
-
- newobj = globalSymbol(name);
- if (newobj == nilobj)
- newobj = newClass(name);
- if (basicAt(newobj, sizeInClass) == nilobj) {
- basicAtPut(newobj, sizeInClass, newInteger(0));
- }
- return newobj;
- }
-
- /*
- readDeclaration reads a declaration of a class
- */
- static readClassDeclaration()
- { object classObj, super, vars;
- int i, size, instanceTop;
- object instanceVariables[15];
-
- if (nextToken() != nameconst)
- sysError("bad file format","no name in declaration");
- classObj = findClass(tokenString);
- size = 0;
- if (nextToken() == nameconst) { /* read superclass name */
- super = findClass(tokenString);
- basicAtPut(classObj, superClassInClass, super);
- size = intValue(basicAt(super, sizeInClass));
- ignore nextToken();
- }
- if (token == nameconst) { /* read instance var names */
- instanceTop = 0;
- while (token == nameconst) {
- instanceVariables[instanceTop++] = newSymbol(tokenString);
- size++;
- ignore nextToken();
- }
- vars = newArray(instanceTop);
- for (i = 0; i < instanceTop; i++) {
- basicAtPut(vars, i+1, instanceVariables[i]);
- }
- basicAtPut(classObj, variablesInClass, vars);
- }
- basicAtPut(classObj, sizeInClass, newInteger(size));
- }
-
- /*
- readClass reads a class method description
- */
- static readMethods(fd, printit)
- FILE *fd;
- boolean printit;
- { object classObj, methTable, theMethod, selector;
- # define LINEBUFFERSIZE 512
- char *cp, *eoftest, lineBuffer[LINEBUFFERSIZE];
-
- if (nextToken() != nameconst)
- sysError("missing name","following Method keyword");
- classObj = findClass(tokenString);
- setInstanceVariables(classObj);
- if (printit)
- cp = charPtr(basicAt(classObj, nameInClass));
-
- /* now find or create a method table */
- methTable = basicAt(classObj, methodsInClass);
- if (methTable == nilobj) { /* must make */
- methTable = newDictionary(MethodTableSize);
- basicAtPut(classObj, methodsInClass, methTable);
- }
-
- /* now go read the methods */
- do {
- if (lineBuffer[0] == '|') /* get any left over text */
- strcpy(textBuffer,&lineBuffer[1]);
- else
- textBuffer[0] = '\0';
- while((eoftest = fgets(lineBuffer, LINEBUFFERSIZE, fd)) != NULL) {
- if ((lineBuffer[0] == '|') || (lineBuffer[0] == ']'))
- break;
- ignore strcat(textBuffer, lineBuffer);
- }
- if (eoftest == NULL) {
- sysError("unexpected end of file","while reading method");
- break;
- }
-
- /* now we have a method */
- theMethod = newMethod();
- if (parse(theMethod, textBuffer, savetext)) {
- selector = basicAt(theMethod, messageInMethod);
- basicAtPut(theMethod, methodClassInMethod, classObj);
- if (printit)
- dspMethod(cp, charPtr(selector));
- nameTableInsert(methTable, (int) selector,
- selector, theMethod);
- }
- else {
- /* get rid of unwanted method */
- incr(theMethod);
- decr(theMethod);
- givepause();
- }
-
- } while (lineBuffer[0] != ']');
- }
-
- /*
- fileIn reads in a module definition
- */
- fileIn(fd, printit)
- FILE *fd;
- boolean printit;
- {
- while(fgets(textBuffer, TextBufferSize, fd) != NULL) {
- lexinit(textBuffer);
- if (token == inputend)
- ; /* do nothing, get next line */
- else if ((token == binary) && streq(tokenString, "*"))
- ; /* do nothing, its a comment */
- else if ((token == nameconst) && streq(tokenString, "Class"))
- readClassDeclaration();
- else if ((token == nameconst) && streq(tokenString,"Methods"))
- readMethods(fd, printit);
- else
- sysError("unrecognized line", textBuffer);
- }
- }
-