diff options
Diffstat (limited to 'jam-files/engine/modules/sequence.c')
-rw-r--r-- | jam-files/engine/modules/sequence.c | 102 |
1 files changed, 76 insertions, 26 deletions
diff --git a/jam-files/engine/modules/sequence.c b/jam-files/engine/modules/sequence.c index 2b539966d..08ed30599 100644 --- a/jam-files/engine/modules/sequence.c +++ b/jam-files/engine/modules/sequence.c @@ -1,47 +1,97 @@ -/* Copyright Vladimir Prus 2003. Distributed under the Boost */ -/* Software License, Version 1.0. (See accompanying */ -/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ +/* + * Copyright Vladimir Prus 2003. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + */ #include "../native.h" #include "../object.h" +#include "../lists.h" +#include "../compile.h" -# ifndef max -# define max( a,b ) ((a)>(b)?(a):(b)) -# endif +#include <stdlib.h> -LIST *sequence_select_highest_ranked( FRAME *frame, int flags ) +#ifndef max +# define max(a,b) ((a)>(b)?(a):(b)) +#endif + + +LIST * sequence_select_highest_ranked( FRAME * frame, int flags ) { /* Returns all of 'elements' for which corresponding element in parallel */ /* list 'rank' is equal to the maximum value in 'rank'. */ - LIST* elements = lol_get( frame->args, 0 ); - LIST* rank = lol_get( frame->args, 1 ); - LISTITER iter, end, elements_iter, elements_end; - - LIST* result = L0; - LIST* tmp; + LIST * const elements = lol_get( frame->args, 0 ); + LIST * const rank = lol_get( frame->args, 1 ); + + LIST * result = L0; int highest_rank = -1; - iter = list_begin(rank), end = list_end(rank); - for (; iter != end; iter = list_next(iter)) - highest_rank = max(highest_rank, atoi(object_str(list_item(iter)))); - - iter = list_begin(rank), end = list_end(rank); - elements_iter = list_begin(elements), 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))); + { + 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; } -void init_sequence() +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 ) ) { - const char* args[] = { "elements", "*", ":", "rank", "*", 0 }; - declare_native_rule("sequence", "select-highest-ranked", args, - sequence_select_highest_ranked, 1); + 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 ); + } } |