// Cons cell definition. // // File: cons.h // Author: course // Version: 3 #ifndef CONS_H #define CONS_H #include "object.h" class cons : public object { public: // Create a cons with a given car and cdr. // friend cons * make_cons (object * car, object * cdr); // Get and set the components of a cons. // friend object * car (cons * c); friend object * cdr (cons * c); friend object * set_car (cons * c, object * val); friend object * set_cdr (cons * c, object * val); // Return a pointer to the cdr so it can be set. // friend object ** cdr_pointer (cons * c); // Some common functions that may be used when you // know you have a list and need not do type // checking. // friend object * unchecked_car (object * ob); friend object * unchecked_cdr (object * ob); friend object * unchecked_cadr (object * ob); friend object * unchecked_cddr (object * ob); friend object * unchecked_caddr (object * ob); friend object * unchecked_cdddr (object * ob); friend object * unchecked_cadddr (object * ob); friend object * unchecked_cddddr (object * ob); friend object * unchecked_caddddr (object * ob); friend object * unchecked_cdddddr (object * ob); private: object * car; object * cdr; // Virtuals to be implemented by subclasses. virtual ostream& print (ostream& s); // Print object. virtual void scavenge(); // Scavenge object during garbage collection. }; // Other cons functions: // Return true iff object is a cons cell. // bool consp (object * ob); // Convert a pointer to an object to a pointer to a cons // cell (which is the same as the object) if the object // is a cons cell, or return NULL if the object is not // a cons cell. // cons * may_be_cons (object * ob); // Convert a pointer to an object to a pointer to a cons // cell (which is the same as the object) if the object // is a cons cell, or call error if the object is not // a cons cell. // cons * must_be_cons (object * ob); // Convert a pointer to an object to a pointer to a cons // cell (which is the same as the object) if the object // is a cons cell. Produces undefined results if object // is not a cons cell, but is the most efficient // conversion because it does no checking. // cons * unchecked_must_be_cons (object * ob); // Get length of list: calls error if argument not list // or if argument is dotted list. // int length (object * list); // Make lists. Caller must preserve elements. // List_star corresponds to the LISP LIST* function. // object * list (object * ob1); object * list (object * ob1, object * ob2); object * list (object * ob1, object * ob2, object * ob3); object * list_star (object * ob1, object * ob2); object * list_star (object * ob1, object * ob2, object * ob3); // Some symbols associated with reading and printing // lists. // extern object * NIL; extern object * QUOTE; extern object * FUNCTION; // Object type for cons. // extern object_type * CONS_TYPE; // Inline implementations of above. See above for // documentation. // inline object * car (cons * c) { return c->car; } inline object * cdr (cons * c) { return c->cdr; } inline object * set_car (cons * c, object * val) { return c->car = val; } inline object * set_cdr (cons * c, object * val) { return c->cdr = val; } inline object ** cdr_pointer (cons * c) { return & c->cdr; } inline object * unchecked_car (object * ob) { return car ((cons *) ob); } inline object * unchecked_cdr (object * ob) { return cdr ((cons *) ob); } inline object * unchecked_cadr (object * ob) { return car ((cons *) unchecked_cdr (ob)); } inline object * unchecked_cddr (object * ob) { return cdr ((cons *) unchecked_cdr (ob)); } inline object * unchecked_caddr (object * ob) { return car ((cons *) unchecked_cddr (ob)); } inline object * unchecked_cdddr (object * ob) { return cdr ((cons *) unchecked_cddr (ob)); } inline object * unchecked_cadddr (object * ob) { return car ((cons *) unchecked_cdddr (ob)); } inline object * unchecked_cddddr (object * ob) { return cdr ((cons *) unchecked_cdddr (ob)); } inline object * unchecked_caddddr (object * ob) { return car ((cons *) unchecked_cddddr (ob)); } inline object * unchecked_cdddddr (object * ob) { return cdr ((cons *) unchecked_cddddr (ob)); } inline bool consp (object * ob) { return type_of (ob) == CONS_TYPE; } inline cons * may_be_cons (object * ob) { return consp(ob) ? (cons *) ob : (cons *) NULL; } inline cons * must_be_cons (object * ob) { if ( ob == NULL || ! consp (ob) ) type_error(ob, CONS_TYPE); return (cons *)ob; } inline cons * unchecked_must_be_cons (object * ob) { return (cons *) ob; } inline object * list (object * ob1) { return make_cons (ob1, NIL); } inline object * list (object * ob1, object * ob2) { return make_cons (ob1, make_cons (ob2, NIL)); } inline object * list (object * ob1, object * ob2, object * ob3) { return make_cons (ob1, make_cons (ob2, make_cons (ob3, NIL))); } inline object * list_star (object * ob1, object * ob2) { return make_cons (ob1, ob2); } inline object * list_star (object * ob1, object * ob2, object * ob3) { return make_cons (ob1, make_cons (ob2, ob3)); } #endif // CONS_H