/* * Lisp memory handling * Don Hopkins */ #include "lisp.h" /* * Increase the size of the cons space, and link the new nodes into * the free list. */ grow_cons_space(conses) int conses; { Cons_Count += conses; /* * Allocate or reallocate more memory. */ if (Cons == NULL) Cons = (struct cons *)malloc(Cons_Count * sizeof(struct cons)); else Cons = (struct cons *)realloc(Cons, Cons_Count * sizeof(struct cons)); if (Cons == NULL) error("grow_cons_space"); Cons_Free += conses; while (conses) { /* Link new conses onto free list */ Cons_Cdr(Cons_Count - conses) = Free_List; Free_List = Cons_Count - conses--; } } /* * Make a cons, initializing car and cdr. If out of conses, garbage * collect (if this isn't the first time), and make more space. Take a * new cons off of the free list and initialize its car and cdr. * Return it. */ object make_cons(car, cdr) object car, cdr; { int growth; object new; if (Free_List == Nil) { if (Cons_Count == 0) growth = CONS_COUNT; else { fprintf(Output_File, "<* Freed %d *>", gc(car, cdr)); growth = CONS_INCREMENT; } grow_cons_space(growth); fprintf(Output_File, "\n<* Grew cons space by %d to %d. (%d free.) *>\n", growth, Cons_Count, Cons_Free); } Cons_Free--; new = Free_List; Free_List = Cons_Cdr(Free_List); Cons_Car(new) = car; Cons_Cdr(new) = cdr; return(Set_Type(cons_object, new)); } /* * Increase the size of the atom space. */ grow_atom_space(atoms) int atoms; { Atom_Count += atoms; if (Atom == NULL) /* Allocate or reallocate more memory */ Atom = (struct atom *)malloc(Atom_Count * sizeof(struct atom)); else Atom = (struct atom *)realloc(Atom, Atom_Count * sizeof(struct atom)); if (Atom == NULL) error("grow_atom_space"); } /* * Get a new atom from the atom space. If there are none left, then * grow the atom space. */ object get_atom(name) { if (Atom_Free == Atom_Count) grow_atom_space(Atom_Count ? ATOM_COUNT : ATOM_INCREMENT); Atom_Name(Atom_Free) = (char *)malloc(strlen(name) + 1); strcpy(Atom_Name(Atom_Free), name); return(Set_Type(atom_object, Atom_Free++)); } /* * Look to see if there is an atom named name in the atom table. * Return either that object, or undefined_object if it is not there. */ object find_atom(name) char *name; { object atom; for (atom = 0; atom < Atom_Free; atom++) if (strcmp(name, Atom_Name(atom)) == 0) return(Set_Type(atom_object, atom)); return(undefined_object); } /* * Make an atom. If the name matches an old atom, then return the old * atom object. Otherwise get a new atom from the atom table, * and initialize its value to undefined. */ object make_atom(name) char *name; { object atom = find_atom(name); if (atom != undefined_object) return(atom); atom = get_atom(name); Atom_Value(atom) = undefined_object; return(atom); } /* * Increase the size of the number space. */ grow_number_space(numbers) int numbers; { Number_Count += numbers; if (Number == NULL) /* Allocate or reallocate more memory */ Number = (struct number *)malloc(Number_Count * sizeof(struct number)); else Number = (struct number *)realloc(Number, Number_Count * sizeof(struct number)); if (Number == NULL) error("grow_number_space"); } /* * Get a new number from the number space. If there are none left, then * grow the number space. */ object get_number() { if(Number_Free == NULL) grow_number_space(Number_Count ? NUMBER_COUNT : NUMBER_INCREMENT); return(Set_Type(number_object, Number_Free++)); } /* * Make a number object with the specified value. */ object make_number(value) double value; { object number = get_number(); Number_Value(number) = value; return(number); }