Still grinding incrementally forward, through barbed wire entanglements.

Morale fading.
This commit is contained in:
Simon Brooke 2026-05-03 17:26:53 +01:00
parent ab0ea09bd4
commit 92490ebd5f
9 changed files with 104 additions and 48 deletions

View file

@ -11,6 +11,7 @@
#define __psse_payloads_cons_h
#include <stdbool.h>
#include "memory/node.h"
#include "memory/pointer.h"
#include "memory/pso2.h"
#include "memory/pso4.h"
@ -32,7 +33,7 @@ struct pso_pointer make_cons( struct pso_pointer frame_pointer,
struct pso_pointer car, struct pso_pointer cdr );
/**
* macro short-cuts for make_cons.
* macro short-cuts for make_cons.
*/
// #define make_cons(frame_pointer,car,cdr) (cons(make_frame(2, frame_pointer, car, cdr)))

View file

@ -24,12 +24,46 @@
#include "ops/reverse.h"
#include "ops/list_ops.h"
#include "ops/stack_ops.h"
/**
* @brief Add an argument to this (already initialised) stack frame, updating
* the args count.
*
* TODO: unit test this to death and back!
*
* @param frame_pointer a pointer to the frame to be modified.
* @param arg_pointer the pointer to the arg to be added.
*
* @return `nil` on success; potentially an exception on failure.
*/
struct pso_pointer add_arg( struct pso_pointer frame_pointer, struct pso_pointer arg_pointer) {
struct pso4* frame = pointer_to_pso4( frame_pointer);
struct pso_pointer result = nil;
if (frame->payload.stack_frame.args < args_in_frame) {
frame->payload.stack_frame.arg[frame->payload.stack_frame.args++] = push_local(frame_pointer, arg_pointer);
} else {
struct pso_pointer new_more = c_reverse( frame_pointer,
make_cons( frame_pointer,
arg_pointer,
c_reverse( frame_pointer, frame->payload.stack_frame.more)));
if (exceptionp(new_more)) {
result = new_more;
} else {
frame->payload.stack_frame.more =
push_local( frame_pointer, new_more);
}
}
return result;
}
/**
* @brief Construct a stack frame with this `previous` pointer, and arguments
* taken from the remaining arguments to this function, which should all be
* struct pso_pointer.
*
*
* @param arg_count the count of arguments to the Lisp function.
* @param previous the parent stack frame.
* @param ... the arguments to the Lisp function, all of which must be of type
@ -42,6 +76,9 @@ struct pso_pointer make_frame( int arg_count, struct pso_pointer previous,
va_list args;
va_start( args, previous );
/* NOTE! It is really important not to `push_local` the new_pointer here,
* since that would stop stack frames and all the temporary objects they
* curate ever being garbage collected! */
struct pso_pointer new_pointer = allocate( previous, STACKTAG, 4 );
struct pso4 *new_frame = pointer_to_pso4( new_pointer );
@ -85,7 +122,7 @@ struct pso_pointer make_frame( int arg_count, struct pso_pointer previous,
more_args );
}
new_frame->payload.stack_frame.more = c_reverse( more_args );
new_frame->payload.stack_frame.more = c_reverse( previous, more_args );
} else {
for ( ; cursor < args_in_frame; cursor++ ) {
new_frame->payload.stack_frame.arg[cursor] = nil;
@ -103,7 +140,10 @@ struct pso_pointer make_frame( int arg_count, struct pso_pointer previous,
* @brief variant of make_frame with an explicit replacement environment, to
* be called by functions like `binding` which add bindings to their upstack
* environment.
*
*
* TODO: someone who really understood how C varargs functions work could save
* a lot of potentially error prone code by having this call `make_frame`, q.v.
*
* @param arg_count the count of arguments to the Lisp function.
* @param previous the parent stack frame.
* @param env the modified environment
@ -119,6 +159,9 @@ struct pso_pointer make_frame_with_env( int arg_count,
va_start( args, env );
struct pso4 *prev_frame = pointer_to_pso4( previous );
/* NOTE! It is really important not to `push_local` the new_pointer here,
* since that would stop stack frames and all the temporary objects they
* curate ever being garbage collected! */
struct pso_pointer new_pointer = allocate( previous, STACKTAG, 4 );
struct pso4 *new_frame = pointer_to_pso4( new_pointer );
@ -159,7 +202,7 @@ struct pso_pointer make_frame_with_env( int arg_count,
more_args );
}
new_frame->payload.stack_frame.more = c_reverse( more_args );
new_frame->payload.stack_frame.more = c_reverse( previous, more_args );
} else {
for ( ; cursor < args_in_frame; cursor++ ) {
new_frame->payload.stack_frame.arg[cursor] = nil;
@ -189,6 +232,9 @@ struct pso_pointer make_frame_with_arglist_and_env( struct pso_pointer
argvalues,
struct pso_pointer env ) {
struct pso4 *prev_frame = pointer_to_pso4( previous );
/* NOTE! It is really important not to `push_local` the new_pointer here,
* since that would stop stack frames and all the temporary objects they
* curate ever being garbage collected! */
struct pso_pointer new_pointer = allocate( previous, STACKTAG, 4 );
struct pso4 *new_frame = pointer_to_pso4( new_pointer );
struct pso_pointer arg_length =

View file

@ -20,7 +20,7 @@
#define args_in_frame 8
/**
* A stack frame.
* A stack frame.
*/
struct stack_frame_payload {
/** the previous frame. */
@ -60,4 +60,6 @@ struct pso_pointer make_frame_with_arglist( struct pso_pointer previous,
struct pso_pointer destroy_stack_frame( struct pso_pointer fp,
struct pso_pointer env );
struct pso_pointer add_arg( struct pso_pointer frame_pointer, struct pso_pointer arg_pointer);
#endif