/**********************************************************************
This file is part of Crack dot Com's free source code release of
Golgotha.
for
information about compiling & licensing issues visit this URL
If that doesn't help, contact Jonathan Clark at
golgotha_source@usa.net (Subject should have "GOLG" in it)
***********************************************************************/
#ifndef LI_LISP_HH
#define LI_LISP_HH
#include "lisp/li_types.hh"
#include "lisp/li_optr.hh"
class i4_status_class;
// this is used for debugging... it doesn't evaluate o
void lip(li_object *o);
// this is the function added into the system, arguments are evaluated
li_object *li_print(li_object *o, li_environment *env=0);
li_object *li_get_expression(char *&s, li_environment *env);
li_object *li_eval(li_object *expression, li_environment *env=0);
li_object *li_call(char *fun_name, li_object *params=0, li_environment *env=0);
li_object *li_call(li_symbol *fun_name, li_object *params=0, li_environment *env=0);
// if env is 0, global function is set
void li_add_function(li_symbol *sym, li_function_type fun, li_environment *env=0);
void li_add_function(char *sym_name, li_function_type fun, li_environment *env=0);
li_symbol *li_find_symbol(const char *name); // if symbol doesn't exsist, 0 is returned
li_symbol *li_get_symbol(const char *name); // if symbol doesn't exsist, it is created
// if cache_to is 0, then the symbol is found and stored there, otherwise cache_to is returned
li_symbol *li_get_symbol(char *name, li_symbol *&cache_to);
inline li_object *li_get_value(li_symbol *sym, li_environment *env=0)
{
if (env)
return env->value(sym);
else return sym->value();
}
inline li_object *li_get_value(char *sym, li_environment *env=0)
{ return li_get_value(li_get_symbol(sym),env); }
inline void li_set_value(li_symbol *sym, li_object *value, li_environment *env=0)
{
if (env)
env->set_value(sym, value);
else sym->set_value(value);
}
inline void li_set_value(char *sym, li_object *value, li_environment *env=0)
{ li_set_value(li_get_symbol(sym),value,env); }
// gets a function for a symbol. Checks to see if it has a local value in the environment
// first
li_object *li_get_fun(li_symbol *sym, li_environment *env);
li_object *li_get_fun(char *sym, li_environment *env);
// return 0 if type doesn't exsist
li_object *li_new(char *type_name, li_object *params=0, li_environment *env=0);
li_object *li_new(int type, li_object *params=0, li_environment *env=0);
// CAR comes from old LISP machines which stands for Contents of the Address Register
// though lisp machines aren't used anymore, the term has stuck around.
inline li_object *li_car(li_object *o, li_environment *env) { return li_list::get(o,env)->data(); }
// CDR = Contents of the Destination Register. or better know by "C" people as ->next
inline li_object *li_cdr(li_object *o, li_environment *env) { return li_list::get(o,env)->next(); }
i4_bool li_get_bool(li_object *o, li_environment *env); // return i4_T if o is 'T, i4_F if it is 'F or nil
float li_get_float(li_object *o, li_environment *env); // will convert int to float
int li_get_int(li_object *o, li_environment *env); // will convert float to int
char *li_get_string(li_object *o, li_environment *env);
i4_bool li_is_number(li_object *o, li_environment *env); // returns true if item is LI_INT or LI_FLOAT
// these function return the 1st, 2nd... item in a list first=li_cdr(o), second=li_cdr(li_cdr(o))
li_object *li_first(li_object *o, li_environment *env);
li_object *li_second(li_object *o, li_environment *env);
li_object *li_third(li_object *o, li_environment *env);
li_object *li_fourth(li_object *o, li_environment *env);
li_object *li_fifth(li_object *o, li_environment *env);
li_object *li_nth(li_object *o, int x, li_environment *env);
// li_make_list takes a variable @ of arguments (null terminated) and return a list of
// add the members : example li_make_list(new li_int(4), new li_string("hello"), 0);
li_list *li_make_list(li_object *first, ...);
int li_length(li_object *o, li_environment *env); // returns the length of the list
// this version of load take a list of li_strings which are loaded sequentially
// return result of last evaluated expression
li_object *li_load(li_object *name, li_environment *env, i4_status_class *status);
li_object *li_load(li_object *name, li_environment *env=0);
// this loads a single file and returns result of last evaluated expression
li_object *li_load(char *filename, li_environment *env=0, i4_status_class *status=0);
// loads from a file pointer, reads entire buffer
li_object *li_load(i4_file_class *fp, li_environment *env=0, i4_status_class *status=0);
// reads an expression from i4_debug and prints the result of evaluation to i4_debug
li_object *li_read_eval(li_object *o, li_environment *env=0);
// simply add an item to the begining of a list
inline void li_push(li_list *&l, li_object *o) { l=new li_list(o, l); }
// global symbols
extern li_symbol *li_nil,
*li_true_sym,
*li_quote,
*li_backquote,
*li_comma,
*li_function_symbol;
class li_symbol_ref
{
char *name;
li_symbol *sym;
public:
li_symbol *get() { if (!sym) sym=li_get_symbol(name); return sym; }
i4_bool operator==(const li_symbol *&b) { return (get() == b); }
li_symbol_ref(char *sym_name) : name(sym_name) { sym=0; }
};
#endif