/* * Lisp header file */ #include #include /* * Constants specifying the initial and growth sizes of the cons, * atom, and number spaces. */ #define CONS_COUNT 2048 #define CONS_INCREMENT 2048 #define ATOM_COUNT 256 #define ATOM_INCREMENT 256 #define NUMBER_COUNT 1024 #define NUMBER_INCREMENT 1024 /* * Maximum atom length. */ #define ATOM_SIZE 256 /* * Maximum number of times to eval a prospective function while it's * still an atom or cons node. */ #define LOOP_MAX 256 /* * Maximum number of elements of a list to print. */ #define MAX_PRINT_LENGTH 256 /* * How close two numbers must to be to be considered equal, and how * small a number must be to be considered zero. */ #define ZERO_THRESHOLD (1e-8) /* * File to read from upon initialization. */ #define LISP_INIT_FILE "lisp-init.l" /* * Mask to extract an object's index. */ #define INDEX_MASK 0x00ffffff /* * Mask to extract an object's type. */ #define TYPE_MASK 0x0f000000 /* * Mask used to mark nodes during garbage collection. */ #define GC_MARK 0x10000000 /* * Number of different types of lisp objects. */ #define TYPE_COUNT 11 /* * Lisp object type values. */ #define undefined_object 0x01000000 #define atom_object 0x02000000 #define number_object 0x03000000 #define cons_object 0x04000000 #define user_function_object 0x05000000 #define user_special_object 0x06000000 #define built_in_function_object 0x07000000 #define built_in_special_object 0x08000000 #define stream_object 0x09000000 #define macro_object 0x0a000000 #define funarg_object 0x0b000000 /* * Define the C data type that represents a lisp object. */ typedef long object; /* * Macros to manipulate a lisp objects. */ /* * The index of an object. */ #define Object_Index(object) (object & INDEX_MASK) /* * The type of an object. */ #define Object_Type(object) (object & TYPE_MASK) /* * The ordinal value of the type of an object. Will range from 1 to * TYPE_COUNT. */ #define Type_Ord(object) (Object_Type(object) >> 24) /* * An object coerced into a given type. */ #define Set_Type(type, object) (type | Object_Index(object)) /* * The cons structure. */ struct cons { object car; object cdr; }; /* * Macros to manipulate cons objects. Cons_Car(cons) references the * car field of a cons object, and Cons_Cdr references the cdr field * of a cons object. */ #define Cons_Car(cons) (Cons[Object_Index(cons)].car) #define Cons_Cdr(cons) (Cons[Object_Index(cons)].cdr) /* * The atom structure. */ struct atom { object value; char *name; }; /* * Macros to manipulate atom objects. Atom_Value(atom) references the * value field of an atom object, and Atom_Name references the name field * of an atom object. */ #define Atom_Value(atom) (Atom[Object_Index(atom)].value) #define Atom_Name(atom) (Atom[Object_Index(atom)].name) /* * The number structure. */ struct number { double value; }; /* * Macro to manipulate number objects. Number_Value(atom) references the * value field of a number object. */ #define Number_Value(number) ((double)Number[Object_Index(number)].value) /* * The built-in structure. */ struct built_in { char *name; object type; object (*fun)(); int args; }; /* * Macros to manipulate built in objects. Built_In_Name(built_in) * references the name field of the built in object, * Built_In_Type(built_in) references its type field, * Built_In_Fun(built_in) references its fun field, and * Built_In_Args(built_in) references its args field. * Apply_Built_In(built_in, args) calls the C code associated with the * built in function, passing it args. */ #define Built_In_Name(built_in) (Built_In[Object_Index(built_in)].name) #define Built_In_Type(built_in) (Built_In[Object_Index(built_in)].type) #define Built_In_Fun(built_in) (Built_In[Object_Index(built_in)].fun) #define Built_In_Args(built_in) (Built_In[Object_Index(built_in)].args) #define Apply_Built_In(built_in, args) ((Built_In_Fun(built_in))(args)) /* * Macros to deal with stacks. O_Push(stack, object) pushes object * onto stack. O_Top(stack) references the top object on stack. * O_Pop(stack) pops the top of a stack. */ #define O_Push(stack, object) ((stack) = make_cons((object), \ (stack))) #define O_Top(stack) (Cons_Car(stack)) #define O_Pop(stack) ((stack) = Cons_Cdr(stack)) /* * Macros for dealing with the Ob_List. Ob_Push() pushed a new frame * onto the Ob_List. Ob_Pop() pops the top frame from the Ob_List. * Ob_Bind(var, val) binds var to val in the current frame. * Ob_Unbind() pops the latest binding off of the current frame. * Ob_Save(object) pushed the pair ( . object) onto the * Ob_List to protect it from garbage collection. Env_Push(env) saves * the current Ob_List on Ob_Stack, and sets Ob_List to env. Env_Pop() * sets the Ob_List to the top of Ob_Stack, and pops Ob_Stack. */ #define Ob_Push() O_Push(Ob_List, Nil) #define Ob_Pop() O_Pop(Ob_List) #define Ob_Bind(var, val) O_Push(O_Top(Ob_List), \ make_cons(var, val)) #define Ob_Unbind() O_Pop(O_Top(Ob_List)) #define Ob_Save(object) Ob_Bind(undefined_object, object) #define Env_Push(env) (O_Push(Ob_Stack, Ob_List), \ (Ob_List = env)) #define Env_Pop() ((Ob_List = O_Top(Ob_Stack)), \ O_Pop(Ob_Stack)) /* * Macros for refering to the arguments of built-in functions. The * variable args is assumed to contain the head of the argument list. */ #define ARG1 Cons_Car(args) #define ARG2 Cons_Car(Cons_Cdr(args)) #define ARG3 Cons_Car(Cons_Cdr(Cons_Cdr(args))) /* * Global function declarations. */ /* In math.c */ object plus(), times(), quotient(), lremainder(), minus(), lfloor(), numberp(), greaterp(), zerop(), lrandom(); /* In util.c */ object *find_variable(); object push_stream(), pop_stream(), push_output(), push_input(), pop_output(), pop_input(), eq(), lcons(), lcar(), lcdr(), latom(), list(), type(), setq(), quote(), and(), or(), explode(), implode(); /* In read.c */ object get_token(), sread(), read_quote(), read_list(); /* In print.c */ object lprin1(), lprint(), lprintcr(), terpri(); /* In gc.c */ object lgc(); /* In eval.c */ object body(), apply(), lapply(), funcall(), lfuncall(), eval(), leval(), dolist(), cond(), lambda(), special(), macro(), function(); /* In memory.c */ object get_cons(), make_cons(), get_atom(), make_atom(), get_number(), make_number(); /* In error.c */ object error(); char *type_name(); /* * Global variables */ /* * Counters for the number of allocated and used conses, atoms, and numbers. */ extern int Cons_Count, Cons_Free; extern int Atom_Count, Atom_Free; extern int Number_Count, Number_Free; /* * Pointers to beginning of the the cons, atom, and number, and * built-in storage spaces. */ extern struct cons *Cons; extern struct atom *Atom; extern struct number *Number; extern struct built_in Built_In[]; /* * Objects refering to atoms. These are set to refer to their * respective atoms in initialize(). */ extern object Nil, T, Quote, Lambda, Special, Macro; /* * Stacks used by lisp and known about by the garbage collector. These * are set to Nil in initialize(). */ extern object Ob_List, Ob_Stack, Back_Trace, Free_List, Input_Stack, Output_Stack; /* * Input and output streams. */ extern FILE *Input_File, *Output_File; /* * A longjmp() label for top level lisp read-eval-print loop. Used by * abort() to jump to lisp warm start in main(). */ extern jmp_buf Top_Level; /* * Names of the lisp object types. */ extern char *Type_Name[];