/** * node.c * Nodes for an implementation of lists. */ // +---------+-------------------------------------------------------- // | Headers | // +---------+ #include #include #include "node.h" #include "set.h" #ifdef UNIT_TESTS #include "utest.h" #endif #ifdef EXPERIMENTS #include "expt.h" #endif // +---------+-------------------------------------------------------- // | Globals | // +---------+ #ifdef UNIT_TESTS static int errors; #endif // +-----------------+------------------------------------------------ // | Basic Functions | // +-----------------+ int is_null (struct node *lst) { return lst == NULL; } // is_null struct node * cons (char *str, struct node *lst) { struct node *newlst = malloc (sizeof (struct node)); if (newlst == NULL) return NULL; newlst->data = str; newlst->next = lst; return newlst; } // cons char * car (struct node *lst) { if (is_null (lst)) { fprintf (stderr, "Cannot take car of empty list.\n"); return NULL; } return lst->data; } // car struct node * cdr (struct node *lst) { if (is_null (lst)) { fprintf (stderr, "Cannot take car of empty list.\n"); return NULL; } return lst->next; } // cdr struct node * set_car (struct node *lst, char *str) { if (is_null (lst)) { fprintf (stderr, "Cannot set the car of empty list.\n"); return NULL; } lst->data = str; return lst; } // set_car struct node * set_cdr (struct node *lst, struct node *rest) { if (is_null (lst)) { fprintf (stderr, "Cannot set the cdr of empty list.\n"); return NULL; } lst->next = rest; return lst; } // set_cdr // +--------------------+--------------------------------------------- // | Advanced Functions | // +--------------------+ char * np_last (struct node *lst) { if (is_null (lst)) { fprintf (stderr, "Cannot take last element of empty list.\n"); return NULL; } while (lst->next != NULL) lst = lst->next; return lst->data; } // np_last int np_length (struct node *lst) { int length; for (length = 0; lst != NULL; length++, lst = lst->next) ; return length; } // np_length void np_print (struct node *lst, FILE *fp) { if (lst == NULL) { fprintf (fp, "()"); return; } fprintf (fp, "(%s", lst->data); while ((lst = lst->next) != NULL) fprintf (fp, " %s", lst->data); fprintf (fp, ")"); } // np_print struct node * np_append (struct node *lst, char *str) { struct node *np = lst; if (lst == NULL) return cons (str, NULL); while (np->next != NULL) np = np->next; np->next = cons (str, NULL); return lst; } // np_append struct node * np_delete (struct node *lst, char *str) { // Not yet implemented return lst; } // np_delete // +--------------------+--------------------------------------------- // | More Functions | // +--------------------+ struct node *find_loop(struct node *start) { while (start != NULL) { if (contains (start)) return start; add (start); start = start->next; } return NULL; } // loop // +------------+----------------------------------------------------- // | Unit Tests | // +------------+ #ifdef UNIT_TESTS int main () { struct node *np = NULL; CHECK_INT (is_null (np), 1); fprintf (stderr, "%d errors encountered.\n", errors); return errors; } // main #endif // UNIT_TESTS // +-------------+---------------------------------------------------- // | Experiments | // +-------------+ #ifdef EXPERIMENTS #define PRINT_LIST(LIST) \ BLOCK( \ fprintf (stderr, VAR_PREFIX "%s = ", #LIST); \ np_print (LIST, stderr); \ fprintf (stderr, "\n"); ) int main () { struct node *lst1, *lst2; char stuff[] = "Hello"; struct node *greet; EXPERIMENT (lst1 = NULL); PRINT_LIST (lst1); EXPERIMENT (lst2 = cons ("a", lst1)); PRINT_LIST (lst1); PRINT_LIST (lst2); EXPERIMENT (lst1 = cons ("b", lst2)); PRINT_LIST (lst1); PRINT_LIST (lst2); EXPERIMENT (lst1 = np_append (lst1, "seek")); PRINT_LIST (lst1); PRINT_LIST (lst2); EXPERIMENT (greet = cons (stuff, NULL)); EXPERIMENT (greet = cons (stuff, greet)); PRINT_LIST (greet); EXPERIMENT (stuff[0] = '\''); PRINT_LIST (greet); EXPERIMENT (set_car(greet, "Why,")); PRINT_LIST (greet); EXPERIMENT (set_cdr(greet, lst2)); PRINT_LIST (greet); PRINT_STR (car(greet)); PRINT_STR (car (cdr (greet))); struct node *result; EXPERIMENT (printf ("%p\n", find_loop (greet))); EXPERIMENT (set_cdr(greet, greet)); PRINT_STR (car(greet)); PRINT_STR (car (cdr (greet))); EXPERIMENT (printf ("%p\n", find_loop (greet))); return 0; } // main #endif // EXPERIMENTS