/** * ops/truth.c * * Post Scarcity Software Environment: nil? true? not. * * Functions associated with truthiness. * * (c) 2026 Simon Brooke * Licensed under GPL version 2.0, or, at your option, any later version. */ #include #include "memory/node.h" #include "memory/pointer.h" #include "memory/pso4.h" #include "ops/stack_ops.h" /** * @brief true if `p` points to `nil`, else false. * * Note that every node has its own copy of `t` and `nil`, and each instance of * each is considered equivalent. So we don't check the node when considering * whether `nil` really is `nil`, or `t` really is `t`. * * @param p a pointer * @return true if `p` points to `nil`. * @return false otherwise. */ bool c_nilp( struct pso_pointer p ) { return ( p.page == 0 && p.offset == 0 ); } /** * @brief `true` if `p` points to `t`, else `false`. * * Note that every node has its own copy of `t` and `nil`, and each instance of * each is considered equivalent. So we don't check the node when considering * whether `nil` really is `nil`, or `t` really is `t`. * * Note that the offset is 4 because `t` should be the second pso2 allocated, * the offset is given in words, and the size of a pso2 should be four words * * @param p a pointer * @return true if `p` points to `t`. * @return false otherwise. */ bool c_truep( struct pso_pointer p ) { return ( p.page == 0 && p.offset == 4 ); } /** * @brief return `t` if the first argument in this frame is `nil`, else `t`. * * @param frame_pointer A pointer to the current stack frame; * @return `t` if the first argument in this frame is `nil`, else `t` */ struct pso_pointer nilp( struct pso_pointer frame_pointer ) { struct pso4 *frame = pointer_to_pso4( frame_pointer ); return ( c_nilp( fetch_arg( frame, 0 ) ) ? t : nil ); } /** * @brief return `t` if the first argument in this frame is `t`, else `nil`. * * @param frame_pointer A pointer to the current stack frame; * @return `t` if the first argument in this frame is `t`, else `nil`. */ struct pso_pointer truep( struct pso_pointer frame_pointer ) { struct pso4 *frame = pointer_to_pso4( frame_pointer ); return ( c_truep( fetch_arg( frame, 0 ) ) ? t : nil ); } /** * @brief return `t` if the first argument in this frame is not `nil`, else * `t`. * * @param frame_pointer A pointer to the current stack frame; * @return `t` if the first argument in this frame is not `nil`, else `t`. */ struct pso_pointer not( struct pso_pointer frame_pointer ) { struct pso4 *frame = pointer_to_pso4( frame_pointer ); return ( !c_nilp( fetch_arg( frame, 0 ) ) ? t : nil ); } /** * @brief (and args...) * * @return `nil` if any `arg` is `nil`, else `t`. */ struct pso_pointer and( struct pso_pointer frame_pointer ) { struct pso4 *frame = pointer_to_pso4( frame_pointer ); struct pso_pointer result = t; for ( int arg = 0; c_truep( result ) && arg < frame->payload.stack_frame.args; arg++ ) { if ( c_nilp( fetch_arg( frame, arg ) ) ) { result = nil; break; } } return result; } /** * @brief (or args...) * * @return `t` if any `arg` is non-nil, else `nil`. */ struct pso_pointer or( struct pso_pointer frame_pointer ) { struct pso4 *frame = pointer_to_pso4( frame_pointer ); struct pso_pointer result = nil; for ( int arg = 0; c_truep( result ) && arg < frame->payload.stack_frame.args; arg++ ) { if ( !c_nilp( fetch_arg( frame, arg ) ) ) { result = t; break; } } return result; }