2 * Copyright 2011 Steven Watanabe
3 * Copyright 2016 Rene Rivera
4 * Distributed under the Boost Software License, Version 1.0.
5 * (See accompanying file LICENSE.txt or copy at
6 * https://www.bfgroup.xyz/b2/LICENSE.txt)
14 #include "constants.h"
37 #define FUNCTION_DEBUG_PROFILE
40 #ifndef FUNCTION_DEBUG_PROFILE
41 #undef PROFILE_ENTER_LOCAL
42 #define PROFILE_ENTER_LOCAL(x) while (false)
43 #undef PROFILE_EXIT_LOCAL
44 #define PROFILE_EXIT_LOCAL(x)
47 int32_t glob( char const * s
, char const * c
);
48 void backtrace( FRAME
* );
49 void backtrace_line( FRAME
* );
51 #define INSTR_PUSH_EMPTY 0
52 #define INSTR_PUSH_CONSTANT 1
53 #define INSTR_PUSH_ARG 2
54 #define INSTR_PUSH_VAR 3
55 #define INSTR_PUSH_VAR_FIXED 57
56 #define INSTR_PUSH_GROUP 4
57 #define INSTR_PUSH_RESULT 5
58 #define INSTR_PUSH_APPEND 6
61 #define INSTR_JUMP_EMPTY 8
62 #define INSTR_JUMP_NOT_EMPTY 9
65 #define INSTR_JUMP_LT 11
66 #define INSTR_JUMP_LE 12
67 #define INSTR_JUMP_GT 13
68 #define INSTR_JUMP_GE 14
69 #define INSTR_JUMP_EQ 15
70 #define INSTR_JUMP_NE 16
71 #define INSTR_JUMP_IN 17
72 #define INSTR_JUMP_NOT_IN 18
74 #define INSTR_JUMP_NOT_GLOB 19
76 #define INSTR_FOR_INIT 56
77 #define INSTR_FOR_LOOP 20
79 #define INSTR_SET_RESULT 21
80 #define INSTR_RETURN 22
83 #define INSTR_PUSH_LOCAL 24
84 #define INSTR_POP_LOCAL 25
86 #define INSTR_APPEND 27
87 #define INSTR_DEFAULT 28
89 #define INSTR_PUSH_LOCAL_FIXED 58
90 #define INSTR_POP_LOCAL_FIXED 59
91 #define INSTR_SET_FIXED 60
92 #define INSTR_APPEND_FIXED 61
93 #define INSTR_DEFAULT_FIXED 62
95 #define INSTR_PUSH_LOCAL_GROUP 29
96 #define INSTR_POP_LOCAL_GROUP 30
97 #define INSTR_SET_GROUP 31
98 #define INSTR_APPEND_GROUP 32
99 #define INSTR_DEFAULT_GROUP 33
101 #define INSTR_PUSH_ON 34
102 #define INSTR_POP_ON 35
103 #define INSTR_SET_ON 36
104 #define INSTR_APPEND_ON 37
105 #define INSTR_DEFAULT_ON 38
106 #define INSTR_GET_ON 65
108 #define INSTR_CALL_RULE 39
109 #define INSTR_CALL_MEMBER_RULE 66
111 #define INSTR_APPLY_MODIFIERS 40
112 #define INSTR_APPLY_INDEX 41
113 #define INSTR_APPLY_INDEX_MODIFIERS 42
114 #define INSTR_APPLY_MODIFIERS_GROUP 43
115 #define INSTR_APPLY_INDEX_GROUP 44
116 #define INSTR_APPLY_INDEX_MODIFIERS_GROUP 45
117 #define INSTR_COMBINE_STRINGS 46
118 #define INSTR_GET_GRIST 64
120 #define INSTR_INCLUDE 47
121 #define INSTR_RULE 48
122 #define INSTR_ACTIONS 49
123 #define INSTR_PUSH_MODULE 50
124 #define INSTR_POP_MODULE 51
125 #define INSTR_CLASS 52
126 #define INSTR_BIND_MODULE_VARIABLES 63
128 #define INSTR_APPEND_STRINGS 53
129 #define INSTR_WRITE_FILE 54
130 #define INSTR_OUTPUT_STRINGS 55
132 #define INSTR_DEBUG_LINE 67
133 #define INSTR_FOR_POP 70
135 typedef struct instruction
141 typedef struct _subfunction
148 typedef struct _subaction
155 #define FUNCTION_BUILTIN 0
156 #define FUNCTION_JAM 1
162 #define ARG_OPTIONAL 1
165 #define ARG_VARIADIC 4
174 struct argument
* args
;
180 int32_t reference_count
;
182 struct arg_list
* formal_arguments
;
183 int32_t num_formal_arguments
;
186 typedef struct _builtin_function
189 LIST
* ( * func
)( FRAME
*, int32_t flags
);
193 typedef struct _jam_function
198 int32_t num_constants
;
199 OBJECT
* * constants
;
200 int32_t num_subfunctions
;
201 SUBFUNCTION
* functions
;
202 int32_t num_subactions
;
212 #define FUNCTION_PYTHON 2
214 typedef struct _python_function
217 PyObject
* python_function
;
220 static LIST
* call_python_function( PYTHON_FUNCTION
*, FRAME
* );
232 STACK
* stack_global()
237 int32_t const size
= 1 << 21;
238 stack
= BJAM_MALLOC( size
);
239 result
.data
= (char *)stack
+ size
;
244 struct list_alignment_helper
250 #define LISTPTR_ALIGN_BASE ( sizeof( struct list_alignment_helper ) - sizeof( LIST * ) )
251 #define LISTPTR_ALIGN ( ( LISTPTR_ALIGN_BASE > sizeof( LIST * ) ) ? sizeof( LIST * ) : LISTPTR_ALIGN_BASE )
253 static void check_alignment( STACK
* s
)
255 assert( (size_t)s
->data
% LISTPTR_ALIGN
== 0 );
258 void * stack_allocate( STACK
* s
, int32_t size
)
260 check_alignment( s
);
261 s
->data
= (char *)s
->data
- size
;
262 check_alignment( s
);
266 void stack_deallocate( STACK
* s
, int32_t size
)
268 check_alignment( s
);
269 s
->data
= (char *)s
->data
+ size
;
270 check_alignment( s
);
273 void stack_push( STACK
* s
, LIST
* l
)
275 *(LIST
* *)stack_allocate( s
, sizeof( LIST
* ) ) = l
;
278 LIST
* stack_pop( STACK
* s
)
280 LIST
* const result
= *(LIST
* *)s
->data
;
281 stack_deallocate( s
, sizeof( LIST
* ) );
285 LIST
* stack_top( STACK
* s
)
287 check_alignment( s
);
288 return *(LIST
* *)s
->data
;
291 LIST
* stack_at( STACK
* s
, int32_t n
)
293 check_alignment( s
);
294 return *( (LIST
* *)s
->data
+ n
);
297 void stack_set( STACK
* s
, int32_t n
, LIST
* value
)
299 check_alignment( s
);
300 *((LIST
* *)s
->data
+ n
) = value
;
303 void * stack_get( STACK
* s
)
305 check_alignment( s
);
309 LIST
* frame_get_local( FRAME
* frame
, int32_t idx
)
311 /* The only local variables are the arguments. */
312 return list_copy( lol_get( frame
->args
, idx
) );
315 static OBJECT
* function_get_constant( JAM_FUNCTION
* function
, int32_t idx
)
317 return function
->constants
[ idx
];
320 static LIST
* function_get_variable( JAM_FUNCTION
* function
, FRAME
* frame
,
323 return list_copy( var_get( frame
->module
, function
->constants
[ idx
] ) );
326 static void function_set_variable( JAM_FUNCTION
* function
, FRAME
* frame
,
327 int32_t idx
, LIST
* value
)
329 var_set( frame
->module
, function
->constants
[ idx
], value
, VAR_SET
);
332 static LIST
* function_swap_variable( JAM_FUNCTION
* function
, FRAME
* frame
,
333 int32_t idx
, LIST
* value
)
335 return var_swap( frame
->module
, function
->constants
[ idx
], value
);
338 static void function_append_variable( JAM_FUNCTION
* function
, FRAME
* frame
,
339 int32_t idx
, LIST
* value
)
341 var_set( frame
->module
, function
->constants
[ idx
], value
, VAR_APPEND
);
344 static void function_default_variable( JAM_FUNCTION
* function
, FRAME
* frame
,
345 int32_t idx
, LIST
* value
)
347 var_set( frame
->module
, function
->constants
[ idx
], value
, VAR_DEFAULT
);
350 static void function_set_rule( JAM_FUNCTION
* function
, FRAME
* frame
,
351 STACK
* s
, int32_t idx
)
353 SUBFUNCTION
* sub
= function
->functions
+ idx
;
354 new_rule_body( frame
->module
, sub
->name
, sub
->code
, !sub
->local
);
357 static void function_set_actions( JAM_FUNCTION
* function
, FRAME
* frame
,
358 STACK
* s
, int32_t idx
)
360 SUBACTION
* sub
= function
->actions
+ idx
;
361 LIST
* bindlist
= stack_pop( s
);
362 new_rule_actions( frame
->module
, sub
->name
, sub
->command
, bindlist
,
368 * Returns the index if name is "<", ">", "1", "2", ... or "19" otherwise
372 static int32_t get_argument_index( char const * s
)
376 if ( s
[ 1 ] == '\0' )
395 else if ( s
[ 0 ] == '1' && s
[ 2 ] == '\0' )
409 return s
[ 1 ] - '0' + 10 - 1;
416 static LIST
* function_get_named_variable( JAM_FUNCTION
* function
,
417 FRAME
* frame
, OBJECT
* name
)
419 int32_t const idx
= get_argument_index( object_str( name
) );
421 ? list_copy( var_get( frame
->module
, name
) )
422 : list_copy( lol_get( frame
->args
, idx
) );
425 static void function_set_named_variable( JAM_FUNCTION
* function
, FRAME
* frame
,
426 OBJECT
* name
, LIST
* value
)
428 var_set( frame
->module
, name
, value
, VAR_SET
);
431 static LIST
* function_swap_named_variable( JAM_FUNCTION
* function
,
432 FRAME
* frame
, OBJECT
* name
, LIST
* value
)
434 return var_swap( frame
->module
, name
, value
);
437 static void function_append_named_variable( JAM_FUNCTION
* function
,
438 FRAME
* frame
, OBJECT
* name
, LIST
* value
)
440 var_set( frame
->module
, name
, value
, VAR_APPEND
);
443 static void function_default_named_variable( JAM_FUNCTION
* function
,
444 FRAME
* frame
, OBJECT
* name
, LIST
* value
)
446 var_set( frame
->module
, name
, value
, VAR_DEFAULT
);
449 static LIST
* function_call_rule( JAM_FUNCTION
* function
, FRAME
* frame
,
450 STACK
* s
, int32_t n_args
, char const * unexpanded
, OBJECT
* file
, int32_t line
)
454 LIST
* first
= stack_pop( s
);
462 if ( list_empty( first
) )
464 backtrace_line( frame
);
465 out_printf( "warning: rulename %s expands to empty string\n", unexpanded
);
468 for ( i
= 0; i
< n_args
; ++i
)
469 list_free( stack_pop( s
) );
473 rulename
= object_copy( list_front( first
) );
477 inner
->prev_user
= frame
->module
->user_module
? frame
: frame
->prev_user
;
478 inner
->module
= frame
->module
; /* This gets fixed up in evaluate_rule(). */
480 if ( n_args
> LOL_MAX
)
482 out_printf( "ERROR: rules are limited to %d arguments\n", LOL_MAX
);
484 b2::clean_exit( EXITBAD
);
487 for ( i
= 0; i
< n_args
; ++i
)
488 lol_add( inner
->args
, stack_at( s
, n_args
- i
- 1 ) );
490 for ( i
= 0; i
< n_args
; ++i
)
493 trailing
= list_pop_front( first
);
496 if ( inner
->args
->count
== 0 )
497 lol_add( inner
->args
, trailing
);
500 LIST
* * const l
= &inner
->args
->list
[ 0 ];
501 *l
= list_append( trailing
, *l
);
505 result
= evaluate_rule( bindrule( rulename
, inner
->module
), rulename
, inner
);
507 object_free( rulename
);
511 static LIST
* function_call_member_rule( JAM_FUNCTION
* function
, FRAME
* frame
, STACK
* s
, int32_t n_args
, OBJECT
* rulename
, OBJECT
* file
, int32_t line
)
515 LIST
* first
= stack_pop( s
);
519 OBJECT
* real_rulename
= 0;
524 if ( list_empty( first
) )
526 backtrace_line( frame
);
527 out_printf( "warning: object is empty\n" );
532 for( i
= 0; i
< n_args
; ++i
)
534 list_free( stack_pop( s
) );
540 /* FIXME: handle generic case */
541 assert( list_length( first
) == 1 );
543 module
= bindmodule( list_front( first
) );
544 if ( module
->class_module
)
546 rule
= bindrule( rulename
, module
);
547 if ( rule
->procedure
)
549 real_rulename
= object_copy( function_rulename( rule
->procedure
) );
555 string_append( buf
, object_str( module
->name
) );
556 string_push_back( buf
, '.' );
557 string_append( buf
, object_str( rulename
) );
558 real_rulename
= object_new( buf
->value
);
566 string_append( buf
, object_str( list_front( first
) ) );
567 string_push_back( buf
, '.' );
568 string_append( buf
, object_str( rulename
) );
569 real_rulename
= object_new( buf
->value
);
571 rule
= bindrule( real_rulename
, frame
->module
);
577 inner
->prev_user
= frame
->module
->user_module
? frame
: frame
->prev_user
;
578 inner
->module
= frame
->module
; /* This gets fixed up in evaluate_rule(), below. */
580 if ( n_args
> LOL_MAX
)
582 out_printf( "ERROR: member rules are limited to %d arguments\n", LOL_MAX
);
584 b2::clean_exit( EXITBAD
);
587 for( i
= 0; i
< n_args
; ++i
)
589 lol_add( inner
->args
, stack_at( s
, n_args
- i
- 1 ) );
592 for( i
= 0; i
< n_args
; ++i
)
597 if ( list_length( first
) > 1 )
600 LIST
* trailing
= L0
;
601 LISTITER iter
= list_begin( first
), end
= list_end( first
);
602 iter
= list_next( iter
);
604 for ( ; iter
!= end
; iter
= list_next( iter
) )
606 string_append( buf
, object_str( list_item( iter
) ) );
607 string_push_back( buf
, '.' );
608 string_append( buf
, object_str( rulename
) );
609 trailing
= list_push_back( trailing
, object_new( buf
->value
) );
610 string_truncate( buf
, 0 );
613 if ( inner
->args
->count
== 0 )
614 lol_add( inner
->args
, trailing
);
617 LIST
* * const l
= &inner
->args
->list
[ 0 ];
618 *l
= list_append( trailing
, *l
);
623 result
= evaluate_rule( rule
, real_rulename
, inner
);
625 object_free( real_rulename
);
630 /* Variable expansion */
640 PATHNAME f
; /* :GDBSMR -- pieces */
641 PATHPART empty
; /* :E -- default for empties */
642 PATHPART join
; /* :J -- join list with char */
643 PATHPART prefix
; /* :< */
644 PATHPART postfix
; /* :> */
645 bool parent
:1; /* :P -- go to parent directory */
646 bool filemods
:1; /* one of the above applied */
647 bool downshift
:1; /* :L -- downshift result */
648 bool upshift
:1; /* :U -- upshift result */
649 bool to_slashes
:1; /* :T -- convert "\" to "/" */
650 bool to_windows
:1; /* :W -- convert cygwin to native paths */
651 bool opt_file
:1; /* :O=F -- replace @() with the file part */
652 bool opt_content
:1; /* :O=C -- repalce @() with the content (E) part */
663 static VAR_EXPANDED
apply_modifiers_impl( LIST
* result
, string
* buf
,
664 VAR_EDITS
* edits
, int32_t n
, LISTITER iter
, LISTITER end
);
665 static void get_iters( subscript_t
const subscript
, LISTITER
* const first
,
666 LISTITER
* const last
, int32_t const length
);
670 * var_edit_parse() - parse : modifiers into PATHNAME structure
672 * The : modifiers in a $(varname:modifier) currently support replacing or
673 * omitting elements of a filename, and so they are parsed into a PATHNAME
674 * structure (which contains pointers into the original string).
676 * Modifiers of the form "X=value" replace the component X with the given value.
677 * Modifiers without the "=value" cause everything but the component X to be
678 * omitted. X is one of:
685 * R root directory - prepended to whole path
691 * -> leave the original component xxx
693 * f->f_xxx.ptr = string
694 * f->f_xxx.len = strlen( string )
695 * -> replace component xxx with string
699 * -> omit component xxx
701 * var_edit_file() below and path_build() obligingly follow this convention.
704 static int32_t var_edit_parse( char const * mods
, VAR_EDITS
* edits
, int32_t havezeroed
714 case 'L': edits
->downshift
= 1; continue;
715 case 'U': edits
->upshift
= 1; continue;
716 case 'P': edits
->parent
= edits
->filemods
= 1; continue;
717 case 'E': fp
= &edits
->empty
; goto strval
;
718 case 'J': fp
= &edits
->join
; goto strval
;
719 case 'G': fp
= &edits
->f
.f_grist
; goto fileval
;
720 case 'R': fp
= &edits
->f
.f_root
; goto fileval
;
721 case 'D': fp
= &edits
->f
.f_dir
; goto fileval
;
722 case 'B': fp
= &edits
->f
.f_base
; goto fileval
;
723 case 'S': fp
= &edits
->f
.f_suffix
; goto fileval
;
724 case 'M': fp
= &edits
->f
.f_member
; goto fileval
;
725 case 'T': edits
->to_slashes
= 1; continue;
726 case 'W': edits
->to_windows
= 1; continue;
727 case '<': fp
= &edits
->prefix
; goto strval
;
728 case '>': fp
= &edits
->postfix
; goto strval
;
729 case 'O': opt
= true; goto strval
;
731 continue; /* Should complain, but so what... */
735 /* Handle :CHARS, where each char (without a following =) selects a
736 * particular file path element. On the first such char, we deselect all
737 * others (by setting ptr = "", len = 0) and for each char we select
738 * that element (by setting ptr = 0).
747 for ( i
= 0; i
< 6; ++i
)
749 edits
->f
.part
[ i
].len
= 0;
750 edits
->f
.part
[ i
].ptr
= "";
764 for (++mods
; *mods
; ++mods
)
768 case 'F': edits
->opt_file
= true; break;
769 case 'C': edits
->opt_content
= true; break;
776 /* Handle :X=value, or :X */
785 fp
->len
= int32_t(strlen( mods
));
796 * var_edit_file() - copy input target name to output, modifying filename.
799 static void var_edit_file( char const * in
, string
* out
, VAR_EDITS
* edits
)
801 if ( edits
->filemods
)
805 /* Parse apart original filename, putting parts into "pathname". */
806 path_parse( in
, &pathname
);
808 /* Replace any pathname with edits->f */
809 if ( edits
->f
.f_grist
.ptr
) pathname
.f_grist
= edits
->f
.f_grist
;
810 if ( edits
->f
.f_root
.ptr
) pathname
.f_root
= edits
->f
.f_root
;
811 if ( edits
->f
.f_dir
.ptr
) pathname
.f_dir
= edits
->f
.f_dir
;
812 if ( edits
->f
.f_base
.ptr
) pathname
.f_base
= edits
->f
.f_base
;
813 if ( edits
->f
.f_suffix
.ptr
) pathname
.f_suffix
= edits
->f
.f_suffix
;
814 if ( edits
->f
.f_member
.ptr
) pathname
.f_member
= edits
->f
.f_member
;
816 /* If requested, modify pathname to point to parent. */
818 path_parent( &pathname
);
820 /* Put filename back together. */
821 path_build( &pathname
, out
);
824 string_append( out
, in
);
828 #if defined( OS_CYGWIN ) || defined( OS_VMS )
831 * var_edit_translate_path() - translate path to os native format.
834 static void var_edit_translate_path( string
* out
, int32_t pos
, VAR_EDITS
* edits
)
836 if ( edits
->to_windows
)
841 /* Translate path to os native format. */
842 translated
= path_translate_to_os( out
->value
+ pos
, result
);
845 string_truncate( out
, pos
);
846 string_append( out
, result
->value
);
847 edits
->to_slashes
= 0;
850 string_free( result
);
858 * var_edit_shift() - do upshift/downshift & other mods.
861 static void var_edit_shift( string
* out
, int32_t pos
, VAR_EDITS
* edits
)
863 #if defined( OS_CYGWIN ) || defined( OS_VMS )
864 var_edit_translate_path( out
, pos
, edits
);
867 if ( edits
->upshift
|| edits
->downshift
|| edits
->to_slashes
)
869 /* Handle upshifting, downshifting and slash translation now. */
871 for ( p
= out
->value
+ pos
; *p
; ++p
)
873 if ( edits
->upshift
)
875 else if ( edits
->downshift
)
877 if ( edits
->to_slashes
&& ( *p
== '\\' ) )
885 * Reads n LISTs from the top of the STACK and combines them to form VAR_EDITS.
886 * Returns the number of VAR_EDITS pushed onto the STACK.
889 static int32_t expand_modifiers( STACK
* s
, int32_t n
)
893 LIST
* * args
= (LIST
**)stack_get( s
);
894 for ( i
= 0; i
< n
; ++i
)
895 total
*= list_length( args
[ i
] );
899 VAR_EDITS
* out
= (VAR_EDITS
*)stack_allocate( s
, total
* sizeof( VAR_EDITS
) );
900 LISTITER
* iter
= (LISTITER
*)stack_allocate( s
, n
* sizeof( LIST
* ) );
901 for ( i
= 0; i
< n
; ++i
)
902 iter
[ i
] = list_begin( args
[ i
] );
907 memset( out
, 0, sizeof( *out
) );
909 for ( i
= 0; i
< n
; ++i
)
910 havezeroed
= var_edit_parse( object_str( list_item( iter
[ i
] )
911 ), out
, havezeroed
);
915 if ( list_next( iter
[ i
] ) != list_end( args
[ i
] ) )
917 iter
[ i
] = list_next( iter
[ i
] );
920 iter
[ i
] = list_begin( args
[ i
] );
923 stack_deallocate( s
, n
* sizeof( LIST
* ) );
928 static VAR_EXPANDED
apply_modifiers( STACK
* s
, int32_t n
)
930 LIST
* value
= stack_top( s
);
932 VAR_EDITS
* const edits
= (VAR_EDITS
*)( (LIST
* *)stack_get( s
) + 1 );
935 result
= apply_modifiers_impl( L0
, buf
, edits
, n
, list_begin( value
),
941 // STACK: LIST * modifiers[modifier_count]
942 static VAR_EXPANDED
eval_modifiers( STACK
* s
, LIST
* value
, int32_t modifier_count
)
944 // Convert modifiers to value edits.
945 int32_t edits
= expand_modifiers( s
, modifier_count
);
946 // Edit the value on the stack.
947 stack_push( s
, value
);
948 VAR_EXPANDED result
= apply_modifiers( s
, edits
);
949 list_free( stack_pop( s
) );
950 // Clean up the value edits on the stack.
951 stack_deallocate( s
, edits
* sizeof( VAR_EDITS
) );
952 // Clean up the filename modifiers.
953 for ( int32_t i
= 0; i
< modifier_count
; ++i
)
954 list_free( stack_pop( s
) );
961 * Parse a string of the form "1-2", "-2--1", "2-" and return the two
965 subscript_t
parse_subscript( char const * s
)
970 do /* so we can use "break" */
972 /* Allow negative subscripts. */
973 if ( !isdigit( *s
) && ( *s
!= '-' ) )
978 result
.sub1
= atoi( s
);
980 /* Skip over the first symbol, which is either a digit or dash. */
982 while ( isdigit( *s
) ) ++s
;
986 result
.sub2
= result
.sub1
;
1004 if ( !isdigit( *s
) && ( *s
!= '-' ) )
1010 /* First, compute the index of the last element. */
1011 result
.sub2
= atoi( s
);
1012 while ( isdigit( *++s
) );
1021 static LIST
* apply_subscript( STACK
* s
)
1023 LIST
* value
= stack_top( s
);
1024 LIST
* indices
= stack_at( s
, 1 );
1026 int32_t length
= list_length( value
);
1028 LISTITER indices_iter
= list_begin( indices
);
1029 LISTITER
const indices_end
= list_end( indices
);
1031 for ( ; indices_iter
!= indices_end
; indices_iter
= list_next( indices_iter
1034 LISTITER iter
= list_begin( value
);
1035 LISTITER end
= list_end( value
);
1036 subscript_t
const subscript
= parse_subscript( object_str( list_item(
1038 get_iters( subscript
, &iter
, &end
, length
);
1039 for ( ; iter
!= end
; iter
= list_next( iter
) )
1040 result
= list_push_back( result
, object_copy( list_item( iter
) ) );
1048 * Reads the LIST from first and applies subscript to it. The results are
1049 * written to *first and *last.
1052 static void get_iters( subscript_t
const subscript
, LISTITER
* const first
,
1053 LISTITER
* const last
, int32_t const length
)
1061 if ( subscript
.sub1
< 0 )
1062 start
= length
+ subscript
.sub1
;
1063 else if ( subscript
.sub1
> length
)
1066 start
= subscript
.sub1
- 1;
1068 size
= subscript
.sub2
< 0
1069 ? length
+ 1 + subscript
.sub2
- start
1070 : subscript
.sub2
- start
;
1073 * HACK: When the first subscript is before the start of the list, it
1074 * magically becomes the beginning of the list. This is inconsistent,
1075 * but needed for backwards compatibility.
1080 /* The "sub2 < 0" test handles the semantic error of sub2 < sub1. */
1084 if ( start
+ size
> length
)
1085 size
= length
- start
;
1089 while ( start
-- > 0 )
1090 iter
= list_next( iter
);
1093 while ( size
-- > 0 )
1094 end
= list_next( end
);
1100 static LIST
* apply_modifiers_prepost( LIST
* result
, string
* buf
,
1101 VAR_EDITS
* edits
, int32_t n
, LISTITER begin
, LISTITER end
)
1103 for ( LISTITER iter
= begin
; iter
!= end
; iter
= list_next( iter
) )
1105 for ( int32_t i
= 0; i
< n
; ++i
)
1107 if ( edits
[ i
].prefix
.ptr
)
1109 string_append( buf
, edits
[ i
].prefix
.ptr
);
1112 string_append( buf
, object_str( list_item( iter
) ) );
1113 for ( int32_t i
= 0; i
< n
; ++i
)
1115 if ( edits
[ i
].postfix
.ptr
)
1117 string_append( buf
, edits
[ i
].postfix
.ptr
);
1120 result
= list_push_back( result
, object_new( buf
->value
) );
1121 string_truncate( buf
, 0 );
1126 static LIST
* apply_modifiers_empty( LIST
* result
, string
* buf
,
1127 VAR_EDITS
* edits
, int32_t n
)
1130 for ( i
= 0; i
< n
; ++i
)
1132 if ( edits
[ i
].empty
.ptr
)
1134 /** FIXME: is empty.ptr always null-terminated? */
1135 var_edit_file( edits
[ i
].empty
.ptr
, buf
, edits
+ i
);
1136 var_edit_shift( buf
, 0, edits
+ i
);
1137 result
= list_push_back( result
, object_new( buf
->value
) );
1138 string_truncate( buf
, 0 );
1144 static LIST
* apply_modifiers_non_empty( LIST
* result
, string
* buf
,
1145 VAR_EDITS
* edits
, int32_t n
, LISTITER begin
, LISTITER end
)
1149 for ( i
= 0; i
< n
; ++i
)
1151 if ( edits
[ i
].join
.ptr
)
1153 var_edit_file( object_str( list_item( begin
) ), buf
, edits
+ i
);
1154 var_edit_shift( buf
, 0, edits
+ i
);
1155 for ( iter
= list_next( begin
); iter
!= end
; iter
= list_next( iter
1159 string_append( buf
, edits
[ i
].join
.ptr
);
1161 var_edit_file( object_str( list_item( iter
) ), buf
, edits
+ i
1163 var_edit_shift( buf
, size
, edits
+ i
);
1165 result
= list_push_back( result
, object_new( buf
->value
) );
1166 string_truncate( buf
, 0 );
1170 for ( iter
= begin
; iter
!= end
; iter
= list_next( iter
) )
1172 var_edit_file( object_str( list_item( iter
) ), buf
, edits
+ i
);
1173 var_edit_shift( buf
, 0, edits
+ i
);
1174 result
= list_push_back( result
, object_new( buf
->value
) );
1175 string_truncate( buf
, 0 );
1182 static VAR_EXPANDED
apply_modifiers_impl( LIST
* result
, string
* buf
,
1183 VAR_EDITS
* edits
, int32_t n
, LISTITER iter
, LISTITER end
)
1185 LIST
* modified
= iter
== end
1186 ? apply_modifiers_empty( result
, buf
, edits
, n
)
1187 : apply_modifiers_non_empty( result
, buf
, edits
, n
, iter
, end
);
1188 VAR_EXPANDED expanded
;
1189 expanded
.value
= apply_modifiers_prepost(
1190 L0
, buf
, edits
, n
, list_begin( modified
), list_end( modified
) );
1191 expanded
.inner
= modified
;
1192 expanded
.opt_file
= false;
1193 expanded
.opt_content
= false;
1194 for ( int32_t i
= 0; i
< n
; ++i
)
1196 expanded
.opt_file
|= edits
[i
].opt_file
;
1197 expanded
.opt_content
|= edits
[i
].opt_content
;
1202 static LIST
* apply_subscript_and_modifiers( STACK
* s
, int32_t n
)
1204 LIST
* const value
= stack_top( s
);
1205 LIST
* const indices
= stack_at( s
, 1 );
1207 VAR_EDITS
* const edits
= (VAR_EDITS
*)((LIST
* *)stack_get( s
) + 2);
1208 int32_t const length
= list_length( value
);
1210 LISTITER indices_iter
= list_begin( indices
);
1211 LISTITER
const indices_end
= list_end( indices
);
1213 for ( ; indices_iter
!= indices_end
; indices_iter
= list_next( indices_iter
1216 LISTITER iter
= list_begin( value
);
1217 LISTITER end
= list_end( value
);
1218 subscript_t
const sub
= parse_subscript( object_str( list_item(
1220 get_iters( sub
, &iter
, &end
, length
);
1221 VAR_EXPANDED modified
1222 = apply_modifiers_impl( result
, buf
, edits
, n
, iter
, end
);
1223 result
= modified
.value
;
1224 list_free( modified
.inner
);
1232 * expand() - expands a list of concatenated strings and variable references
1234 * Takes a list of expansion items - each representing one element to be
1235 * concatenated and each containing a list of its values. Returns a list of all
1236 * possible values constructed by selecting a single value from each of the
1237 * elements and concatenating them together.
1239 * For example, in the following code:
1241 * local a = one two three four ;
1242 * local b = foo bar ;
1243 * ECHO /$(a)/$(b)/$(a)/ ;
1245 * When constructing the result of /$(a)/$(b)/ this function would get called
1246 * with the following 7 expansion items:
1248 * 2. one two three four
1252 * 6. one two three four
1255 * And would result in a list containing 32 values:
1258 * 3. /one/foo/three/
1265 typedef struct expansion_item
1267 /* Item's value list initialized prior to calling expand(). */
1270 /* Internal data initialized and used inside expand(). */
1271 LISTITER current
; /* Currently used value. */
1272 int32_t size
; /* Concatenated string length prior to concatenating the
1273 * item's current value.
1277 static LIST
* expand( expansion_item
* items
, int32_t const length
)
1284 assert( length
> 0 );
1285 for ( i
= 0; i
< length
; ++i
)
1287 LISTITER iter
= list_begin( items
[ i
].values
);
1288 LISTITER
const end
= list_end( items
[ i
].values
);
1290 /* If any of the items has no values - the result is an empty list. */
1291 if ( iter
== end
) return L0
;
1293 /* Set each item's 'current' to its first listed value. This indicates
1294 * each item's next value to be used when constructing the list of all
1295 * possible concatenated values.
1297 items
[ i
].current
= iter
;
1299 /* Calculate the longest concatenated string length - to know how much
1300 * memory we need to allocate as a buffer for holding the concatenated
1305 for ( ; iter
!= end
; iter
= list_next( iter
) )
1307 int32_t const len
= int32_t(strlen( object_str( list_item( iter
) ) ));
1308 if ( len
> max
) max
= len
;
1315 string_reserve( buf
, size
);
1320 for ( ; i
< length
; ++i
)
1322 items
[ i
].size
= buf
->size
;
1323 string_append( buf
, object_str( list_item( items
[ i
].current
) ) );
1325 result
= list_push_back( result
, object_new( buf
->value
) );
1328 if ( list_next( items
[ i
].current
) != list_end( items
[ i
].values
1331 items
[ i
].current
= list_next( items
[ i
].current
);
1332 string_truncate( buf
, items
[ i
].size
);
1336 items
[ i
].current
= list_begin( items
[ i
].values
);
1344 static void combine_strings( STACK
* s
, int32_t n
, string
* out
)
1347 for ( i
= 0; i
< n
; ++i
)
1349 LIST
* const values
= stack_pop( s
);
1350 LISTITER iter
= list_begin( values
);
1351 LISTITER
const end
= list_end( values
);
1354 string_append( out
, object_str( list_item( iter
) ) );
1355 for ( iter
= list_next( iter
); iter
!= end
; iter
= list_next( iter
1358 string_push_back( out
, ' ' );
1359 string_append( out
, object_str( list_item( iter
) ) );
1361 list_free( values
);
1366 struct dynamic_array
1374 static void dynamic_array_init( struct dynamic_array
* array
)
1377 array
->capacity
= 0;
1378 array
->unit_size
= 0;
1382 static void dynamic_array_free( struct dynamic_array
* array
)
1384 BJAM_FREE( array
->data
);
1387 static void dynamic_array_push_impl( struct dynamic_array
* const array
,
1388 void const * const value
, int32_t const unit_size
)
1390 if ( array
->unit_size
== 0 )
1392 array
->unit_size
= unit_size
;
1396 assert( array
->unit_size
== unit_size
);
1398 if ( array
->capacity
== 0 )
1400 array
->capacity
= 2;
1401 array
->data
= BJAM_MALLOC( array
->capacity
* unit_size
);
1403 else if ( array
->capacity
== array
->size
)
1406 array
->capacity
*= 2;
1407 new_data
= BJAM_MALLOC( array
->capacity
* unit_size
);
1408 memcpy( new_data
, array
->data
, array
->size
* unit_size
);
1409 BJAM_FREE( array
->data
);
1410 array
->data
= new_data
;
1412 memcpy( (char *)array
->data
+ array
->size
* unit_size
, value
, unit_size
);
1416 #define dynamic_array_push( array, value ) (dynamic_array_push_impl(array, &value, sizeof(value)))
1417 #define dynamic_array_at( type, array, idx ) ( (assert( array->unit_size == sizeof(type) )) , (((type *)(array)->data)[idx]) )
1418 #define dynamic_array_pop( array ) (--(array)->size)
1426 int32_t absolute_position
;
1427 struct dynamic_array uses
[ 1 ];
1430 #define LOOP_INFO_BREAK 0
1431 #define LOOP_INFO_CONTINUE 1
1437 int32_t cleanup_depth
;
1444 int32_t num_arguments
;
1445 struct arg_list
* arguments
;
1449 typedef struct compiler
1451 struct dynamic_array code
[ 1 ];
1452 struct dynamic_array constants
[ 1 ];
1453 struct dynamic_array labels
[ 1 ];
1454 struct dynamic_array rules
[ 1 ];
1455 struct dynamic_array actions
[ 1 ];
1456 struct dynamic_array cleanups
[ 1 ];
1457 struct dynamic_array loop_scopes
[ 1 ];
1460 static void compiler_init( compiler
* c
)
1462 dynamic_array_init( c
->code
);
1463 dynamic_array_init( c
->constants
);
1464 dynamic_array_init( c
->labels
);
1465 dynamic_array_init( c
->rules
);
1466 dynamic_array_init( c
->actions
);
1467 dynamic_array_init( c
->cleanups
);
1468 dynamic_array_init( c
->loop_scopes
);
1471 static void compiler_free( compiler
* c
)
1474 dynamic_array_free( c
->actions
);
1475 dynamic_array_free( c
->rules
);
1476 for ( i
= 0; i
< c
->labels
->size
; ++i
)
1477 dynamic_array_free( dynamic_array_at( struct label_info
, c
->labels
, i
1479 dynamic_array_free( c
->labels
);
1480 dynamic_array_free( c
->constants
);
1481 dynamic_array_free( c
->code
);
1482 dynamic_array_free( c
->cleanups
);
1483 dynamic_array_free( c
->loop_scopes
);
1486 static void compile_emit_instruction( compiler
* c
, instruction instr
)
1488 dynamic_array_push( c
->code
, instr
);
1491 static int32_t compile_new_label( compiler
* c
)
1493 int32_t result
= c
->labels
->size
;
1494 struct label_info info
;
1495 info
.absolute_position
= -1;
1496 dynamic_array_init( info
.uses
);
1497 dynamic_array_push( c
->labels
, info
);
1501 static void compile_set_label( compiler
* c
, int32_t label
)
1503 struct label_info
* const l
= &dynamic_array_at( struct label_info
,
1505 int32_t const pos
= c
->code
->size
;
1507 assert( l
->absolute_position
== -1 );
1508 l
->absolute_position
= pos
;
1509 for ( i
= 0; i
< l
->uses
->size
; ++i
)
1511 int32_t id
= dynamic_array_at( int32_t, l
->uses
, i
);
1512 int32_t offset
= (int32_t)( pos
- id
- 1 );
1513 dynamic_array_at( instruction
, c
->code
, id
).arg
= offset
;
1517 static void compile_emit( compiler
* c
, uint32_t op_code
, int32_t arg
)
1520 instr
.op_code
= op_code
;
1522 compile_emit_instruction( c
, instr
);
1525 static void compile_emit_branch( compiler
* c
, uint32_t op_code
, int32_t label
)
1527 struct label_info
* const l
= &dynamic_array_at( struct label_info
,
1529 int32_t const pos
= c
->code
->size
;
1531 instr
.op_code
= op_code
;
1532 if ( l
->absolute_position
== -1 )
1535 dynamic_array_push( l
->uses
, pos
);
1538 instr
.arg
= (int32_t)( l
->absolute_position
- pos
- 1 );
1539 compile_emit_instruction( c
, instr
);
1542 static int32_t compile_emit_constant( compiler
* c
, OBJECT
* value
)
1544 OBJECT
* copy
= object_copy( value
);
1545 dynamic_array_push( c
->constants
, copy
);
1546 return c
->constants
->size
- 1;
1549 static void compile_push_cleanup( compiler
* c
, uint32_t op_code
, int32_t arg
)
1552 instr
.op_code
= op_code
;
1554 dynamic_array_push( c
->cleanups
, instr
);
1557 static void compile_pop_cleanup( compiler
* c
)
1559 dynamic_array_pop( c
->cleanups
);
1562 static void compile_emit_cleanups( compiler
* c
, int32_t end
)
1565 for ( i
= c
->cleanups
->size
; --i
>= end
; )
1567 compile_emit_instruction( c
, dynamic_array_at( instruction
, c
->cleanups
, i
) );
1571 static void compile_emit_loop_jump( compiler
* c
, int32_t type
)
1573 struct loop_info
* info
= NULL
;
1575 for ( i
= c
->loop_scopes
->size
; --i
>= 0; )
1577 struct loop_info
* elem
= &dynamic_array_at( struct loop_info
, c
->loop_scopes
, i
);
1578 if ( elem
->type
== type
)
1586 printf( "warning: ignoring break statement used outside of loop\n" );
1589 compile_emit_cleanups( c
, info
->cleanup_depth
);
1590 compile_emit_branch( c
, INSTR_JUMP
, info
->label
);
1593 static void compile_push_break_scope( compiler
* c
, int32_t label
)
1595 struct loop_info info
;
1596 info
.type
= LOOP_INFO_BREAK
;
1598 info
.cleanup_depth
= c
->cleanups
->size
;
1599 dynamic_array_push( c
->loop_scopes
, info
);
1602 static void compile_push_continue_scope( compiler
* c
, int32_t label
)
1604 struct loop_info info
;
1605 info
.type
= LOOP_INFO_CONTINUE
;
1607 info
.cleanup_depth
= c
->cleanups
->size
;
1608 dynamic_array_push( c
->loop_scopes
, info
);
1611 static void compile_pop_break_scope( compiler
* c
)
1613 assert( c
->loop_scopes
->size
> 0 );
1614 assert( dynamic_array_at( struct loop_info
, c
->loop_scopes
, c
->loop_scopes
->size
- 1 ).type
== LOOP_INFO_BREAK
);
1615 dynamic_array_pop( c
->loop_scopes
);
1618 static void compile_pop_continue_scope( compiler
* c
)
1620 assert( c
->loop_scopes
->size
> 0 );
1621 assert( dynamic_array_at( struct loop_info
, c
->loop_scopes
, c
->loop_scopes
->size
- 1 ).type
== LOOP_INFO_CONTINUE
);
1622 dynamic_array_pop( c
->loop_scopes
);
1625 static int32_t compile_emit_rule( compiler
* c
, OBJECT
* name
, PARSE
* parse
,
1626 int32_t num_arguments
, struct arg_list
* arguments
, int32_t local
)
1628 struct stored_rule rule
;
1629 rule
.name
= object_copy( name
);
1631 rule
.num_arguments
= num_arguments
;
1632 rule
.arguments
= arguments
;
1634 dynamic_array_push( c
->rules
, rule
);
1635 return (int32_t)( c
->rules
->size
- 1 );
1638 static int32_t compile_emit_actions( compiler
* c
, PARSE
* parse
)
1641 a
.name
= object_copy( parse
->string
);
1642 a
.command
= function_compile_actions( object_str( parse
->string1
),
1643 parse
->file
, parse
->line
);
1644 a
.flags
= parse
->num
;
1645 dynamic_array_push( c
->actions
, a
);
1646 return (int32_t)( c
->actions
->size
- 1 );
1649 static JAM_FUNCTION
* compile_to_function( compiler
* c
)
1651 JAM_FUNCTION
* const result
= (JAM_FUNCTION
*)BJAM_MALLOC( sizeof( JAM_FUNCTION
) );
1653 result
->base
.type
= FUNCTION_JAM
;
1654 result
->base
.reference_count
= 1;
1655 result
->base
.formal_arguments
= 0;
1656 result
->base
.num_formal_arguments
= 0;
1658 result
->base
.rulename
= 0;
1660 result
->code_size
= c
->code
->size
;
1661 result
->code
= (instruction
*)BJAM_MALLOC( c
->code
->size
* sizeof( instruction
) );
1662 memcpy( result
->code
, c
->code
->data
, c
->code
->size
* sizeof( instruction
) );
1664 result
->constants
= (OBJECT
**)BJAM_MALLOC( c
->constants
->size
* sizeof( OBJECT
* ) );
1665 if ( c
->constants
->size
!= 0 )
1666 memcpy( result
->constants
, c
->constants
->data
,
1667 c
->constants
->size
* sizeof( OBJECT
* ) );
1668 result
->num_constants
= c
->constants
->size
;
1670 result
->num_subfunctions
= c
->rules
->size
;
1671 result
->functions
= (SUBFUNCTION
*)BJAM_MALLOC( c
->rules
->size
* sizeof( SUBFUNCTION
) );
1672 for ( i
= 0; i
< c
->rules
->size
; ++i
)
1674 struct stored_rule
* const rule
= &dynamic_array_at( struct stored_rule
,
1676 result
->functions
[ i
].name
= rule
->name
;
1677 result
->functions
[ i
].code
= function_compile( rule
->parse
);
1678 result
->functions
[ i
].code
->num_formal_arguments
= rule
->num_arguments
;
1679 result
->functions
[ i
].code
->formal_arguments
= rule
->arguments
;
1680 result
->functions
[ i
].local
= rule
->local
;
1683 result
->actions
= (SUBACTION
*)BJAM_MALLOC( c
->actions
->size
* sizeof( SUBACTION
) );
1684 if ( c
->actions
->size
!= 0 )
1685 memcpy( result
->actions
, c
->actions
->data
,
1686 c
->actions
->size
* sizeof( SUBACTION
) );
1687 result
->num_subactions
= c
->actions
->size
;
1689 result
->generic
= 0;
1699 * Parsing of variable expansions
1702 typedef struct VAR_PARSE_GROUP
1704 struct dynamic_array elems
[ 1 ];
1707 typedef struct VAR_PARSE_ACTIONS
1709 struct dynamic_array elems
[ 1 ];
1710 } VAR_PARSE_ACTIONS
;
1712 #define VAR_PARSE_TYPE_VAR 0
1713 #define VAR_PARSE_TYPE_STRING 1
1714 #define VAR_PARSE_TYPE_FILE 2
1716 typedef struct _var_parse
1718 int32_t type
; /* string, variable or file */
1724 VAR_PARSE_GROUP
* name
;
1725 VAR_PARSE_GROUP
* subscript
;
1726 struct dynamic_array modifiers
[ 1 ];
1735 static void var_parse_free( VAR_PARSE
* );
1737 static std::string
var_parse_to_string( VAR_PARSE_STRING
* string
, bool debug
= false );
1738 static std::string
var_parse_to_string( VAR_PARSE_GROUP
* group
, bool debug
= false );
1739 static std::string
var_parse_to_string( VAR_PARSE_VAR
const * parse
, bool debug
= false );
1741 static std::string
var_parse_to_string( VAR_PARSE_STRING
* string
, bool debug
)
1744 if ( debug
) result
+= "'";
1745 result
+= object_str( string
->s
) ? object_str( string
->s
) : "";
1746 if ( debug
) result
+= "'";
1749 static std::string
var_parse_to_string( VAR_PARSE_GROUP
* group
, bool debug
)
1752 if ( debug
) result
+= "[";
1753 for ( int32_t i
= 0; i
< group
->elems
->size
; ++i
)
1755 switch ( dynamic_array_at( VAR_PARSE
*, group
->elems
, i
)->type
)
1757 case VAR_PARSE_TYPE_VAR
:
1758 result
+= var_parse_to_string( dynamic_array_at( VAR_PARSE_VAR
*, group
->elems
, i
), debug
);
1761 case VAR_PARSE_TYPE_STRING
:
1762 result
+= var_parse_to_string( dynamic_array_at( VAR_PARSE_STRING
*, group
->elems
, i
), debug
);
1766 if ( debug
) result
+= "[";
1769 static std::string
var_parse_to_string( VAR_PARSE_VAR
const * parse
, bool debug
)
1771 std::string result
= "$(";
1772 result
+= var_parse_to_string( parse
->name
, debug
);
1773 if ( parse
->subscript
)
1775 result
+= "[" + var_parse_to_string( parse
->subscript
, debug
) + "]";
1777 for ( int32_t i
= 0; i
< parse
->modifiers
->size
; ++i
)
1779 result
+= ":" + var_parse_to_string( dynamic_array_at( VAR_PARSE_GROUP
*, parse
->modifiers
, i
), debug
);
1781 return result
+ ")";
1789 static VAR_PARSE_GROUP
* var_parse_group_new()
1791 VAR_PARSE_GROUP
* const result
= (VAR_PARSE_GROUP
*)BJAM_MALLOC( sizeof( VAR_PARSE_GROUP
) );
1792 dynamic_array_init( result
->elems
);
1796 static void var_parse_group_free( VAR_PARSE_GROUP
* group
)
1799 for ( i
= 0; i
< group
->elems
->size
; ++i
)
1800 var_parse_free( dynamic_array_at( VAR_PARSE
*, group
->elems
, i
) );
1801 dynamic_array_free( group
->elems
);
1805 static void var_parse_group_add( VAR_PARSE_GROUP
* group
, VAR_PARSE
* elem
)
1807 dynamic_array_push( group
->elems
, elem
);
1810 static void var_parse_group_maybe_add_constant( VAR_PARSE_GROUP
* group
,
1811 char const * start
, char const * end
)
1816 VAR_PARSE_STRING
* const value
= (VAR_PARSE_STRING
*)BJAM_MALLOC(
1817 sizeof(VAR_PARSE_STRING
) );
1818 value
->base
.type
= VAR_PARSE_TYPE_STRING
;
1820 string_append_range( buf
, start
, end
);
1821 value
->s
= object_new( buf
->value
);
1823 var_parse_group_add( group
, (VAR_PARSE
*)value
);
1827 VAR_PARSE_STRING
* var_parse_group_as_literal( VAR_PARSE_GROUP
* group
)
1829 if ( group
->elems
->size
== 1 )
1831 VAR_PARSE
* result
= dynamic_array_at( VAR_PARSE
*, group
->elems
, 0 );
1832 if ( result
->type
== VAR_PARSE_TYPE_STRING
)
1833 return (VAR_PARSE_STRING
*)result
;
1843 static VAR_PARSE_ACTIONS
* var_parse_actions_new()
1845 VAR_PARSE_ACTIONS
* const result
= (VAR_PARSE_ACTIONS
*)BJAM_MALLOC(
1846 sizeof(VAR_PARSE_ACTIONS
) );
1847 dynamic_array_init( result
->elems
);
1851 static void var_parse_actions_free( VAR_PARSE_ACTIONS
* actions
)
1854 for ( i
= 0; i
< actions
->elems
->size
; ++i
)
1855 var_parse_group_free( dynamic_array_at( VAR_PARSE_GROUP
*,
1856 actions
->elems
, i
) );
1857 dynamic_array_free( actions
->elems
);
1858 BJAM_FREE( actions
);
1866 static VAR_PARSE_VAR
* var_parse_var_new()
1868 VAR_PARSE_VAR
* result
= (VAR_PARSE_VAR
*)BJAM_MALLOC( sizeof( VAR_PARSE_VAR
) );
1869 result
->base
.type
= VAR_PARSE_TYPE_VAR
;
1870 result
->name
= var_parse_group_new();
1871 result
->subscript
= 0;
1872 dynamic_array_init( result
->modifiers
);
1876 static void var_parse_var_free( VAR_PARSE_VAR
* var
)
1879 var_parse_group_free( var
->name
);
1880 if ( var
->subscript
)
1881 var_parse_group_free( var
->subscript
);
1882 for ( i
= 0; i
< var
->modifiers
->size
; ++i
)
1883 var_parse_group_free( dynamic_array_at( VAR_PARSE_GROUP
*,
1884 var
->modifiers
, i
) );
1885 dynamic_array_free( var
->modifiers
);
1889 static VAR_PARSE_GROUP
* var_parse_var_new_modifier( VAR_PARSE_VAR
* var
)
1891 VAR_PARSE_GROUP
* result
= var_parse_group_new();
1892 dynamic_array_push( var
->modifiers
, result
);
1896 static int32_t var_parse_var_mod_index( VAR_PARSE_VAR
const * var
, char m
)
1898 for ( int32_t i
= 0; i
< var
->modifiers
->size
; ++i
)
1900 VAR_PARSE_GROUP
* mod
= dynamic_array_at( VAR_PARSE_GROUP
*, var
->modifiers
, i
);
1901 VAR_PARSE_STRING
* mod_val
= dynamic_array_at( VAR_PARSE_STRING
*, mod
->elems
, 0 );
1902 const char * mod_str
= object_str(mod_val
->s
);
1903 if (mod_str
&& mod_str
[0] == m
)
1916 static void var_parse_string_free( VAR_PARSE_STRING
* string
)
1918 object_free( string
->s
);
1919 BJAM_FREE( string
);
1927 static void var_parse_free( VAR_PARSE
* parse
)
1929 switch ( parse
->type
)
1931 case VAR_PARSE_TYPE_VAR
:
1932 case VAR_PARSE_TYPE_FILE
:
1933 var_parse_var_free( (VAR_PARSE_VAR
*)parse
);
1936 case VAR_PARSE_TYPE_STRING
:
1937 var_parse_string_free( (VAR_PARSE_STRING
*)parse
);
1941 assert( !"Invalid type" );
1950 static void var_parse_group_compile( VAR_PARSE_GROUP
const * parse
,
1953 static void var_parse_var_compile( VAR_PARSE_VAR
const * parse
, compiler
* c
)
1955 int32_t expand_name
= 0;
1956 int32_t is_get_grist
= 0;
1957 int32_t has_modifiers
= 0;
1958 /* Special case common modifiers */
1959 if ( parse
->modifiers
->size
== 1 )
1961 VAR_PARSE_GROUP
* mod
= dynamic_array_at( VAR_PARSE_GROUP
*, parse
->modifiers
, 0 );
1962 if ( mod
->elems
->size
== 1 )
1964 VAR_PARSE
* mod1
= dynamic_array_at( VAR_PARSE
*, mod
->elems
, 0 );
1965 if ( mod1
->type
== VAR_PARSE_TYPE_STRING
)
1967 OBJECT
* s
= ( (VAR_PARSE_STRING
*)mod1
)->s
;
1968 if ( ! strcmp ( object_str( s
), "G" ) )
1975 /* If there are modifiers, emit them in reverse order. */
1976 if ( parse
->modifiers
->size
> 0 && !is_get_grist
)
1980 for ( i
= 0; i
< parse
->modifiers
->size
; ++i
)
1981 var_parse_group_compile( dynamic_array_at( VAR_PARSE_GROUP
*,
1982 parse
->modifiers
, parse
->modifiers
->size
- i
- 1 ), c
);
1985 /* If there is a subscript, emit it. */
1986 if ( parse
->subscript
)
1987 var_parse_group_compile( parse
->subscript
, c
);
1989 /* If the variable name is empty, look it up. */
1990 if ( parse
->name
->elems
->size
== 0 )
1991 compile_emit( c
, INSTR_PUSH_VAR
, compile_emit_constant( c
,
1993 /* If the variable name does not need to be expanded, look it up. */
1994 else if ( parse
->name
->elems
->size
== 1 && dynamic_array_at( VAR_PARSE
*,
1995 parse
->name
->elems
, 0 )->type
== VAR_PARSE_TYPE_STRING
)
1997 OBJECT
* const name
= ( (VAR_PARSE_STRING
*)dynamic_array_at(
1998 VAR_PARSE
*, parse
->name
->elems
, 0 ) )->s
;
1999 int32_t const idx
= get_argument_index( object_str( name
) );
2001 compile_emit( c
, INSTR_PUSH_ARG
, idx
);
2003 compile_emit( c
, INSTR_PUSH_VAR
, compile_emit_constant( c
, name
) );
2005 /* Otherwise, push the var names and use the group instruction. */
2008 var_parse_group_compile( parse
->name
, c
);
2012 /** Select the instruction for expanding the variable. */
2013 if ( !has_modifiers
&& !parse
->subscript
&& !expand_name
)
2015 else if ( !has_modifiers
&& !parse
->subscript
&& expand_name
)
2016 compile_emit( c
, INSTR_PUSH_GROUP
, 0 );
2017 else if ( !has_modifiers
&& parse
->subscript
&& !expand_name
)
2018 compile_emit( c
, INSTR_APPLY_INDEX
, 0 );
2019 else if ( !has_modifiers
&& parse
->subscript
&& expand_name
)
2020 compile_emit( c
, INSTR_APPLY_INDEX_GROUP
, 0 );
2021 else if ( has_modifiers
&& !parse
->subscript
&& !expand_name
)
2022 compile_emit( c
, INSTR_APPLY_MODIFIERS
, parse
->modifiers
->size
);
2023 else if ( has_modifiers
&& !parse
->subscript
&& expand_name
)
2024 compile_emit( c
, INSTR_APPLY_MODIFIERS_GROUP
, parse
->modifiers
->size
);
2025 else if ( has_modifiers
&& parse
->subscript
&& !expand_name
)
2026 compile_emit( c
, INSTR_APPLY_INDEX_MODIFIERS
, parse
->modifiers
->size
);
2027 else if ( has_modifiers
&& parse
->subscript
&& expand_name
)
2028 compile_emit( c
, INSTR_APPLY_INDEX_MODIFIERS_GROUP
,
2029 parse
->modifiers
->size
);
2031 /* Now apply any special modifiers */
2034 compile_emit( c
, INSTR_GET_GRIST
, 0 );
2038 static void var_parse_string_compile( VAR_PARSE_STRING
const * parse
,
2041 compile_emit( c
, INSTR_PUSH_CONSTANT
, compile_emit_constant( c
, parse
->s
)
2045 static void parse_var_string( char const * first
, char const * last
,
2046 struct dynamic_array
* out
);
2048 static void var_parse_file_compile( VAR_PARSE_VAR
const * parse
, compiler
* c
)
2050 std::string var
= var_parse_to_string( parse
, true );
2051 int32_t empty_mod_index
= var_parse_var_mod_index( parse
, 'E' );
2052 int32_t grist_mod_index
= var_parse_var_mod_index( parse
, 'G' );
2053 int32_t modifier_count
= 0;
2054 // Push the contents, aka the edit modifier value.
2056 assert( empty_mod_index
>= 0 );
2057 // We reparse the edit modifier as we do teh expansion differently than
2058 // regular var expansion.
2059 std::string contents_val
= var_parse_to_string(
2061 VAR_PARSE_GROUP
*, parse
->modifiers
, empty_mod_index
), false );
2062 dynamic_array contents_dyn_array
;
2063 dynamic_array_init( &contents_dyn_array
);
2065 contents_val
.c_str() + 2, contents_val
.c_str() + contents_val
.size(),
2066 &contents_dyn_array
);
2067 for ( int32_t i
= contents_dyn_array
.size
- 1; i
>= 0; --i
)
2069 auto group
= dynamic_array_at(
2070 VAR_PARSE_GROUP
*, ( &contents_dyn_array
), i
);
2071 var_parse_group_compile( group
, c
);
2072 var_parse_group_free( group
);
2074 dynamic_array_free( &contents_dyn_array
);
2075 compile_emit( c
, INSTR_APPEND_STRINGS
, contents_dyn_array
.size
);
2077 // If there are modifiers, emit them in reverse order.
2078 if ( parse
->modifiers
->size
> 0 )
2080 for ( int32_t i
= parse
->modifiers
->size
- 1; i
>= 0; --i
)
2082 // Skip special modifiers.
2083 if ( i
== empty_mod_index
|| i
== grist_mod_index
) continue;
2084 modifier_count
+= 1;
2085 var_parse_group_compile(
2086 dynamic_array_at( VAR_PARSE_GROUP
*, parse
->modifiers
, i
), c
);
2089 // Push the filename, aka var name.
2090 var_parse_group_compile( parse
->name
, c
);
2091 // This instruction applies the modifiers and writes out the file and fills
2092 // in the file name.
2093 compile_emit( c
, INSTR_WRITE_FILE
, modifier_count
);
2096 static void var_parse_compile( VAR_PARSE
const * parse
, compiler
* c
)
2098 switch ( parse
->type
)
2100 case VAR_PARSE_TYPE_VAR
:
2101 var_parse_var_compile( (VAR_PARSE_VAR
const *)parse
, c
);
2104 case VAR_PARSE_TYPE_STRING
:
2105 var_parse_string_compile( (VAR_PARSE_STRING
const *)parse
, c
);
2108 case VAR_PARSE_TYPE_FILE
:
2109 var_parse_file_compile( (VAR_PARSE_VAR
const *)parse
, c
);
2113 assert( !"Unknown var parse type." );
2117 static void var_parse_group_compile( VAR_PARSE_GROUP
const * parse
, compiler
* c
2120 /* Emit the elements in reverse order. */
2122 for ( i
= 0; i
< parse
->elems
->size
; ++i
)
2123 var_parse_compile( dynamic_array_at( VAR_PARSE
*, parse
->elems
,
2124 parse
->elems
->size
- i
- 1 ), c
);
2125 /* If there are no elements, emit an empty string. */
2126 if ( parse
->elems
->size
== 0 )
2127 compile_emit( c
, INSTR_PUSH_CONSTANT
, compile_emit_constant( c
,
2129 /* If there is more than one element, combine them. */
2130 if ( parse
->elems
->size
> 1 )
2131 compile_emit( c
, INSTR_COMBINE_STRINGS
, parse
->elems
->size
);
2134 static void var_parse_actions_compile( VAR_PARSE_ACTIONS
const * actions
,
2138 for ( i
= 0; i
< actions
->elems
->size
; ++i
)
2139 var_parse_group_compile( dynamic_array_at( VAR_PARSE_GROUP
*,
2140 actions
->elems
, actions
->elems
->size
- i
- 1 ), c
);
2141 compile_emit( c
, INSTR_OUTPUT_STRINGS
, actions
->elems
->size
);
2146 * Parse VAR_PARSE_VAR
2149 static VAR_PARSE
* parse_variable( char const * * string
);
2150 static int32_t try_parse_variable( char const * * s_
, char const * * string
,
2151 VAR_PARSE_GROUP
* out
);
2152 static void balance_parentheses( char const * * s_
, char const * * string
,
2153 VAR_PARSE_GROUP
* out
);
2154 static void parse_var_string( char const * first
, char const * last
,
2155 struct dynamic_array
* out
);
2159 * Parses a string that can contain variables to expand.
2162 static VAR_PARSE_GROUP
* parse_expansion( char const * * string
)
2164 VAR_PARSE_GROUP
* result
= var_parse_group_new();
2165 char const * s
= *string
;
2168 if ( try_parse_variable( &s
, string
, result
) ) {}
2169 else if ( s
[ 0 ] == '\0' )
2171 var_parse_group_maybe_add_constant( result
, *string
, s
);
2179 static VAR_PARSE_ACTIONS
* parse_actions( char const * string
)
2181 VAR_PARSE_ACTIONS
* const result
= var_parse_actions_new();
2182 parse_var_string( string
, string
+ strlen( string
), result
->elems
);
2187 * Checks whether the string a *s_ starts with a variable expansion "$(".
2188 * *string should point to the first unemitted character before *s. If *s_
2189 * starts with variable expansion, appends elements to out up to the closing
2190 * ")", and adjusts *s_ and *string to point to next character. Returns 1 if s_
2191 * starts with a variable, 0 otherwise.
2194 static int32_t try_parse_variable( char const * * s_
, char const * * string
,
2195 VAR_PARSE_GROUP
* out
)
2197 char const * s
= *s_
;
2198 if ( s
[ 0 ] == '$' && s
[ 1 ] == '(' )
2200 var_parse_group_maybe_add_constant( out
, *string
, s
);
2202 var_parse_group_add( out
, parse_variable( &s
) );
2207 if ( s
[ 0 ] == '@' && s
[ 1 ] == '(' )
2209 var_parse_group_maybe_add_constant( out
, *string
, s
);
2211 VAR_PARSE_VAR
*vp
= (VAR_PARSE_VAR
*)parse_variable( &s
);
2212 /* We at least need the empty (:E) modifier. */
2213 if (var_parse_var_mod_index(vp
, 'E') >= 0)
2215 vp
->base
.type
= VAR_PARSE_TYPE_FILE
;
2216 var_parse_group_add( out
, (VAR_PARSE
*)vp
);
2223 var_parse_var_free( vp
);
2230 static char const * current_file
= "";
2231 static int32_t current_line
;
2233 static void parse_error( char const * message
)
2235 out_printf( "%s:%d: %s\n", current_file
, current_line
, message
);
2240 * Parses a single variable up to the closing ")" and adjusts *string to point
2241 * to the next character. *string should point to the character immediately
2242 * after the initial "$(".
2245 static VAR_PARSE
* parse_variable( char const * * string
)
2247 VAR_PARSE_VAR
* const result
= var_parse_var_new();
2248 VAR_PARSE_GROUP
* const name
= result
->name
;
2249 char const * s
= *string
;
2252 if ( try_parse_variable( &s
, string
, name
) ) {}
2253 else if ( s
[ 0 ] == ':' )
2255 VAR_PARSE_GROUP
* mod
;
2256 var_parse_group_maybe_add_constant( name
, *string
, s
);
2259 mod
= var_parse_var_new_modifier( result
);
2262 if ( try_parse_variable( &s
, string
, mod
) ) {}
2263 else if ( s
[ 0 ] == ')' )
2265 var_parse_group_maybe_add_constant( mod
, *string
, s
);
2267 return (VAR_PARSE
*)result
;
2269 else if ( s
[ 0 ] == '(' )
2272 balance_parentheses( &s
, string
, mod
);
2274 else if ( s
[ 0 ] == ':' )
2276 var_parse_group_maybe_add_constant( mod
, *string
, s
);
2278 mod
= var_parse_var_new_modifier( result
);
2280 else if ( s
[ 0 ] == '[' )
2282 parse_error("unexpected subscript");
2285 else if ( s
[ 0 ] == '\0' )
2287 parse_error( "unbalanced parentheses" );
2288 var_parse_group_maybe_add_constant( mod
, *string
, s
);
2290 return (VAR_PARSE
*)result
;
2296 else if ( s
[ 0 ] == '[' )
2298 VAR_PARSE_GROUP
* subscript
= var_parse_group_new();
2299 result
->subscript
= subscript
;
2300 var_parse_group_maybe_add_constant( name
, *string
, s
);
2304 if ( try_parse_variable( &s
, string
, subscript
) ) {}
2305 else if ( s
[ 0 ] == ']' )
2307 var_parse_group_maybe_add_constant( subscript
, *string
, s
);
2309 if ( s
[ 0 ] != ')' && s
[ 0 ] != ':' && s
[ 0 ] != '\0' )
2310 parse_error( "unexpected text following []" );
2313 else if ( isdigit( s
[ 0 ] ) || s
[ 0 ] == '-' )
2317 else if ( s
[ 0 ] == '\0' )
2319 parse_error( "malformed subscript" );
2324 parse_error( "malformed subscript" );
2329 else if ( s
[ 0 ] == ')' )
2331 var_parse_group_maybe_add_constant( name
, *string
, s
);
2333 return (VAR_PARSE
*)result
;
2335 else if ( s
[ 0 ] == '(' )
2338 balance_parentheses( &s
, string
, name
);
2340 else if ( s
[ 0 ] == '\0' )
2342 parse_error( "unbalanced parentheses" );
2343 var_parse_group_maybe_add_constant( name
, *string
, s
);
2345 return (VAR_PARSE
*)result
;
2352 static void parse_var_string( char const * first
, char const * last
,
2353 struct dynamic_array
* out
)
2355 char const * saved
= first
;
2356 while ( first
!= last
)
2358 /* Handle whitespace. */
2359 while ( first
!= last
&& isspace( *first
) ) ++first
;
2360 if ( saved
!= first
)
2362 VAR_PARSE_GROUP
* const group
= var_parse_group_new();
2363 var_parse_group_maybe_add_constant( group
, saved
, first
);
2365 dynamic_array_push( out
, group
);
2367 if ( first
== last
) break;
2369 /* Handle non-whitespace */
2371 VAR_PARSE_GROUP
* group
= var_parse_group_new();
2374 if ( first
== last
|| isspace( *first
) )
2376 var_parse_group_maybe_add_constant( group
, saved
, first
);
2380 if ( try_parse_variable( &first
, &saved
, group
) )
2381 assert( first
<= last
);
2385 dynamic_array_push( out
, group
);
2391 * Given that *s_ points to the character after a "(", parses up to the matching
2392 * ")". *string should point to the first unemitted character before *s_.
2394 * When the function returns, *s_ will point to the character after the ")", and
2395 * *string will point to the first unemitted character before *s_. The range
2396 * from *string to *s_ does not contain any variables that need to be expanded.
2399 void balance_parentheses( char const * * s_
, char const * * string
,
2400 VAR_PARSE_GROUP
* out
)
2403 char const * s
= *s_
;
2406 if ( try_parse_variable( &s
, string
, out
) ) { }
2407 else if ( s
[ 0 ] == ':' || s
[ 0 ] == '[' )
2409 parse_error( "unbalanced parentheses" );
2412 else if ( s
[ 0 ] == '\0' )
2414 parse_error( "unbalanced parentheses" );
2417 else if ( s
[ 0 ] == ')' )
2420 if ( --depth
== 0 ) break;
2422 else if ( s
[ 0 ] == '(' )
2438 #define RESULT_STACK 0
2439 #define RESULT_RETURN 1
2440 #define RESULT_NONE 2
2442 static void compile_parse( PARSE
* parse
, compiler
* c
, int32_t result_location
);
2443 static struct arg_list
* arg_list_compile( PARSE
* parse
, int32_t * num_arguments
);
2445 static void compile_condition( PARSE
* parse
, compiler
* c
, int32_t branch_true
, int32_t label
)
2447 assert( parse
->type
== PARSE_EVAL
);
2448 switch ( parse
->num
)
2451 compile_parse( parse
->left
, c
, RESULT_STACK
);
2453 compile_emit_branch( c
, INSTR_JUMP_NOT_EMPTY
, label
);
2455 compile_emit_branch( c
, INSTR_JUMP_EMPTY
, label
);
2459 compile_parse( parse
->left
, c
, RESULT_STACK
);
2460 compile_parse( parse
->right
, c
, RESULT_STACK
);
2462 compile_emit_branch( c
, INSTR_JUMP_EQ
, label
);
2464 compile_emit_branch( c
, INSTR_JUMP_NE
, label
);
2468 compile_parse( parse
->left
, c
, RESULT_STACK
);
2469 compile_parse( parse
->right
, c
, RESULT_STACK
);
2471 compile_emit_branch( c
, INSTR_JUMP_NE
, label
);
2473 compile_emit_branch( c
, INSTR_JUMP_EQ
, label
);
2477 compile_parse( parse
->left
, c
, RESULT_STACK
);
2478 compile_parse( parse
->right
, c
, RESULT_STACK
);
2480 compile_emit_branch( c
, INSTR_JUMP_LT
, label
);
2482 compile_emit_branch( c
, INSTR_JUMP_GE
, label
);
2486 compile_parse( parse
->left
, c
, RESULT_STACK
);
2487 compile_parse( parse
->right
, c
, RESULT_STACK
);
2489 compile_emit_branch( c
, INSTR_JUMP_LE
, label
);
2491 compile_emit_branch( c
, INSTR_JUMP_GT
, label
);
2495 compile_parse( parse
->left
, c
, RESULT_STACK
);
2496 compile_parse( parse
->right
, c
, RESULT_STACK
);
2498 compile_emit_branch( c
, INSTR_JUMP_GT
, label
);
2500 compile_emit_branch( c
, INSTR_JUMP_LE
, label
);
2504 compile_parse( parse
->left
, c
, RESULT_STACK
);
2505 compile_parse( parse
->right
, c
, RESULT_STACK
);
2507 compile_emit_branch( c
, INSTR_JUMP_GE
, label
);
2509 compile_emit_branch( c
, INSTR_JUMP_LT
, label
);
2513 compile_parse( parse
->left
, c
, RESULT_STACK
);
2514 compile_parse( parse
->right
, c
, RESULT_STACK
);
2516 compile_emit_branch( c
, INSTR_JUMP_IN
, label
);
2518 compile_emit_branch( c
, INSTR_JUMP_NOT_IN
, label
);
2524 int32_t f
= compile_new_label( c
);
2525 compile_condition( parse
->left
, c
, 0, f
);
2526 compile_condition( parse
->right
, c
, 1, label
);
2527 compile_set_label( c
, f
);
2531 compile_condition( parse
->left
, c
, 0, label
);
2532 compile_condition( parse
->right
, c
, 0, label
);
2539 compile_condition( parse
->left
, c
, 1, label
);
2540 compile_condition( parse
->right
, c
, 1, label
);
2544 int32_t t
= compile_new_label( c
);
2545 compile_condition( parse
->left
, c
, 1, t
);
2546 compile_condition( parse
->right
, c
, 0, label
);
2547 compile_set_label( c
, t
);
2552 compile_condition( parse
->left
, c
, !branch_true
, label
);
2557 static void adjust_result( compiler
* c
, int32_t actual_location
,
2558 int32_t desired_location
)
2560 if ( actual_location
== desired_location
)
2562 else if ( actual_location
== RESULT_STACK
&& desired_location
== RESULT_RETURN
)
2563 compile_emit( c
, INSTR_SET_RESULT
, 0 );
2564 else if ( actual_location
== RESULT_STACK
&& desired_location
== RESULT_NONE
)
2565 compile_emit( c
, INSTR_POP
, 0 );
2566 else if ( actual_location
== RESULT_RETURN
&& desired_location
== RESULT_STACK
)
2567 compile_emit( c
, INSTR_PUSH_RESULT
, 0 );
2568 else if ( actual_location
== RESULT_RETURN
&& desired_location
== RESULT_NONE
)
2570 else if ( actual_location
== RESULT_NONE
&& desired_location
== RESULT_STACK
)
2571 compile_emit( c
, INSTR_PUSH_EMPTY
, 0 );
2572 else if ( actual_location
== RESULT_NONE
&& desired_location
== RESULT_RETURN
)
2574 compile_emit( c
, INSTR_PUSH_EMPTY
, 0 );
2575 compile_emit( c
, INSTR_SET_RESULT
, 0 );
2578 assert( !"invalid result location" );
2581 static void compile_append_chain( PARSE
* parse
, compiler
* c
)
2583 assert( parse
->type
== PARSE_APPEND
);
2584 if ( parse
->left
->type
== PARSE_NULL
)
2585 compile_parse( parse
->right
, c
, RESULT_STACK
);
2588 if ( parse
->left
->type
== PARSE_APPEND
)
2589 compile_append_chain( parse
->left
, c
);
2591 compile_parse( parse
->left
, c
, RESULT_STACK
);
2592 compile_parse( parse
->right
, c
, RESULT_STACK
);
2593 compile_emit( c
, INSTR_PUSH_APPEND
, 0 );
2597 static void compile_emit_debug(compiler
* c
, int32_t line
)
2600 if ( debug_is_debugging() )
2601 compile_emit( c
, INSTR_DEBUG_LINE
, line
);
2605 static void compile_parse( PARSE
* parse
, compiler
* c
, int32_t result_location
)
2607 compile_emit_debug(c
, parse
->line
);
2608 if ( parse
->type
== PARSE_APPEND
)
2610 compile_append_chain( parse
, c
);
2611 adjust_result( c
, RESULT_STACK
, result_location
);
2613 else if ( parse
->type
== PARSE_EVAL
)
2615 /* FIXME: This is only needed because of the bizarre parsing of
2618 if ( parse
->num
== EXPR_EXISTS
)
2619 compile_parse( parse
->left
, c
, result_location
);
2622 int32_t f
= compile_new_label( c
);
2623 int32_t end
= compile_new_label( c
);
2625 out_printf( "%s:%d: Conditional used as list (check operator "
2626 "precedence).\n", object_str( parse
->file
), parse
->line
);
2628 /* Emit the condition */
2629 compile_condition( parse
, c
, 0, f
);
2630 compile_emit( c
, INSTR_PUSH_CONSTANT
, compile_emit_constant( c
,
2632 compile_emit_branch( c
, INSTR_JUMP
, end
);
2633 compile_set_label( c
, f
);
2634 compile_emit( c
, INSTR_PUSH_EMPTY
, 0 );
2635 compile_set_label( c
, end
);
2636 adjust_result( c
, RESULT_STACK
, result_location
);
2639 else if ( parse
->type
== PARSE_FOREACH
)
2641 int32_t var
= compile_emit_constant( c
, parse
->string
);
2642 int32_t top
= compile_new_label( c
);
2643 int32_t end
= compile_new_label( c
);
2644 int32_t continue_
= compile_new_label( c
);
2647 * Evaluate the list.
2649 compile_parse( parse
->left
, c
, RESULT_STACK
);
2651 /* Localize the loop variable */
2654 compile_emit( c
, INSTR_PUSH_EMPTY
, 0 );
2655 compile_emit( c
, INSTR_PUSH_LOCAL
, var
);
2656 compile_emit( c
, INSTR_SWAP
, 1 );
2657 compile_push_cleanup( c
, INSTR_POP_LOCAL
, var
);
2660 compile_emit( c
, INSTR_FOR_INIT
, 0 );
2661 compile_set_label( c
, top
);
2662 compile_emit_branch( c
, INSTR_FOR_LOOP
, end
);
2663 compile_emit_debug( c
, parse
->line
);
2664 compile_emit( c
, INSTR_SET
, var
);
2666 compile_push_break_scope( c
, end
);
2667 compile_push_cleanup( c
, INSTR_FOR_POP
, 0 );
2668 compile_push_continue_scope( c
, continue_
);
2670 /* Run the loop body */
2671 compile_parse( parse
->right
, c
, RESULT_NONE
);
2673 compile_pop_continue_scope( c
);
2674 compile_pop_cleanup( c
);
2675 compile_pop_break_scope( c
);
2677 compile_set_label( c
, continue_
);
2678 compile_emit_branch( c
, INSTR_JUMP
, top
);
2679 compile_set_label( c
, end
);
2683 compile_pop_cleanup( c
);
2684 compile_emit( c
, INSTR_POP_LOCAL
, var
);
2687 adjust_result( c
, RESULT_NONE
, result_location
);
2689 else if ( parse
->type
== PARSE_IF
)
2691 int32_t f
= compile_new_label( c
);
2692 /* Emit the condition */
2693 compile_condition( parse
->left
, c
, 0, f
);
2694 /* Emit the if block */
2695 compile_parse( parse
->right
, c
, result_location
);
2696 if ( parse
->third
->type
!= PARSE_NULL
|| result_location
!= RESULT_NONE
)
2698 /* Emit the else block */
2699 int32_t end
= compile_new_label( c
);
2700 compile_emit_branch( c
, INSTR_JUMP
, end
);
2701 compile_set_label( c
, f
);
2702 compile_parse( parse
->third
, c
, result_location
);
2703 compile_set_label( c
, end
);
2706 compile_set_label( c
, f
);
2709 else if ( parse
->type
== PARSE_WHILE
)
2711 int32_t nested_result
= result_location
== RESULT_NONE
2714 int32_t test
= compile_new_label( c
);
2715 int32_t top
= compile_new_label( c
);
2716 int32_t end
= compile_new_label( c
);
2717 /* Make sure that we return an empty list if the loop runs zero times.
2719 adjust_result( c
, RESULT_NONE
, nested_result
);
2720 /* Jump to the loop test. */
2721 compile_emit_branch( c
, INSTR_JUMP
, test
);
2722 compile_set_label( c
, top
);
2723 /* Emit the loop body. */
2724 compile_push_break_scope( c
, end
);
2725 compile_push_continue_scope( c
, test
);
2726 compile_parse( parse
->right
, c
, nested_result
);
2727 compile_pop_continue_scope( c
);
2728 compile_pop_break_scope( c
);
2729 /* Emit the condition. */
2730 compile_set_label( c
, test
);
2731 compile_condition( parse
->left
, c
, 1, top
);
2732 compile_set_label( c
, end
);
2734 adjust_result( c
, nested_result
, result_location
);
2736 else if ( parse
->type
== PARSE_INCLUDE
)
2738 compile_parse( parse
->left
, c
, RESULT_STACK
);
2739 compile_emit( c
, INSTR_INCLUDE
, 0 );
2740 compile_emit( c
, INSTR_BIND_MODULE_VARIABLES
, 0 );
2741 adjust_result( c
, RESULT_NONE
, result_location
);
2743 else if ( parse
->type
== PARSE_MODULE
)
2745 int32_t const nested_result
= result_location
== RESULT_NONE
2748 compile_parse( parse
->left
, c
, RESULT_STACK
);
2749 compile_emit( c
, INSTR_PUSH_MODULE
, 0 );
2750 compile_push_cleanup( c
, INSTR_POP_MODULE
, 0 );
2751 compile_parse( parse
->right
, c
, nested_result
);
2752 compile_pop_cleanup( c
);
2753 compile_emit( c
, INSTR_POP_MODULE
, 0 );
2754 adjust_result( c
, nested_result
, result_location
);
2756 else if ( parse
->type
== PARSE_CLASS
)
2758 /* Evaluate the class name. */
2759 compile_parse( parse
->left
->right
, c
, RESULT_STACK
);
2760 /* Evaluate the base classes. */
2761 if ( parse
->left
->left
)
2762 compile_parse( parse
->left
->left
->right
, c
, RESULT_STACK
);
2764 compile_emit( c
, INSTR_PUSH_EMPTY
, 0 );
2765 compile_emit( c
, INSTR_CLASS
, 0 );
2766 compile_push_cleanup( c
, INSTR_POP_MODULE
, 0 );
2767 compile_parse( parse
->right
, c
, RESULT_NONE
);
2768 compile_emit( c
, INSTR_BIND_MODULE_VARIABLES
, 0 );
2769 compile_pop_cleanup( c
);
2770 compile_emit( c
, INSTR_POP_MODULE
, 0 );
2772 adjust_result( c
, RESULT_NONE
, result_location
);
2774 else if ( parse
->type
== PARSE_LIST
)
2776 OBJECT
* const o
= parse
->string
;
2777 char const * s
= object_str( o
);
2778 VAR_PARSE_GROUP
* group
;
2779 current_file
= object_str( parse
->file
);
2780 current_line
= parse
->line
;
2781 group
= parse_expansion( &s
);
2782 var_parse_group_compile( group
, c
);
2783 var_parse_group_free( group
);
2784 adjust_result( c
, RESULT_STACK
, result_location
);
2786 else if ( parse
->type
== PARSE_LOCAL
)
2788 int32_t nested_result
= result_location
== RESULT_NONE
2791 /* This should be left recursive group of compile_appends. */
2792 PARSE
* vars
= parse
->left
;
2794 /* Special case an empty list of vars */
2795 if ( vars
->type
== PARSE_NULL
)
2797 compile_parse( parse
->right
, c
, RESULT_NONE
);
2798 compile_parse( parse
->third
, c
, result_location
);
2799 nested_result
= result_location
;
2801 /* Check whether there is exactly one variable with a constant name. */
2802 else if ( vars
->left
->type
== PARSE_NULL
&&
2803 vars
->right
->type
== PARSE_LIST
)
2805 char const * s
= object_str( vars
->right
->string
);
2806 VAR_PARSE_GROUP
* group
;
2807 current_file
= object_str( parse
->file
);
2808 current_line
= parse
->line
;
2809 group
= parse_expansion( &s
);
2810 if ( group
->elems
->size
== 1 && dynamic_array_at( VAR_PARSE
*,
2811 group
->elems
, 0 )->type
== VAR_PARSE_TYPE_STRING
)
2813 int32_t const name
= compile_emit_constant( c
, (
2814 (VAR_PARSE_STRING
*)dynamic_array_at( VAR_PARSE
*,
2815 group
->elems
, 0 ) )->s
);
2816 var_parse_group_free( group
);
2817 compile_parse( parse
->right
, c
, RESULT_STACK
);
2818 compile_emit_debug(c
, parse
->line
);
2819 compile_emit( c
, INSTR_PUSH_LOCAL
, name
);
2820 compile_push_cleanup( c
, INSTR_POP_LOCAL
, name
);
2821 compile_parse( parse
->third
, c
, nested_result
);
2822 compile_pop_cleanup( c
);
2823 compile_emit( c
, INSTR_POP_LOCAL
, name
);
2827 var_parse_group_compile( group
, c
);
2828 var_parse_group_free( group
);
2829 compile_parse( parse
->right
, c
, RESULT_STACK
);
2830 compile_emit_debug(c
, parse
->line
);
2831 compile_emit( c
, INSTR_PUSH_LOCAL_GROUP
, 0 );
2832 compile_push_cleanup( c
, INSTR_POP_LOCAL_GROUP
, 0 );
2833 compile_parse( parse
->third
, c
, nested_result
);
2834 compile_pop_cleanup( c
);
2835 compile_emit( c
, INSTR_POP_LOCAL_GROUP
, 0 );
2840 compile_parse( parse
->left
, c
, RESULT_STACK
);
2841 compile_parse( parse
->right
, c
, RESULT_STACK
);
2842 compile_emit_debug(c
, parse
->line
);
2843 compile_emit( c
, INSTR_PUSH_LOCAL_GROUP
, 0 );
2844 compile_push_cleanup( c
, INSTR_POP_LOCAL_GROUP
, 0 );
2845 compile_parse( parse
->third
, c
, nested_result
);
2846 compile_pop_cleanup( c
);
2847 compile_emit( c
, INSTR_POP_LOCAL_GROUP
, 0 );
2849 adjust_result( c
, nested_result
, result_location
);
2851 else if ( parse
->type
== PARSE_ON
)
2853 if ( parse
->right
->type
== PARSE_APPEND
&&
2854 parse
->right
->left
->type
== PARSE_NULL
&&
2855 parse
->right
->right
->type
== PARSE_LIST
)
2857 /* [ on $(target) return $(variable) ] */
2858 PARSE
* value
= parse
->right
->right
;
2859 OBJECT
* const o
= value
->string
;
2860 char const * s
= object_str( o
);
2861 VAR_PARSE_GROUP
* group
;
2862 OBJECT
* varname
= 0;
2863 current_file
= object_str( value
->file
);
2864 current_line
= value
->line
;
2865 group
= parse_expansion( &s
);
2866 if ( group
->elems
->size
== 1 )
2868 VAR_PARSE
* one
= dynamic_array_at( VAR_PARSE
*, group
->elems
, 0 );
2869 if ( one
->type
== VAR_PARSE_TYPE_VAR
)
2871 VAR_PARSE_VAR
* var
= ( VAR_PARSE_VAR
* )one
;
2872 if ( var
->modifiers
->size
== 0 && !var
->subscript
&& var
->name
->elems
->size
== 1 )
2874 VAR_PARSE
* name
= dynamic_array_at( VAR_PARSE
*, var
->name
->elems
, 0 );
2875 if ( name
->type
== VAR_PARSE_TYPE_STRING
)
2877 varname
= ( ( VAR_PARSE_STRING
* )name
)->s
;
2884 /* We have one variable with a fixed name and no modifiers. */
2885 compile_parse( parse
->left
, c
, RESULT_STACK
);
2886 compile_emit( c
, INSTR_GET_ON
, compile_emit_constant( c
, varname
) );
2890 /* Too complex. Fall back on push/pop. */
2891 int32_t end
= compile_new_label( c
);
2892 compile_parse( parse
->left
, c
, RESULT_STACK
);
2893 compile_emit_branch( c
, INSTR_PUSH_ON
, end
);
2894 compile_push_cleanup( c
, INSTR_POP_ON
, 0 );
2895 var_parse_group_compile( group
, c
);
2896 compile_pop_cleanup( c
);
2897 compile_emit( c
, INSTR_POP_ON
, 0 );
2898 compile_set_label( c
, end
);
2900 var_parse_group_free( group
);
2904 int32_t end
= compile_new_label( c
);
2905 compile_parse( parse
->left
, c
, RESULT_STACK
);
2906 compile_emit_branch( c
, INSTR_PUSH_ON
, end
);
2907 compile_push_cleanup( c
, INSTR_POP_ON
, 0 );
2908 compile_parse( parse
->right
, c
, RESULT_STACK
);
2909 compile_pop_cleanup( c
);
2910 compile_emit( c
, INSTR_POP_ON
, 0 );
2911 compile_set_label( c
, end
);
2913 adjust_result( c
, RESULT_STACK
, result_location
);
2915 else if ( parse
->type
== PARSE_RULE
)
2919 VAR_PARSE_GROUP
* group
;
2920 char const * s
= object_str( parse
->string
);
2922 if ( parse
->left
->left
|| parse
->left
->right
->type
!= PARSE_NULL
)
2923 for ( p
= parse
->left
; p
; p
= p
->left
)
2925 compile_parse( p
->right
, c
, RESULT_STACK
);
2929 current_file
= object_str( parse
->file
);
2930 current_line
= parse
->line
;
2931 group
= parse_expansion( &s
);
2933 if ( group
->elems
->size
== 2 &&
2934 dynamic_array_at( VAR_PARSE
*, group
->elems
, 0 )->type
== VAR_PARSE_TYPE_VAR
&&
2935 dynamic_array_at( VAR_PARSE
*, group
->elems
, 1 )->type
== VAR_PARSE_TYPE_STRING
&&
2936 ( object_str( ( (VAR_PARSE_STRING
*)dynamic_array_at( VAR_PARSE
*, group
->elems
, 1 ) )->s
)[ 0 ] == '.' ) )
2938 VAR_PARSE_STRING
* access
= (VAR_PARSE_STRING
*)dynamic_array_at( VAR_PARSE
*, group
->elems
, 1 );
2939 OBJECT
* member
= object_new( object_str( access
->s
) + 1 );
2940 /* Emit the object */
2941 var_parse_var_compile( (VAR_PARSE_VAR
*)dynamic_array_at( VAR_PARSE
*, group
->elems
, 0 ), c
);
2942 var_parse_group_free( group
);
2943 compile_emit( c
, INSTR_CALL_MEMBER_RULE
, n
);
2944 compile_emit( c
, compile_emit_constant( c
, member
), parse
->line
);
2945 object_free( member
);
2949 var_parse_group_compile( group
, c
);
2950 var_parse_group_free( group
);
2951 compile_emit( c
, INSTR_CALL_RULE
, n
);
2952 compile_emit( c
, compile_emit_constant( c
, parse
->string
), parse
->line
);
2955 adjust_result( c
, RESULT_STACK
, result_location
);
2957 else if ( parse
->type
== PARSE_RULES
)
2959 do compile_parse( parse
->left
, c
, RESULT_NONE
);
2960 while ( ( parse
= parse
->right
)->type
== PARSE_RULES
);
2961 compile_parse( parse
, c
, result_location
);
2963 else if ( parse
->type
== PARSE_SET
)
2965 PARSE
* vars
= parse
->left
;
2967 uint32_t op_code_group
;
2969 switch ( parse
->num
)
2971 case ASSIGN_APPEND
: op_code
= INSTR_APPEND
; op_code_group
= INSTR_APPEND_GROUP
; break;
2972 case ASSIGN_DEFAULT
: op_code
= INSTR_DEFAULT
; op_code_group
= INSTR_DEFAULT_GROUP
; break;
2973 default: op_code
= INSTR_SET
; op_code_group
= INSTR_SET_GROUP
; break;
2976 /* Check whether there is exactly one variable with a constant name. */
2977 if ( vars
->type
== PARSE_LIST
)
2979 char const * s
= object_str( vars
->string
);
2980 VAR_PARSE_GROUP
* group
;
2981 current_file
= object_str( parse
->file
);
2982 current_line
= parse
->line
;
2983 group
= parse_expansion( &s
);
2984 if ( group
->elems
->size
== 1 && dynamic_array_at( VAR_PARSE
*,
2985 group
->elems
, 0 )->type
== VAR_PARSE_TYPE_STRING
)
2987 int32_t const name
= compile_emit_constant( c
, (
2988 (VAR_PARSE_STRING
*)dynamic_array_at( VAR_PARSE
*,
2989 group
->elems
, 0 ) )->s
);
2990 var_parse_group_free( group
);
2991 compile_parse( parse
->right
, c
, RESULT_STACK
);
2992 compile_emit_debug(c
, parse
->line
);
2993 if ( result_location
!= RESULT_NONE
)
2995 compile_emit( c
, INSTR_SET_RESULT
, 1 );
2997 compile_emit( c
, op_code
, name
);
3001 var_parse_group_compile( group
, c
);
3002 var_parse_group_free( group
);
3003 compile_parse( parse
->right
, c
, RESULT_STACK
);
3004 compile_emit_debug(c
, parse
->line
);
3005 if ( result_location
!= RESULT_NONE
)
3007 compile_emit( c
, INSTR_SET_RESULT
, 1 );
3009 compile_emit( c
, op_code_group
, 0 );
3014 compile_parse( parse
->left
, c
, RESULT_STACK
);
3015 compile_parse( parse
->right
, c
, RESULT_STACK
);
3016 compile_emit_debug(c
, parse
->line
);
3017 if ( result_location
!= RESULT_NONE
)
3019 compile_emit( c
, INSTR_SET_RESULT
, 1 );
3021 compile_emit( c
, op_code_group
, 0 );
3023 if ( result_location
!= RESULT_NONE
)
3025 adjust_result( c
, RESULT_RETURN
, result_location
);
3028 else if ( parse
->type
== PARSE_SETCOMP
)
3031 struct arg_list
* args
= arg_list_compile( parse
->right
, &n_args
);
3032 int32_t const rule_id
= compile_emit_rule( c
, parse
->string
, parse
->left
,
3033 n_args
, args
, parse
->num
);
3034 compile_emit( c
, INSTR_RULE
, rule_id
);
3035 adjust_result( c
, RESULT_NONE
, result_location
);
3037 else if ( parse
->type
== PARSE_SETEXEC
)
3039 int32_t const actions_id
= compile_emit_actions( c
, parse
);
3040 compile_parse( parse
->left
, c
, RESULT_STACK
);
3041 compile_emit( c
, INSTR_ACTIONS
, actions_id
);
3042 adjust_result( c
, RESULT_NONE
, result_location
);
3044 else if ( parse
->type
== PARSE_SETTINGS
)
3046 compile_parse( parse
->left
, c
, RESULT_STACK
);
3047 compile_parse( parse
->third
, c
, RESULT_STACK
);
3048 compile_parse( parse
->right
, c
, RESULT_STACK
);
3050 compile_emit_debug(c
, parse
->line
);
3051 switch ( parse
->num
)
3053 case ASSIGN_APPEND
: compile_emit( c
, INSTR_APPEND_ON
, 0 ); break;
3054 case ASSIGN_DEFAULT
: compile_emit( c
, INSTR_DEFAULT_ON
, 0 ); break;
3055 default: compile_emit( c
, INSTR_SET_ON
, 0 ); break;
3058 adjust_result( c
, RESULT_STACK
, result_location
);
3060 else if ( parse
->type
== PARSE_SWITCH
)
3062 int32_t const switch_end
= compile_new_label( c
);
3063 compile_parse( parse
->left
, c
, RESULT_STACK
);
3065 for ( parse
= parse
->right
; parse
; parse
= parse
->right
)
3067 int32_t const id
= compile_emit_constant( c
, parse
->left
->string
);
3068 int32_t const next_case
= compile_new_label( c
);
3069 compile_emit( c
, INSTR_PUSH_CONSTANT
, id
);
3070 compile_emit_branch( c
, INSTR_JUMP_NOT_GLOB
, next_case
);
3071 compile_parse( parse
->left
->left
, c
, result_location
);
3072 compile_emit_branch( c
, INSTR_JUMP
, switch_end
);
3073 compile_set_label( c
, next_case
);
3075 compile_emit( c
, INSTR_POP
, 0 );
3076 adjust_result( c
, RESULT_NONE
, result_location
);
3077 compile_set_label( c
, switch_end
);
3079 else if ( parse
->type
== PARSE_RETURN
)
3081 compile_parse( parse
->left
, c
, RESULT_RETURN
);
3082 compile_emit_cleanups( c
, 0 );
3083 compile_emit( c
, INSTR_RETURN
, 0 ); /* 0 for return in the middle of a function. */
3085 else if ( parse
->type
== PARSE_BREAK
)
3087 compile_emit_loop_jump( c
, LOOP_INFO_BREAK
);
3089 else if ( parse
->type
== PARSE_CONTINUE
)
3091 compile_emit_loop_jump( c
, LOOP_INFO_CONTINUE
);
3093 else if ( parse
->type
== PARSE_NULL
)
3094 adjust_result( c
, RESULT_NONE
, result_location
);
3096 assert( !"unknown PARSE type." );
3099 OBJECT
* function_rulename( FUNCTION
* function
)
3101 return function
->rulename
;
3104 void function_set_rulename( FUNCTION
* function
, OBJECT
* rulename
)
3106 function
->rulename
= rulename
;
3109 void function_location( FUNCTION
* function_
, OBJECT
* * file
, int32_t * line
)
3111 if ( function_
->type
== FUNCTION_BUILTIN
)
3113 *file
= constant_builtin
;
3117 if ( function_
->type
== FUNCTION_PYTHON
)
3119 *file
= constant_builtin
;
3125 JAM_FUNCTION
* function
= (JAM_FUNCTION
*)function_
;
3126 assert( function_
->type
== FUNCTION_JAM
);
3127 *file
= function
->file
;
3128 *line
= function
->line
;
3132 static struct arg_list
* arg_list_compile_builtin( char const * * args
,
3133 int32_t * num_arguments
);
3135 FUNCTION
* function_builtin( LIST
* ( * func
)( FRAME
* frame
, int32_t flags
),
3136 int32_t flags
, char const * * args
)
3138 BUILTIN_FUNCTION
* result
= (BUILTIN_FUNCTION
*)BJAM_MALLOC( sizeof( BUILTIN_FUNCTION
) );
3139 result
->base
.type
= FUNCTION_BUILTIN
;
3140 result
->base
.reference_count
= 1;
3141 result
->base
.rulename
= 0;
3142 result
->base
.formal_arguments
= arg_list_compile_builtin( args
,
3143 &result
->base
.num_formal_arguments
);
3144 result
->func
= func
;
3145 result
->flags
= flags
;
3146 return (FUNCTION
*)result
;
3149 FUNCTION
* function_compile( PARSE
* parse
)
3152 JAM_FUNCTION
* result
;
3154 compile_parse( parse
, c
, RESULT_RETURN
);
3155 compile_emit( c
, INSTR_RETURN
, 1 );
3156 result
= compile_to_function( c
);
3158 result
->file
= object_copy( parse
->file
);
3159 result
->line
= parse
->line
;
3160 return (FUNCTION
*)result
;
3163 FUNCTION
* function_compile_actions( char const * actions
, OBJECT
* file
,
3167 JAM_FUNCTION
* result
;
3168 VAR_PARSE_ACTIONS
* parse
;
3169 current_file
= object_str( file
);
3170 current_line
= line
;
3171 parse
= parse_actions( actions
);
3173 var_parse_actions_compile( parse
, c
);
3174 var_parse_actions_free( parse
);
3175 compile_emit( c
, INSTR_RETURN
, 1 );
3176 result
= compile_to_function( c
);
3178 result
->file
= object_copy( file
);
3179 result
->line
= line
;
3180 return (FUNCTION
*)result
;
3183 static void argument_list_print( struct arg_list
* args
, int32_t num_args
);
3186 /* Define delimiters for type check elements in argument lists (and return type
3187 * specifications, eventually).
3189 # define TYPE_OPEN_DELIM '['
3190 # define TYPE_CLOSE_DELIM ']'
3193 * is_type_name() - true iff the given string represents a type check
3197 int32_t is_type_name( char const * s
)
3199 return s
[ 0 ] == TYPE_OPEN_DELIM
&& s
[ strlen( s
) - 1 ] ==
3203 static void argument_error( char const * message
, FUNCTION
* procedure
,
3204 FRAME
* frame
, OBJECT
* arg
)
3206 extern void print_source_line( FRAME
* );
3207 LOL
* actual
= frame
->args
;
3208 backtrace_line( frame
->prev
);
3209 out_printf( "*** argument error\n* rule %s ( ", frame
->rulename
);
3210 argument_list_print( procedure
->formal_arguments
,
3211 procedure
->num_formal_arguments
);
3212 out_printf( " )\n* called with: ( " );
3213 lol_print( actual
);
3214 out_printf( " )\n* %s %s\n", message
, arg
? object_str ( arg
) : "" );
3215 function_location( procedure
, &frame
->file
, &frame
->line
);
3216 print_source_line( frame
);
3217 out_printf( "see definition of rule '%s' being called\n", frame
->rulename
);
3218 backtrace( frame
->prev
);
3219 b2::clean_exit( EXITBAD
);
3222 static void type_check_range( OBJECT
* type_name
, LISTITER iter
, LISTITER end
,
3223 FRAME
* caller
, FUNCTION
* called
, OBJECT
* arg_name
)
3225 static module_t
* typecheck
= 0;
3227 /* If nothing to check, bail now. */
3228 if ( iter
== end
|| !type_name
)
3232 typecheck
= bindmodule( constant_typecheck
);
3234 /* If the checking rule can not be found, also bail. */
3235 if ( !typecheck
->rules
|| !hash_find( typecheck
->rules
, type_name
) )
3238 for ( ; iter
!= end
; iter
= list_next( iter
) )
3242 frame_init( frame
);
3243 frame
->module
= typecheck
;
3244 frame
->prev
= caller
;
3245 frame
->prev_user
= caller
->module
->user_module
3247 : caller
->prev_user
;
3249 /* Prepare the argument list */
3250 lol_add( frame
->args
, list_new( object_copy( list_item( iter
) ) ) );
3251 error
= evaluate_rule( bindrule( type_name
, frame
->module
), type_name
, frame
);
3253 if ( !list_empty( error
) )
3254 argument_error( object_str( list_front( error
) ), called
, caller
,
3257 frame_free( frame
);
3261 static void type_check( OBJECT
* type_name
, LIST
* values
, FRAME
* caller
,
3262 FUNCTION
* called
, OBJECT
* arg_name
)
3264 type_check_range( type_name
, list_begin( values
), list_end( values
),
3265 caller
, called
, arg_name
);
3268 void argument_list_check( struct arg_list
* formal
, int32_t formal_count
,
3269 FUNCTION
* function
, FRAME
* frame
)
3271 LOL
* all_actual
= frame
->args
;
3274 for ( i
= 0; i
< formal_count
; ++i
)
3276 LIST
* actual
= lol_get( all_actual
, i
);
3277 LISTITER actual_iter
= list_begin( actual
);
3278 LISTITER
const actual_end
= list_end( actual
);
3280 for ( j
= 0; j
< formal
[ i
].size
; ++j
)
3282 struct argument
* formal_arg
= &formal
[ i
].args
[ j
];
3284 switch ( formal_arg
->flags
)
3287 if ( actual_iter
== actual_end
)
3288 argument_error( "missing argument", function
, frame
,
3289 formal_arg
->arg_name
);
3290 type_check_range( formal_arg
->type_name
, actual_iter
,
3291 list_next( actual_iter
), frame
, function
,
3292 formal_arg
->arg_name
);
3293 actual_iter
= list_next( actual_iter
);
3296 if ( actual_iter
!= actual_end
)
3298 type_check_range( formal_arg
->type_name
, actual_iter
,
3299 list_next( actual_iter
), frame
, function
,
3300 formal_arg
->arg_name
);
3301 actual_iter
= list_next( actual_iter
);
3305 if ( actual_iter
== actual_end
)
3306 argument_error( "missing argument", function
, frame
,
3307 formal_arg
->arg_name
);
3310 type_check_range( formal_arg
->type_name
, actual_iter
,
3311 actual_end
, frame
, function
, formal_arg
->arg_name
);
3312 actual_iter
= actual_end
;
3319 if ( actual_iter
!= actual_end
)
3320 argument_error( "extra argument", function
, frame
, list_item(
3324 for ( ; i
< all_actual
->count
; ++i
)
3326 LIST
* actual
= lol_get( all_actual
, i
);
3327 if ( !list_empty( actual
) )
3328 argument_error( "extra argument", function
, frame
, list_front(
3333 void argument_list_push( struct arg_list
* formal
, int32_t formal_count
,
3334 FUNCTION
* function
, FRAME
* frame
, STACK
* s
)
3336 LOL
* all_actual
= frame
->args
;
3339 for ( i
= 0; i
< formal_count
; ++i
)
3341 LIST
* actual
= lol_get( all_actual
, i
);
3342 LISTITER actual_iter
= list_begin( actual
);
3343 LISTITER
const actual_end
= list_end( actual
);
3345 for ( j
= 0; j
< formal
[ i
].size
; ++j
)
3347 struct argument
* formal_arg
= &formal
[ i
].args
[ j
];
3350 switch ( formal_arg
->flags
)
3353 if ( actual_iter
== actual_end
)
3354 argument_error( "missing argument", function
, frame
,
3355 formal_arg
->arg_name
);
3356 value
= list_new( object_copy( list_item( actual_iter
) ) );
3357 actual_iter
= list_next( actual_iter
);
3360 if ( actual_iter
== actual_end
)
3364 value
= list_new( object_copy( list_item( actual_iter
) ) );
3365 actual_iter
= list_next( actual_iter
);
3369 if ( actual_iter
== actual_end
)
3370 argument_error( "missing argument", function
, frame
,
3371 formal_arg
->arg_name
);
3374 value
= list_copy_range( actual
, actual_iter
, actual_end
);
3375 actual_iter
= actual_end
;
3381 type_check( formal_arg
->type_name
, value
, frame
, function
,
3382 formal_arg
->arg_name
);
3384 if ( formal_arg
->index
!= -1 )
3386 LIST
* * const old
= &frame
->module
->fixed_variables
[
3387 formal_arg
->index
];
3388 stack_push( s
, *old
);
3392 stack_push( s
, var_swap( frame
->module
, formal_arg
->arg_name
,
3396 if ( actual_iter
!= actual_end
)
3397 argument_error( "extra argument", function
, frame
, list_item(
3401 for ( ; i
< all_actual
->count
; ++i
)
3403 LIST
* const actual
= lol_get( all_actual
, i
);
3404 if ( !list_empty( actual
) )
3405 argument_error( "extra argument", function
, frame
, list_front(
3410 void argument_list_pop( struct arg_list
* formal
, int32_t formal_count
,
3411 FRAME
* frame
, STACK
* s
)
3414 for ( i
= formal_count
- 1; i
>= 0; --i
)
3417 for ( j
= formal
[ i
].size
- 1; j
>= 0 ; --j
)
3419 struct argument
* formal_arg
= &formal
[ i
].args
[ j
];
3421 if ( formal_arg
->flags
== ARG_VARIADIC
)
3423 if ( formal_arg
->index
!= -1 )
3425 LIST
* const old
= stack_pop( s
);
3426 LIST
* * const pos
= &frame
->module
->fixed_variables
[
3427 formal_arg
->index
];
3432 var_set( frame
->module
, formal_arg
->arg_name
, stack_pop( s
),
3439 struct argument_compiler
3441 struct dynamic_array args
[ 1 ];
3442 struct argument arg
;
3444 #define ARGUMENT_COMPILER_START 0
3445 #define ARGUMENT_COMPILER_FOUND_TYPE 1
3446 #define ARGUMENT_COMPILER_FOUND_OBJECT 2
3447 #define ARGUMENT_COMPILER_DONE 3
3451 static void argument_compiler_init( struct argument_compiler
* c
)
3453 dynamic_array_init( c
->args
);
3454 c
->state
= ARGUMENT_COMPILER_START
;
3457 static void argument_compiler_free( struct argument_compiler
* c
)
3459 dynamic_array_free( c
->args
);
3462 static void argument_compiler_add( struct argument_compiler
* c
, OBJECT
* arg
,
3463 OBJECT
* file
, int32_t line
)
3467 case ARGUMENT_COMPILER_FOUND_OBJECT
:
3469 if ( object_equal( arg
, constant_question_mark
) )
3471 c
->arg
.flags
= ARG_OPTIONAL
;
3473 else if ( object_equal( arg
, constant_plus
) )
3475 c
->arg
.flags
= ARG_PLUS
;
3477 else if ( object_equal( arg
, constant_star
) )
3479 c
->arg
.flags
= ARG_STAR
;
3482 dynamic_array_push( c
->args
, c
->arg
);
3483 c
->state
= ARGUMENT_COMPILER_START
;
3485 if ( c
->arg
.flags
!= ARG_ONE
)
3489 case ARGUMENT_COMPILER_START
:
3491 c
->arg
.type_name
= 0;
3493 c
->arg
.flags
= ARG_ONE
;
3495 if ( is_type_name( object_str( arg
) ) )
3497 c
->arg
.type_name
= object_copy( arg
);
3498 c
->state
= ARGUMENT_COMPILER_FOUND_TYPE
;
3503 case ARGUMENT_COMPILER_FOUND_TYPE
:
3505 if ( is_type_name( object_str( arg
) ) )
3507 err_printf( "%s:%d: missing argument name before type name: %s\n",
3508 object_str( file
), line
, object_str( arg
) );
3509 b2::clean_exit( EXITBAD
);
3512 c
->arg
.arg_name
= object_copy( arg
);
3513 if ( object_equal( arg
, constant_star
) )
3515 c
->arg
.flags
= ARG_VARIADIC
;
3516 dynamic_array_push( c
->args
, c
->arg
);
3517 c
->state
= ARGUMENT_COMPILER_DONE
;
3521 c
->state
= ARGUMENT_COMPILER_FOUND_OBJECT
;
3525 case ARGUMENT_COMPILER_DONE
:
3530 static void argument_compiler_recurse( struct argument_compiler
* c
,
3533 if ( parse
->type
== PARSE_APPEND
)
3535 argument_compiler_recurse( c
, parse
->left
);
3536 argument_compiler_recurse( c
, parse
->right
);
3538 else if ( parse
->type
!= PARSE_NULL
)
3540 assert( parse
->type
== PARSE_LIST
);
3541 argument_compiler_add( c
, parse
->string
, parse
->file
, parse
->line
);
3545 static struct arg_list
arg_compile_impl( struct argument_compiler
* c
,
3546 OBJECT
* file
, int32_t line
)
3548 struct arg_list result
;
3551 case ARGUMENT_COMPILER_START
:
3552 case ARGUMENT_COMPILER_DONE
:
3554 case ARGUMENT_COMPILER_FOUND_TYPE
:
3555 err_printf( "%s:%d: missing argument name after type name: %s\n",
3556 object_str( file
), line
, object_str( c
->arg
.type_name
) );
3557 b2::clean_exit( EXITBAD
);
3558 case ARGUMENT_COMPILER_FOUND_OBJECT
:
3559 dynamic_array_push( c
->args
, c
->arg
);
3562 result
.size
= c
->args
->size
;
3563 result
.args
= (struct argument
*)BJAM_MALLOC( c
->args
->size
* sizeof( struct argument
) );
3564 if ( c
->args
->size
!= 0 )
3565 memcpy( result
.args
, c
->args
->data
,
3566 c
->args
->size
* sizeof( struct argument
) );
3570 static struct arg_list
arg_compile( PARSE
* parse
)
3572 struct argument_compiler c
[ 1 ];
3573 struct arg_list result
;
3574 argument_compiler_init( c
);
3575 argument_compiler_recurse( c
, parse
);
3576 result
= arg_compile_impl( c
, parse
->file
, parse
->line
);
3577 argument_compiler_free( c
);
3581 struct argument_list_compiler
3583 struct dynamic_array args
[ 1 ];
3586 static void argument_list_compiler_init( struct argument_list_compiler
* c
)
3588 dynamic_array_init( c
->args
);
3591 static void argument_list_compiler_free( struct argument_list_compiler
* c
)
3593 dynamic_array_free( c
->args
);
3596 static void argument_list_compiler_add( struct argument_list_compiler
* c
,
3599 struct arg_list args
= arg_compile( parse
);
3600 dynamic_array_push( c
->args
, args
);
3603 static void argument_list_compiler_recurse( struct argument_list_compiler
* c
,
3608 argument_list_compiler_add( c
, parse
->right
);
3609 argument_list_compiler_recurse( c
, parse
->left
);
3613 static struct arg_list
* arg_list_compile( PARSE
* parse
, int32_t * num_arguments
)
3617 struct argument_list_compiler c
[ 1 ];
3618 struct arg_list
* result
;
3619 argument_list_compiler_init( c
);
3620 argument_list_compiler_recurse( c
, parse
);
3621 *num_arguments
= c
->args
->size
;
3622 result
= (struct arg_list
*)BJAM_MALLOC( c
->args
->size
* sizeof( struct arg_list
) );
3623 memcpy( result
, c
->args
->data
, c
->args
->size
* sizeof( struct arg_list
)
3625 argument_list_compiler_free( c
);
3632 static struct arg_list
* arg_list_compile_builtin( char const * * args
,
3633 int32_t * num_arguments
)
3637 struct argument_list_compiler c
[ 1 ];
3638 struct arg_list
* result
;
3639 argument_list_compiler_init( c
);
3642 struct argument_compiler arg_comp
[ 1 ];
3643 struct arg_list arg
;
3644 argument_compiler_init( arg_comp
);
3645 for ( ; *args
; ++args
)
3648 if ( strcmp( *args
, ":" ) == 0 )
3653 token
= object_new( *args
);
3654 argument_compiler_add( arg_comp
, token
, constant_builtin
, -1 );
3655 object_free( token
);
3657 arg
= arg_compile_impl( arg_comp
, constant_builtin
, -1 );
3658 dynamic_array_push( c
->args
, arg
);
3659 argument_compiler_free( arg_comp
);
3661 *num_arguments
= c
->args
->size
;
3662 result
= (struct arg_list
*)BJAM_MALLOC( c
->args
->size
* sizeof( struct arg_list
) );
3663 if ( c
->args
->size
!= 0 )
3664 memcpy( result
, c
->args
->data
,
3665 c
->args
->size
* sizeof( struct arg_list
) );
3666 argument_list_compiler_free( c
);
3673 static void argument_list_print( struct arg_list
* args
, int32_t num_args
)
3678 for ( i
= 0; i
< num_args
; ++i
)
3681 if ( i
) out_printf( " : " );
3682 for ( j
= 0; j
< args
[ i
].size
; ++j
)
3684 struct argument
* formal_arg
= &args
[ i
].args
[ j
];
3685 if ( j
) out_printf( " " );
3686 if ( formal_arg
->type_name
)
3687 out_printf( "%s ", object_str( formal_arg
->type_name
) );
3688 out_printf( "%s", object_str( formal_arg
->arg_name
) );
3689 switch ( formal_arg
->flags
)
3691 case ARG_OPTIONAL
: out_printf( " ?" ); break;
3692 case ARG_PLUS
: out_printf( " +" ); break;
3693 case ARG_STAR
: out_printf( " *" ); break;
3701 struct arg_list
* argument_list_bind_variables( struct arg_list
* formal
,
3702 int32_t formal_count
, module_t
* module
, int32_t * counter
)
3706 struct arg_list
* result
= (struct arg_list
*)BJAM_MALLOC( sizeof(
3707 struct arg_list
) * formal_count
);
3710 for ( i
= 0; i
< formal_count
; ++i
)
3713 struct argument
* args
= (struct argument
*)BJAM_MALLOC( sizeof(
3714 struct argument
) * formal
[ i
].size
);
3715 for ( j
= 0; j
< formal
[ i
].size
; ++j
)
3717 args
[ j
] = formal
[ i
].args
[ j
];
3718 if ( args
[ j
].type_name
)
3719 args
[ j
].type_name
= object_copy( args
[ j
].type_name
);
3720 args
[ j
].arg_name
= object_copy( args
[ j
].arg_name
);
3721 if ( args
[ j
].flags
!= ARG_VARIADIC
)
3722 args
[ j
].index
= module_add_fixed_var( module
,
3723 args
[ j
].arg_name
, counter
);
3725 result
[ i
].args
= args
;
3726 result
[ i
].size
= formal
[ i
].size
;
3735 void argument_list_free( struct arg_list
* args
, int32_t args_count
)
3738 for ( i
= 0; i
< args_count
; ++i
)
3741 for ( j
= 0; j
< args
[ i
].size
; ++j
)
3743 if ( args
[ i
].args
[ j
].type_name
)
3744 object_free( args
[ i
].args
[ j
].type_name
);
3745 object_free( args
[ i
].args
[ j
].arg_name
);
3747 BJAM_FREE( args
[ i
].args
);
3753 FUNCTION
* function_unbind_variables( FUNCTION
* f
)
3755 if ( f
->type
== FUNCTION_JAM
)
3757 JAM_FUNCTION
* const func
= (JAM_FUNCTION
*)f
;
3758 return func
->generic
? func
->generic
: f
;
3761 if ( f
->type
== FUNCTION_PYTHON
)
3764 assert( f
->type
== FUNCTION_BUILTIN
);
3768 FUNCTION
* function_bind_variables( FUNCTION
* f
, module_t
* module
,
3771 if ( f
->type
== FUNCTION_BUILTIN
)
3774 if ( f
->type
== FUNCTION_PYTHON
)
3778 JAM_FUNCTION
* func
= (JAM_FUNCTION
*)f
;
3779 JAM_FUNCTION
* new_func
= (JAM_FUNCTION
*)BJAM_MALLOC( sizeof( JAM_FUNCTION
) );
3782 assert( f
->type
== FUNCTION_JAM
);
3783 memcpy( new_func
, func
, sizeof( JAM_FUNCTION
) );
3784 new_func
->base
.reference_count
= 1;
3785 new_func
->base
.formal_arguments
= argument_list_bind_variables(
3786 f
->formal_arguments
, f
->num_formal_arguments
, module
, counter
);
3787 new_func
->code
= (instruction
*)BJAM_MALLOC( func
->code_size
* sizeof( instruction
) );
3788 memcpy( new_func
->code
, func
->code
, func
->code_size
* sizeof(
3790 new_func
->generic
= (FUNCTION
*)func
;
3792 for ( i
= 0; ; ++i
)
3796 code
= func
->code
+ i
;
3797 switch ( code
->op_code
)
3799 case INSTR_PUSH_VAR
: op_code
= INSTR_PUSH_VAR_FIXED
; break;
3800 case INSTR_PUSH_LOCAL
: op_code
= INSTR_PUSH_LOCAL_FIXED
; break;
3801 case INSTR_POP_LOCAL
: op_code
= INSTR_POP_LOCAL_FIXED
; break;
3802 case INSTR_SET
: op_code
= INSTR_SET_FIXED
; break;
3803 case INSTR_APPEND
: op_code
= INSTR_APPEND_FIXED
; break;
3804 case INSTR_DEFAULT
: op_code
= INSTR_DEFAULT_FIXED
; break;
3806 if( code
->arg
== 1 ) return (FUNCTION
*)new_func
;
3808 case INSTR_CALL_MEMBER_RULE
:
3809 case INSTR_CALL_RULE
: ++i
; continue;
3810 case INSTR_PUSH_MODULE
:
3816 code
= func
->code
+ i
;
3817 switch ( code
->op_code
)
3819 case INSTR_PUSH_MODULE
:
3823 case INSTR_POP_MODULE
:
3826 case INSTR_CALL_RULE
:
3836 key
= func
->constants
[ code
->arg
];
3837 if ( !( object_equal( key
, constant_TMPDIR
) ||
3838 object_equal( key
, constant_TMPNAME
) ||
3839 object_equal( key
, constant_TMPFILE
) ||
3840 object_equal( key
, constant_STDOUT
) ||
3841 object_equal( key
, constant_STDERR
) ) )
3843 code
->op_code
= op_code
;
3844 code
->arg
= module_add_fixed_var( module
, key
, counter
);
3850 LIST
* function_get_variables( FUNCTION
* f
)
3852 if ( f
->type
== FUNCTION_BUILTIN
)
3855 if ( f
->type
== FUNCTION_PYTHON
)
3859 JAM_FUNCTION
* func
= (JAM_FUNCTION
*)f
;
3863 assert( f
->type
== FUNCTION_JAM
);
3864 if ( func
->generic
) func
= ( JAM_FUNCTION
* )func
->generic
;
3866 for ( i
= 0; ; ++i
)
3869 code
= func
->code
+ i
;
3870 switch ( code
->op_code
)
3872 case INSTR_PUSH_LOCAL
: break;
3873 case INSTR_RETURN
: return result
;
3874 case INSTR_CALL_MEMBER_RULE
:
3875 case INSTR_CALL_RULE
: ++i
; continue;
3876 case INSTR_PUSH_MODULE
:
3882 code
= func
->code
+ i
;
3883 switch ( code
->op_code
)
3885 case INSTR_PUSH_MODULE
:
3889 case INSTR_POP_MODULE
:
3892 case INSTR_CALL_RULE
:
3902 var
= func
->constants
[ code
->arg
];
3903 if ( !( object_equal( var
, constant_TMPDIR
) ||
3904 object_equal( var
, constant_TMPNAME
) ||
3905 object_equal( var
, constant_TMPFILE
) ||
3906 object_equal( var
, constant_STDOUT
) ||
3907 object_equal( var
, constant_STDERR
) ) )
3909 result
= list_push_back( result
, var
);
3915 void function_refer( FUNCTION
* func
)
3917 ++func
->reference_count
;
3920 void function_free( FUNCTION
* function_
)
3924 if ( --function_
->reference_count
!= 0 )
3927 if ( function_
->formal_arguments
)
3928 argument_list_free( function_
->formal_arguments
,
3929 function_
->num_formal_arguments
);
3931 if ( function_
->type
== FUNCTION_JAM
)
3933 JAM_FUNCTION
* func
= (JAM_FUNCTION
*)function_
;
3935 BJAM_FREE( func
->code
);
3937 if ( func
->generic
)
3938 function_free( func
->generic
);
3941 if ( function_
->rulename
) object_free( function_
->rulename
);
3943 for ( i
= 0; i
< func
->num_constants
; ++i
)
3944 object_free( func
->constants
[ i
] );
3945 BJAM_FREE( func
->constants
);
3947 for ( i
= 0; i
< func
->num_subfunctions
; ++i
)
3949 object_free( func
->functions
[ i
].name
);
3950 function_free( func
->functions
[ i
].code
);
3952 BJAM_FREE( func
->functions
);
3954 for ( i
= 0; i
< func
->num_subactions
; ++i
)
3956 object_free( func
->actions
[ i
].name
);
3957 function_free( func
->actions
[ i
].command
);
3959 BJAM_FREE( func
->actions
);
3961 object_free( func
->file
);
3965 else if ( function_
->type
== FUNCTION_PYTHON
)
3967 PYTHON_FUNCTION
* func
= (PYTHON_FUNCTION
*)function_
;
3968 Py_DECREF( func
->python_function
);
3969 if ( function_
->rulename
) object_free( function_
->rulename
);
3974 assert( function_
->type
== FUNCTION_BUILTIN
);
3975 if ( function_
->rulename
) object_free( function_
->rulename
);
3978 BJAM_FREE( function_
);
3982 /* Alignment check for stack */
3984 struct align_var_edits
3990 struct align_expansion_item
3997 sizeof(struct align_var_edits
) <= sizeof(VAR_EDITS
) + sizeof(void *),
3998 "sizeof(struct align_var_edits) <= sizeof(VAR_EDITS) + sizeof(void *)" );
4000 sizeof(struct align_expansion_item
) <= sizeof(expansion_item
) + sizeof(void *),
4001 "sizeof(struct align_expansion_item) <= sizeof(expansion_item) + sizeof(void *)" );
4003 static_assert( sizeof(LIST
*) <= sizeof(void *), "sizeof(LIST *) <= sizeof(void *)" );
4004 static_assert( sizeof(char *) <= sizeof(void *), "sizeof(char *) <= sizeof(void *)" );
4006 void function_run_actions( FUNCTION
* function
, FRAME
* frame
, STACK
* s
,
4009 *(string
* *)stack_allocate( s
, sizeof( string
* ) ) = out
;
4010 list_free( function_run( function
, frame
, s
) );
4011 stack_deallocate( s
, sizeof( string
* ) );
4014 // Result is either the filename or contents depending on:
4015 // 1. If the RESPONSE_FILE_SUB == f or not set (it's filename)
4016 // 2. If the RESPONSE_FILE_SUB == c (it's contents)
4017 // 3. If the RESPONSE_FILE_SUB == a (depends on the length of contents)
4018 // Note, returns a *copy* of the filename or contents.
4019 LIST
* function_execute_write_file(
4020 JAM_FUNCTION
* function
, FRAME
* frame
, STACK
* s
,
4021 VAR_EXPANDED filename
, LIST
* contents
)
4023 LIST
* filename_or_contents_result
= nullptr;
4025 char response_file_sub_c
= 'f';
4026 if ( filename
.opt_file
&& filename
.opt_content
)
4028 LIST
* response_file_sub
= function_get_named_variable(
4029 function
, frame
, constant_RESPONSE_FILE_SUB
);
4030 if ( response_file_sub
&& list_front( response_file_sub
) )
4031 response_file_sub_c
= object_str( list_front( response_file_sub
) )[0];
4032 list_free( response_file_sub
);
4033 const char * contents_str
= object_str( list_front( contents
) );
4034 if ( response_file_sub_c
== 'a' )
4036 if ( int32_t( strlen( contents_str
) + 256 ) > shell_maxline() )
4037 response_file_sub_c
= 'f';
4039 response_file_sub_c
= 'c';
4042 else if ( filename
.opt_file
)
4043 response_file_sub_c
= 'f';
4044 else if ( filename
.opt_content
)
4045 response_file_sub_c
= 'c';
4046 if ( response_file_sub_c
== 'c' )
4048 filename_or_contents_result
= list_copy( contents
);
4052 char const * out
= object_str( list_front( filename
.inner
) );
4053 OBJECT
* tmp_filename
= nullptr;
4054 FILE * out_file
= nullptr;
4055 bool out_debug
= DEBUG_EXEC
!= 0;
4057 /* For stdout/stderr we will create a temp file and generate a
4058 * command that outputs the content as needed.
4060 if ( ( strcmp( "STDOUT", out
) == 0 ) ||
4061 ( strcmp( "STDERR", out
) == 0 ) )
4063 int32_t err_redir
= strcmp( "STDERR", out
) == 0;
4066 tmp_filename
= path_tmpfile();
4068 /* Construct os-specific cat command. */
4070 const char * command
= "cat";
4071 const char * quote
= "\"";
4072 const char * redirect
= "1>&2";
4077 #elif defined( OS_VMS )
4078 command
= "pipe type";
4081 /* Get tmp file name in os-format. */
4083 string os_filename
[ 1 ];
4085 string_new( os_filename
);
4086 path_translate_to_os( object_str( tmp_filename
), os_filename
);
4087 object_free( tmp_filename
);
4088 tmp_filename
= object_new( os_filename
->value
);
4089 string_free( os_filename
);
4093 string_new( result
);
4094 string_append( result
, command
);
4095 string_append( result
, " " );
4096 string_append( result
, quote
);
4097 string_append( result
, object_str( tmp_filename
) );
4098 string_append( result
, quote
);
4101 string_append( result
, " " );
4102 string_append( result
, redirect
);
4106 /* Replace STDXXX with the temporary file. */
4107 filename_or_contents_result
= list_new( object_new( result
->value
) );
4108 out
= object_str( tmp_filename
);
4110 string_free( result
);
4112 /* Make sure temp files created by this get nuked eventually. */
4113 file_remove_atexit( tmp_filename
);
4117 filename_or_contents_result
= list_copy( filename
.value
);
4120 if ( !globs
.noexec
)
4122 string out_name
[ 1 ];
4123 /* Handle "path to file" filenames. */
4124 if ( ( out
[ 0 ] == '"' ) && ( out
[ strlen( out
) - 1 ] == '"' )
4127 string_copy( out_name
, out
+ 1 );
4128 string_truncate( out_name
, out_name
->size
- 1 );
4131 string_copy( out_name
, out
);
4132 out_file
= fopen( out_name
->value
, "w" );
4136 err_printf( "[errno %d] failed to write output file '%s': %s",
4137 errno
, out_name
->value
, strerror(errno
) );
4138 b2::clean_exit( EXITBAD
);
4140 string_free( out_name
);
4143 if ( out_debug
) out_printf( "\nfile %s\n", out
);
4144 if ( out_file
) fputs( object_str( list_front( contents
) ), out_file
);
4145 if ( out_debug
) out_puts( object_str( list_front( contents
) ) );
4152 object_free( tmp_filename
);
4154 if ( out_debug
) out_putc( '\n' );
4157 return filename_or_contents_result
;
4161 * WARNING: The instruction set is tuned for Jam and is not really generic. Be
4162 * especially careful about stack push/pop.
4165 LIST
* function_run( FUNCTION
* function_
, FRAME
* frame
, STACK
* s
)
4167 JAM_FUNCTION
* function
;
4173 void * saved_stack
= s
->data
;
4176 PROFILE_ENTER_LOCAL(function_run
);
4179 frame
->function
= function_
;
4182 if ( function_
->type
== FUNCTION_BUILTIN
)
4184 PROFILE_ENTER_LOCAL(function_run_FUNCTION_BUILTIN
);
4185 BUILTIN_FUNCTION
const * const f
= (BUILTIN_FUNCTION
*)function_
;
4186 if ( function_
->formal_arguments
)
4187 argument_list_check( function_
->formal_arguments
,
4188 function_
->num_formal_arguments
, function_
, frame
);
4190 debug_on_enter_function( frame
, f
->base
.rulename
, NULL
, -1 );
4191 result
= f
->func( frame
, f
->flags
);
4192 debug_on_exit_function( f
->base
.rulename
);
4193 PROFILE_EXIT_LOCAL(function_run_FUNCTION_BUILTIN
);
4194 PROFILE_EXIT_LOCAL(function_run
);
4199 else if ( function_
->type
== FUNCTION_PYTHON
)
4201 PROFILE_ENTER_LOCAL(function_run_FUNCTION_PYTHON
);
4202 PYTHON_FUNCTION
* f
= (PYTHON_FUNCTION
*)function_
;
4203 debug_on_enter_function( frame
, f
->base
.rulename
, NULL
, -1 );
4204 result
= call_python_function( f
, frame
);
4205 debug_on_exit_function( f
->base
.rulename
);
4206 PROFILE_EXIT_LOCAL(function_run_FUNCTION_PYTHON
);
4207 PROFILE_EXIT_LOCAL(function_run
);
4212 assert( function_
->type
== FUNCTION_JAM
);
4214 if ( function_
->formal_arguments
)
4215 argument_list_push( function_
->formal_arguments
,
4216 function_
->num_formal_arguments
, function_
, frame
, s
);
4218 function
= (JAM_FUNCTION
*)function_
;
4219 debug_on_enter_function( frame
, function
->base
.rulename
, function
->file
, function
->line
);
4220 code
= function
->code
;
4223 switch ( code
->op_code
)
4227 * Basic stack manipulation
4230 case INSTR_PUSH_EMPTY
:
4232 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_EMPTY
);
4233 stack_push( s
, L0
);
4234 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_EMPTY
);
4238 case INSTR_PUSH_CONSTANT
:
4240 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_CONSTANT
);
4241 OBJECT
* value
= function_get_constant( function
, code
->arg
);
4242 stack_push( s
, list_new( object_copy( value
) ) );
4243 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_CONSTANT
);
4247 case INSTR_PUSH_ARG
:
4249 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_ARG
);
4250 stack_push( s
, frame_get_local( frame
, code
->arg
) );
4251 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_ARG
);
4255 case INSTR_PUSH_VAR
:
4257 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_VAR
);
4258 stack_push( s
, function_get_variable( function
, frame
, code
->arg
) );
4259 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_VAR
);
4263 case INSTR_PUSH_VAR_FIXED
:
4265 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_VAR_FIXED
);
4266 stack_push( s
, list_copy( frame
->module
->fixed_variables
[ code
->arg
4268 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_VAR_FIXED
);
4272 case INSTR_PUSH_GROUP
:
4274 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_GROUP
);
4279 for ( iter
= list_begin( l
), end
= list_end( l
); iter
!= end
;
4280 iter
= list_next( iter
) )
4281 value
= list_append( value
, function_get_named_variable(
4282 function
, frame
, list_item( iter
) ) );
4284 stack_push( s
, value
);
4285 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_GROUP
);
4289 case INSTR_PUSH_APPEND
:
4291 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_APPEND
);
4294 stack_push( s
, list_append( l
, r
) );
4295 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_APPEND
);
4301 PROFILE_ENTER_LOCAL(function_run_INSTR_SWAP
);
4303 stack_set( s
, 0, stack_at( s
, code
->arg
) );
4304 stack_set( s
, code
->arg
, l
);
4305 PROFILE_EXIT_LOCAL(function_run_INSTR_SWAP
);
4311 PROFILE_ENTER_LOCAL(function_run_INSTR_POP
);
4312 list_free( stack_pop( s
) );
4313 PROFILE_EXIT_LOCAL(function_run_INSTR_POP
);
4318 * Branch instructions
4323 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP
);
4325 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP
);
4329 case INSTR_JUMP_EMPTY
:
4331 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_EMPTY
);
4333 if ( !list_cmp( l
, L0
) ) code
+= code
->arg
;
4335 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_EMPTY
);
4339 case INSTR_JUMP_NOT_EMPTY
:
4341 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_NOT_EMPTY
);
4343 if ( list_cmp( l
, L0
) ) code
+= code
->arg
;
4345 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_NOT_EMPTY
);
4351 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_LT
);
4354 if ( list_cmp( l
, r
) < 0 ) code
+= code
->arg
;
4357 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_LT
);
4363 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_LE
);
4366 if ( list_cmp( l
, r
) <= 0 ) code
+= code
->arg
;
4369 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_LE
);
4375 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_GT
);
4378 if ( list_cmp( l
, r
) > 0 ) code
+= code
->arg
;
4381 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_GT
);
4387 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_GE
);
4390 if ( list_cmp( l
, r
) >= 0 ) code
+= code
->arg
;
4393 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_GE
);
4399 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_EQ
);
4402 if ( list_cmp( l
, r
) == 0 ) code
+= code
->arg
;
4405 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_EQ
);
4411 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_NE
);
4414 if ( list_cmp(l
, r
) != 0 ) code
+= code
->arg
;
4417 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_NE
);
4423 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_IN
);
4426 if ( list_is_sublist( l
, r
) ) code
+= code
->arg
;
4429 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_IN
);
4433 case INSTR_JUMP_NOT_IN
:
4435 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_NOT_IN
);
4438 if ( !list_is_sublist( l
, r
) ) code
+= code
->arg
;
4441 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_NOT_IN
);
4449 case INSTR_FOR_INIT
:
4451 PROFILE_ENTER_LOCAL(function_run_INSTR_FOR_INIT
);
4453 *(LISTITER
*)stack_allocate( s
, sizeof( LISTITER
) ) =
4455 PROFILE_EXIT_LOCAL(function_run_INSTR_FOR_INIT
);
4459 case INSTR_FOR_LOOP
:
4461 PROFILE_ENTER_LOCAL(function_run_INSTR_FOR_LOOP
);
4462 LISTITER iter
= *(LISTITER
*)stack_get( s
);
4463 stack_deallocate( s
, sizeof( LISTITER
) );
4465 if ( iter
== list_end( l
) )
4467 list_free( stack_pop( s
) );
4472 r
= list_new( object_copy( list_item( iter
) ) );
4473 iter
= list_next( iter
);
4474 *(LISTITER
*)stack_allocate( s
, sizeof( LISTITER
) ) = iter
;
4477 PROFILE_EXIT_LOCAL(function_run_INSTR_FOR_LOOP
);
4483 PROFILE_ENTER_LOCAL(function_run_INSTR_FOR_POP
);
4484 stack_deallocate( s
, sizeof( LISTITER
) );
4485 list_free( stack_pop( s
) );
4486 PROFILE_EXIT_LOCAL(function_run_INSTR_FOR_POP
);
4494 case INSTR_JUMP_NOT_GLOB
:
4496 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_NOT_GLOB
);
4497 char const * pattern
;
4501 pattern
= list_empty( l
) ? "" : object_str( list_front( l
) );
4502 match
= list_empty( r
) ? "" : object_str( list_front( r
) );
4503 if ( glob( pattern
, match
) )
4506 list_free( stack_pop( s
) );
4508 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_NOT_GLOB
);
4516 case INSTR_SET_RESULT
:
4518 PROFILE_ENTER_LOCAL(function_run_INSTR_SET_RESULT
);
4519 list_free( result
);
4521 result
= stack_pop( s
);
4523 result
= list_copy( stack_top( s
) );
4524 PROFILE_EXIT_LOCAL(function_run_INSTR_SET_RESULT
);
4528 case INSTR_PUSH_RESULT
:
4530 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_RESULT
);
4531 stack_push( s
, result
);
4533 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_RESULT
);
4539 PROFILE_ENTER_LOCAL(function_run_INSTR_RETURN
);
4540 if ( function_
->formal_arguments
)
4541 argument_list_pop( function_
->formal_arguments
,
4542 function_
->num_formal_arguments
, frame
, s
);
4544 if ( !( saved_stack
== s
->data
) )
4546 frame
->file
= function
->file
;
4547 frame
->line
= function
->line
;
4548 backtrace_line( frame
);
4549 out_printf( "error: stack check failed.\n" );
4551 assert( saved_stack
== s
->data
);
4553 assert( saved_stack
== s
->data
);
4555 debug_on_exit_function( function
->base
.rulename
);
4556 PROFILE_EXIT_LOCAL(function_run_INSTR_RETURN
);
4557 PROFILE_EXIT_LOCAL(function_run
);
4565 case INSTR_PUSH_LOCAL
:
4567 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_LOCAL
);
4568 LIST
* value
= stack_pop( s
);
4569 stack_push( s
, function_swap_variable( function
, frame
, code
->arg
,
4571 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_LOCAL
);
4575 case INSTR_POP_LOCAL
:
4577 PROFILE_ENTER_LOCAL(function_run_INSTR_POP_LOCAL
);
4578 function_set_variable( function
, frame
, code
->arg
, stack_pop( s
) );
4579 PROFILE_EXIT_LOCAL(function_run_INSTR_POP_LOCAL
);
4583 case INSTR_PUSH_LOCAL_FIXED
:
4585 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_LOCAL_FIXED
);
4586 LIST
* value
= stack_pop( s
);
4587 LIST
* * ptr
= &frame
->module
->fixed_variables
[ code
->arg
];
4588 assert( code
->arg
< frame
->module
->num_fixed_variables
);
4589 stack_push( s
, *ptr
);
4591 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_LOCAL_FIXED
);
4595 case INSTR_POP_LOCAL_FIXED
:
4597 PROFILE_ENTER_LOCAL(function_run_INSTR_POP_LOCAL_FIXED
);
4598 LIST
* value
= stack_pop( s
);
4599 LIST
* * ptr
= &frame
->module
->fixed_variables
[ code
->arg
];
4600 assert( code
->arg
< frame
->module
->num_fixed_variables
);
4603 PROFILE_EXIT_LOCAL(function_run_INSTR_POP_LOCAL_FIXED
);
4607 case INSTR_PUSH_LOCAL_GROUP
:
4609 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_LOCAL_GROUP
);
4610 LIST
* const value
= stack_pop( s
);
4614 for ( iter
= list_begin( l
), end
= list_end( l
); iter
!= end
;
4615 iter
= list_next( iter
) )
4616 stack_push( s
, function_swap_named_variable( function
, frame
,
4617 list_item( iter
), list_copy( value
) ) );
4620 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_LOCAL_GROUP
);
4624 case INSTR_POP_LOCAL_GROUP
:
4626 PROFILE_ENTER_LOCAL(function_run_INSTR_POP_LOCAL_GROUP
);
4630 l
= list_reverse( r
);
4632 for ( iter
= list_begin( l
), end
= list_end( l
); iter
!= end
;
4633 iter
= list_next( iter
) )
4634 function_set_named_variable( function
, frame
, list_item( iter
),
4637 PROFILE_EXIT_LOCAL(function_run_INSTR_POP_LOCAL_GROUP
);
4642 * on $(TARGET) variables
4647 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_ON
);
4648 LIST
* targets
= stack_top( s
);
4649 if ( !list_empty( targets
) )
4651 /* FIXME: push the state onto the stack instead of using
4654 TARGET
* t
= bindtarget( list_front( targets
) );
4655 pushsettings( frame
->module
, t
->settings
);
4659 /* [ on $(TARGET) ... ] is ignored if $(TARGET) is empty. */
4660 list_free( stack_pop( s
) );
4661 stack_push( s
, L0
);
4664 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_ON
);
4670 PROFILE_ENTER_LOCAL(function_run_INSTR_POP_ON
);
4671 LIST
* result
= stack_pop( s
);
4672 LIST
* targets
= stack_pop( s
);
4673 if ( !list_empty( targets
) )
4675 TARGET
* t
= bindtarget( list_front( targets
) );
4676 popsettings( frame
->module
, t
->settings
);
4678 list_free( targets
);
4679 stack_push( s
, result
);
4680 PROFILE_EXIT_LOCAL(function_run_INSTR_POP_ON
);
4686 PROFILE_ENTER_LOCAL(function_run_INSTR_SET_ON
);
4687 LIST
* targets
= stack_pop( s
);
4688 LIST
* value
= stack_pop( s
);
4689 LIST
* vars
= stack_pop( s
);
4690 LISTITER iter
= list_begin( targets
);
4691 LISTITER
const end
= list_end( targets
);
4692 for ( ; iter
!= end
; iter
= list_next( iter
) )
4694 TARGET
* t
= bindtarget( list_item( iter
) );
4695 LISTITER vars_iter
= list_begin( vars
);
4696 LISTITER
const vars_end
= list_end( vars
);
4697 for ( ; vars_iter
!= vars_end
; vars_iter
= list_next( vars_iter
4699 t
->settings
= addsettings( t
->settings
, VAR_SET
, list_item(
4700 vars_iter
), list_copy( value
) );
4703 list_free( targets
);
4704 stack_push( s
, value
);
4705 PROFILE_EXIT_LOCAL(function_run_INSTR_SET_ON
);
4709 case INSTR_APPEND_ON
:
4711 PROFILE_ENTER_LOCAL(function_run_INSTR_APPEND_ON
);
4712 LIST
* targets
= stack_pop( s
);
4713 LIST
* value
= stack_pop( s
);
4714 LIST
* vars
= stack_pop( s
);
4715 LISTITER iter
= list_begin( targets
);
4716 LISTITER
const end
= list_end( targets
);
4717 for ( ; iter
!= end
; iter
= list_next( iter
) )
4719 TARGET
* const t
= bindtarget( list_item( iter
) );
4720 LISTITER vars_iter
= list_begin( vars
);
4721 LISTITER
const vars_end
= list_end( vars
);
4722 for ( ; vars_iter
!= vars_end
; vars_iter
= list_next( vars_iter
4724 t
->settings
= addsettings( t
->settings
, VAR_APPEND
,
4725 list_item( vars_iter
), list_copy( value
) );
4728 list_free( targets
);
4729 stack_push( s
, value
);
4730 PROFILE_EXIT_LOCAL(function_run_INSTR_APPEND_ON
);
4734 case INSTR_DEFAULT_ON
:
4736 PROFILE_ENTER_LOCAL(function_run_INSTR_DEFAULT_ON
);
4737 LIST
* targets
= stack_pop( s
);
4738 LIST
* value
= stack_pop( s
);
4739 LIST
* vars
= stack_pop( s
);
4740 LISTITER iter
= list_begin( targets
);
4741 LISTITER
const end
= list_end( targets
);
4742 for ( ; iter
!= end
; iter
= list_next( iter
) )
4744 TARGET
* t
= bindtarget( list_item( iter
) );
4745 LISTITER vars_iter
= list_begin( vars
);
4746 LISTITER
const vars_end
= list_end( vars
);
4747 for ( ; vars_iter
!= vars_end
; vars_iter
= list_next( vars_iter
4749 t
->settings
= addsettings( t
->settings
, VAR_DEFAULT
,
4750 list_item( vars_iter
), list_copy( value
) );
4753 list_free( targets
);
4754 stack_push( s
, value
);
4755 PROFILE_EXIT_LOCAL(function_run_INSTR_DEFAULT_ON
);
4759 /* [ on $(target) return $(variable) ] */
4762 PROFILE_ENTER_LOCAL(function_run_INSTR_GET_ON
);
4763 LIST
* targets
= stack_pop( s
);
4765 if ( !list_empty( targets
) )
4767 OBJECT
* varname
= function
->constants
[ code
->arg
];
4768 TARGET
* t
= bindtarget( list_front( targets
) );
4769 SETTINGS
* s
= t
->settings
;
4771 for ( ; s
!= 0; s
= s
->next
)
4773 if ( object_equal( s
->symbol
, varname
) )
4782 result
= var_get( frame
->module
, varname
) ;
4785 list_free( targets
);
4786 stack_push( s
, list_copy( result
) );
4787 PROFILE_EXIT_LOCAL(function_run_INSTR_GET_ON
);
4797 PROFILE_ENTER_LOCAL(function_run_INSTR_SET
);
4798 function_set_variable( function
, frame
, code
->arg
,
4800 PROFILE_EXIT_LOCAL(function_run_INSTR_SET
);
4806 PROFILE_ENTER_LOCAL(function_run_INSTR_APPEND
);
4807 function_append_variable( function
, frame
, code
->arg
,
4809 PROFILE_EXIT_LOCAL(function_run_INSTR_APPEND
);
4815 PROFILE_ENTER_LOCAL(function_run_INSTR_DEFAULT
);
4816 function_default_variable( function
, frame
, code
->arg
,
4818 PROFILE_EXIT_LOCAL(function_run_INSTR_DEFAULT
);
4822 case INSTR_SET_FIXED
:
4824 PROFILE_ENTER_LOCAL(function_run_INSTR_SET_FIXED
);
4825 LIST
* * ptr
= &frame
->module
->fixed_variables
[ code
->arg
];
4826 assert( code
->arg
< frame
->module
->num_fixed_variables
);
4828 *ptr
= stack_pop( s
);
4829 PROFILE_EXIT_LOCAL(function_run_INSTR_SET_FIXED
);
4833 case INSTR_APPEND_FIXED
:
4835 PROFILE_ENTER_LOCAL(function_run_INSTR_APPEND_FIXED
);
4836 LIST
* * ptr
= &frame
->module
->fixed_variables
[ code
->arg
];
4837 assert( code
->arg
< frame
->module
->num_fixed_variables
);
4838 *ptr
= list_append( *ptr
, stack_pop( s
) );
4839 PROFILE_EXIT_LOCAL(function_run_INSTR_APPEND_FIXED
);
4843 case INSTR_DEFAULT_FIXED
:
4845 PROFILE_ENTER_LOCAL(function_run_INSTR_DEFAULT_FIXED
);
4846 LIST
* * ptr
= &frame
->module
->fixed_variables
[ code
->arg
];
4847 LIST
* value
= stack_pop( s
);
4848 assert( code
->arg
< frame
->module
->num_fixed_variables
);
4849 if ( list_empty( *ptr
) )
4853 PROFILE_EXIT_LOCAL(function_run_INSTR_DEFAULT_FIXED
);
4857 case INSTR_SET_GROUP
:
4859 PROFILE_ENTER_LOCAL(function_run_INSTR_SET_GROUP
);
4860 LIST
* value
= stack_pop( s
);
4861 LIST
* vars
= stack_pop( s
);
4862 LISTITER iter
= list_begin( vars
);
4863 LISTITER
const end
= list_end( vars
);
4864 for ( ; iter
!= end
; iter
= list_next( iter
) )
4865 function_set_named_variable( function
, frame
, list_item( iter
),
4866 list_copy( value
) );
4869 PROFILE_EXIT_LOCAL(function_run_INSTR_SET_GROUP
);
4873 case INSTR_APPEND_GROUP
:
4875 PROFILE_ENTER_LOCAL(function_run_INSTR_APPEND_GROUP
);
4876 LIST
* value
= stack_pop( s
);
4877 LIST
* vars
= stack_pop( s
);
4878 LISTITER iter
= list_begin( vars
);
4879 LISTITER
const end
= list_end( vars
);
4880 for ( ; iter
!= end
; iter
= list_next( iter
) )
4881 function_append_named_variable( function
, frame
, list_item( iter
4882 ), list_copy( value
) );
4885 PROFILE_EXIT_LOCAL(function_run_INSTR_APPEND_GROUP
);
4889 case INSTR_DEFAULT_GROUP
:
4891 PROFILE_ENTER_LOCAL(function_run_INSTR_DEFAULT_GROUP
);
4892 LIST
* value
= stack_pop( s
);
4893 LIST
* vars
= stack_pop( s
);
4894 LISTITER iter
= list_begin( vars
);
4895 LISTITER
const end
= list_end( vars
);
4896 for ( ; iter
!= end
; iter
= list_next( iter
) )
4897 function_default_named_variable( function
, frame
, list_item(
4898 iter
), list_copy( value
) );
4901 PROFILE_EXIT_LOCAL(function_run_INSTR_DEFAULT_GROUP
);
4909 case INSTR_CALL_RULE
:
4911 PROFILE_ENTER_LOCAL(function_run_INSTR_CALL_RULE
);
4912 char const * unexpanded
= object_str( function_get_constant(
4913 function
, code
[ 1 ].op_code
) );
4914 LIST
* result
= function_call_rule( function
, frame
, s
, code
->arg
,
4915 unexpanded
, function
->file
, code
[ 1 ].arg
);
4916 stack_push( s
, result
);
4918 PROFILE_EXIT_LOCAL(function_run_INSTR_CALL_RULE
);
4922 case INSTR_CALL_MEMBER_RULE
:
4924 PROFILE_ENTER_LOCAL(function_run_INSTR_CALL_MEMBER_RULE
);
4925 OBJECT
* rule_name
= function_get_constant( function
, code
[1].op_code
);
4926 LIST
* result
= function_call_member_rule( function
, frame
, s
, code
->arg
, rule_name
, function
->file
, code
[1].arg
);
4927 stack_push( s
, result
);
4929 PROFILE_EXIT_LOCAL(function_run_INSTR_CALL_MEMBER_RULE
);
4935 PROFILE_ENTER_LOCAL(function_run_INSTR_RULE
);
4936 function_set_rule( function
, frame
, s
, code
->arg
);
4937 PROFILE_EXIT_LOCAL(function_run_INSTR_RULE
);
4943 PROFILE_ENTER_LOCAL(function_run_INSTR_ACTIONS
);
4944 function_set_actions( function
, frame
, s
, code
->arg
);
4945 PROFILE_EXIT_LOCAL(function_run_INSTR_ACTIONS
);
4950 * Variable expansion
4953 case INSTR_APPLY_MODIFIERS
:
4955 PROFILE_ENTER_LOCAL(function_run_INSTR_APPLY_MODIFIERS
);
4959 n
= expand_modifiers( s
, code
->arg
);
4961 VAR_EXPANDED m
= apply_modifiers( s
, n
);
4963 list_free( m
.inner
);
4964 list_free( stack_pop( s
) );
4965 stack_deallocate( s
, n
* sizeof( VAR_EDITS
) );
4966 for ( i
= 0; i
< code
->arg
; ++i
)
4967 list_free( stack_pop( s
) ); /* pop modifiers */
4969 PROFILE_EXIT_LOCAL(function_run_INSTR_APPLY_MODIFIERS
);
4973 case INSTR_APPLY_INDEX
:
4975 PROFILE_ENTER_LOCAL(function_run_INSTR_APPLY_INDEX
);
4976 l
= apply_subscript( s
);
4977 list_free( stack_pop( s
) );
4978 list_free( stack_pop( s
) );
4980 PROFILE_EXIT_LOCAL(function_run_INSTR_APPLY_INDEX
);
4984 case INSTR_APPLY_INDEX_MODIFIERS
:
4986 PROFILE_ENTER_LOCAL(function_run_INSTR_APPLY_INDEX_MODIFIERS
);
4991 n
= expand_modifiers( s
, code
->arg
);
4994 l
= apply_subscript_and_modifiers( s
, n
);
4995 list_free( stack_pop( s
) );
4996 list_free( stack_pop( s
) );
4997 stack_deallocate( s
, n
* sizeof( VAR_EDITS
) );
4998 for ( i
= 0; i
< code
->arg
; ++i
)
4999 list_free( stack_pop( s
) ); /* pop modifiers */
5001 PROFILE_EXIT_LOCAL(function_run_INSTR_APPLY_INDEX_MODIFIERS
);
5005 case INSTR_APPLY_MODIFIERS_GROUP
:
5007 PROFILE_ENTER_LOCAL(function_run_INSTR_APPLY_MODIFIERS_GROUP
);
5009 LIST
* const vars
= stack_pop( s
);
5010 int32_t const n
= expand_modifiers( s
, code
->arg
);
5012 LISTITER iter
= list_begin( vars
);
5013 LISTITER
const end
= list_end( vars
);
5014 for ( ; iter
!= end
; iter
= list_next( iter
) )
5016 stack_push( s
, function_get_named_variable( function
, frame
,
5017 list_item( iter
) ) );
5018 VAR_EXPANDED m
= apply_modifiers( s
, n
);
5020 list_free( m
.inner
);
5021 list_free( stack_pop( s
) );
5024 stack_deallocate( s
, n
* sizeof( VAR_EDITS
) );
5025 for ( i
= 0; i
< code
->arg
; ++i
)
5026 list_free( stack_pop( s
) ); /* pop modifiers */
5027 stack_push( s
, result
);
5028 PROFILE_EXIT_LOCAL(function_run_INSTR_APPLY_MODIFIERS_GROUP
);
5032 case INSTR_APPLY_INDEX_GROUP
:
5034 PROFILE_ENTER_LOCAL(function_run_INSTR_APPLY_INDEX_GROUP
);
5035 LIST
* vars
= stack_pop( s
);
5037 LISTITER iter
= list_begin( vars
);
5038 LISTITER
const end
= list_end( vars
);
5039 for ( ; iter
!= end
; iter
= list_next( iter
) )
5041 stack_push( s
, function_get_named_variable( function
, frame
,
5042 list_item( iter
) ) );
5043 result
= list_append( result
, apply_subscript( s
) );
5044 list_free( stack_pop( s
) );
5047 list_free( stack_pop( s
) );
5048 stack_push( s
, result
);
5049 PROFILE_EXIT_LOCAL(function_run_INSTR_APPLY_INDEX_GROUP
);
5053 case INSTR_APPLY_INDEX_MODIFIERS_GROUP
:
5055 PROFILE_ENTER_LOCAL(function_run_INSTR_APPLY_INDEX_MODIFIERS_GROUP
);
5057 LIST
* const vars
= stack_pop( s
);
5058 LIST
* const r
= stack_pop( s
);
5059 int32_t const n
= expand_modifiers( s
, code
->arg
);
5061 LISTITER iter
= list_begin( vars
);
5062 LISTITER
const end
= list_end( vars
);
5064 for ( ; iter
!= end
; iter
= list_next( iter
) )
5066 stack_push( s
, function_get_named_variable( function
, frame
,
5067 list_item( iter
) ) );
5068 result
= list_append( result
, apply_subscript_and_modifiers( s
,
5070 list_free( stack_pop( s
) );
5072 list_free( stack_pop( s
) );
5074 stack_deallocate( s
, n
* sizeof( VAR_EDITS
) );
5075 for ( i
= 0; i
< code
->arg
; ++i
)
5076 list_free( stack_pop( s
) ); /* pop modifiers */
5077 stack_push( s
, result
);
5078 PROFILE_EXIT_LOCAL(function_run_INSTR_APPLY_INDEX_MODIFIERS_GROUP
);
5082 case INSTR_COMBINE_STRINGS
:
5084 PROFILE_ENTER_LOCAL(function_run_INSTR_COMBINE_STRINGS
);
5085 int32_t const buffer_size
= code
->arg
* sizeof( expansion_item
);
5086 LIST
* * const stack_pos
= (LIST
* * const)stack_get( s
);
5087 expansion_item
* items
= (expansion_item
*)stack_allocate( s
, buffer_size
);
5090 for ( i
= 0; i
< code
->arg
; ++i
)
5091 items
[ i
].values
= stack_pos
[ i
];
5092 result
= expand( items
, code
->arg
);
5093 stack_deallocate( s
, buffer_size
);
5094 for ( i
= 0; i
< code
->arg
; ++i
)
5095 list_free( stack_pop( s
) );
5096 stack_push( s
, result
);
5097 PROFILE_EXIT_LOCAL(function_run_INSTR_COMBINE_STRINGS
);
5101 case INSTR_GET_GRIST
:
5103 PROFILE_ENTER_LOCAL(function_run_INSTR_GET_GRIST
);
5104 LIST
* vals
= stack_pop( s
);
5108 for ( iter
= list_begin( vals
), end
= list_end( vals
); iter
!= end
; ++iter
)
5110 OBJECT
* new_object
;
5111 const char * value
= object_str( list_item( iter
) );
5113 if ( value
[ 0 ] == '<' && ( p
= strchr( value
, '>' ) ) )
5116 new_object
= object_new_range( value
, int32_t(p
- value
+ 1) );
5118 new_object
= object_copy( list_item( iter
) );
5122 new_object
= object_copy( constant_empty
);
5124 result
= list_push_back( result
, new_object
);
5128 stack_push( s
, result
);
5129 PROFILE_EXIT_LOCAL(function_run_INSTR_GET_GRIST
);
5135 PROFILE_ENTER_LOCAL(function_run_INSTR_INCLUDE
);
5136 LIST
* nt
= stack_pop( s
);
5137 if ( !list_empty( nt
) )
5139 TARGET
* const t
= bindtarget( list_front( nt
) );
5142 /* DWA 2001/10/22 - Perforce Jam cleared the arguments here,
5143 * which prevented an included file from being treated as part
5144 * of the body of a rule. I did not see any reason to do that,
5145 * so I lifted the restriction.
5148 /* Bind the include file under the influence of "on-target"
5149 * variables. Though they are targets, include files are not
5150 * built with make().
5153 pushsettings( root_module(), t
->settings
);
5154 /* We do not expect that a file to be included is generated by
5155 * some action. Therefore, pass 0 as third argument. If the name
5156 * resolves to a directory, let it error out.
5158 object_free( t
->boundname
);
5159 t
->boundname
= search( t
->name
, &t
->time
, 0, 0 );
5160 popsettings( root_module(), t
->settings
);
5162 parse_file( t
->boundname
, frame
);
5164 frame
->function
= function_
;
5167 PROFILE_EXIT_LOCAL(function_run_INSTR_INCLUDE
);
5172 * Classes and modules
5175 case INSTR_PUSH_MODULE
:
5177 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_MODULE
);
5178 LIST
* const module_name
= stack_pop( s
);
5179 module_t
* const outer_module
= frame
->module
;
5180 frame
->module
= !list_empty( module_name
)
5181 ? bindmodule( list_front( module_name
) )
5183 list_free( module_name
);
5184 *(module_t
* *)stack_allocate( s
, sizeof( module_t
* ) ) =
5186 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_MODULE
);
5190 case INSTR_POP_MODULE
:
5192 PROFILE_ENTER_LOCAL(function_run_INSTR_POP_MODULE
);
5193 module_t
* const outer_module
= *(module_t
* *)stack_get( s
);
5194 stack_deallocate( s
, sizeof( module_t
* ) );
5195 frame
->module
= outer_module
;
5196 PROFILE_EXIT_LOCAL(function_run_INSTR_POP_MODULE
);
5202 PROFILE_ENTER_LOCAL(function_run_INSTR_CLASS
);
5203 LIST
* bases
= stack_pop( s
);
5204 LIST
* name
= stack_pop( s
);
5205 OBJECT
* class_module
= make_class_module( name
, bases
, frame
);
5207 module_t
* const outer_module
= frame
->module
;
5208 frame
->module
= bindmodule( class_module
);
5209 object_free( class_module
);
5211 *(module_t
* *)stack_allocate( s
, sizeof( module_t
* ) ) =
5213 PROFILE_EXIT_LOCAL(function_run_INSTR_CLASS
);
5217 case INSTR_BIND_MODULE_VARIABLES
:
5219 PROFILE_ENTER_LOCAL(function_run_INSTR_BIND_MODULE_VARIABLES
);
5220 module_bind_variables( frame
->module
);
5221 PROFILE_EXIT_LOCAL(function_run_INSTR_BIND_MODULE_VARIABLES
);
5225 case INSTR_APPEND_STRINGS
:
5227 PROFILE_ENTER_LOCAL(function_run_INSTR_APPEND_STRINGS
);
5230 combine_strings( s
, code
->arg
, buf
);
5231 stack_push( s
, list_new( object_new( buf
->value
) ) );
5233 PROFILE_EXIT_LOCAL(function_run_INSTR_APPEND_STRINGS
);
5237 // WRITE_FILE( LIST*1 filename, LIST*1 modifiers[N], LIST*1 contents )
5238 case INSTR_WRITE_FILE
:
5240 PROFILE_ENTER_LOCAL(function_run_INSTR_WRITE_FILE
);
5241 // Get expanded filename.
5242 LIST
* filename
= nullptr;
5244 expansion_item ei
= { stack_pop( s
) };
5245 filename
= expand( &ei
, 1 );
5246 list_free( ei
.values
);
5248 // Apply modifiers to "raw" filename.
5249 VAR_EXPANDED filename_mod
= eval_modifiers( s
, filename
, code
->arg
);
5251 LIST
* contents
= stack_pop( s
);
5252 // Write out the contents file, or expand the contents, as needed.
5253 LIST
* filename_or_contents
= function_execute_write_file( function
, frame
, s
, filename_mod
, contents
);
5254 // The result that gets replaced into the @() space.
5255 stack_push( s
, filename_or_contents
);
5256 list_free( filename_mod
.value
);
5257 list_free( filename_mod
.inner
);
5258 list_free( contents
);
5259 PROFILE_EXIT_LOCAL(function_run_INSTR_WRITE_FILE
);
5263 case INSTR_OUTPUT_STRINGS
:
5265 PROFILE_ENTER_LOCAL(function_run_INSTR_OUTPUT_STRINGS
);
5266 string
* const buf
= *(string
* *)( (char *)stack_get( s
) + (
5267 code
->arg
* sizeof( LIST
* ) ) );
5268 combine_strings( s
, code
->arg
, buf
);
5269 PROFILE_EXIT_LOCAL(function_run_INSTR_OUTPUT_STRINGS
);
5273 case INSTR_DEBUG_LINE
:
5275 debug_on_instruction( frame
, function
->file
, code
->arg
);
5283 PROFILE_EXIT_LOCAL(function_run
);
5289 static struct arg_list
* arg_list_compile_python( PyObject
* bjam_signature
,
5290 int32_t * num_arguments
)
5292 if ( bjam_signature
)
5294 struct argument_list_compiler c
[ 1 ];
5295 struct arg_list
* result
;
5298 argument_list_compiler_init( c
);
5300 s
= PySequence_Size( bjam_signature
);
5301 for ( i
= 0; i
< s
; ++i
)
5303 struct argument_compiler arg_comp
[ 1 ];
5304 struct arg_list arg
;
5305 PyObject
* v
= PySequence_GetItem( bjam_signature
, i
);
5308 argument_compiler_init( arg_comp
);
5310 inner
= PySequence_Size( v
);
5311 for ( j
= 0; j
< inner
; ++j
)
5312 argument_compiler_add( arg_comp
, object_new( PyString_AsString(
5313 PySequence_GetItem( v
, j
) ) ), constant_builtin
, -1 );
5315 arg
= arg_compile_impl( arg_comp
, constant_builtin
, -1 );
5316 dynamic_array_push( c
->args
, arg
);
5317 argument_compiler_free( arg_comp
);
5321 *num_arguments
= c
->args
->size
;
5322 result
= (struct arg_list
*)BJAM_MALLOC( c
->args
->size
* sizeof( struct arg_list
) );
5323 memcpy( result
, c
->args
->data
, c
->args
->size
* sizeof( struct arg_list
)
5325 argument_list_compiler_free( c
);
5332 FUNCTION
* function_python( PyObject
* function
, PyObject
* bjam_signature
)
5334 PYTHON_FUNCTION
* result
= (PYTHON_FUNCTION
*)BJAM_MALLOC( sizeof( PYTHON_FUNCTION
) );
5336 result
->base
.type
= FUNCTION_PYTHON
;
5337 result
->base
.reference_count
= 1;
5338 result
->base
.rulename
= 0;
5339 result
->base
.formal_arguments
= arg_list_compile_python( bjam_signature
,
5340 &result
->base
.num_formal_arguments
);
5341 Py_INCREF( function
);
5342 result
->python_function
= function
;
5344 return (FUNCTION
*)result
;
5348 static void argument_list_to_python( struct arg_list
* formal
, int32_t formal_count
,
5349 FUNCTION
* function
, FRAME
* frame
, PyObject
* kw
)
5351 LOL
* all_actual
= frame
->args
;
5354 for ( i
= 0; i
< formal_count
; ++i
)
5356 LIST
* actual
= lol_get( all_actual
, i
);
5357 LISTITER actual_iter
= list_begin( actual
);
5358 LISTITER
const actual_end
= list_end( actual
);
5360 for ( j
= 0; j
< formal
[ i
].size
; ++j
)
5362 struct argument
* formal_arg
= &formal
[ i
].args
[ j
];
5366 switch ( formal_arg
->flags
)
5369 if ( actual_iter
== actual_end
)
5370 argument_error( "missing argument", function
, frame
,
5371 formal_arg
->arg_name
);
5372 type_check_range( formal_arg
->type_name
, actual_iter
, list_next(
5373 actual_iter
), frame
, function
, formal_arg
->arg_name
);
5374 value
= PyString_FromString( object_str( list_item( actual_iter
5376 actual_iter
= list_next( actual_iter
);
5379 if ( actual_iter
== actual_end
)
5383 type_check_range( formal_arg
->type_name
, actual_iter
,
5384 list_next( actual_iter
), frame
, function
,
5385 formal_arg
->arg_name
);
5386 value
= PyString_FromString( object_str( list_item(
5388 actual_iter
= list_next( actual_iter
);
5392 if ( actual_iter
== actual_end
)
5393 argument_error( "missing argument", function
, frame
,
5394 formal_arg
->arg_name
);
5397 type_check_range( formal_arg
->type_name
, actual_iter
,
5398 actual_end
, frame
, function
, formal_arg
->arg_name
);
5399 l
= list_copy_range( actual
, actual_iter
, actual_end
);
5400 value
= list_to_python( l
);
5402 actual_iter
= actual_end
;
5410 PyObject
* key
= PyString_FromString( object_str(
5411 formal_arg
->arg_name
) );
5412 PyDict_SetItem( kw
, key
, value
);
5418 if ( actual_iter
!= actual_end
)
5419 argument_error( "extra argument", function
, frame
, list_item(
5423 for ( ; i
< all_actual
->count
; ++i
)
5425 LIST
* const actual
= lol_get( all_actual
, i
);
5426 if ( !list_empty( actual
) )
5427 argument_error( "extra argument", function
, frame
, list_front(
5433 /* Given a Python object, return a string to use in Jam code instead of the said
5436 * If the object is a string, use the string value.
5437 * If the object implemenets __jam_repr__ method, use that.
5438 * Otherwise return 0.
5441 OBJECT
* python_to_string( PyObject
* value
)
5443 if ( PyString_Check( value
) )
5444 return object_new( PyString_AS_STRING( value
) );
5446 /* See if this instance defines the special __jam_repr__ method. */
5447 if ( PyInstance_Check( value
)
5448 && PyObject_HasAttrString( value
, "__jam_repr__" ) )
5450 PyObject
* repr
= PyObject_GetAttrString( value
, "__jam_repr__" );
5453 PyObject
* arguments2
= PyTuple_New( 0 );
5454 PyObject
* value2
= PyObject_Call( repr
, arguments2
, 0 );
5456 Py_DECREF( arguments2
);
5457 if ( PyString_Check( value2
) )
5458 return object_new( PyString_AS_STRING( value2
) );
5459 Py_DECREF( value2
);
5466 static module_t
* python_module()
5468 static module_t
* python
= 0;
5470 python
= bindmodule( constant_python
);
5475 static LIST
* call_python_function( PYTHON_FUNCTION
* function
, FRAME
* frame
)
5478 PyObject
* arguments
= 0;
5479 PyObject
* kw
= NULL
;
5481 PyObject
* py_result
;
5482 FRAME
* prev_frame_before_python_call
;
5484 if ( function
->base
.formal_arguments
)
5486 arguments
= PyTuple_New( 0 );
5488 argument_list_to_python( function
->base
.formal_arguments
,
5489 function
->base
.num_formal_arguments
, &function
->base
, frame
, kw
);
5493 arguments
= PyTuple_New( frame
->args
->count
);
5494 for ( i
= 0; i
< frame
->args
->count
; ++i
)
5495 PyTuple_SetItem( arguments
, i
, list_to_python( lol_get( frame
->args
,
5499 frame
->module
= python_module();
5501 prev_frame_before_python_call
= frame_before_python_call
;
5502 frame_before_python_call
= frame
;
5503 py_result
= PyObject_Call( function
->python_function
, arguments
, kw
);
5504 frame_before_python_call
= prev_frame_before_python_call
;
5505 Py_DECREF( arguments
);
5507 if ( py_result
!= NULL
)
5509 if ( PyList_Check( py_result
) )
5511 int32_t size
= PyList_Size( py_result
);
5513 for ( i
= 0; i
< size
; ++i
)
5515 OBJECT
* s
= python_to_string( PyList_GetItem( py_result
, i
) );
5518 "Non-string object returned by Python call.\n" );
5520 result
= list_push_back( result
, s
);
5523 else if ( py_result
== Py_None
)
5529 OBJECT
* const s
= python_to_string( py_result
);
5531 result
= list_new( s
);
5533 /* We have tried all we could. Return empty list. There are
5534 * cases, e.g. feature.feature function that should return a
5535 * value for the benefit of Python code and which also can be
5536 * called by Jam code, where no sensible value can be returned.
5537 * We cannot even emit a warning, since there would be a pile of
5543 Py_DECREF( py_result
);
5548 err_printf( "Call failed\n" );
5557 void function_done( void )