/* bobmem.c - memory manager */ /* Copyright (c) 1991, by David Michael Betz All rights reserved */ #include #include "bob.h" /* external variables */ extern jmp_buf error_trap; /* the error trap target */ /* global variables */ DICTIONARY *symbols; /* the symbol table */ DICTIONARY *classes; /* the class table */ /* initialize - initialize the virtual machine */ initialize(smax,cmax) int smax,cmax; { int obj_class(),cls_new(); VALUE *allocvector(); /* setup an error trap handler */ if (setjmp(error_trap) != 0) return; /* initialize the compiler */ init_compiler(cmax); /* allocate the stack */ stkbase = (VALUE *)getmemory(smax * sizeof(VALUE)); stktop = sp = stkbase + smax; /* create the symbol and class tables */ symbols = newdictionary(NULL); classes = newdictionary(NULL); /* enter the built-in functions */ init_functions(); } /* newclass - create a new class */ CLASS *newclass(name,base) char *name; CLASS *base; { CLASS *theclass; /* allocate the memory for the new class */ theclass = (CLASS *)getmemory(sizeof(CLASS)); /* initialize */ theclass->cl_name = copystring(name); theclass->cl_base = base; theclass->cl_members = newdictionary(theclass); theclass->cl_functions = newdictionary(theclass); theclass->cl_size = 0; /* return the new class */ return (theclass); } /* newdictionary - create a new dictionary */ DICTIONARY *newdictionary(class) CLASS *class; { DICTIONARY *dict; dict = (DICTIONARY *)getmemory(sizeof(DICTIONARY)); dict->di_class = class; dict->di_contents = NULL; return (dict); } /* addentry - add an entry to a dictionary */ DICT_ENTRY *addentry(dict,key,type) DICTIONARY *dict; char *key; int type; { DICT_ENTRY *entry; if ((entry = findentry(dict,key)) == NULL) { entry = (DICT_ENTRY *)getmemory(sizeof(DICT_ENTRY)); entry->de_dictionary = dict; entry->de_key = copystring(key); entry->de_type = type; set_nil(&entry->de_value); entry->de_next = dict->di_contents; dict->di_contents = entry; } return (entry); } /* findentry - find an entry in a dictionary */ DICT_ENTRY *findentry(dict,key) DICTIONARY *dict; char *key; { DICT_ENTRY *entry; for (entry = dict->di_contents; entry != NULL; entry = entry->de_next) if (strcmp(key,entry->de_key) == 0) return (entry); return (NULL); } /* copystring - make a copy of a string */ char *copystring(str) char *str; { char *val; val = getmemory(strlen(str)+1); strcpy(val,str); return (val); } /* makestring - make an initialized string */ STRING *makestring(str) char *str; { STRING *val; int len; len = strlen(str); val = newstring(len); strncpy(val->s_data,str,len); return (val); } /* getcstring - get a C-style version of a string */ getcstring(buf,max,str) char *buf; int max; STRING *str; { int len; if ((len = str->s_length) >= max) len = max - 1; strncpy(buf,str->s_data,len); buf[len] = '\0'; } /* newstring - allocate a new string object */ STRING *newstring(n) int n; { STRING *val; char *p; val = (STRING *)getmemory(sizeof(STRING)+n-1); val->s_length = n; for (p = val->s_data; --n >= 0; ) *p++ = '\0'; return (val); } /* newobject - allocate a new object */ VALUE *newobject(class) CLASS *class; { VALUE *allocvector(),*val; val = allocvector(class->cl_size); set_class(&val[OB_CLASS],class); return (val); } /* newvector - allocate a new vector */ VALUE *newvector(n) int n; { VALUE *allocvector(),*val; val = allocvector(n+1); set_integer(&val[0],n); return (val); } /* allocvector - allocate a new vector */ static VALUE *allocvector(n) int n; { VALUE *val,*p; val = (VALUE *)getmemory(n * sizeof(VALUE)); for (p = val; --n >= 0; ++p) set_nil(p); return (val); } /* getmemory - allocate memory and complain if there isn't enough */ char *getmemory(size) int size; { char *malloc(),*val; if ((val = malloc(size)) == NULL) error("Insufficient memory"); return (val); }