101 result =
lisp_eval( next, next_pointer, env );
135 while (
consp( list ) ) {
139 list =
c_cdr( list );
161 c_progn( frame, frame_pointer, frame->arg[0], env );
165 result =
c_progn( frame, frame_pointer, frame->arg[1],
168 ( L
"*exception*" ), result ), env ) );
198 if ( !
nilp( body ) ) {
200 }
else if ( !
nilp( frame->arg[i] ) ) {
266 if (
consp( names ) ) {
269 for (
int i = 0; i < frame->args &&
consp( names ); i++ ) {
273 new_env =
set( name, val, new_env );
276 names =
c_cdr( names );
281 }
else if (
symbolp( names ) ) {
286 eval_forms( frame, frame_pointer, frame->more, env );
290 eval_form( frame, frame_pointer, frame->arg[i], env );
292 if (
nilp( val ) &&
nilp( vals ) ) {
298 new_env =
set( names, vals, new_env );
302 while ( !
nilp( body ) ) {
304 body =
c_cdr( body );
312 if ( !
nilp( result ) )
315 result =
eval_form( frame, frame_pointer, sexpr, new_env );
354 switch ( fn_cell.
tag.value ) {
367 result = next_pointer;
373 ( *fn_cell.
payload.function.executable ) ( next,
396 result = next_pointer;
429 result = next_pointer;
446 result = next_pointer;
462 int bs =
sizeof( wchar_t ) * 1024;
463 wchar_t *buffer = malloc( bs );
464 memset( buffer,
'\0', bs );
465 swprintf( buffer, bs,
466 L
"Unexpected cell with tag %d (%4.4s) in function position",
467 fn_cell.
tag.value, &fn_cell.
tag.bytes[0] );
512 switch ( cell.
tag.value ) {
514 result =
c_apply( frame, frame_pointer, env );
521 if (
nilp( canonical ) ) {
524 ( L
"Attempt to take value of unbound symbol." ),
528 result =
c_assoc( canonical, env );
540 result = frame->arg[0];
596 return frame->arg[0];
620 nilp( frame->arg[2] ) ?
oblist : frame->arg[2];
622 if (
symbolp( frame->arg[0] ) ) {
623 deep_bind( frame->arg[0], frame->arg[1] );
624 result = frame->arg[1];
629 ( L
"The first argument to `set` is not a symbol: " ),
659 if (
symbolp( frame->arg[0] ) ) {
661 eval_form( frame, frame_pointer, frame->arg[1], env );
668 ( L
"The first argument to `set!` is not a symbol: " ),
681 return nilp( arg ) ||
683 pointer2cell( arg ).payload.string.character == ( wint_t )
'\0' );
740 switch ( cell.
tag.value ) {
742 result = cell.
payload.cons.car;
756 ( L
"Attempt to take CAR of non sequence" ),
784 switch ( cell.
tag.value ) {
786 result = cell.
payload.cons.cdr;
792 result = frame->arg[0];
795 result = cell.
payload.string.cdr;
800 ( L
"Attempt to take CDR of non sequence" ),
837 return c_assoc( frame->arg[0], frame->arg[1] );
845 }
else if (
consp( store ) ) {
857 return c_keys( frame->arg[0] );
873 return eq( frame->arg[0], frame->arg[1] ) ?
TRUE :
NIL;
889 return equal( frame->arg[0], frame->arg[1] ) ?
TRUE :
NIL;
916 if (
readp( in_stream ) ) {
919 input =
pointer2cell( in_stream ).payload.stream.stream;
929 if (
readp( in_stream ) ) {
949 switch ( o.
tag.value ) {
1011 if (
writep( out_stream ) ) {
1014 output =
pointer2cell( out_stream ).payload.stream.stream;
1048 if (
writep( out_stream ) ) {
1051 output =
pointer2cell( out_stream ).payload.stream.stream;
1060 result =
print( output, frame->arg[0] );
1065 if (
writep( out_stream ) ) {
1088 return c_type( frame->arg[0] );
1100 while (
consp( expressions ) ) {
1103 result =
eval_form( frame, frame_pointer,
c_car( expressions ), env );
1135 result =
eval_form( frame, frame_pointer, frame->arg[i], env );
1140 if (
consp( frame->more ) ) {
1141 result =
c_progn( frame, frame_pointer, frame->more, env );
1171 if (
consp( clause_pointer ) ) {
1177 if ( !
nilp( result ) ) {
1179 c_progn( frame, frame_pointer,
c_cdr( clause_pointer ),
1183 }
else if (
nilp( clause_pointer ) ) {
1187 ( L
"Arguments to `cond` must be lists" ),
1276 if (
truep( frame->arg[0] ) ) {
1279 if (
readp( frame->arg[1] ) ) {
1282 input = frame->arg[1];
1284 if (
readp( frame->arg[2] ) ) {
1287 output = frame->arg[2];
1316 while ( !
nilp( cursor ) && !
eq( cursor, old_oblist ) ) {
1319 ( L
"lisp_repl: copying new oblist binding into REPL environment:\n",
1327 cursor =
c_cdr( cursor );
1335 if ( !
nilp( prompt ) ) {
1336 print( os, prompt );
1383 switch ( cell.
tag.value ) {
1422 ( L
"Can't append: not same type" ),
NIL );
1432 string.character ), l2,
1443 ( L
"Can't append: not same type" ),
NIL );
1448 ( L
"Can't append: not a sequence" ),
NIL );
1461 for (
int a = frame->args - 2; a >= 0; a-- ) {
1535 truep( cursor ); cursor =
c_cdr( cursor ) ) {
1544 bindings ) ), bindings );
1549 ( L
"Let: cannot bind, not a symbol" ),
1556 for (
int form = 1; !
exceptionp( result ) && form < frame->args; form++ ) {
struct cons_pointer make_cons(struct cons_pointer car, struct cons_pointer cdr)
Construct a cons cell from this pair of pointers.
#define KEYTV
The string KEYW, considered as an unsigned int.
#define SPECIALTV
The string SPFM, considered as an unsigned int.
#define exceptionp(conspoint)
true if conspoint points to an exception, else false
#define writep(conspoint)
true if conspoint points to a write stream cell, else false.
#define VECTORPOINTTV
The string VECP, considered as an unsigned int.
int args
the number of arguments provided.
#define truep(conspoint)
true if conspoint points to something that is truthy, i.e.
#define SYMBOLTV
The string SYMB, considered as an unsigned int.
union cons_space_object::@2 tag
union cons_space_object::@3 payload
#define NIL
a cons pointer which points to the special NIL cell
#define FUNCTIONTV
The string FUNC, considered as an unsigned int.
struct cons_pointer make_exception(struct cons_pointer message, struct cons_pointer frame_pointer)
Construct an exception cell.
struct cons_pointer make_lambda(struct cons_pointer args, struct cons_pointer body)
Construct a lambda (interpretable source) cell.
struct cons_pointer make_symbol_or_key(wint_t c, struct cons_pointer tail, uint32_t tag)
Construct a symbol or keyword from the character c and this tail.
struct cons_pointer c_string_to_lisp_keyword(wchar_t *symbol)
Return a lisp keyword representation of this wide character string.
struct cons_pointer c_cdr(struct cons_pointer arg)
Implementation of cdr in C.
#define STRINGTV
The string STRG, considered as an unsigned int.
struct cons_pointer make_string_like_thing(wint_t c, struct cons_pointer tail, uint32_t tag)
Construct a string from this character (which later will be UTF) and this tail.
#define TIMETV
The string TIME, considered as an unsigned int.
#define INTEGERTV
The string INTR, considered as an unsigned int.
#define FREETV
The string FREE, considered as an unsigned int.
#define readp(conspoint)
true if conspoint points to a read stream cell, else false
int c_length(struct cons_pointer arg)
Implementation of length in C.
#define RATIOTV
The string RTIO, considered as an unsigned int.
#define consp(conspoint)
true if conspoint points to a cons cell, else false
#define CONSTV
The string CONS, considered as an unsigned int.
#define LOOPTV
The string LOOX, considered as an unsigned int.
struct cons_pointer make_string(wint_t c, struct cons_pointer tail)
Construct a string from the character c and this tail.
#define nilp(conspoint)
true if conspoint points to the special cell NIL, else false (there should only be one of these so it...
#define NLAMBDATV
The string NLMD, considered as an unsigned int.
#define TRUETV
The string TRUE, considered as an unsigned int.
#define symbolp(conspoint)
true if conspoint points to a symbol cell, else false
#define REALTV
The string REAL, considered as an unsigned int.
struct cons_pointer c_string_to_lisp_string(wchar_t *string)
Return a lisp string representation of this wide character string.
struct cons_pointer inc_ref(struct cons_pointer pointer)
increment the reference count of the object at this cons pointer.
#define NILTV
The string NIL, considered as an unsigned int.
#define EXCEPTIONTV
The string EXEP, considered as an unsigned int.
#define TRUE
a cons pointer which points to the special T cell
#define sequencep(conspoint)
true if conspoint points to a sequence (list, string or, later, vector), else false.
#define stringp(conspoint)
true if conspoint points to a string cell, else false
struct cons_pointer c_string_to_lisp_symbol(wchar_t *symbol)
Return a lisp symbol representation of this wide character string.
struct cons_pointer c_car(struct cons_pointer arg)
Implementation of car in C.
#define LAMBDATV
The string LMDA, considered as an unsigned int.
#define WRITETV
The string WRIT, considered as an unsigned int.
struct cons_pointer c_type(struct cons_pointer pointer)
Get the Lisp type of the single argument.
struct cons_pointer make_nlambda(struct cons_pointer args, struct cons_pointer body)
Construct an nlambda (interpretable source) cell; to a lambda as a special form is to a function.
#define READTV
The string READ, considered as an unsigned int.
struct cons_pointer dec_ref(struct cons_pointer pointer)
Decrement the reference count of the object at this cons pointer.
#define pointer2cell(pointer)
given a cons_pointer as argument, return the cell.
struct cons_pointer make_cons(struct cons_pointer car, struct cons_pointer cdr)
Construct a cons cell from this pair of pointers.
An indirect pointer to a cons cell.
void debug_println(int level)
print a line feed to stderr, if verbosity matches level.
void debug_dump_object(struct cons_pointer pointer, int level)
Like dump_object, q.v., but protected by the verbosity mechanism.
void debug_printf(int level, wchar_t *format,...)
wprintf adapted for the debug logging system.
void debug_print(wchar_t *message, int level)
print this debug message to stderr, if verbosity matches level.
void debug_print_object(struct cons_pointer pointer, int level)
print the object indicated by this pointer to stderr, if verbosity matches level.
#define DEBUG_LAMBDA
Print messages debugging lambda functions (interpretation).
#define DEBUG_REPL
Print messages debugging the read eval print loop.
#define DEBUG_IO
Print messages debugging input/output operations.
#define DEBUG_ALLOC
Print messages debugging memory allocation.
#define DEBUG_EVAL
Print messages debugging evaluation.
void dump_object(URL_FILE *output, struct cons_pointer pointer)
dump the object at this cons_pointer to this output stream.
bool equal(struct cons_pointer a, struct cons_pointer b)
Deep, and thus expensive, equality: true if these two objects have identical structure,...
bool eq(struct cons_pointer a, struct cons_pointer b)
Shallow, and thus cheap, equality: true if these two objects are the same object, else false.
int url_feof(URL_FILE *file)
struct cons_pointer make_integer(int64_t value, struct cons_pointer more)
Allocate an integer cell representing this value and return a cons_pointer to it.
struct cons_pointer hashmap_keys(struct cons_pointer mapp)
return a flat list of all the keys in the hashmap indicated by map.
struct cons_pointer internedp(struct cons_pointer key, struct cons_pointer store)
Implementation of interned? in C.
struct cons_pointer c_assoc(struct cons_pointer key, struct cons_pointer store)
Implementation of assoc in C.
struct cons_pointer oblist
The global object list/or, to put it differently, the root namespace.
struct cons_pointer deep_bind(struct cons_pointer key, struct cons_pointer value)
Binds this key to this value in the global oblist.
struct cons_pointer set(struct cons_pointer key, struct cons_pointer value, struct cons_pointer store)
Return a new key/value store containing all the key/value pairs in this store with this key/value pai...
wint_t url_fgetwc(URL_FILE *input)
get one wide character from the buffer.
URL_FILE * file_to_url_file(FILE *f)
given this file handle f, return a new url_file handle wrapping it.
struct cons_pointer get_default_stream(bool inputp, struct cons_pointer env)
Resutn the current default input, or of inputp is false, output stream from this environment.
struct cons_pointer lisp_nlambda(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Construct an interpretable special form.
struct cons_pointer lisp_assoc(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function; look up the value of a key in a store.
struct cons_pointer c_apply(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Internal guts of apply.
struct cons_pointer lisp_source(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function.
struct cons_pointer lisp_mapcar(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
struct cons_pointer lisp_cons(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function; returns a cell constructed from a and b.
struct cons_pointer lisp_eq(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function; are these two objects the same object? Shallow, cheap equality.
struct cons_pointer lisp_read(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function; read one complete lisp form and return it.
struct cons_pointer throw_exception(struct cons_pointer message, struct cons_pointer frame_pointer)
Throw an exception.
struct cons_pointer lisp_exception(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function; create an exception.
struct cons_pointer c_reverse(struct cons_pointer arg)
reverse a sequence (if it is a sequence); else return it unchanged.
struct cons_pointer lisp_car(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function; returns the first item (head) of a sequence.
struct cons_pointer compose_body(struct stack_frame *frame)
Used to construct the body for lambda and nlambda expressions.
struct cons_pointer eval_form(struct stack_frame *parent, struct cons_pointer parent_pointer, struct cons_pointer form, struct cons_pointer env)
Useful building block; evaluate this single form in the context of this parent stack frame and this e...
struct cons_pointer lisp_let(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Special form: evaluate a series of forms in an environment in which these bindings are bound.
struct cons_pointer lisp_inspect(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function: dump/inspect one complete lisp expression and return NIL.
struct cons_pointer lisp_length(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function: return, as an integer, the length of the sequence indicated by the first argument,...
struct cons_pointer lisp_try(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
OK, the idea here (and I know this is less than perfect) is that the basic try special form in PSSE t...
struct cons_pointer lisp_apply(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function; apply the function which is the result of evaluating the first argument to the list of valu...
struct cons_pointer c_progn(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer expressions, struct cons_pointer env)
Evaluate each of these expressions in this environment over this frame, returning only the value of t...
struct cons_pointer lisp_eval(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function; evaluate the expression which is the first argument in the frame; further arguments are ign...
struct cons_pointer eval_forms(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer list, struct cons_pointer env)
Evaluate all the forms in this list in the context of this stack frame and this env,...
struct cons_pointer lisp_type(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function: get the Lisp type of the single argument.
struct cons_pointer c_keys(struct cons_pointer store)
struct cons_pointer lisp_progn(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Special form; evaluate the expressions which are listed in my arguments sequentially and return the v...
bool end_of_stringp(struct cons_pointer arg)
struct cons_pointer lisp_keys(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
struct cons_pointer lisp_equal(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function; are these two arguments identical? Deep, expensive equality.
struct cons_pointer lisp_repl(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function: the read/eval/print loop.
struct cons_pointer lisp_set_shriek(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Special form; binds symbol in the namespace to value of value, altering the namespace in so doing,...
struct cons_pointer lisp_append(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
should really be overwritten with a version in Lisp, since this is much easier to write in Lisp
struct cons_pointer lisp_quote(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Special form; returns its argument (strictly first argument - only one is expected but this isn't at ...
struct cons_pointer lisp_set(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function; binds the value of name in the namespace to value of value, altering the namespace in so do...
struct cons_pointer lisp_lambda(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Construct an interpretable function.
struct cons_pointer lisp_print(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function; print one complete lisp expression and return NIL.
struct cons_pointer lisp_cdr(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function; returns the remainder of a sequence when the head is removed.
struct cons_pointer lisp_list(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
void log_binding(struct cons_pointer name, struct cons_pointer val)
struct cons_pointer c_append(struct cons_pointer l1, struct cons_pointer l2)
A version of append which can conveniently be called from C.
struct cons_pointer lisp_oblist(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Return the object list (root namespace).
struct cons_pointer lisp_cond(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Special form: conditional.
struct cons_pointer lisp_reverse(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function; reverse the order of members in s sequence.
struct cons_pointer prompt_name
the name of the symbol to which the prompt is bound;
struct cons_pointer eval_lambda(struct cons_space_object cell, struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Evaluate a lambda or nlambda expression.
void println(URL_FILE *output)
struct cons_pointer print(URL_FILE *output, struct cons_pointer pointer)
Print the cons-space object indicated by pointer to the stream indicated by output.
struct cons_pointer read(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env, URL_FILE *input)
Read the next object on this input stream and return a cons_pointer to it.
struct cons_pointer make_special_frame(struct cons_pointer previous, struct cons_pointer args, struct cons_pointer env)
A 'special' frame is exactly like a normal stack frame except that the arguments are unevaluated.
struct cons_pointer fetch_arg(struct stack_frame *frame, unsigned int index)
Fetch a pointer to the value of the local variable at this index.
void set_reg(struct stack_frame *frame, int reg, struct cons_pointer value)
set a register in a stack frame.
struct stack_frame * get_stack_frame(struct cons_pointer pointer)
get the actual stackframe object from this pointer, or NULL if pointer is not a stackframe pointer.
struct cons_pointer make_empty_frame(struct cons_pointer previous)
Make an empty stack frame, and return it.
struct cons_pointer make_stack_frame(struct cons_pointer previous, struct cons_pointer args, struct cons_pointer env)
Allocate a new stack frame with its previous pointer set to this value, its arguments set up from the...
#define pointer_to_vso(pointer)
given a pointer to a vector space object, return the object.
#define hashmapp(conspoint)