|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "../native.h" |
|
#include "../object.h" |
|
#include "../lists.h" |
|
#include "../compile.h" |
|
|
|
#include <stdlib.h> |
|
|
|
|
|
#ifndef max |
|
# define max(a,b) ((a)>(b)?(a):(b)) |
|
#endif |
|
|
|
|
|
LIST * sequence_select_highest_ranked( FRAME * frame, int flags ) |
|
{ |
|
|
|
|
|
|
|
LIST * const elements = lol_get( frame->args, 0 ); |
|
LIST * const rank = lol_get( frame->args, 1 ); |
|
|
|
LIST * result = L0; |
|
int highest_rank = -1; |
|
|
|
{ |
|
LISTITER iter = list_begin( rank ); |
|
LISTITER const end = list_end( rank ); |
|
for ( ; iter != end; iter = list_next( iter ) ) |
|
{ |
|
int const current = atoi( object_str( list_item( iter ) ) ); |
|
highest_rank = max( highest_rank, current ); |
|
} |
|
} |
|
|
|
{ |
|
LISTITER iter = list_begin( rank ); |
|
LISTITER const end = list_end( rank ); |
|
LISTITER elements_iter = list_begin( elements ); |
|
LISTITER const elements_end = list_end( elements ); |
|
for ( ; iter != end; iter = list_next( iter ), elements_iter = |
|
list_next( elements_iter ) ) |
|
if ( atoi( object_str( list_item( iter ) ) ) == highest_rank ) |
|
result = list_push_back( result, object_copy( list_item( |
|
elements_iter ) ) ); |
|
} |
|
|
|
return result; |
|
} |
|
|
|
LIST * sequence_transform( FRAME * frame, int flags ) |
|
{ |
|
LIST * function = lol_get( frame->args, 0 ); |
|
LIST * sequence = lol_get( frame->args, 1 ); |
|
LIST * result = L0; |
|
OBJECT * function_name = list_front( function ); |
|
LISTITER args_begin = list_next( list_begin( function ) ), args_end = list_end( function ); |
|
LISTITER iter = list_begin( sequence ), end = list_end( sequence ); |
|
RULE * rule = bindrule( function_name, frame->prev->module ); |
|
|
|
for ( ; iter != end; iter = list_next( iter ) ) |
|
{ |
|
FRAME inner[ 1 ]; |
|
|
|
frame_init( inner ); |
|
inner->prev = frame; |
|
inner->prev_user = frame->prev_user; |
|
inner->module = frame->prev->module; |
|
|
|
lol_add( inner->args, list_push_back( list_copy_range( function, args_begin, args_end ), object_copy( list_item( iter ) ) ) ); |
|
result = list_append( result, evaluate_rule( rule, function_name, inner ) ); |
|
|
|
frame_free( inner ); |
|
} |
|
|
|
return result; |
|
} |
|
|
|
void init_sequence() |
|
{ |
|
{ |
|
char const * args[] = { "elements", "*", ":", "rank", "*", 0 }; |
|
declare_native_rule( "sequence", "select-highest-ranked", args, |
|
sequence_select_highest_ranked, 1 ); |
|
} |
|
{ |
|
char const * args[] = { "function", "+", ":", "sequence", "*", 0 }; |
|
declare_native_rule( "sequence", "transform", args, |
|
sequence_transform, 1 ); |
|
} |
|
} |
|
|