/** * ops/reverse.c * * Post Scarcity Software Environment: reverse. * * Reverse a sequence. Didn'e want to do this in the substrate, but I need * if for reading atoms!. * * (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/pso.h" #include "memory/pso2.h" #include "memory/tags.h" #include "payloads/cons.h" #include "payloads/exception.h" #include "payloads/psse_string.h" #include "ops/string_ops.h" #include "ops/truth.h" /** * @brief reverse a sequence. * * A sequence is a list or a string-like-thing. A dotted pair is not a * sequence. * * @param sequence a pointer to a sequence. * @return a sequence like the `sequence` passed, but reversed; or `nil` if * the argument was not a sequence. */ struct pso_pointer c_reverse( struct pso_pointer sequence ) { struct pso_pointer result = nil; for ( struct pso_pointer cursor = sequence; !nilp( sequence ); cursor = c_cdr( cursor ) ) { struct pso2 *object = pointer_to_object( cursor ); switch ( get_tag_value( cursor ) ) { case CONSTV: result = c_cons( c_car( cursor ), result ); break; case KEYTV: // TODO: should you be able to reverse keywords and symbols? result = make_string_like_thing( object->payload.string.character, result, KEYTAG ); break; case STRINGTV: result = make_string_like_thing( object->payload.string.character, result, STRINGTAG ); break; case SYMBOLTV: // TODO: should you be able to reverse keywords and symbols? result = make_string_like_thing( object->payload.string.character, result, SYMBOLTAG ); break; default: result = make_exception( c_string_to_lisp_string ( L"Invalid object in sequence" ), nil, nil ); goto exit; break; } } exit: return result; }