From dc5cac0bd8663630efa1f8e2fb6f943b38861c13 Mon Sep 17 00:00:00 2001 From: Simon Brooke Date: Wed, 18 Mar 2026 20:44:18 +0000 Subject: [PATCH] Work on the 'member?' bug - (issue #8) -- which turns out to be assoc/interned. Progress has been made, but this is not fixed. --- src/ops/intern.c | 36 +++++++++++++++++++++++++++++++++--- src/ops/intern.h | 3 +++ src/ops/lispops.c | 19 ++++++++++++++----- unit-tests/memberp.sh | 4 ++-- 4 files changed, 52 insertions(+), 10 deletions(-) diff --git a/src/ops/intern.c b/src/ops/intern.c index bba5ee5..6221b2a 100644 --- a/src/ops/intern.c +++ b/src/ops/intern.c @@ -191,7 +191,7 @@ struct cons_pointer hashmap_put_all( struct cons_pointer mapp, for ( struct cons_pointer pair = c_car( assoc ); !nilp( pair ); pair = c_car( assoc ) ) { /* TODO: this is really hammering the memory management system, because - * it will make a new lone for every key/value pair added. Fix. */ + * it will make a new clone for every key/value pair added. Fix. */ if ( consp( pair ) ) { mapp = hashmap_put( mapp, c_car( pair ), c_cdr( pair ) ); } else if ( hashmapp( pair ) ) { @@ -338,6 +338,7 @@ struct cons_pointer search_store( struct cons_pointer key, result = return_key ? c_car( entry_ptr ) : c_cdr( entry_ptr ); + break; } break; case HASHTV: @@ -426,7 +427,7 @@ struct cons_pointer interned( struct cons_pointer key, } /** - * @brief Implementation of `interned?` in C: predicate wrapped around interned. + * @brief Implementation of `interned?` in C. * * @param key the key to search for. * @param store the store to search in. @@ -434,7 +435,36 @@ struct cons_pointer interned( struct cons_pointer key, */ struct cons_pointer internedp( struct cons_pointer key, struct cons_pointer store ) { - return nilp( interned( key, store ) ) ? NIL : TRUE; + struct cons_pointer result = NIL; + + if ( consp( store ) ) { + for ( struct cons_pointer pair = c_car( store ); eq( result, NIL) && !nilp( pair ); + pair = c_car( store ) ) { + if ( consp( pair ) ) { + if ( equal( c_car( pair), key)) { + // yes, this should be `eq`, but if symbols are correctly + // interned this will work efficiently, and if not it will + // still work. + result = TRUE; + } + } else if ( hashmapp( pair ) ) { + result=internedp( key, pair); + } + + store = c_cdr( store ); + } + } else if ( hashmapp( store ) ) { + struct vector_space_object *map = pointer_to_vso( store ); + + for ( int i = 0; i < map->payload.hashmap.n_buckets; i++ ) { + for ( struct cons_pointer c = map->payload.hashmap.buckets[i]; + !nilp( c ); c = c_cdr( c ) ) { + result = internedp( key, c); + } + } + } + + return result; } /** diff --git a/src/ops/intern.h b/src/ops/intern.h index 18fc084..e54ae7b 100644 --- a/src/ops/intern.h +++ b/src/ops/intern.h @@ -75,4 +75,7 @@ struct cons_pointer deep_bind( struct cons_pointer key, struct cons_pointer intern( struct cons_pointer key, struct cons_pointer environment ); +struct cons_pointer internedp( struct cons_pointer key, + struct cons_pointer store ); + #endif diff --git a/src/ops/lispops.c b/src/ops/lispops.c index 914301d..98c518f 100644 --- a/src/ops/lispops.c +++ b/src/ops/lispops.c @@ -919,17 +919,26 @@ lisp_internedp( struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer c_keys( struct cons_pointer store ) { struct cons_pointer result = NIL; - if ( hashmapp( store ) ) { - result = hashmap_keys( store ); - } else if ( consp( store ) ) { - for ( struct cons_pointer c = store; !nilp( c ); c = c_cdr( c ) ) { - result = make_cons( c_car( c ), result ); + if ( consp( store ) ) { + for ( struct cons_pointer pair = c_car( store ); !nilp( pair ); + pair = c_car( store ) ) { + if ( consp( pair ) ) { + result = make_cons( c_car( pair), result); + } else if ( hashmapp( pair ) ) { + result=c_append( hashmap_keys( pair), result); + } + + store = c_cdr( store ); } + } else if ( hashmapp( store ) ) { + result = hashmap_keys( store ); } return result; } + + struct cons_pointer lisp_keys( struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env ) { diff --git a/unit-tests/memberp.sh b/unit-tests/memberp.sh index f3a50af..e1795fc 100644 --- a/unit-tests/memberp.sh +++ b/unit-tests/memberp.sh @@ -53,14 +53,14 @@ else fi -expected='nil'(CDR ) +expected='nil' output=`target/psse $1 <