#include "Object.h" #include "value.h" #include "List.h" #include "parser.h" #include <iostream.h> #include <fstream.h> #pragma implementation /*********************************************************************** ** on disk, an object will look like this: ** <parent1><parent2>...<parentn> -1 ... each is an integer (sizeof(long)) ** <symboltable>\0<commandlist>\0 ************************************************************************/ char* Object::pack_object (char* buffer){ buffer = parents->dump(buffer); buffer = symbols.pack_syms (buffer); return commands.pack_cmds (buffer); } long nos=0; Object::Object (char* buffer, int object_num){ char* temp_buf; int pval; String* tempstring; Value* tempval; id = object_num; temp_buf = buffer; parents = new intlist (&temp_buf); while (*temp_buf) {tempstring = new String (temp_buf); temp_buf += tempstring->length() + 1; tempval = unpack_value (&temp_buf); symbols.add (tempval , tempstring); tempval->release();} temp_buf++; temp_buf = commands.unpack(temp_buf); } Object::Object (int oid, int iparent){ parents = new intlist (iparent); id = oid; } #define MAX_LINE_LEN 40000 Object::Object (ifstream* input, int onum){ int i, ilist [30], temptype; char templine [MAX_LINE_LEN]; Value* tempval; String *sym, *key; id = onum; for (i=0 ; input->peek() != '\n' ; i++) /** get parents **/ *input >> ilist [i]; ilist [i] = -1; parents = new intlist (ilist); input->get(); while (input->peek() != '/') /** get variables **/ {key = new String; *input >> *key; sym = new String; while (input->peek() != '/') {input->getline (templine, MAX_LINE_LEN); *sym += templine; *sym += "\n";} input->getline (templine, MAX_LINE_LEN); tempval = parse_string (sym); if (!tempval) {cout << parse_fail_msg << "\n"; cout << "In symbol: " << *key << "\n"; exit (1);} temptype = (int) tempval->type; *sym += " "; /** horrible kludge **/ delete sym; if ((int) tempval->type != temptype) {cout << "tempval was changed.\n"; exit (1);} symbols.add (tempval, key); tempval->release();} input->getline (templine, MAX_LINE_LEN); while (input->peek() != '/') /** get commands **/ {input->getline (templine, MAX_LINE_LEN); tempval = parse_string (key = new String (templine)); if (! (tempval->get_type() == LIST)) {cerr << "invalid command: " << *key << "\nnot a list.\n"; exit (1);} input->getline (templine, MAX_LINE_LEN); sym = new String (templine); if (! commands.add (tempval->list->copy(), sym)) {cerr << "invalid command: " << *key << "\nnot a valid command list format.\n"; exit (1);} tempval->release(); delete key;} input->getline (templine, MAX_LINE_LEN); } Object::~Object(){ delete parents; } void Object::dump_to_stdout (){ parents->dump_to_stdout(); symbols.dump_to_stdout(); cout << "/\n"; commands.dump_to_stdout(); cout << "/+++++++++++++ end of object #" << id << " +++++++++++++\n"; }; Value* Object::get_parent_list(){ return parents->toval(); } Value* Object::tostr(){ Value* retval, *temp; retval = new Value (id, OBJ); retval->tostr(); temp = get_parent_list(); temp->tostr(); retval->add(temp); temp->release(); temp = symbols.list_vars(); temp->tostr(); retval->add(temp); temp->release(); temp = commands.list_cmds(); temp->tostr(); retval->add(temp); temp->release(); return retval; } int Object::set_sym (Value* v, String* s){ return symbols.add (v, s); } int Object::rm_sym (String* s){ return symbols.remove (s); } int Object::add_cmd (Val_List* key, String* data){ return (commands.add (key, data)) ? 1 : 0; } int Object::rm_cmd (String* key){ return commands.remove (key); } void Object::purge_cmds (){ commands.purge (); } int Object::change_parents (int* ilist){ delete parents; parents = new intlist (ilist); return 1; } /*************************************************** ** methods for the intlist class ******************* ****************************************************/ intlist::intlist(int iparent, int max){ list = new int [max]; allocated = max; size = 0; if (iparent >= 0) list [size++] = iparent; } intlist::intlist(char** inbuff_ptr, int max){ char* buf; int i; buf = *inbuff_ptr; size = (int) *buf++; allocated = (max > size ? max : size); list = new int [allocated]; memcpy (list , buf , (size * (sizeof (long)))); *inbuff_ptr = buf + (size * (sizeof (long))); } intlist::intlist(int* inlist, int max){ list = new int [max]; for (size=0 ; inlist[size] >= 0 ; size++) {list[size] = inlist[size]; if (size >= max) {grow(max); max += 2;}} allocated = max; } intlist::intlist(){ list = new int [allocated = MAXPARENTS]; size = 0; } intlist::~intlist(){ delete list; } intlist::check_is_inlist (int i){ int j; for (j=0 ; j<size ; j++) if (list[j] == i) return 1; return 0; } void intlist::grow(int by){ int i, *templist; templist = new int [allocated + by]; for (i=0 ; i<allocated ; i++) templist[i] = list[i]; allocated += by; delete list; list = templist; } void intlist::set_contents (intlist source){ int i; if (source.size >= allocated) grow (source.size - allocated + 1); for (i = 0 ; i<source.size ; i++) list[i] = source.list[i]; size = source.size; } void intlist::pop(){ if (size > 0) size--; } void intlist::dump_to_stdout(){ int j; for (j=0 ; j<size ; j++) {cout << list[j]; if (j+1 != size) cout << " ";} cout << "\n"; } int intlist::peek(){ return ((size > 0) ? list[size-1] : -1); } void intlist::push(int inval){ list[size++] = inval; if (size >= allocated) grow (); } char* intlist::dump (char* buf){ *buf++ = (char) size; memcpy (buf , list , (size * (sizeof (long)))); return buf + (size * (sizeof (long))); } Value* intlist::toval (){ int j; Val_List* i; for (j=0 , i=NULL ; j<size ; j++) i = new Val_List (new Value (list[j], OBJ), i); return new Value (i); }