post-scarcity/src/c/ops/reverse.c
Simon Brooke f915a9993f Fixed assigning arguments to slots in the frame; also fixed a bug in bind...
But did that by switching away from using Lisp calling convention, because
that broke horribly. This is bad news and must be sorted out.
2026-04-16 17:13:20 +01:00

77 lines
2.4 KiB
C

/**
* 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 <simon@journeyman.cc>
* Licensed under GPL version 2.0, or, at your option, any later version.
*/
#include <stdbool.h>
#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;
}