diff --git a/Makefile b/Makefile index b662908..49bf5e1 100644 --- a/Makefile +++ b/Makefile @@ -8,8 +8,9 @@ DEPS := $(OBJS:.o=.d) TESTS := $(shell find unit-tests -name *.sh) -INC_DIRS := $(shell find $(SRC_DIRS) -type d) -INC_FLAGS := $(addprefix -I,$(INC_DIRS)) +# INC_DIRS := $(shell find $(SRC_DIRS) -type d) +# INC_FLAGS := $(addprefix -I,$(INC_DIRS)) +INC_FLAGS := -I $(SRC_DIRS) TMP_DIR ?= ./tmp diff --git a/src/c/debug.c b/src/c/debug.c index ae57c16..d6c5c27 100644 --- a/src/c/debug.c +++ b/src/c/debug.c @@ -127,4 +127,4 @@ void debug_printf( int level, int indent, wchar_t *format, ... ) { } // debug_dump_object, debug_print_binding, debug_print_exception, debug_print_object, -// not yet implemented but probably will be. \ No newline at end of file +// not yet implemented but probably will be. diff --git a/src/c/environment/environment.c b/src/c/environment/environment.c index f7ec199..cf512c4 100644 --- a/src/c/environment/environment.c +++ b/src/c/environment/environment.c @@ -23,14 +23,14 @@ bool environment_initialised = false; * @param node theindex of the node we are initialising. * @return struct pso_pointer t on success, else an exception. */ - -struct pso_pointer initialise_environment( uint32_t node) { + +struct pso_pointer initialise_environment( uint32_t node ) { struct pso_pointer result = t; - if (environment_initialised) { + if ( environment_initialised ) { // TODO: throw an exception "Attempt to reinitialise environment" } else { // TODO: actually initialise it. } return result; -} \ No newline at end of file +} diff --git a/src/c/memory/memory.c b/src/c/memory/memory.c index 530d3e6..ca41d67 100644 --- a/src/c/memory/memory.c +++ b/src/c/memory/memory.c @@ -34,10 +34,10 @@ bool memory_initialised = false; * @return int */ struct pso_pointer initialise_memory( uint32_t node ) { - if (memory_initialised) { + if ( memory_initialised ) { // TODO: throw an exception } else { - for (uint8_t i = 0; i <= MAX_SIZE_CLASS; i++) { + for ( uint8_t i = 0; i <= MAX_SIZE_CLASS; i++ ) { freelists[i] = nil; } memory_initialised = true; diff --git a/src/c/memory/node.c b/src/c/memory/node.c index 84228c4..ebf470e 100644 --- a/src/c/memory/node.c +++ b/src/c/memory/node.c @@ -37,13 +37,13 @@ uint32_t node_index = 0; * @brief The canonical `nil` pointer * */ -struct pso_pointer nil = (struct pso_pointer) { 0, 0, 0}; +struct pso_pointer nil = ( struct pso_pointer ) { 0, 0, 0 }; /** * @brief the canonical `t` (true) pointer. * */ -struct pso_pointer t = (struct pso_pointer) { 0, 0, 1 }; +struct pso_pointer t = ( struct pso_pointer ) { 0, 0, 1 }; /** diff --git a/src/c/memory/page.c b/src/c/memory/page.c index eb424e7..b0afe4f 100644 --- a/src/c/memory/page.c +++ b/src/c/memory/page.c @@ -38,7 +38,7 @@ * to hold the number of pages we *might* create at start up time. We need a * way to grow the number of pages, while keeping access to them cheap. */ -union page * pages[NPAGES]; +union page *pages[NPAGES]; /** * @brief the number of pages which have thus far been allocated. @@ -55,25 +55,30 @@ uint32_t npages_allocated = 0; * @param freelist the freelist for objects of this size class. * @return struct pso_pointer the new head for the freelist for this size_class, */ -struct pso_pointer initialise_page( union page* page_addr, uint16_t page_index, - uint8_t size_class, struct pso_pointer freelist) { +struct pso_pointer initialise_page( union page *page_addr, uint16_t page_index, + uint8_t size_class, + struct pso_pointer freelist ) { struct pso_pointer result = freelist; - int obj_size = pow(2, size_class); - int obj_bytes = obj_size * sizeof(uint64_t); - int objs_in_page = PAGE_BYTES/obj_bytes; + int obj_size = pow( 2, size_class ); + int obj_bytes = obj_size * sizeof( uint64_t ); + int objs_in_page = PAGE_BYTES / obj_bytes; // we do this backwards (i--) so that object {0, 0, 0} will be first on the // freelist when the first page is initiated, so we can grab that one for // `nil` and the next on for `t`. - for (int i = objs_in_page - 1; i >= 0; i--) { + for ( int i = objs_in_page - 1; i >= 0; i-- ) { // it should be safe to cast any pso object to a pso2 - struct pso2* object = (struct pso2 *)(page_addr + (i * obj_bytes)); + struct pso2 *object = + ( struct pso2 * ) ( page_addr + ( i * obj_bytes ) ); object->header.tag.bytes.size_class = size_class; - strncpy( &(object->header.tag.bytes.mnemonic[0]), FREETAG, TAGLENGTH); + strncpy( &( object->header.tag.bytes.mnemonic[0] ), FREETAG, + TAGLENGTH ); object->payload.free.next = result; - result = make_pointer( node_index, page_index, (uint16_t)( i * obj_size)); + result = + make_pointer( node_index, page_index, + ( uint16_t ) ( i * obj_size ) ); } return result; @@ -89,56 +94,56 @@ struct pso_pointer initialise_page( union page* page_addr, uint16_t page_index, struct pso_pointer allocate_page( uint8_t size_class ) { struct pso_pointer result = t; - if ( npages_allocated == 0) { - for (int i = 0; i < NPAGES; i++) { + if ( npages_allocated == 0 ) { + for ( int i = 0; i < NPAGES; i++ ) { pages[i] = NULL; } - debug_print( L"Pages array zeroed.\n", DEBUG_ALLOC, 0); + debug_print( L"Pages array zeroed.\n", DEBUG_ALLOC, 0 ); } - if ( npages_allocated < NPAGES) { + if ( npages_allocated < NPAGES ) { if ( size_class >= 2 && size_class <= MAX_SIZE_CLASS ) { - void* pg = malloc( sizeof( union page ) ); + void *pg = malloc( sizeof( union page ) ); if ( pg != NULL ) { memset( pg, 0, sizeof( union page ) ); - pages[ npages_allocated] = pg; - debug_printf( DEBUG_ALLOC, 0, - L"Allocated page %d for objects of size class %x.\n", - npages_allocated, size_class); + pages[npages_allocated] = pg; + debug_printf( DEBUG_ALLOC, 0, + L"Allocated page %d for objects of size class %x.\n", + npages_allocated, size_class ); freelists[size_class] = - initialise_page( (union page*)pg, npages_allocated, size_class, freelists[size_class] ); + initialise_page( ( union page * ) pg, npages_allocated, + size_class, freelists[size_class] ); - debug_printf( DEBUG_ALLOC, 0, - L"Initialised page %d; freelist for size class %x updated.\n", - npages_allocated, - size_class); + debug_printf( DEBUG_ALLOC, 0, + L"Initialised page %d; freelist for size class %x updated.\n", + npages_allocated, size_class ); - npages_allocated ++; + npages_allocated++; } else { // TODO: exception when we have one. result = nil; fwide( stderr, 1 ); - fwprintf( stderr, - L"\nCannot allocate page: heap exhausted,\n", - size_class, MAX_SIZE_CLASS ); + fwprintf( stderr, + L"\nCannot allocate page: heap exhausted,\n", + size_class, MAX_SIZE_CLASS ); } } else { // TODO: exception when we have one. result = nil; fwide( stderr, 1 ); - fwprintf( stderr, - L"\nCannot allocate page for size class %x, min is 2 max is %x.\n", - size_class, MAX_SIZE_CLASS ); + fwprintf( stderr, + L"\nCannot allocate page for size class %x, min is 2 max is %x.\n", + size_class, MAX_SIZE_CLASS ); } } else { // TODO: exception when we have one. - result = nil; + result = nil; fwide( stderr, 1 ); - fwprintf( stderr, - L"\nCannot allocate page: page space exhausted.\n", - size_class, MAX_SIZE_CLASS ); + fwprintf( stderr, + L"\nCannot allocate page: page space exhausted.\n", + size_class, MAX_SIZE_CLASS ); } return result; diff --git a/src/c/memory/pointer.c b/src/c/memory/pointer.c index 5c46540..8227151 100644 --- a/src/c/memory/pointer.c +++ b/src/c/memory/pointer.c @@ -22,8 +22,9 @@ * @param offset The offset, in words, within that page, of the object. * @return struct pso_pointer a pointer referencing the specified object. */ -struct pso_pointer make_pointer( uint32_t node, uint16_t page, uint16_t offset) { - return (struct pso_pointer){ node, page, offset}; +struct pso_pointer make_pointer( uint32_t node, uint16_t page, + uint16_t offset ) { + return ( struct pso_pointer ) { node, page, offset }; } /** @@ -36,16 +37,15 @@ struct pso_pointer make_pointer( uint32_t node, uint16_t page, uint16_t offset) * @param pointer a pso_pointer which references an object. * @return struct pso2* the actual address in memory of that object. */ -struct pso2* pointer_to_object( struct pso_pointer pointer) { - struct pso2* result = NULL; +struct pso2 *pointer_to_object( struct pso_pointer pointer ) { + struct pso2 *result = NULL; - if ( pointer.node == node_index) { - union page* pg = pages[pointer.page]; - result = (struct pso2*) &pg->words[pointer.offset]; + if ( pointer.node == node_index ) { + union page *pg = pages[pointer.page]; + result = ( struct pso2 * ) &pg->words[pointer.offset]; } // TODO: else if we have a copy of the object in cache, return that; // else request a copy of the object from the node which curates it. return result; } - diff --git a/src/c/memory/pso.c b/src/c/memory/pso.c index c4fc711..6982ca8 100644 --- a/src/c/memory/pso.c +++ b/src/c/memory/pso.c @@ -33,58 +33,61 @@ * @param size_class The size class for the object to be allocated; * @return struct pso_pointer a pointer to the newly allocated object */ -struct pso_pointer allocate( char* tag, uint8_t size_class) { +struct pso_pointer allocate( char *tag, uint8_t size_class ) { struct pso_pointer result = nil; - if (size_class <= MAX_SIZE_CLASS) { - if (nilp( freelists[size_class])) { - result = allocate_page(size_class); + if ( size_class <= MAX_SIZE_CLASS ) { + if ( nilp( freelists[size_class] ) ) { + result = allocate_page( size_class ); } - if ( !exceptionp( result) && not( freelists[size_class] ) ) { + if ( !exceptionp( result ) && not( freelists[size_class] ) ) { result = freelists[size_class]; - struct pso2* object = pointer_to_object( result); + struct pso2 *object = pointer_to_object( result ); freelists[size_class] = object->payload.free.next; - strncpy( (char *)(object->header.tag.bytes.mnemonic), tag, TAGLENGTH); + strncpy( ( char * ) ( object->header.tag.bytes.mnemonic ), tag, + TAGLENGTH ); /* the object ought already to have the right size class in its tag * because it was popped off the freelist for that size class. */ - if ( object->header.tag.bytes.size_class != size_class) { + if ( object->header.tag.bytes.size_class != size_class ) { // TODO: return an exception instead? Or warn, set it, and continue? } /* the objext ought to have a reference count ot zero, because it's * on the freelist, but again we should sanity check. */ - if ( object->header.count != 0) { + if ( object->header.count != 0 ) { // TODO: return an exception instead? Or warn, set it, and continue? } } - } // TODO: else throw exception + } // TODO: else throw exception return result; } -uint32_t payload_size( struct pso2* object) { - // TODO: Unit tests DEFINITELY needed! - return ((1 << object->header.tag.bytes.size_class) - sizeof( struct pso_header)); +uint32_t payload_size( struct pso2 *object ) { + // TODO: Unit tests DEFINITELY needed! + return ( ( 1 << object->header.tag.bytes.size_class ) - + sizeof( struct pso_header ) ); } -void free_cell( struct pso_pointer p) { - struct pso2* p2 = pointer_to_object( p); - uint32_t array_size = payload_size(p2); - uint8_t size_class = p2->header.tag.bytes.size_class; +void free_cell( struct pso_pointer p ) { + struct pso2 *p2 = pointer_to_object( p ); + uint32_t array_size = payload_size( p2 ); + uint8_t size_class = p2->header.tag.bytes.size_class; - strncpy( (char *)(p2->header.tag.bytes.mnemonic), FREETAG, TAGLENGTH); + strncpy( ( char * ) ( p2->header.tag.bytes.mnemonic ), FREETAG, + TAGLENGTH ); - /* will C just let me cheerfully walk off the end of the array I've declared? */ - for (int i = 0; i < array_size; i++) { - p2->payload.words[i] = 0; - } + /* will C just let me cheerfully walk off the end of the array I've declared? */ + for ( int i = 0; i < array_size; i++ ) { + p2->payload.words[i] = 0; + } - /* TODO: obtain mutex on freelist */ - p2->payload.free.next = freelists[size_class]; - freelists[size_class] = p; + /* TODO: obtain mutex on freelist */ + p2->payload.free.next = freelists[size_class]; + freelists[size_class] = p; } /** @@ -103,12 +106,13 @@ struct pso_pointer inc_ref( struct pso_pointer pointer ) { #ifdef DEBUG debug_printf( DEBUG_ALLOC, 0, L"\nIncremented object of type %3.3s at page %u, offset %u to count %u", - ( ( char * ) &object->header.tag.bytes.mnemonic[0] ), pointer.page, - pointer.offset, object->header.count ); - if ( vectorpointp( pointer) ) { + ( ( char * ) &object->header.tag.bytes.mnemonic[0] ), + pointer.page, pointer.offset, object->header.count ); + if ( vectorpointp( pointer ) ) { debug_printf( DEBUG_ALLOC, 0, L"; pointer to vector object of type %3.3s.\n", - ( ( char * ) &( object->payload.vectorp.tag.bytes[0] ) ) ); + ( ( char * ) + &( object->payload.vectorp.tag.bytes[0] ) ) ); } else { debug_println( DEBUG_ALLOC ); } @@ -134,12 +138,13 @@ struct pso_pointer dec_ref( struct pso_pointer pointer ) { #ifdef DEBUG debug_printf( DEBUG_ALLOC, 0, L"\nDecremented object of type %4.4s at page %d, offset %d to count %d", - ( ( char * ) (object->header.tag.bytes.mnemonic )), pointer.page, - pointer.offset, object->header.count ); - if ( vectorpointp( pointer)) { + ( ( char * ) ( object->header.tag.bytes.mnemonic ) ), + pointer.page, pointer.offset, object->header.count ); + if ( vectorpointp( pointer ) ) { debug_printf( DEBUG_ALLOC, 0, L"; pointer to vector object of type %3.3s.\n", - ( ( char * ) &( object->payload.vectorp.tag.bytes ) ) ); + ( ( char * ) + &( object->payload.vectorp.tag.bytes ) ) ); } else { debug_println( DEBUG_ALLOC ); } @@ -159,8 +164,8 @@ struct pso_pointer dec_ref( struct pso_pointer pointer ) { * * @param pointer pointer to an object to lock. */ -void lock_object( struct pso_pointer pointer) { - struct pso2* object = pointer_to_object( pointer ); +void lock_object( struct pso_pointer pointer ) { + struct pso2 *object = pointer_to_object( pointer ); object->header.count = MAXREFERENCE; } @@ -173,12 +178,12 @@ void lock_object( struct pso_pointer pointer) { * @param pointer a pointer to an object. * @return the tag value of the object indicated. */ -uint32_t get_tag_value( struct pso_pointer pointer) { - struct pso2* object = pointer_to_object( pointer); - uint32_t result = (object->header.tag.value & 0xffffff); +uint32_t get_tag_value( struct pso_pointer pointer ) { + struct pso2 *object = pointer_to_object( pointer ); + uint32_t result = ( object->header.tag.value & 0xffffff ); - if (vectorpointp( pointer)) { - result = (object->payload.vectorp.tag.value & 0xffffff); + if ( vectorpointp( pointer ) ) { + result = ( object->payload.vectorp.tag.value & 0xffffff ); } return result; diff --git a/src/c/ops/eq.c b/src/c/ops/eq.c index 9830b96..8ca0550 100644 --- a/src/c/ops/eq.c +++ b/src/c/ops/eq.c @@ -13,6 +13,7 @@ #include "memory/node.h" #include "memory/pointer.h" #include "payloads/stack.h" +#include "ops/stack_ops.h" #include "ops/truth.h" /** @@ -48,9 +49,12 @@ struct pso_pointer lisp_eq( struct pso4 *frame, struct pso_pointer env ) { struct pso_pointer result = t; - if ( frame->args > 1 ) { - for ( int b = 1; ( truep( result ) ) && ( b < frame->args ); b++ ) { - result = eq( fetch_arg(frame, 0), fetch_arg( frame, b ) ) ? t : nil; + if ( frame->payload.stack_frame.args > 1 ) { + for ( int b = 1; + ( truep( result ) ) && ( b < frame->payload.stack_frame.args ); + b++ ) { + result = + eq( fetch_arg( frame, 0 ), fetch_arg( frame, b ) ) ? t : nil; } } diff --git a/src/c/ops/repl.h b/src/c/ops/repl.h index e69de29..7a99f48 100644 --- a/src/c/ops/repl.h +++ b/src/c/ops/repl.h @@ -0,0 +1,15 @@ +/** + * ops/repl.h + * + * The read/eval/print loop. + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ + +#ifndef __psse_ops_repl_h +#define __psse_ops_repl_h + +// struct pso_pointer repl( struct pso_pointer prompt, struct pso_pointer readtable); + +#endif \ No newline at end of file diff --git a/src/c/payloads/stack.c b/src/c/ops/stack_ops.c similarity index 88% rename from src/c/payloads/stack.c rename to src/c/ops/stack_ops.c index 5cb2113..0fd28c5 100644 --- a/src/c/payloads/stack.c +++ b/src/c/ops/stack_ops.c @@ -32,10 +32,10 @@ struct pso_pointer fetch_arg( struct pso4 *frame, unsigned int index ) { struct pso_pointer p = frame->payload.stack_frame.more; for ( int i = args_in_frame; i < index; i++ ) { - p = pointer_to_object( p)->payload.cons.cdr; + p = pointer_to_object( p )->payload.cons.cdr; } - result = pointer_to_object( p)->payload.cons.car; + result = pointer_to_object( p )->payload.cons.car; } return result; diff --git a/src/c/ops/stack_ops.h b/src/c/ops/stack_ops.h new file mode 100644 index 0000000..837d49a --- /dev/null +++ b/src/c/ops/stack_ops.h @@ -0,0 +1,30 @@ +/** + * ops/stack_ops.h + * + * Operations on a Lisp stack frame. + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ + +#ifndef __psse_ops_stack_ops_h +#define __psse_ops_stack_ops_h + +#include "memory/pointer.h" +#include "memory/pso4.h" + +/* + * number of arguments stored in a stack frame + */ +#define args_in_frame 8 + +/** + * @brief The maximum depth of stack before we throw an exception. + * + * `0` is interpeted as `unlimited`. + */ +extern uint32_t stack_limit; + +struct pso_pointer fetch_arg( struct pso4 *frame, unsigned int index ); + +#endif diff --git a/src/c/ops/truth.c b/src/c/ops/truth.c index 8e10dd6..5d3db10 100644 --- a/src/c/ops/truth.c +++ b/src/c/ops/truth.c @@ -9,6 +9,12 @@ * Licensed under GPL version 2.0, or, at your option, any later version. */ +#include + +#include "memory/node.h" +#include "memory/pointer.h" +#include "ops/stack_ops.h" + /** * @brief true if `p` points to `nil`, else false. * @@ -20,8 +26,8 @@ * @return true if `p` points to `nil`. * @return false otherwise. */ -bool nilp( struct pso_pointer p) { - return (p.page == 0 && p.offset = 0); +bool nilp( struct pso_pointer p ) { + return ( p.page == 0 && p.offset == 0 ); } /** @@ -31,8 +37,8 @@ bool nilp( struct pso_pointer p) { * @return true if `p` points to `nil`; * @return false otherwise. */ -bool not( struct pso_pointer p) { - return !nilp( p); +bool not( struct pso_pointer p ) { + return !nilp( p ); } /** @@ -46,8 +52,8 @@ bool not( struct pso_pointer p) { * @return true if `p` points to `t`. * @return false otherwise. */ -bool truep( struct pso_pointer p) { - return (p.page == 0 && p.offset = 1); +bool truep( struct pso_pointer p ) { + return ( p.page == 0 && p.offset == 1 ); } /** @@ -58,10 +64,10 @@ bool truep( struct pso_pointer p) { * @param env the evaluation environment. * @return `t` if the first argument in this frame is `nil`, else `t` */ -pso_pointer lisp_nilp( struct pso4 *frame, - struct pso_pointer frame_pointer, - struct pso_pointer env ){ - return (nilp(frame->payload.stack_frame.arg[0]) ? t : nil); +struct pso_pointer lisp_nilp( struct pso4 *frame, + struct pso_pointer frame_pointer, + struct pso_pointer env ) { +return ( nilp( fetch_arg( frame, 0 )) ? t : nil ); } /** @@ -72,10 +78,10 @@ pso_pointer lisp_nilp( struct pso4 *frame, * @param env the evaluation environment. * @return `t` if the first argument in this frame is `t`, else `nil`. */ -pso_pointer lisp_truep( struct pso4 *frame, - struct pso_pointer frame_pointer, - struct pso_pointer env ){ - return (truep(frame->payload.stack_frame.arg[0]) ? t : nil); +struct pso_pointer lisp_truep( struct pso4 *frame, + struct pso_pointer frame_pointer, + struct pso_pointer env ) { + return ( truep( fetch_arg( frame, 0 ) ) ? t : nil ); } /** @@ -87,8 +93,8 @@ pso_pointer lisp_truep( struct pso4 *frame, * @param env the evaluation environment. * @return `t` if the first argument in this frame is not `nil`, else `t`. */ -pso_pointer lisp_not( struct pso4 *frame, - struct pso_pointer frame_pointer, - struct pso_pointer env ){ - return (not(frame->payload.stack_frame.arg[0]) ? t : nil); +struct pso_pointer lisp_not( struct pso4 *frame, + struct pso_pointer frame_pointer, + struct pso_pointer env ) { + return ( not( fetch_arg( frame, 0 ) ) ? t : nil ); } diff --git a/src/c/ops/truth.h b/src/c/ops/truth.h index 50fa6e5..e81eacd 100644 --- a/src/c/ops/truth.h +++ b/src/c/ops/truth.h @@ -11,6 +11,10 @@ #ifndef __psse_ops_truth_h #define __psse_ops_truth_h +#include + +#include "memory/pointer.h" +#include "memory/pso4.h" bool nilp( struct pso_pointer p ); diff --git a/src/c/payloads/cons.c b/src/c/payloads/cons.c index 6a002c8..00219e7 100644 --- a/src/c/payloads/cons.c +++ b/src/c/payloads/cons.c @@ -23,15 +23,15 @@ * @param cdr the pointer which should form the cdr of this cons cell. * @return struct pso_pointer a pointer to the newly allocated cons cell. */ -struct pso_pointer cons( struct pso_pointer car, struct pso_pointer cdr) { - struct pso_pointer result = allocate( CONSTAG, 2); +struct pso_pointer cons( struct pso_pointer car, struct pso_pointer cdr ) { + struct pso_pointer result = allocate( CONSTAG, 2 ); struct pso2 *object = pointer_to_object( result ); object->payload.cons.car = car; object->payload.cons.cdr = cdr; - inc_ref( car); - inc_ref( cdr); + inc_ref( car ); + inc_ref( cdr ); return result; } @@ -43,7 +43,7 @@ struct pso_pointer cons( struct pso_pointer car, struct pso_pointer cdr) { * @return true if `ptr` indicates a cons cell. * @return false otherwise */ -bool consp( struct pso_pointer ptr) { +bool consp( struct pso_pointer ptr ) { // TODO: make it actually work! return false; } @@ -55,11 +55,11 @@ bool consp( struct pso_pointer ptr) { * @return the car of the indicated cell. * @exception if the pointer does not indicate a cons cell. */ -struct pso_pointer car( struct pso_pointer cons) { +struct pso_pointer car( struct pso_pointer cons ) { struct pso_pointer result = nil; struct pso2 *object = pointer_to_object( result ); - if ( consp( cons)) { + if ( consp( cons ) ) { result = object->payload.cons.car; } // TODO: else throw an exception @@ -74,14 +74,14 @@ struct pso_pointer car( struct pso_pointer cons) { * @return the cdr of the indicated cell. * @exception if the pointer does not indicate a cons cell. */ -struct pso_pointer cdr( struct pso_pointer cons) { +struct pso_pointer cdr( struct pso_pointer cons ) { struct pso_pointer result = nil; struct pso2 *object = pointer_to_object( result ); - if ( consp( cons)) { + if ( consp( cons ) ) { result = object->payload.cons.cdr; } // TODO: else throw an exception return result; -} \ No newline at end of file +} diff --git a/src/c/payloads/cons.h b/src/c/payloads/cons.h index a2e8129..91d1f1b 100644 --- a/src/c/payloads/cons.h +++ b/src/c/payloads/cons.h @@ -30,12 +30,12 @@ struct cons_payload { struct pso_pointer cdr; }; -struct pso_pointer car( struct pso_pointer cons); +struct pso_pointer car( struct pso_pointer cons ); -struct pso_pointer cdr( struct pso_pointer cons); +struct pso_pointer cdr( struct pso_pointer cons ); -struct pso_pointer cons( struct pso_pointer car, struct pso_pointer cdr); +struct pso_pointer cons( struct pso_pointer car, struct pso_pointer cdr ); -bool consp( struct pso_pointer ptr); +bool consp( struct pso_pointer ptr ); #endif diff --git a/src/c/payloads/exception.c b/src/c/payloads/exception.c index ea9a1df..507b804 100644 --- a/src/c/payloads/exception.c +++ b/src/c/payloads/exception.c @@ -1,13 +1,21 @@ +/** + * payloads/exception.c + * + * An exception; required three pointers, so use object of size class 3. + * + * (c) 2026 Simon Brooke + * Licensed under GPL version 2.0, or, at your option, any later version. + */ -#import "memory/pointer.h" -#import "memory/pso.h" -#import "payloads/exception.h" +#include "memory/pointer.h" +#include "memory/pso.h" +#include "payloads/exception.h" /** * @param p a pointer to an object. * @return true if that object is an exception, else false. */ -bool exceptionp( struct pso_pointer p) { - return (get_tag_value( p) == EXCEPTIONTV); +bool exceptionp( struct pso_pointer p ) { + return ( get_tag_value( p ) == EXCEPTIONTV ); } diff --git a/src/c/payloads/exception.h b/src/c/payloads/exception.h index edc95ec..38314ee 100644 --- a/src/c/payloads/exception.h +++ b/src/c/payloads/exception.h @@ -28,6 +28,6 @@ struct exception_payload { struct pso_pointer cause; }; -bool exceptionp( struct pso_pointer p); +bool exceptionp( struct pso_pointer p ); #endif diff --git a/src/c/payloads/function.h b/src/c/payloads/function.h index 2f43bef..bd02836 100644 --- a/src/c/payloads/function.h +++ b/src/c/payloads/function.h @@ -41,9 +41,9 @@ struct function_payload { * a cons pointer (representing its result). * \todo check this documentation is current! */ - struct pso_pointer ( *executable ) ( struct pso4*, - struct pso_pointer, - struct pso_pointer ); + struct pso_pointer ( *executable ) ( struct pso4 *, + struct pso_pointer, + struct pso_pointer ); }; #endif diff --git a/src/c/payloads/hashtable.h b/src/c/payloads/hashtable.h index 3619847..b235b0b 100644 --- a/src/c/payloads/hashtable.h +++ b/src/c/payloads/hashtable.h @@ -45,11 +45,11 @@ * i.e. either an assoc list or a further hashtable. */ struct hashtable_payload { - struct pso_pointer hash_fn; /* function for hashing values in this hashtable, or `NIL` to use - the default hashing function */ - uint32_t n_buckets; /* number of hash buckets */ - struct pso_pointer buckets[]; /* actual hash buckets, which should be `NIL` - * or assoc lists or (possibly) further hashtables. */ + struct pso_pointer hash_fn; /* function for hashing values in this hashtable, or `NIL` to use + the default hashing function */ + uint32_t n_buckets; /* number of hash buckets */ + struct pso_pointer buckets[]; /* actual hash buckets, which should be `NIL` + * or assoc lists or (possibly) further hashtables. */ }; #endif diff --git a/src/c/payloads/mutex.h b/src/c/payloads/mutex.h index ca5704b..f158b0d 100644 --- a/src/c/payloads/mutex.h +++ b/src/c/payloads/mutex.h @@ -32,7 +32,7 @@ struct mutex_payload { pthread_mutex_t mutex; }; -struct pso_pointer make_mutex(); +struct pso_pointer make_mutex( ); /** * @brief evaluates these forms within the context of a thread-safe lock. @@ -50,7 +50,8 @@ struct pso_pointer make_mutex(); * @param forms a list of arbitrary Lisp forms. * @return struct pso_pointer the result. */ -struct pso_pointer with_lock( struct pso_pointer lock, struct pso_pointer forms); +struct pso_pointer with_lock( struct pso_pointer lock, + struct pso_pointer forms ); /** * @brief as with_lock, q.v. but attempts to obtain a lock and returns an @@ -64,6 +65,7 @@ struct pso_pointer with_lock( struct pso_pointer lock, struct pso_pointer forms) * @param forms a list of arbitrary Lisp forms. * @return struct pso_pointer the result. */ -struct pso_pointer attempt_with_lock( struct pso_pointer lock, struct pso_pointer forms); +struct pso_pointer attempt_with_lock( struct pso_pointer lock, + struct pso_pointer forms ); #endif diff --git a/src/c/payloads/namespace.h b/src/c/payloads/namespace.h index bb1b1b3..229c8e4 100644 --- a/src/c/payloads/namespace.h +++ b/src/c/payloads/namespace.h @@ -48,17 +48,17 @@ * i.e. either an assoc list or a further namespace. */ struct namespace_payload { - struct pso_pointer hash_fn; /* function for hashing values in this namespace, or - * `NIL` to use the default hashing function */ - uint32_t n_buckets; /* number of hash buckets */ - uint32_t unused; /* for word alignment and possible later expansion */ - struct pso_pointer write_acl; /* it seems to me that it is likely that the - * principal difference between a hashtable and a - * namespace is that a hashtable has a write ACL - * of `NIL`, meaning not writeable by anyone */ - struct pso_pointer mutex; /* the mutex to lock when modifying this namespace.*/ - struct pso_pointer buckets[]; /* actual hash buckets, which should be `NIL` - * or assoc lists or (possibly) further hashtables. */ + struct pso_pointer hash_fn; /* function for hashing values in this namespace, or + * `NIL` to use the default hashing function */ + uint32_t n_buckets; /* number of hash buckets */ + uint32_t unused; /* for word alignment and possible later expansion */ + struct pso_pointer write_acl; /* it seems to me that it is likely that the + * principal difference between a hashtable and a + * namespace is that a hashtable has a write ACL + * of `NIL`, meaning not writeable by anyone */ + struct pso_pointer mutex; /* the mutex to lock when modifying this namespace. */ + struct pso_pointer buckets[]; /* actual hash buckets, which should be `NIL` + * or assoc lists or (possibly) further hashtables. */ }; #endif diff --git a/src/c/payloads/stack.h b/src/c/payloads/stack.h index b8510c1..b02e8f0 100644 --- a/src/c/payloads/stack.h +++ b/src/c/payloads/stack.h @@ -13,7 +13,7 @@ #define __psse_payloads_stack_h #include "memory/pointer.h" -#include "memory/pso4.h" +// #include "memory/pso4.h" #define STACKTAG "STK" #define STACKTV 4936787 @@ -23,13 +23,6 @@ */ #define args_in_frame 8 -/** - * @brief The maximum depth of stack before we throw an exception. - * - * `0` is interpeted as `unlimited`. - */ -extern uint32_t stack_limit; - /** * A stack frame. */ @@ -48,6 +41,4 @@ struct stack_frame_payload { uint32_t depth; }; -struct pso_pointer fetch_arg( struct pso4 *frame, unsigned int index ); - #endif diff --git a/src/c/payloads/vector_pointer.c b/src/c/payloads/vector_pointer.c index 6a09cd1..e575874 100644 --- a/src/c/payloads/vector_pointer.c +++ b/src/c/payloads/vector_pointer.c @@ -13,6 +13,6 @@ #include "memory/pso.h" #include "payloads/vector_pointer.h" -bool vectorpointp( struct pso_pointer p) { - return (get_tag_value( p) == VECTORPOINTTV); +bool vectorpointp( struct pso_pointer p ) { + return ( get_tag_value( p ) == VECTORPOINTTV ); } diff --git a/src/c/payloads/vector_pointer.h b/src/c/payloads/vector_pointer.h index 31b45f0..e527bb1 100644 --- a/src/c/payloads/vector_pointer.h +++ b/src/c/payloads/vector_pointer.h @@ -39,6 +39,6 @@ struct vectorp_payload { void *address; }; -bool vectorpointp( struct pso_pointer p); +bool vectorpointp( struct pso_pointer p ); #endif diff --git a/src/c/psse.c b/src/c/psse.c index 5f5f2fb..fc1293b 100644 --- a/src/c/psse.c +++ b/src/c/psse.c @@ -14,6 +14,7 @@ #include "psse.h" #include "memory/node.h" +#include "ops/stack_ops.h" void print_banner( ) { fwprintf( stdout, L"Post-Scarcity Software Environment version %s\n\n",