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_1_0.txt or copy at
6 * http://www.boost.org/LICENSE_1_0.txt)
14 #include "constants.h"
32 #define FUNCTION_DEBUG_PROFILE
35 #ifndef FUNCTION_DEBUG_PROFILE
36 #undef PROFILE_ENTER_LOCAL
37 #define PROFILE_ENTER_LOCAL(x) while (false)
38 #undef PROFILE_EXIT_LOCAL
39 #define PROFILE_EXIT_LOCAL(x)
42 int glob( char const * s
, char const * c
);
43 void backtrace( FRAME
* );
44 void backtrace_line( FRAME
* );
46 #define INSTR_PUSH_EMPTY 0
47 #define INSTR_PUSH_CONSTANT 1
48 #define INSTR_PUSH_ARG 2
49 #define INSTR_PUSH_VAR 3
50 #define INSTR_PUSH_VAR_FIXED 57
51 #define INSTR_PUSH_GROUP 4
52 #define INSTR_PUSH_RESULT 5
53 #define INSTR_PUSH_APPEND 6
56 #define INSTR_JUMP_EMPTY 8
57 #define INSTR_JUMP_NOT_EMPTY 9
60 #define INSTR_JUMP_LT 11
61 #define INSTR_JUMP_LE 12
62 #define INSTR_JUMP_GT 13
63 #define INSTR_JUMP_GE 14
64 #define INSTR_JUMP_EQ 15
65 #define INSTR_JUMP_NE 16
66 #define INSTR_JUMP_IN 17
67 #define INSTR_JUMP_NOT_IN 18
69 #define INSTR_JUMP_NOT_GLOB 19
71 #define INSTR_FOR_INIT 56
72 #define INSTR_FOR_LOOP 20
74 #define INSTR_SET_RESULT 21
75 #define INSTR_RETURN 22
78 #define INSTR_PUSH_LOCAL 24
79 #define INSTR_POP_LOCAL 25
81 #define INSTR_APPEND 27
82 #define INSTR_DEFAULT 28
84 #define INSTR_PUSH_LOCAL_FIXED 58
85 #define INSTR_POP_LOCAL_FIXED 59
86 #define INSTR_SET_FIXED 60
87 #define INSTR_APPEND_FIXED 61
88 #define INSTR_DEFAULT_FIXED 62
90 #define INSTR_PUSH_LOCAL_GROUP 29
91 #define INSTR_POP_LOCAL_GROUP 30
92 #define INSTR_SET_GROUP 31
93 #define INSTR_APPEND_GROUP 32
94 #define INSTR_DEFAULT_GROUP 33
96 #define INSTR_PUSH_ON 34
97 #define INSTR_POP_ON 35
98 #define INSTR_SET_ON 36
99 #define INSTR_APPEND_ON 37
100 #define INSTR_DEFAULT_ON 38
101 #define INSTR_GET_ON 65
103 #define INSTR_CALL_RULE 39
104 #define INSTR_CALL_MEMBER_RULE 66
106 #define INSTR_APPLY_MODIFIERS 40
107 #define INSTR_APPLY_INDEX 41
108 #define INSTR_APPLY_INDEX_MODIFIERS 42
109 #define INSTR_APPLY_MODIFIERS_GROUP 43
110 #define INSTR_APPLY_INDEX_GROUP 44
111 #define INSTR_APPLY_INDEX_MODIFIERS_GROUP 45
112 #define INSTR_COMBINE_STRINGS 46
113 #define INSTR_GET_GRIST 64
115 #define INSTR_INCLUDE 47
116 #define INSTR_RULE 48
117 #define INSTR_ACTIONS 49
118 #define INSTR_PUSH_MODULE 50
119 #define INSTR_POP_MODULE 51
120 #define INSTR_CLASS 52
121 #define INSTR_BIND_MODULE_VARIABLES 63
123 #define INSTR_APPEND_STRINGS 53
124 #define INSTR_WRITE_FILE 54
125 #define INSTR_OUTPUT_STRINGS 55
127 #define INSTR_DEBUG_LINE 67
128 #define INSTR_FOR_POP 70
130 typedef struct instruction
132 unsigned int op_code
;
136 typedef struct _subfunction
143 typedef struct _subaction
150 #define FUNCTION_BUILTIN 0
151 #define FUNCTION_JAM 1
157 #define ARG_OPTIONAL 1
160 #define ARG_VARIADIC 4
169 struct argument
* args
;
177 struct arg_list
* formal_arguments
;
178 int num_formal_arguments
;
181 typedef struct _builtin_function
184 LIST
* ( * func
)( FRAME
*, int flags
);
188 typedef struct _jam_function
194 OBJECT
* * constants
;
195 int num_subfunctions
;
196 SUBFUNCTION
* functions
;
207 #define FUNCTION_PYTHON 2
209 typedef struct _python_function
212 PyObject
* python_function
;
215 static LIST
* call_python_function( PYTHON_FUNCTION
*, FRAME
* );
227 STACK
* stack_global()
232 int const size
= 1 << 21;
233 stack
= BJAM_MALLOC( size
);
234 result
.data
= (char *)stack
+ size
;
239 struct list_alignment_helper
245 #define LISTPTR_ALIGN_BASE ( sizeof( struct list_alignment_helper ) - sizeof( LIST * ) )
246 #define LISTPTR_ALIGN ( ( LISTPTR_ALIGN_BASE > sizeof( LIST * ) ) ? sizeof( LIST * ) : LISTPTR_ALIGN_BASE )
248 static void check_alignment( STACK
* s
)
250 assert( (size_t)s
->data
% LISTPTR_ALIGN
== 0 );
253 void * stack_allocate( STACK
* s
, int size
)
255 check_alignment( s
);
256 s
->data
= (char *)s
->data
- size
;
257 check_alignment( s
);
261 void stack_deallocate( STACK
* s
, int size
)
263 check_alignment( s
);
264 s
->data
= (char *)s
->data
+ size
;
265 check_alignment( s
);
268 void stack_push( STACK
* s
, LIST
* l
)
270 *(LIST
* *)stack_allocate( s
, sizeof( LIST
* ) ) = l
;
273 LIST
* stack_pop( STACK
* s
)
275 LIST
* const result
= *(LIST
* *)s
->data
;
276 stack_deallocate( s
, sizeof( LIST
* ) );
280 LIST
* stack_top( STACK
* s
)
282 check_alignment( s
);
283 return *(LIST
* *)s
->data
;
286 LIST
* stack_at( STACK
* s
, int n
)
288 check_alignment( s
);
289 return *( (LIST
* *)s
->data
+ n
);
292 void stack_set( STACK
* s
, int n
, LIST
* value
)
294 check_alignment( s
);
295 *((LIST
* *)s
->data
+ n
) = value
;
298 void * stack_get( STACK
* s
)
300 check_alignment( s
);
304 LIST
* frame_get_local( FRAME
* frame
, int idx
)
306 /* The only local variables are the arguments. */
307 return list_copy( lol_get( frame
->args
, idx
) );
310 static OBJECT
* function_get_constant( JAM_FUNCTION
* function
, int idx
)
312 return function
->constants
[ idx
];
315 static LIST
* function_get_variable( JAM_FUNCTION
* function
, FRAME
* frame
,
318 return list_copy( var_get( frame
->module
, function
->constants
[ idx
] ) );
321 static void function_set_variable( JAM_FUNCTION
* function
, FRAME
* frame
,
322 int idx
, LIST
* value
)
324 var_set( frame
->module
, function
->constants
[ idx
], value
, VAR_SET
);
327 static LIST
* function_swap_variable( JAM_FUNCTION
* function
, FRAME
* frame
,
328 int idx
, LIST
* value
)
330 return var_swap( frame
->module
, function
->constants
[ idx
], value
);
333 static void function_append_variable( JAM_FUNCTION
* function
, FRAME
* frame
,
334 int idx
, LIST
* value
)
336 var_set( frame
->module
, function
->constants
[ idx
], value
, VAR_APPEND
);
339 static void function_default_variable( JAM_FUNCTION
* function
, FRAME
* frame
,
340 int idx
, LIST
* value
)
342 var_set( frame
->module
, function
->constants
[ idx
], value
, VAR_DEFAULT
);
345 static void function_set_rule( JAM_FUNCTION
* function
, FRAME
* frame
,
348 SUBFUNCTION
* sub
= function
->functions
+ idx
;
349 new_rule_body( frame
->module
, sub
->name
, sub
->code
, !sub
->local
);
352 static void function_set_actions( JAM_FUNCTION
* function
, FRAME
* frame
,
355 SUBACTION
* sub
= function
->actions
+ idx
;
356 LIST
* bindlist
= stack_pop( s
);
357 new_rule_actions( frame
->module
, sub
->name
, sub
->command
, bindlist
,
363 * Returns the index if name is "<", ">", "1", "2", ... or "19" otherwise
367 static int get_argument_index( char const * s
)
371 if ( s
[ 1 ] == '\0' )
390 else if ( s
[ 0 ] == '1' && s
[ 2 ] == '\0' )
404 return s
[ 1 ] - '0' + 10 - 1;
411 static LIST
* function_get_named_variable( JAM_FUNCTION
* function
,
412 FRAME
* frame
, OBJECT
* name
)
414 int const idx
= get_argument_index( object_str( name
) );
416 ? list_copy( var_get( frame
->module
, name
) )
417 : list_copy( lol_get( frame
->args
, idx
) );
420 static void function_set_named_variable( JAM_FUNCTION
* function
, FRAME
* frame
,
421 OBJECT
* name
, LIST
* value
)
423 var_set( frame
->module
, name
, value
, VAR_SET
);
426 static LIST
* function_swap_named_variable( JAM_FUNCTION
* function
,
427 FRAME
* frame
, OBJECT
* name
, LIST
* value
)
429 return var_swap( frame
->module
, name
, value
);
432 static void function_append_named_variable( JAM_FUNCTION
* function
,
433 FRAME
* frame
, OBJECT
* name
, LIST
* value
)
435 var_set( frame
->module
, name
, value
, VAR_APPEND
);
438 static void function_default_named_variable( JAM_FUNCTION
* function
,
439 FRAME
* frame
, OBJECT
* name
, LIST
* value
)
441 var_set( frame
->module
, name
, value
, VAR_DEFAULT
);
444 static LIST
* function_call_rule( JAM_FUNCTION
* function
, FRAME
* frame
,
445 STACK
* s
, int n_args
, char const * unexpanded
, OBJECT
* file
, int line
)
449 LIST
* first
= stack_pop( s
);
457 if ( list_empty( first
) )
459 backtrace_line( frame
);
460 out_printf( "warning: rulename %s expands to empty string\n", unexpanded
);
463 for ( i
= 0; i
< n_args
; ++i
)
464 list_free( stack_pop( s
) );
468 rulename
= object_copy( list_front( first
) );
472 inner
->prev_user
= frame
->module
->user_module
? frame
: frame
->prev_user
;
473 inner
->module
= frame
->module
; /* This gets fixed up in evaluate_rule(). */
475 for ( i
= 0; i
< n_args
; ++i
)
476 lol_add( inner
->args
, stack_at( s
, n_args
- i
- 1 ) );
478 for ( i
= 0; i
< n_args
; ++i
)
481 trailing
= list_pop_front( first
);
484 if ( inner
->args
->count
== 0 )
485 lol_add( inner
->args
, trailing
);
488 LIST
* * const l
= &inner
->args
->list
[ 0 ];
489 *l
= list_append( trailing
, *l
);
493 result
= evaluate_rule( bindrule( rulename
, inner
->module
), rulename
, inner
);
495 object_free( rulename
);
499 static LIST
* function_call_member_rule( JAM_FUNCTION
* function
, FRAME
* frame
, STACK
* s
, int n_args
, OBJECT
* rulename
, OBJECT
* file
, int line
)
503 LIST
* first
= stack_pop( s
);
507 OBJECT
* real_rulename
= 0;
512 if ( list_empty( first
) )
514 backtrace_line( frame
);
515 out_printf( "warning: object is empty\n" );
520 for( i
= 0; i
< n_args
; ++i
)
522 list_free( stack_pop( s
) );
528 /* FIXME: handle generic case */
529 assert( list_length( first
) == 1 );
531 module
= bindmodule( list_front( first
) );
532 if ( module
->class_module
)
534 rule
= bindrule( rulename
, module
);
535 if ( rule
->procedure
)
537 real_rulename
= object_copy( function_rulename( rule
->procedure
) );
543 string_append( buf
, object_str( module
->name
) );
544 string_push_back( buf
, '.' );
545 string_append( buf
, object_str( rulename
) );
546 real_rulename
= object_new( buf
->value
);
554 string_append( buf
, object_str( list_front( first
) ) );
555 string_push_back( buf
, '.' );
556 string_append( buf
, object_str( rulename
) );
557 real_rulename
= object_new( buf
->value
);
559 rule
= bindrule( real_rulename
, frame
->module
);
565 inner
->prev_user
= frame
->module
->user_module
? frame
: frame
->prev_user
;
566 inner
->module
= frame
->module
; /* This gets fixed up in evaluate_rule(), below. */
568 for( i
= 0; i
< n_args
; ++i
)
570 lol_add( inner
->args
, stack_at( s
, n_args
- i
- 1 ) );
573 for( i
= 0; i
< n_args
; ++i
)
578 if ( list_length( first
) > 1 )
581 LIST
* trailing
= L0
;
582 LISTITER iter
= list_begin( first
), end
= list_end( first
);
583 iter
= list_next( iter
);
585 for ( ; iter
!= end
; iter
= list_next( iter
) )
587 string_append( buf
, object_str( list_item( iter
) ) );
588 string_push_back( buf
, '.' );
589 string_append( buf
, object_str( rulename
) );
590 trailing
= list_push_back( trailing
, object_new( buf
->value
) );
591 string_truncate( buf
, 0 );
594 if ( inner
->args
->count
== 0 )
595 lol_add( inner
->args
, trailing
);
598 LIST
* * const l
= &inner
->args
->list
[ 0 ];
599 *l
= list_append( trailing
, *l
);
604 result
= evaluate_rule( rule
, real_rulename
, inner
);
606 object_free( real_rulename
);
611 /* Variable expansion */
621 PATHNAME f
; /* :GDBSMR -- pieces */
622 char parent
; /* :P -- go to parent directory */
623 char filemods
; /* one of the above applied */
624 char downshift
; /* :L -- downshift result */
625 char upshift
; /* :U -- upshift result */
626 char to_slashes
; /* :T -- convert "\" to "/" */
627 char to_windows
; /* :W -- convert cygwin to native paths */
628 PATHPART empty
; /* :E -- default for empties */
629 PATHPART join
; /* :J -- join list with char */
632 static LIST
* apply_modifiers_impl( LIST
* result
, string
* buf
,
633 VAR_EDITS
* edits
, int n
, LISTITER iter
, LISTITER end
);
634 static void get_iters( subscript_t
const subscript
, LISTITER
* const first
,
635 LISTITER
* const last
, int const length
);
639 * var_edit_parse() - parse : modifiers into PATHNAME structure
641 * The : modifiers in a $(varname:modifier) currently support replacing or
642 * omitting elements of a filename, and so they are parsed into a PATHNAME
643 * structure (which contains pointers into the original string).
645 * Modifiers of the form "X=value" replace the component X with the given value.
646 * Modifiers without the "=value" cause everything but the component X to be
647 * omitted. X is one of:
654 * R root directory - prepended to whole path
660 * -> leave the original component xxx
662 * f->f_xxx.ptr = string
663 * f->f_xxx.len = strlen( string )
664 * -> replace component xxx with string
668 * -> omit component xxx
670 * var_edit_file() below and path_build() obligingly follow this convention.
673 static int var_edit_parse( char const * mods
, VAR_EDITS
* edits
, int havezeroed
682 case 'L': edits
->downshift
= 1; continue;
683 case 'U': edits
->upshift
= 1; continue;
684 case 'P': edits
->parent
= edits
->filemods
= 1; continue;
685 case 'E': fp
= &edits
->empty
; goto strval
;
686 case 'J': fp
= &edits
->join
; goto strval
;
687 case 'G': fp
= &edits
->f
.f_grist
; goto fileval
;
688 case 'R': fp
= &edits
->f
.f_root
; goto fileval
;
689 case 'D': fp
= &edits
->f
.f_dir
; goto fileval
;
690 case 'B': fp
= &edits
->f
.f_base
; goto fileval
;
691 case 'S': fp
= &edits
->f
.f_suffix
; goto fileval
;
692 case 'M': fp
= &edits
->f
.f_member
; goto fileval
;
693 case 'T': edits
->to_slashes
= 1; continue;
694 case 'W': edits
->to_windows
= 1; continue;
696 continue; /* Should complain, but so what... */
700 /* Handle :CHARS, where each char (without a following =) selects a
701 * particular file path element. On the first such char, we deselect all
702 * others (by setting ptr = "", len = 0) and for each char we select
703 * that element (by setting ptr = 0).
712 for ( i
= 0; i
< 6; ++i
)
714 edits
->f
.part
[ i
].len
= 0;
715 edits
->f
.part
[ i
].ptr
= "";
724 /* Handle :X=value, or :X */
733 fp
->len
= strlen( mods
);
743 * var_edit_file() - copy input target name to output, modifying filename.
746 static void var_edit_file( char const * in
, string
* out
, VAR_EDITS
* edits
)
748 if ( edits
->filemods
)
752 /* Parse apart original filename, putting parts into "pathname". */
753 path_parse( in
, &pathname
);
755 /* Replace any pathname with edits->f */
756 if ( edits
->f
.f_grist
.ptr
) pathname
.f_grist
= edits
->f
.f_grist
;
757 if ( edits
->f
.f_root
.ptr
) pathname
.f_root
= edits
->f
.f_root
;
758 if ( edits
->f
.f_dir
.ptr
) pathname
.f_dir
= edits
->f
.f_dir
;
759 if ( edits
->f
.f_base
.ptr
) pathname
.f_base
= edits
->f
.f_base
;
760 if ( edits
->f
.f_suffix
.ptr
) pathname
.f_suffix
= edits
->f
.f_suffix
;
761 if ( edits
->f
.f_member
.ptr
) pathname
.f_member
= edits
->f
.f_member
;
763 /* If requested, modify pathname to point to parent. */
765 path_parent( &pathname
);
767 /* Put filename back together. */
768 path_build( &pathname
, out
);
771 string_append( out
, in
);
775 #if defined( OS_CYGWIN ) || defined( OS_VMS )
778 * var_edit_translate_path() - translate path to os native format.
781 static void var_edit_translate_path( string
* out
, size_t pos
, VAR_EDITS
* edits
)
783 if ( edits
->to_windows
)
788 /* Translate path to os native format. */
789 translated
= path_translate_to_os( out
->value
+ pos
, result
);
792 string_truncate( out
, pos
);
793 string_append( out
, result
->value
);
794 edits
->to_slashes
= 0;
797 string_free( result
);
805 * var_edit_shift() - do upshift/downshift & other mods.
808 static void var_edit_shift( string
* out
, size_t pos
, VAR_EDITS
* edits
)
810 #if defined( OS_CYGWIN ) || defined( OS_VMS )
811 var_edit_translate_path( out
, pos
, edits
);
814 if ( edits
->upshift
|| edits
->downshift
|| edits
->to_slashes
)
816 /* Handle upshifting, downshifting and slash translation now. */
818 for ( p
= out
->value
+ pos
; *p
; ++p
)
820 if ( edits
->upshift
)
822 else if ( edits
->downshift
)
824 if ( edits
->to_slashes
&& ( *p
== '\\' ) )
832 * Reads n LISTs from the top of the STACK and combines them to form VAR_EDITS.
833 * Returns the number of VAR_EDITS pushed onto the STACK.
836 static int expand_modifiers( STACK
* s
, int n
)
840 LIST
* * args
= (LIST
**)stack_get( s
);
841 for ( i
= 0; i
< n
; ++i
)
842 total
*= list_length( args
[ i
] );
846 VAR_EDITS
* out
= (VAR_EDITS
*)stack_allocate( s
, total
* sizeof( VAR_EDITS
) );
847 LISTITER
* iter
= (LISTITER
*)stack_allocate( s
, n
* sizeof( LIST
* ) );
848 for ( i
= 0; i
< n
; ++i
)
849 iter
[ i
] = list_begin( args
[ i
] );
854 memset( out
, 0, sizeof( *out
) );
856 for ( i
= 0; i
< n
; ++i
)
857 havezeroed
= var_edit_parse( object_str( list_item( iter
[ i
] )
858 ), out
, havezeroed
);
862 if ( list_next( iter
[ i
] ) != list_end( args
[ i
] ) )
864 iter
[ i
] = list_next( iter
[ i
] );
867 iter
[ i
] = list_begin( args
[ i
] );
870 stack_deallocate( s
, n
* sizeof( LIST
* ) );
875 static LIST
* apply_modifiers( STACK
* s
, int n
)
877 LIST
* value
= stack_top( s
);
879 VAR_EDITS
* const edits
= (VAR_EDITS
*)( (LIST
* *)stack_get( s
) + 1 );
882 result
= apply_modifiers_impl( result
, buf
, edits
, n
, list_begin( value
),
890 * Parse a string of the form "1-2", "-2--1", "2-" and return the two
894 subscript_t
parse_subscript( char const * s
)
899 do /* so we can use "break" */
901 /* Allow negative subscripts. */
902 if ( !isdigit( *s
) && ( *s
!= '-' ) )
907 result
.sub1
= atoi( s
);
909 /* Skip over the first symbol, which is either a digit or dash. */
911 while ( isdigit( *s
) ) ++s
;
915 result
.sub2
= result
.sub1
;
933 if ( !isdigit( *s
) && ( *s
!= '-' ) )
939 /* First, compute the index of the last element. */
940 result
.sub2
= atoi( s
);
941 while ( isdigit( *++s
) );
950 static LIST
* apply_subscript( STACK
* s
)
952 LIST
* value
= stack_top( s
);
953 LIST
* indices
= stack_at( s
, 1 );
955 int length
= list_length( value
);
957 LISTITER indices_iter
= list_begin( indices
);
958 LISTITER
const indices_end
= list_end( indices
);
960 for ( ; indices_iter
!= indices_end
; indices_iter
= list_next( indices_iter
963 LISTITER iter
= list_begin( value
);
964 LISTITER end
= list_end( value
);
965 subscript_t
const subscript
= parse_subscript( object_str( list_item(
967 get_iters( subscript
, &iter
, &end
, length
);
968 for ( ; iter
!= end
; iter
= list_next( iter
) )
969 result
= list_push_back( result
, object_copy( list_item( iter
) ) );
977 * Reads the LIST from first and applies subscript to it. The results are
978 * written to *first and *last.
981 static void get_iters( subscript_t
const subscript
, LISTITER
* const first
,
982 LISTITER
* const last
, int const length
)
990 if ( subscript
.sub1
< 0 )
991 start
= length
+ subscript
.sub1
;
992 else if ( subscript
.sub1
> length
)
995 start
= subscript
.sub1
- 1;
997 size
= subscript
.sub2
< 0
998 ? length
+ 1 + subscript
.sub2
- start
999 : subscript
.sub2
- start
;
1002 * HACK: When the first subscript is before the start of the list, it
1003 * magically becomes the beginning of the list. This is inconsistent,
1004 * but needed for backwards compatibility.
1009 /* The "sub2 < 0" test handles the semantic error of sub2 < sub1. */
1013 if ( start
+ size
> length
)
1014 size
= length
- start
;
1018 while ( start
-- > 0 )
1019 iter
= list_next( iter
);
1022 while ( size
-- > 0 )
1023 end
= list_next( end
);
1029 static LIST
* apply_modifiers_empty( LIST
* result
, string
* buf
,
1030 VAR_EDITS
* edits
, int n
)
1033 for ( i
= 0; i
< n
; ++i
)
1035 if ( edits
[ i
].empty
.ptr
)
1037 /** FIXME: is empty.ptr always null-terminated? */
1038 var_edit_file( edits
[ i
].empty
.ptr
, buf
, edits
+ i
);
1039 var_edit_shift( buf
, 0, edits
+ i
);
1040 result
= list_push_back( result
, object_new( buf
->value
) );
1041 string_truncate( buf
, 0 );
1047 static LIST
* apply_modifiers_non_empty( LIST
* result
, string
* buf
,
1048 VAR_EDITS
* edits
, int n
, LISTITER begin
, LISTITER end
)
1052 for ( i
= 0; i
< n
; ++i
)
1054 if ( edits
[ i
].join
.ptr
)
1056 var_edit_file( object_str( list_item( begin
) ), buf
, edits
+ i
);
1057 var_edit_shift( buf
, 0, edits
+ i
);
1058 for ( iter
= list_next( begin
); iter
!= end
; iter
= list_next( iter
1062 string_append( buf
, edits
[ i
].join
.ptr
);
1064 var_edit_file( object_str( list_item( iter
) ), buf
, edits
+ i
1066 var_edit_shift( buf
, size
, edits
+ i
);
1068 result
= list_push_back( result
, object_new( buf
->value
) );
1069 string_truncate( buf
, 0 );
1073 for ( iter
= begin
; iter
!= end
; iter
= list_next( iter
) )
1075 var_edit_file( object_str( list_item( iter
) ), buf
, edits
+ i
);
1076 var_edit_shift( buf
, 0, edits
+ i
);
1077 result
= list_push_back( result
, object_new( buf
->value
) );
1078 string_truncate( buf
, 0 );
1085 static LIST
* apply_modifiers_impl( LIST
* result
, string
* buf
,
1086 VAR_EDITS
* edits
, int n
, LISTITER iter
, LISTITER end
)
1089 ? apply_modifiers_empty( result
, buf
, edits
, n
)
1090 : apply_modifiers_non_empty( result
, buf
, edits
, n
, iter
, end
);
1093 static LIST
* apply_subscript_and_modifiers( STACK
* s
, int n
)
1095 LIST
* const value
= stack_top( s
);
1096 LIST
* const indices
= stack_at( s
, 1 );
1098 VAR_EDITS
* const edits
= (VAR_EDITS
*)((LIST
* *)stack_get( s
) + 2);
1099 int const length
= list_length( value
);
1101 LISTITER indices_iter
= list_begin( indices
);
1102 LISTITER
const indices_end
= list_end( indices
);
1104 for ( ; indices_iter
!= indices_end
; indices_iter
= list_next( indices_iter
1107 LISTITER iter
= list_begin( value
);
1108 LISTITER end
= list_end( value
);
1109 subscript_t
const sub
= parse_subscript( object_str( list_item(
1111 get_iters( sub
, &iter
, &end
, length
);
1112 result
= apply_modifiers_impl( result
, buf
, edits
, n
, iter
, end
);
1120 * expand() - expands a list of concatenated strings and variable references
1122 * Takes a list of expansion items - each representing one element to be
1123 * concatenated and each containing a list of its values. Returns a list of all
1124 * possible values constructed by selecting a single value from each of the
1125 * elements and concatenating them together.
1127 * For example, in the following code:
1129 * local a = one two three four ;
1130 * local b = foo bar ;
1131 * ECHO /$(a)/$(b)/$(a)/ ;
1133 * When constructing the result of /$(a)/$(b)/ this function would get called
1134 * with the following 7 expansion items:
1136 * 2. one two three four
1140 * 6. one two three four
1143 * And would result in a list containing 32 values:
1146 * 3. /one/foo/three/
1153 typedef struct expansion_item
1155 /* Item's value list initialized prior to calling expand(). */
1158 /* Internal data initialized and used inside expand(). */
1159 LISTITER current
; /* Currently used value. */
1160 int size
; /* Concatenated string length prior to concatenating the
1161 * item's current value.
1165 static LIST
* expand( expansion_item
* items
, int const length
)
1172 assert( length
> 0 );
1173 for ( i
= 0; i
< length
; ++i
)
1175 LISTITER iter
= list_begin( items
[ i
].values
);
1176 LISTITER
const end
= list_end( items
[ i
].values
);
1178 /* If any of the items has no values - the result is an empty list. */
1179 if ( iter
== end
) return L0
;
1181 /* Set each item's 'current' to its first listed value. This indicates
1182 * each item's next value to be used when constructing the list of all
1183 * possible concatenated values.
1185 items
[ i
].current
= iter
;
1187 /* Calculate the longest concatenated string length - to know how much
1188 * memory we need to allocate as a buffer for holding the concatenated
1193 for ( ; iter
!= end
; iter
= list_next( iter
) )
1195 int const len
= strlen( object_str( list_item( iter
) ) );
1196 if ( len
> max
) max
= len
;
1203 string_reserve( buf
, size
);
1208 for ( ; i
< length
; ++i
)
1210 items
[ i
].size
= buf
->size
;
1211 string_append( buf
, object_str( list_item( items
[ i
].current
) ) );
1213 result
= list_push_back( result
, object_new( buf
->value
) );
1216 if ( list_next( items
[ i
].current
) != list_end( items
[ i
].values
1219 items
[ i
].current
= list_next( items
[ i
].current
);
1220 string_truncate( buf
, items
[ i
].size
);
1224 items
[ i
].current
= list_begin( items
[ i
].values
);
1232 static void combine_strings( STACK
* s
, int n
, string
* out
)
1235 for ( i
= 0; i
< n
; ++i
)
1237 LIST
* const values
= stack_pop( s
);
1238 LISTITER iter
= list_begin( values
);
1239 LISTITER
const end
= list_end( values
);
1242 string_append( out
, object_str( list_item( iter
) ) );
1243 for ( iter
= list_next( iter
); iter
!= end
; iter
= list_next( iter
1246 string_push_back( out
, ' ' );
1247 string_append( out
, object_str( list_item( iter
) ) );
1249 list_free( values
);
1254 struct dynamic_array
1261 static void dynamic_array_init( struct dynamic_array
* array
)
1264 array
->capacity
= 0;
1268 static void dynamic_array_free( struct dynamic_array
* array
)
1270 BJAM_FREE( array
->data
);
1273 static void dynamic_array_push_impl( struct dynamic_array
* const array
,
1274 void const * const value
, int const unit_size
)
1276 if ( array
->capacity
== 0 )
1278 array
->capacity
= 2;
1279 array
->data
= BJAM_MALLOC( array
->capacity
* unit_size
);
1281 else if ( array
->capacity
== array
->size
)
1284 array
->capacity
*= 2;
1285 new_data
= BJAM_MALLOC( array
->capacity
* unit_size
);
1286 memcpy( new_data
, array
->data
, array
->size
* unit_size
);
1287 BJAM_FREE( array
->data
);
1288 array
->data
= new_data
;
1290 memcpy( (char *)array
->data
+ array
->size
* unit_size
, value
, unit_size
);
1294 #define dynamic_array_push( array, value ) (dynamic_array_push_impl(array, &value, sizeof(value)))
1295 #define dynamic_array_at( type, array, idx ) (((type *)(array)->data)[idx])
1296 #define dynamic_array_pop( array ) (--(array)->size)
1304 int absolute_position
;
1305 struct dynamic_array uses
[ 1 ];
1308 #define LOOP_INFO_BREAK 0
1309 #define LOOP_INFO_CONTINUE 1
1323 struct arg_list
* arguments
;
1327 typedef struct compiler
1329 struct dynamic_array code
[ 1 ];
1330 struct dynamic_array constants
[ 1 ];
1331 struct dynamic_array labels
[ 1 ];
1332 struct dynamic_array rules
[ 1 ];
1333 struct dynamic_array actions
[ 1 ];
1334 struct dynamic_array cleanups
[ 1 ];
1335 struct dynamic_array loop_scopes
[ 1 ];
1338 static void compiler_init( compiler
* c
)
1340 dynamic_array_init( c
->code
);
1341 dynamic_array_init( c
->constants
);
1342 dynamic_array_init( c
->labels
);
1343 dynamic_array_init( c
->rules
);
1344 dynamic_array_init( c
->actions
);
1345 dynamic_array_init( c
->cleanups
);
1346 dynamic_array_init( c
->loop_scopes
);
1349 static void compiler_free( compiler
* c
)
1352 dynamic_array_free( c
->actions
);
1353 dynamic_array_free( c
->rules
);
1354 for ( i
= 0; i
< c
->labels
->size
; ++i
)
1355 dynamic_array_free( dynamic_array_at( struct label_info
, c
->labels
, i
1357 dynamic_array_free( c
->labels
);
1358 dynamic_array_free( c
->constants
);
1359 dynamic_array_free( c
->code
);
1360 dynamic_array_free( c
->cleanups
);
1361 dynamic_array_free( c
->loop_scopes
);
1364 static void compile_emit_instruction( compiler
* c
, instruction instr
)
1366 dynamic_array_push( c
->code
, instr
);
1369 static int compile_new_label( compiler
* c
)
1371 int result
= c
->labels
->size
;
1372 struct label_info info
;
1373 info
.absolute_position
= -1;
1374 dynamic_array_init( info
.uses
);
1375 dynamic_array_push( c
->labels
, info
);
1379 static void compile_set_label( compiler
* c
, int label
)
1381 struct label_info
* const l
= &dynamic_array_at( struct label_info
,
1383 int const pos
= c
->code
->size
;
1385 assert( l
->absolute_position
== -1 );
1386 l
->absolute_position
= pos
;
1387 for ( i
= 0; i
< l
->uses
->size
; ++i
)
1389 int id
= dynamic_array_at( int, l
->uses
, i
);
1390 int offset
= (int)( pos
- id
- 1 );
1391 dynamic_array_at( instruction
, c
->code
, id
).arg
= offset
;
1395 static void compile_emit( compiler
* c
, unsigned int op_code
, int arg
)
1398 instr
.op_code
= op_code
;
1400 compile_emit_instruction( c
, instr
);
1403 static void compile_emit_branch( compiler
* c
, unsigned int op_code
, int label
)
1405 struct label_info
* const l
= &dynamic_array_at( struct label_info
,
1407 int const pos
= c
->code
->size
;
1409 instr
.op_code
= op_code
;
1410 if ( l
->absolute_position
== -1 )
1413 dynamic_array_push( l
->uses
, pos
);
1416 instr
.arg
= (int)( l
->absolute_position
- pos
- 1 );
1417 compile_emit_instruction( c
, instr
);
1420 static int compile_emit_constant( compiler
* c
, OBJECT
* value
)
1422 OBJECT
* copy
= object_copy( value
);
1423 dynamic_array_push( c
->constants
, copy
);
1424 return c
->constants
->size
- 1;
1427 static void compile_push_cleanup( compiler
* c
, unsigned int op_code
, int arg
)
1430 instr
.op_code
= op_code
;
1432 dynamic_array_push( c
->cleanups
, instr
);
1435 static void compile_pop_cleanup( compiler
* c
)
1437 dynamic_array_pop( c
->cleanups
);
1440 static void compile_emit_cleanups( compiler
* c
, int end
)
1443 for ( i
= c
->cleanups
->size
; --i
>= end
; )
1445 compile_emit_instruction( c
, dynamic_array_at( instruction
, c
->cleanups
, i
) );
1449 static void compile_emit_loop_jump( compiler
* c
, int type
)
1451 struct loop_info
* info
= NULL
;
1453 for ( i
= c
->loop_scopes
->size
; --i
>= 0; )
1455 struct loop_info
* elem
= &dynamic_array_at( struct loop_info
, c
->loop_scopes
, i
);
1456 if ( elem
->type
== type
)
1464 printf( "warning: ignoring break statement used outside of loop\n" );
1467 compile_emit_cleanups( c
, info
->cleanup_depth
);
1468 compile_emit_branch( c
, INSTR_JUMP
, info
->label
);
1471 static void compile_push_break_scope( compiler
* c
, int label
)
1473 struct loop_info info
;
1474 info
.type
= LOOP_INFO_BREAK
;
1476 info
.cleanup_depth
= c
->cleanups
->size
;
1477 dynamic_array_push( c
->loop_scopes
, info
);
1480 static void compile_push_continue_scope( compiler
* c
, int label
)
1482 struct loop_info info
;
1483 info
.type
= LOOP_INFO_CONTINUE
;
1485 info
.cleanup_depth
= c
->cleanups
->size
;
1486 dynamic_array_push( c
->loop_scopes
, info
);
1489 static void compile_pop_break_scope( compiler
* c
)
1491 assert( c
->loop_scopes
->size
> 0 );
1492 assert( dynamic_array_at( struct loop_info
, c
->loop_scopes
, c
->loop_scopes
->size
- 1 ).type
== LOOP_INFO_BREAK
);
1493 dynamic_array_pop( c
->loop_scopes
);
1496 static void compile_pop_continue_scope( compiler
* c
)
1498 assert( c
->loop_scopes
->size
> 0 );
1499 assert( dynamic_array_at( struct loop_info
, c
->loop_scopes
, c
->loop_scopes
->size
- 1 ).type
== LOOP_INFO_CONTINUE
);
1500 dynamic_array_pop( c
->loop_scopes
);
1503 static int compile_emit_rule( compiler
* c
, OBJECT
* name
, PARSE
* parse
,
1504 int num_arguments
, struct arg_list
* arguments
, int local
)
1506 struct stored_rule rule
;
1507 rule
.name
= object_copy( name
);
1509 rule
.num_arguments
= num_arguments
;
1510 rule
.arguments
= arguments
;
1512 dynamic_array_push( c
->rules
, rule
);
1513 return (int)( c
->rules
->size
- 1 );
1516 static int compile_emit_actions( compiler
* c
, PARSE
* parse
)
1519 a
.name
= object_copy( parse
->string
);
1520 a
.command
= function_compile_actions( object_str( parse
->string1
),
1521 parse
->file
, parse
->line
);
1522 a
.flags
= parse
->num
;
1523 dynamic_array_push( c
->actions
, a
);
1524 return (int)( c
->actions
->size
- 1 );
1527 static JAM_FUNCTION
* compile_to_function( compiler
* c
)
1529 JAM_FUNCTION
* const result
= (JAM_FUNCTION
*)BJAM_MALLOC( sizeof( JAM_FUNCTION
) );
1531 result
->base
.type
= FUNCTION_JAM
;
1532 result
->base
.reference_count
= 1;
1533 result
->base
.formal_arguments
= 0;
1534 result
->base
.num_formal_arguments
= 0;
1536 result
->base
.rulename
= 0;
1538 result
->code_size
= c
->code
->size
;
1539 result
->code
= (instruction
*)BJAM_MALLOC( c
->code
->size
* sizeof( instruction
) );
1540 memcpy( result
->code
, c
->code
->data
, c
->code
->size
* sizeof( instruction
) );
1542 result
->constants
= (OBJECT
**)BJAM_MALLOC( c
->constants
->size
* sizeof( OBJECT
* ) );
1543 if ( c
->constants
->size
!= 0 )
1544 memcpy( result
->constants
, c
->constants
->data
,
1545 c
->constants
->size
* sizeof( OBJECT
* ) );
1546 result
->num_constants
= c
->constants
->size
;
1548 result
->num_subfunctions
= c
->rules
->size
;
1549 result
->functions
= (SUBFUNCTION
*)BJAM_MALLOC( c
->rules
->size
* sizeof( SUBFUNCTION
) );
1550 for ( i
= 0; i
< c
->rules
->size
; ++i
)
1552 struct stored_rule
* const rule
= &dynamic_array_at( struct stored_rule
,
1554 result
->functions
[ i
].name
= rule
->name
;
1555 result
->functions
[ i
].code
= function_compile( rule
->parse
);
1556 result
->functions
[ i
].code
->num_formal_arguments
= rule
->num_arguments
;
1557 result
->functions
[ i
].code
->formal_arguments
= rule
->arguments
;
1558 result
->functions
[ i
].local
= rule
->local
;
1561 result
->actions
= (SUBACTION
*)BJAM_MALLOC( c
->actions
->size
* sizeof( SUBACTION
) );
1562 if ( c
->actions
->size
!= 0 )
1563 memcpy( result
->actions
, c
->actions
->data
,
1564 c
->actions
->size
* sizeof( SUBACTION
) );
1565 result
->num_subactions
= c
->actions
->size
;
1567 result
->generic
= 0;
1577 * Parsing of variable expansions
1580 typedef struct VAR_PARSE_GROUP
1582 struct dynamic_array elems
[ 1 ];
1585 typedef struct VAR_PARSE_ACTIONS
1587 struct dynamic_array elems
[ 1 ];
1588 } VAR_PARSE_ACTIONS
;
1590 #define VAR_PARSE_TYPE_VAR 0
1591 #define VAR_PARSE_TYPE_STRING 1
1592 #define VAR_PARSE_TYPE_FILE 2
1594 typedef struct _var_parse
1596 int type
; /* string, variable or file */
1602 VAR_PARSE_GROUP
* name
;
1603 VAR_PARSE_GROUP
* subscript
;
1604 struct dynamic_array modifiers
[ 1 ];
1616 struct dynamic_array filename
[ 1 ];
1617 struct dynamic_array contents
[ 1 ];
1620 static void var_parse_free( VAR_PARSE
* );
1627 static VAR_PARSE_GROUP
* var_parse_group_new()
1629 VAR_PARSE_GROUP
* const result
= (VAR_PARSE_GROUP
*)BJAM_MALLOC( sizeof( VAR_PARSE_GROUP
) );
1630 dynamic_array_init( result
->elems
);
1634 static void var_parse_group_free( VAR_PARSE_GROUP
* group
)
1637 for ( i
= 0; i
< group
->elems
->size
; ++i
)
1638 var_parse_free( dynamic_array_at( VAR_PARSE
*, group
->elems
, i
) );
1639 dynamic_array_free( group
->elems
);
1643 static void var_parse_group_add( VAR_PARSE_GROUP
* group
, VAR_PARSE
* elem
)
1645 dynamic_array_push( group
->elems
, elem
);
1648 static void var_parse_group_maybe_add_constant( VAR_PARSE_GROUP
* group
,
1649 char const * start
, char const * end
)
1654 VAR_PARSE_STRING
* const value
= (VAR_PARSE_STRING
*)BJAM_MALLOC(
1655 sizeof(VAR_PARSE_STRING
) );
1656 value
->base
.type
= VAR_PARSE_TYPE_STRING
;
1658 string_append_range( buf
, start
, end
);
1659 value
->s
= object_new( buf
->value
);
1661 var_parse_group_add( group
, (VAR_PARSE
*)value
);
1665 VAR_PARSE_STRING
* var_parse_group_as_literal( VAR_PARSE_GROUP
* group
)
1667 if ( group
->elems
->size
== 1 )
1669 VAR_PARSE
* result
= dynamic_array_at( VAR_PARSE
*, group
->elems
, 0 );
1670 if ( result
->type
== VAR_PARSE_TYPE_STRING
)
1671 return (VAR_PARSE_STRING
*)result
;
1681 static VAR_PARSE_ACTIONS
* var_parse_actions_new()
1683 VAR_PARSE_ACTIONS
* const result
= (VAR_PARSE_ACTIONS
*)BJAM_MALLOC(
1684 sizeof(VAR_PARSE_ACTIONS
) );
1685 dynamic_array_init( result
->elems
);
1689 static void var_parse_actions_free( VAR_PARSE_ACTIONS
* actions
)
1692 for ( i
= 0; i
< actions
->elems
->size
; ++i
)
1693 var_parse_group_free( dynamic_array_at( VAR_PARSE_GROUP
*,
1694 actions
->elems
, i
) );
1695 dynamic_array_free( actions
->elems
);
1696 BJAM_FREE( actions
);
1704 static VAR_PARSE_VAR
* var_parse_var_new()
1706 VAR_PARSE_VAR
* result
= (VAR_PARSE_VAR
*)BJAM_MALLOC( sizeof( VAR_PARSE_VAR
) );
1707 result
->base
.type
= VAR_PARSE_TYPE_VAR
;
1708 result
->name
= var_parse_group_new();
1709 result
->subscript
= 0;
1710 dynamic_array_init( result
->modifiers
);
1714 static void var_parse_var_free( VAR_PARSE_VAR
* var
)
1717 var_parse_group_free( var
->name
);
1718 if ( var
->subscript
)
1719 var_parse_group_free( var
->subscript
);
1720 for ( i
= 0; i
< var
->modifiers
->size
; ++i
)
1721 var_parse_group_free( dynamic_array_at( VAR_PARSE_GROUP
*,
1722 var
->modifiers
, i
) );
1723 dynamic_array_free( var
->modifiers
);
1727 static VAR_PARSE_GROUP
* var_parse_var_new_modifier( VAR_PARSE_VAR
* var
)
1729 VAR_PARSE_GROUP
* result
= var_parse_group_new();
1730 dynamic_array_push( var
->modifiers
, result
);
1739 static void var_parse_string_free( VAR_PARSE_STRING
* string
)
1741 object_free( string
->s
);
1742 BJAM_FREE( string
);
1750 static VAR_PARSE_FILE
* var_parse_file_new( void )
1752 VAR_PARSE_FILE
* const result
= (VAR_PARSE_FILE
*)BJAM_MALLOC( sizeof(
1754 result
->base
.type
= VAR_PARSE_TYPE_FILE
;
1755 dynamic_array_init( result
->filename
);
1756 dynamic_array_init( result
->contents
);
1760 static void var_parse_file_free( VAR_PARSE_FILE
* file
)
1763 for ( i
= 0; i
< file
->filename
->size
; ++i
)
1764 var_parse_group_free( dynamic_array_at( VAR_PARSE_GROUP
*,
1765 file
->filename
, i
) );
1766 dynamic_array_free( file
->filename
);
1767 for ( i
= 0; i
< file
->contents
->size
; ++i
)
1768 var_parse_group_free( dynamic_array_at( VAR_PARSE_GROUP
*,
1769 file
->contents
, i
) );
1770 dynamic_array_free( file
->contents
);
1779 static void var_parse_free( VAR_PARSE
* parse
)
1781 switch ( parse
->type
)
1783 case VAR_PARSE_TYPE_VAR
:
1784 var_parse_var_free( (VAR_PARSE_VAR
*)parse
);
1787 case VAR_PARSE_TYPE_STRING
:
1788 var_parse_string_free( (VAR_PARSE_STRING
*)parse
);
1791 case VAR_PARSE_TYPE_FILE
:
1792 var_parse_file_free( (VAR_PARSE_FILE
*)parse
);
1796 assert( !"Invalid type" );
1805 static void var_parse_group_compile( VAR_PARSE_GROUP
const * parse
,
1808 static void var_parse_var_compile( VAR_PARSE_VAR
const * parse
, compiler
* c
)
1810 int expand_name
= 0;
1811 int is_get_grist
= 0;
1812 int has_modifiers
= 0;
1813 /* Special case common modifiers */
1814 if ( parse
->modifiers
->size
== 1 )
1816 VAR_PARSE_GROUP
* mod
= dynamic_array_at( VAR_PARSE_GROUP
*, parse
->modifiers
, 0 );
1817 if ( mod
->elems
->size
== 1 )
1819 VAR_PARSE
* mod1
= dynamic_array_at( VAR_PARSE
*, mod
->elems
, 0 );
1820 if ( mod1
->type
== VAR_PARSE_TYPE_STRING
)
1822 OBJECT
* s
= ( (VAR_PARSE_STRING
*)mod1
)->s
;
1823 if ( ! strcmp ( object_str( s
), "G" ) )
1830 /* If there are modifiers, emit them in reverse order. */
1831 if ( parse
->modifiers
->size
> 0 && !is_get_grist
)
1835 for ( i
= 0; i
< parse
->modifiers
->size
; ++i
)
1836 var_parse_group_compile( dynamic_array_at( VAR_PARSE_GROUP
*,
1837 parse
->modifiers
, parse
->modifiers
->size
- i
- 1 ), c
);
1840 /* If there is a subscript, emit it. */
1841 if ( parse
->subscript
)
1842 var_parse_group_compile( parse
->subscript
, c
);
1844 /* If the variable name is empty, look it up. */
1845 if ( parse
->name
->elems
->size
== 0 )
1846 compile_emit( c
, INSTR_PUSH_VAR
, compile_emit_constant( c
,
1848 /* If the variable name does not need to be expanded, look it up. */
1849 else if ( parse
->name
->elems
->size
== 1 && dynamic_array_at( VAR_PARSE
*,
1850 parse
->name
->elems
, 0 )->type
== VAR_PARSE_TYPE_STRING
)
1852 OBJECT
* const name
= ( (VAR_PARSE_STRING
*)dynamic_array_at(
1853 VAR_PARSE
*, parse
->name
->elems
, 0 ) )->s
;
1854 int const idx
= get_argument_index( object_str( name
) );
1856 compile_emit( c
, INSTR_PUSH_ARG
, idx
);
1858 compile_emit( c
, INSTR_PUSH_VAR
, compile_emit_constant( c
, name
) );
1860 /* Otherwise, push the var names and use the group instruction. */
1863 var_parse_group_compile( parse
->name
, c
);
1867 /** Select the instruction for expanding the variable. */
1868 if ( !has_modifiers
&& !parse
->subscript
&& !expand_name
)
1870 else if ( !has_modifiers
&& !parse
->subscript
&& expand_name
)
1871 compile_emit( c
, INSTR_PUSH_GROUP
, 0 );
1872 else if ( !has_modifiers
&& parse
->subscript
&& !expand_name
)
1873 compile_emit( c
, INSTR_APPLY_INDEX
, 0 );
1874 else if ( !has_modifiers
&& parse
->subscript
&& expand_name
)
1875 compile_emit( c
, INSTR_APPLY_INDEX_GROUP
, 0 );
1876 else if ( has_modifiers
&& !parse
->subscript
&& !expand_name
)
1877 compile_emit( c
, INSTR_APPLY_MODIFIERS
, parse
->modifiers
->size
);
1878 else if ( has_modifiers
&& !parse
->subscript
&& expand_name
)
1879 compile_emit( c
, INSTR_APPLY_MODIFIERS_GROUP
, parse
->modifiers
->size
);
1880 else if ( has_modifiers
&& parse
->subscript
&& !expand_name
)
1881 compile_emit( c
, INSTR_APPLY_INDEX_MODIFIERS
, parse
->modifiers
->size
);
1882 else if ( has_modifiers
&& parse
->subscript
&& expand_name
)
1883 compile_emit( c
, INSTR_APPLY_INDEX_MODIFIERS_GROUP
,
1884 parse
->modifiers
->size
);
1886 /* Now apply any special modifiers */
1889 compile_emit( c
, INSTR_GET_GRIST
, 0 );
1893 static void var_parse_string_compile( VAR_PARSE_STRING
const * parse
,
1896 compile_emit( c
, INSTR_PUSH_CONSTANT
, compile_emit_constant( c
, parse
->s
)
1900 static void var_parse_file_compile( VAR_PARSE_FILE
const * parse
, compiler
* c
)
1903 for ( i
= 0; i
< parse
->filename
->size
; ++i
)
1904 var_parse_group_compile( dynamic_array_at( VAR_PARSE_GROUP
*,
1905 parse
->filename
, parse
->filename
->size
- i
- 1 ), c
);
1906 compile_emit( c
, INSTR_APPEND_STRINGS
, parse
->filename
->size
);
1907 for ( i
= 0; i
< parse
->contents
->size
; ++i
)
1908 var_parse_group_compile( dynamic_array_at( VAR_PARSE_GROUP
*,
1909 parse
->contents
, parse
->contents
->size
- i
- 1 ), c
);
1910 compile_emit( c
, INSTR_WRITE_FILE
, parse
->contents
->size
);
1913 static void var_parse_compile( VAR_PARSE
const * parse
, compiler
* c
)
1915 switch ( parse
->type
)
1917 case VAR_PARSE_TYPE_VAR
:
1918 var_parse_var_compile( (VAR_PARSE_VAR
const *)parse
, c
);
1921 case VAR_PARSE_TYPE_STRING
:
1922 var_parse_string_compile( (VAR_PARSE_STRING
const *)parse
, c
);
1925 case VAR_PARSE_TYPE_FILE
:
1926 var_parse_file_compile( (VAR_PARSE_FILE
const *)parse
, c
);
1930 assert( !"Unknown var parse type." );
1934 static void var_parse_group_compile( VAR_PARSE_GROUP
const * parse
, compiler
* c
1937 /* Emit the elements in reverse order. */
1939 for ( i
= 0; i
< parse
->elems
->size
; ++i
)
1940 var_parse_compile( dynamic_array_at( VAR_PARSE
*, parse
->elems
,
1941 parse
->elems
->size
- i
- 1 ), c
);
1942 /* If there are no elements, emit an empty string. */
1943 if ( parse
->elems
->size
== 0 )
1944 compile_emit( c
, INSTR_PUSH_CONSTANT
, compile_emit_constant( c
,
1946 /* If there is more than one element, combine them. */
1947 if ( parse
->elems
->size
> 1 )
1948 compile_emit( c
, INSTR_COMBINE_STRINGS
, parse
->elems
->size
);
1951 static void var_parse_actions_compile( VAR_PARSE_ACTIONS
const * actions
,
1955 for ( i
= 0; i
< actions
->elems
->size
; ++i
)
1956 var_parse_group_compile( dynamic_array_at( VAR_PARSE_GROUP
*,
1957 actions
->elems
, actions
->elems
->size
- i
- 1 ), c
);
1958 compile_emit( c
, INSTR_OUTPUT_STRINGS
, actions
->elems
->size
);
1963 * Parse VAR_PARSE_VAR
1966 static VAR_PARSE
* parse_at_file( char const * start
, char const * mid
,
1968 static VAR_PARSE
* parse_variable( char const * * string
);
1969 static int try_parse_variable( char const * * s_
, char const * * string
,
1970 VAR_PARSE_GROUP
* out
);
1971 static void balance_parentheses( char const * * s_
, char const * * string
,
1972 VAR_PARSE_GROUP
* out
);
1973 static void parse_var_string( char const * first
, char const * last
,
1974 struct dynamic_array
* out
);
1978 * Parses a string that can contain variables to expand.
1981 static VAR_PARSE_GROUP
* parse_expansion( char const * * string
)
1983 VAR_PARSE_GROUP
* result
= var_parse_group_new();
1984 char const * s
= *string
;
1987 if ( try_parse_variable( &s
, string
, result
) ) {}
1988 else if ( s
[ 0 ] == '\0' )
1990 var_parse_group_maybe_add_constant( result
, *string
, s
);
1998 static VAR_PARSE_ACTIONS
* parse_actions( char const * string
)
2000 VAR_PARSE_ACTIONS
* const result
= var_parse_actions_new();
2001 parse_var_string( string
, string
+ strlen( string
), result
->elems
);
2006 * Checks whether the string a *s_ starts with a variable expansion "$(".
2007 * *string should point to the first unemitted character before *s. If *s_
2008 * starts with variable expansion, appends elements to out up to the closing
2009 * ")", and adjusts *s_ and *string to point to next character. Returns 1 if s_
2010 * starts with a variable, 0 otherwise.
2013 static int try_parse_variable( char const * * s_
, char const * * string
,
2014 VAR_PARSE_GROUP
* out
)
2016 char const * s
= *s_
;
2017 if ( s
[ 0 ] == '$' && s
[ 1 ] == '(' )
2019 var_parse_group_maybe_add_constant( out
, *string
, s
);
2021 var_parse_group_add( out
, parse_variable( &s
) );
2026 if ( s
[ 0 ] == '@' && s
[ 1 ] == '(' )
2030 char const * split
= 0;
2031 var_parse_group_maybe_add_constant( out
, *string
, s
);
2035 /* Scan the content of the response file @() section. */
2036 while ( *ine
&& ( depth
> 0 ) )
2040 case '(': ++depth
; break;
2041 case ')': --depth
; break;
2043 if ( ( depth
== 1 ) && ( ine
[ 1 ] == 'E' ) && ( ine
[ 2 ] == '='
2051 if ( !split
|| depth
)
2054 var_parse_group_add( out
, parse_at_file( s
, split
, ine
- 1 ) );
2063 static char const * current_file
= "";
2064 static int current_line
;
2066 static void parse_error( char const * message
)
2068 out_printf( "%s:%d: %s\n", current_file
, current_line
, message
);
2073 * Parses a single variable up to the closing ")" and adjusts *string to point
2074 * to the next character. *string should point to the character immediately
2075 * after the initial "$(".
2078 static VAR_PARSE
* parse_variable( char const * * string
)
2080 VAR_PARSE_VAR
* const result
= var_parse_var_new();
2081 VAR_PARSE_GROUP
* const name
= result
->name
;
2082 char const * s
= *string
;
2085 if ( try_parse_variable( &s
, string
, name
) ) {}
2086 else if ( s
[ 0 ] == ':' )
2088 VAR_PARSE_GROUP
* mod
;
2089 var_parse_group_maybe_add_constant( name
, *string
, s
);
2092 mod
= var_parse_var_new_modifier( result
);
2095 if ( try_parse_variable( &s
, string
, mod
) ) {}
2096 else if ( s
[ 0 ] == ')' )
2098 var_parse_group_maybe_add_constant( mod
, *string
, s
);
2100 return (VAR_PARSE
*)result
;
2102 else if ( s
[ 0 ] == '(' )
2105 balance_parentheses( &s
, string
, mod
);
2107 else if ( s
[ 0 ] == ':' )
2109 var_parse_group_maybe_add_constant( mod
, *string
, s
);
2111 mod
= var_parse_var_new_modifier( result
);
2113 else if ( s
[ 0 ] == '[' )
2115 parse_error("unexpected subscript");
2118 else if ( s
[ 0 ] == '\0' )
2120 parse_error( "unbalanced parentheses" );
2121 var_parse_group_maybe_add_constant( mod
, *string
, s
);
2123 return (VAR_PARSE
*)result
;
2129 else if ( s
[ 0 ] == '[' )
2131 VAR_PARSE_GROUP
* subscript
= var_parse_group_new();
2132 result
->subscript
= subscript
;
2133 var_parse_group_maybe_add_constant( name
, *string
, s
);
2137 if ( try_parse_variable( &s
, string
, subscript
) ) {}
2138 else if ( s
[ 0 ] == ']' )
2140 var_parse_group_maybe_add_constant( subscript
, *string
, s
);
2142 if ( s
[ 0 ] != ')' && s
[ 0 ] != ':' && s
[ 0 ] != '\0' )
2143 parse_error( "unexpected text following []" );
2146 else if ( isdigit( s
[ 0 ] ) || s
[ 0 ] == '-' )
2150 else if ( s
[ 0 ] == '\0' )
2152 parse_error( "malformed subscript" );
2157 parse_error( "malformed subscript" );
2162 else if ( s
[ 0 ] == ')' )
2164 var_parse_group_maybe_add_constant( name
, *string
, s
);
2166 return (VAR_PARSE
*)result
;
2168 else if ( s
[ 0 ] == '(' )
2171 balance_parentheses( &s
, string
, name
);
2173 else if ( s
[ 0 ] == '\0' )
2175 parse_error( "unbalanced parentheses" );
2176 var_parse_group_maybe_add_constant( name
, *string
, s
);
2178 return (VAR_PARSE
*)result
;
2185 static void parse_var_string( char const * first
, char const * last
,
2186 struct dynamic_array
* out
)
2188 char const * saved
= first
;
2189 while ( first
!= last
)
2191 /* Handle whitespace. */
2192 while ( first
!= last
&& isspace( *first
) ) ++first
;
2193 if ( saved
!= first
)
2195 VAR_PARSE_GROUP
* const group
= var_parse_group_new();
2196 var_parse_group_maybe_add_constant( group
, saved
, first
);
2198 dynamic_array_push( out
, group
);
2200 if ( first
== last
) break;
2202 /* Handle non-whitespace */
2204 VAR_PARSE_GROUP
* group
= var_parse_group_new();
2207 if ( first
== last
|| isspace( *first
) )
2209 var_parse_group_maybe_add_constant( group
, saved
, first
);
2213 if ( try_parse_variable( &first
, &saved
, group
) )
2214 assert( first
<= last
);
2218 dynamic_array_push( out
, group
);
2224 * start should point to the character immediately following the opening "@(",
2225 * mid should point to the ":E=", and end should point to the closing ")".
2228 static VAR_PARSE
* parse_at_file( char const * start
, char const * mid
,
2231 VAR_PARSE_FILE
* result
= var_parse_file_new();
2232 parse_var_string( start
, mid
, result
->filename
);
2233 parse_var_string( mid
+ 3, end
, result
->contents
);
2234 return (VAR_PARSE
*)result
;
2238 * Given that *s_ points to the character after a "(", parses up to the matching
2239 * ")". *string should point to the first unemitted character before *s_.
2241 * When the function returns, *s_ will point to the character after the ")", and
2242 * *string will point to the first unemitted character before *s_. The range
2243 * from *string to *s_ does not contain any variables that need to be expanded.
2246 void balance_parentheses( char const * * s_
, char const * * string
,
2247 VAR_PARSE_GROUP
* out
)
2250 char const * s
= *s_
;
2253 if ( try_parse_variable( &s
, string
, out
) ) { }
2254 else if ( s
[ 0 ] == ':' || s
[ 0 ] == '[' )
2256 parse_error( "unbalanced parentheses" );
2259 else if ( s
[ 0 ] == '\0' )
2261 parse_error( "unbalanced parentheses" );
2264 else if ( s
[ 0 ] == ')' )
2267 if ( --depth
== 0 ) break;
2269 else if ( s
[ 0 ] == '(' )
2285 #define RESULT_STACK 0
2286 #define RESULT_RETURN 1
2287 #define RESULT_NONE 2
2289 static void compile_parse( PARSE
* parse
, compiler
* c
, int result_location
);
2290 static struct arg_list
* arg_list_compile( PARSE
* parse
, int * num_arguments
);
2292 static void compile_condition( PARSE
* parse
, compiler
* c
, int branch_true
, int label
)
2294 assert( parse
->type
== PARSE_EVAL
);
2295 switch ( parse
->num
)
2298 compile_parse( parse
->left
, c
, RESULT_STACK
);
2300 compile_emit_branch( c
, INSTR_JUMP_NOT_EMPTY
, label
);
2302 compile_emit_branch( c
, INSTR_JUMP_EMPTY
, label
);
2306 compile_parse( parse
->left
, c
, RESULT_STACK
);
2307 compile_parse( parse
->right
, c
, RESULT_STACK
);
2309 compile_emit_branch( c
, INSTR_JUMP_EQ
, label
);
2311 compile_emit_branch( c
, INSTR_JUMP_NE
, label
);
2315 compile_parse( parse
->left
, c
, RESULT_STACK
);
2316 compile_parse( parse
->right
, c
, RESULT_STACK
);
2318 compile_emit_branch( c
, INSTR_JUMP_NE
, label
);
2320 compile_emit_branch( c
, INSTR_JUMP_EQ
, label
);
2324 compile_parse( parse
->left
, c
, RESULT_STACK
);
2325 compile_parse( parse
->right
, c
, RESULT_STACK
);
2327 compile_emit_branch( c
, INSTR_JUMP_LT
, label
);
2329 compile_emit_branch( c
, INSTR_JUMP_GE
, label
);
2333 compile_parse( parse
->left
, c
, RESULT_STACK
);
2334 compile_parse( parse
->right
, c
, RESULT_STACK
);
2336 compile_emit_branch( c
, INSTR_JUMP_LE
, label
);
2338 compile_emit_branch( c
, INSTR_JUMP_GT
, label
);
2342 compile_parse( parse
->left
, c
, RESULT_STACK
);
2343 compile_parse( parse
->right
, c
, RESULT_STACK
);
2345 compile_emit_branch( c
, INSTR_JUMP_GT
, label
);
2347 compile_emit_branch( c
, INSTR_JUMP_LE
, label
);
2351 compile_parse( parse
->left
, c
, RESULT_STACK
);
2352 compile_parse( parse
->right
, c
, RESULT_STACK
);
2354 compile_emit_branch( c
, INSTR_JUMP_GE
, label
);
2356 compile_emit_branch( c
, INSTR_JUMP_LT
, label
);
2360 compile_parse( parse
->left
, c
, RESULT_STACK
);
2361 compile_parse( parse
->right
, c
, RESULT_STACK
);
2363 compile_emit_branch( c
, INSTR_JUMP_IN
, label
);
2365 compile_emit_branch( c
, INSTR_JUMP_NOT_IN
, label
);
2371 int f
= compile_new_label( c
);
2372 compile_condition( parse
->left
, c
, 0, f
);
2373 compile_condition( parse
->right
, c
, 1, label
);
2374 compile_set_label( c
, f
);
2378 compile_condition( parse
->left
, c
, 0, label
);
2379 compile_condition( parse
->right
, c
, 0, label
);
2386 compile_condition( parse
->left
, c
, 1, label
);
2387 compile_condition( parse
->right
, c
, 1, label
);
2391 int t
= compile_new_label( c
);
2392 compile_condition( parse
->left
, c
, 1, t
);
2393 compile_condition( parse
->right
, c
, 0, label
);
2394 compile_set_label( c
, t
);
2399 compile_condition( parse
->left
, c
, !branch_true
, label
);
2404 static void adjust_result( compiler
* c
, int actual_location
,
2405 int desired_location
)
2407 if ( actual_location
== desired_location
)
2409 else if ( actual_location
== RESULT_STACK
&& desired_location
== RESULT_RETURN
)
2410 compile_emit( c
, INSTR_SET_RESULT
, 0 );
2411 else if ( actual_location
== RESULT_STACK
&& desired_location
== RESULT_NONE
)
2412 compile_emit( c
, INSTR_POP
, 0 );
2413 else if ( actual_location
== RESULT_RETURN
&& desired_location
== RESULT_STACK
)
2414 compile_emit( c
, INSTR_PUSH_RESULT
, 0 );
2415 else if ( actual_location
== RESULT_RETURN
&& desired_location
== RESULT_NONE
)
2417 else if ( actual_location
== RESULT_NONE
&& desired_location
== RESULT_STACK
)
2418 compile_emit( c
, INSTR_PUSH_EMPTY
, 0 );
2419 else if ( actual_location
== RESULT_NONE
&& desired_location
== RESULT_RETURN
)
2421 compile_emit( c
, INSTR_PUSH_EMPTY
, 0 );
2422 compile_emit( c
, INSTR_SET_RESULT
, 0 );
2425 assert( !"invalid result location" );
2428 static void compile_append_chain( PARSE
* parse
, compiler
* c
)
2430 assert( parse
->type
== PARSE_APPEND
);
2431 if ( parse
->left
->type
== PARSE_NULL
)
2432 compile_parse( parse
->right
, c
, RESULT_STACK
);
2435 if ( parse
->left
->type
== PARSE_APPEND
)
2436 compile_append_chain( parse
->left
, c
);
2438 compile_parse( parse
->left
, c
, RESULT_STACK
);
2439 compile_parse( parse
->right
, c
, RESULT_STACK
);
2440 compile_emit( c
, INSTR_PUSH_APPEND
, 0 );
2444 static void compile_emit_debug(compiler
* c
, int line
)
2447 if ( debug_is_debugging() )
2448 compile_emit( c
, INSTR_DEBUG_LINE
, line
);
2452 static void compile_parse( PARSE
* parse
, compiler
* c
, int result_location
)
2454 compile_emit_debug(c
, parse
->line
);
2455 if ( parse
->type
== PARSE_APPEND
)
2457 compile_append_chain( parse
, c
);
2458 adjust_result( c
, RESULT_STACK
, result_location
);
2460 else if ( parse
->type
== PARSE_EVAL
)
2462 /* FIXME: This is only needed because of the bizarre parsing of
2465 if ( parse
->num
== EXPR_EXISTS
)
2466 compile_parse( parse
->left
, c
, result_location
);
2469 int f
= compile_new_label( c
);
2470 int end
= compile_new_label( c
);
2472 out_printf( "%s:%d: Conditional used as list (check operator "
2473 "precedence).\n", object_str( parse
->file
), parse
->line
);
2475 /* Emit the condition */
2476 compile_condition( parse
, c
, 0, f
);
2477 compile_emit( c
, INSTR_PUSH_CONSTANT
, compile_emit_constant( c
,
2479 compile_emit_branch( c
, INSTR_JUMP
, end
);
2480 compile_set_label( c
, f
);
2481 compile_emit( c
, INSTR_PUSH_EMPTY
, 0 );
2482 compile_set_label( c
, end
);
2483 adjust_result( c
, RESULT_STACK
, result_location
);
2486 else if ( parse
->type
== PARSE_FOREACH
)
2488 int var
= compile_emit_constant( c
, parse
->string
);
2489 int top
= compile_new_label( c
);
2490 int end
= compile_new_label( c
);
2491 int continue_
= compile_new_label( c
);
2494 * Evaluate the list.
2496 compile_parse( parse
->left
, c
, RESULT_STACK
);
2498 /* Localize the loop variable */
2501 compile_emit( c
, INSTR_PUSH_EMPTY
, 0 );
2502 compile_emit( c
, INSTR_PUSH_LOCAL
, var
);
2503 compile_emit( c
, INSTR_SWAP
, 1 );
2504 compile_push_cleanup( c
, INSTR_POP_LOCAL
, var
);
2507 compile_emit( c
, INSTR_FOR_INIT
, 0 );
2508 compile_set_label( c
, top
);
2509 compile_emit_branch( c
, INSTR_FOR_LOOP
, end
);
2510 compile_emit_debug( c
, parse
->line
);
2511 compile_emit( c
, INSTR_SET
, var
);
2513 compile_push_break_scope( c
, end
);
2514 compile_push_cleanup( c
, INSTR_FOR_POP
, 0 );
2515 compile_push_continue_scope( c
, continue_
);
2517 /* Run the loop body */
2518 compile_parse( parse
->right
, c
, RESULT_NONE
);
2520 compile_pop_continue_scope( c
);
2521 compile_pop_cleanup( c
);
2522 compile_pop_break_scope( c
);
2524 compile_set_label( c
, continue_
);
2525 compile_emit_branch( c
, INSTR_JUMP
, top
);
2526 compile_set_label( c
, end
);
2530 compile_pop_cleanup( c
);
2531 compile_emit( c
, INSTR_POP_LOCAL
, var
);
2534 adjust_result( c
, RESULT_NONE
, result_location
);
2536 else if ( parse
->type
== PARSE_IF
)
2538 int f
= compile_new_label( c
);
2539 /* Emit the condition */
2540 compile_condition( parse
->left
, c
, 0, f
);
2541 /* Emit the if block */
2542 compile_parse( parse
->right
, c
, result_location
);
2543 if ( parse
->third
->type
!= PARSE_NULL
|| result_location
!= RESULT_NONE
)
2545 /* Emit the else block */
2546 int end
= compile_new_label( c
);
2547 compile_emit_branch( c
, INSTR_JUMP
, end
);
2548 compile_set_label( c
, f
);
2549 compile_parse( parse
->third
, c
, result_location
);
2550 compile_set_label( c
, end
);
2553 compile_set_label( c
, f
);
2556 else if ( parse
->type
== PARSE_WHILE
)
2558 int nested_result
= result_location
== RESULT_NONE
2561 int test
= compile_new_label( c
);
2562 int top
= compile_new_label( c
);
2563 int end
= compile_new_label( c
);
2564 /* Make sure that we return an empty list if the loop runs zero times.
2566 adjust_result( c
, RESULT_NONE
, nested_result
);
2567 /* Jump to the loop test. */
2568 compile_emit_branch( c
, INSTR_JUMP
, test
);
2569 compile_set_label( c
, top
);
2570 /* Emit the loop body. */
2571 compile_push_break_scope( c
, end
);
2572 compile_push_continue_scope( c
, test
);
2573 compile_parse( parse
->right
, c
, nested_result
);
2574 compile_pop_continue_scope( c
);
2575 compile_pop_break_scope( c
);
2576 /* Emit the condition. */
2577 compile_set_label( c
, test
);
2578 compile_condition( parse
->left
, c
, 1, top
);
2579 compile_set_label( c
, end
);
2581 adjust_result( c
, nested_result
, result_location
);
2583 else if ( parse
->type
== PARSE_INCLUDE
)
2585 compile_parse( parse
->left
, c
, RESULT_STACK
);
2586 compile_emit( c
, INSTR_INCLUDE
, 0 );
2587 compile_emit( c
, INSTR_BIND_MODULE_VARIABLES
, 0 );
2588 adjust_result( c
, RESULT_NONE
, result_location
);
2590 else if ( parse
->type
== PARSE_MODULE
)
2592 int const nested_result
= result_location
== RESULT_NONE
2595 compile_parse( parse
->left
, c
, RESULT_STACK
);
2596 compile_emit( c
, INSTR_PUSH_MODULE
, 0 );
2597 compile_push_cleanup( c
, INSTR_POP_MODULE
, 0 );
2598 compile_parse( parse
->right
, c
, nested_result
);
2599 compile_pop_cleanup( c
);
2600 compile_emit( c
, INSTR_POP_MODULE
, 0 );
2601 adjust_result( c
, nested_result
, result_location
);
2603 else if ( parse
->type
== PARSE_CLASS
)
2605 /* Evaluate the class name. */
2606 compile_parse( parse
->left
->right
, c
, RESULT_STACK
);
2607 /* Evaluate the base classes. */
2608 if ( parse
->left
->left
)
2609 compile_parse( parse
->left
->left
->right
, c
, RESULT_STACK
);
2611 compile_emit( c
, INSTR_PUSH_EMPTY
, 0 );
2612 compile_emit( c
, INSTR_CLASS
, 0 );
2613 compile_push_cleanup( c
, INSTR_POP_MODULE
, 0 );
2614 compile_parse( parse
->right
, c
, RESULT_NONE
);
2615 compile_emit( c
, INSTR_BIND_MODULE_VARIABLES
, 0 );
2616 compile_pop_cleanup( c
);
2617 compile_emit( c
, INSTR_POP_MODULE
, 0 );
2619 adjust_result( c
, RESULT_NONE
, result_location
);
2621 else if ( parse
->type
== PARSE_LIST
)
2623 OBJECT
* const o
= parse
->string
;
2624 char const * s
= object_str( o
);
2625 VAR_PARSE_GROUP
* group
;
2626 current_file
= object_str( parse
->file
);
2627 current_line
= parse
->line
;
2628 group
= parse_expansion( &s
);
2629 var_parse_group_compile( group
, c
);
2630 var_parse_group_free( group
);
2631 adjust_result( c
, RESULT_STACK
, result_location
);
2633 else if ( parse
->type
== PARSE_LOCAL
)
2635 int nested_result
= result_location
== RESULT_NONE
2638 /* This should be left recursive group of compile_appends. */
2639 PARSE
* vars
= parse
->left
;
2641 /* Special case an empty list of vars */
2642 if ( vars
->type
== PARSE_NULL
)
2644 compile_parse( parse
->right
, c
, RESULT_NONE
);
2645 compile_parse( parse
->third
, c
, result_location
);
2646 nested_result
= result_location
;
2648 /* Check whether there is exactly one variable with a constant name. */
2649 else if ( vars
->left
->type
== PARSE_NULL
&&
2650 vars
->right
->type
== PARSE_LIST
)
2652 char const * s
= object_str( vars
->right
->string
);
2653 VAR_PARSE_GROUP
* group
;
2654 current_file
= object_str( parse
->file
);
2655 current_line
= parse
->line
;
2656 group
= parse_expansion( &s
);
2657 if ( group
->elems
->size
== 1 && dynamic_array_at( VAR_PARSE
*,
2658 group
->elems
, 0 )->type
== VAR_PARSE_TYPE_STRING
)
2660 int const name
= compile_emit_constant( c
, (
2661 (VAR_PARSE_STRING
*)dynamic_array_at( VAR_PARSE
*,
2662 group
->elems
, 0 ) )->s
);
2663 var_parse_group_free( group
);
2664 compile_parse( parse
->right
, c
, RESULT_STACK
);
2665 compile_emit_debug(c
, parse
->line
);
2666 compile_emit( c
, INSTR_PUSH_LOCAL
, name
);
2667 compile_push_cleanup( c
, INSTR_POP_LOCAL
, name
);
2668 compile_parse( parse
->third
, c
, nested_result
);
2669 compile_pop_cleanup( c
);
2670 compile_emit( c
, INSTR_POP_LOCAL
, name
);
2674 var_parse_group_compile( group
, c
);
2675 var_parse_group_free( group
);
2676 compile_parse( parse
->right
, c
, RESULT_STACK
);
2677 compile_emit_debug(c
, parse
->line
);
2678 compile_emit( c
, INSTR_PUSH_LOCAL_GROUP
, 0 );
2679 compile_push_cleanup( c
, INSTR_POP_LOCAL_GROUP
, 0 );
2680 compile_parse( parse
->third
, c
, nested_result
);
2681 compile_pop_cleanup( c
);
2682 compile_emit( c
, INSTR_POP_LOCAL_GROUP
, 0 );
2687 compile_parse( parse
->left
, c
, RESULT_STACK
);
2688 compile_parse( parse
->right
, c
, RESULT_STACK
);
2689 compile_emit_debug(c
, parse
->line
);
2690 compile_emit( c
, INSTR_PUSH_LOCAL_GROUP
, 0 );
2691 compile_push_cleanup( c
, INSTR_POP_LOCAL_GROUP
, 0 );
2692 compile_parse( parse
->third
, c
, nested_result
);
2693 compile_pop_cleanup( c
);
2694 compile_emit( c
, INSTR_POP_LOCAL_GROUP
, 0 );
2696 adjust_result( c
, nested_result
, result_location
);
2698 else if ( parse
->type
== PARSE_ON
)
2700 if ( parse
->right
->type
== PARSE_APPEND
&&
2701 parse
->right
->left
->type
== PARSE_NULL
&&
2702 parse
->right
->right
->type
== PARSE_LIST
)
2704 /* [ on $(target) return $(variable) ] */
2705 PARSE
* value
= parse
->right
->right
;
2706 OBJECT
* const o
= value
->string
;
2707 char const * s
= object_str( o
);
2708 VAR_PARSE_GROUP
* group
;
2709 OBJECT
* varname
= 0;
2710 current_file
= object_str( value
->file
);
2711 current_line
= value
->line
;
2712 group
= parse_expansion( &s
);
2713 if ( group
->elems
->size
== 1 )
2715 VAR_PARSE
* one
= dynamic_array_at( VAR_PARSE
*, group
->elems
, 0 );
2716 if ( one
->type
== VAR_PARSE_TYPE_VAR
)
2718 VAR_PARSE_VAR
* var
= ( VAR_PARSE_VAR
* )one
;
2719 if ( var
->modifiers
->size
== 0 && !var
->subscript
&& var
->name
->elems
->size
== 1 )
2721 VAR_PARSE
* name
= dynamic_array_at( VAR_PARSE
*, var
->name
->elems
, 0 );
2722 if ( name
->type
== VAR_PARSE_TYPE_STRING
)
2724 varname
= ( ( VAR_PARSE_STRING
* )name
)->s
;
2731 /* We have one variable with a fixed name and no modifiers. */
2732 compile_parse( parse
->left
, c
, RESULT_STACK
);
2733 compile_emit( c
, INSTR_GET_ON
, compile_emit_constant( c
, varname
) );
2737 /* Too complex. Fall back on push/pop. */
2738 int end
= compile_new_label( c
);
2739 compile_parse( parse
->left
, c
, RESULT_STACK
);
2740 compile_emit_branch( c
, INSTR_PUSH_ON
, end
);
2741 compile_push_cleanup( c
, INSTR_POP_ON
, 0 );
2742 var_parse_group_compile( group
, c
);
2743 compile_pop_cleanup( c
);
2744 compile_emit( c
, INSTR_POP_ON
, 0 );
2745 compile_set_label( c
, end
);
2747 var_parse_group_free( group
);
2751 int end
= compile_new_label( c
);
2752 compile_parse( parse
->left
, c
, RESULT_STACK
);
2753 compile_emit_branch( c
, INSTR_PUSH_ON
, end
);
2754 compile_push_cleanup( c
, INSTR_POP_ON
, 0 );
2755 compile_parse( parse
->right
, c
, RESULT_STACK
);
2756 compile_pop_cleanup( c
);
2757 compile_emit( c
, INSTR_POP_ON
, 0 );
2758 compile_set_label( c
, end
);
2760 adjust_result( c
, RESULT_STACK
, result_location
);
2762 else if ( parse
->type
== PARSE_RULE
)
2766 VAR_PARSE_GROUP
* group
;
2767 char const * s
= object_str( parse
->string
);
2769 if ( parse
->left
->left
|| parse
->left
->right
->type
!= PARSE_NULL
)
2770 for ( p
= parse
->left
; p
; p
= p
->left
)
2772 compile_parse( p
->right
, c
, RESULT_STACK
);
2776 current_file
= object_str( parse
->file
);
2777 current_line
= parse
->line
;
2778 group
= parse_expansion( &s
);
2780 if ( group
->elems
->size
== 2 &&
2781 dynamic_array_at( VAR_PARSE
*, group
->elems
, 0 )->type
== VAR_PARSE_TYPE_VAR
&&
2782 dynamic_array_at( VAR_PARSE
*, group
->elems
, 1 )->type
== VAR_PARSE_TYPE_STRING
&&
2783 ( object_str( ( (VAR_PARSE_STRING
*)dynamic_array_at( VAR_PARSE
*, group
->elems
, 1 ) )->s
)[ 0 ] == '.' ) )
2785 VAR_PARSE_STRING
* access
= (VAR_PARSE_STRING
*)dynamic_array_at( VAR_PARSE
*, group
->elems
, 1 );
2786 OBJECT
* member
= object_new( object_str( access
->s
) + 1 );
2787 /* Emit the object */
2788 var_parse_var_compile( (VAR_PARSE_VAR
*)dynamic_array_at( VAR_PARSE
*, group
->elems
, 0 ), c
);
2789 var_parse_group_free( group
);
2790 compile_emit( c
, INSTR_CALL_MEMBER_RULE
, n
);
2791 compile_emit( c
, compile_emit_constant( c
, member
), parse
->line
);
2792 object_free( member
);
2796 var_parse_group_compile( group
, c
);
2797 var_parse_group_free( group
);
2798 compile_emit( c
, INSTR_CALL_RULE
, n
);
2799 compile_emit( c
, compile_emit_constant( c
, parse
->string
), parse
->line
);
2802 adjust_result( c
, RESULT_STACK
, result_location
);
2804 else if ( parse
->type
== PARSE_RULES
)
2806 do compile_parse( parse
->left
, c
, RESULT_NONE
);
2807 while ( ( parse
= parse
->right
)->type
== PARSE_RULES
);
2808 compile_parse( parse
, c
, result_location
);
2810 else if ( parse
->type
== PARSE_SET
)
2812 PARSE
* vars
= parse
->left
;
2813 unsigned int op_code
;
2814 unsigned int op_code_group
;
2816 switch ( parse
->num
)
2818 case ASSIGN_APPEND
: op_code
= INSTR_APPEND
; op_code_group
= INSTR_APPEND_GROUP
; break;
2819 case ASSIGN_DEFAULT
: op_code
= INSTR_DEFAULT
; op_code_group
= INSTR_DEFAULT_GROUP
; break;
2820 default: op_code
= INSTR_SET
; op_code_group
= INSTR_SET_GROUP
; break;
2823 /* Check whether there is exactly one variable with a constant name. */
2824 if ( vars
->type
== PARSE_LIST
)
2826 char const * s
= object_str( vars
->string
);
2827 VAR_PARSE_GROUP
* group
;
2828 current_file
= object_str( parse
->file
);
2829 current_line
= parse
->line
;
2830 group
= parse_expansion( &s
);
2831 if ( group
->elems
->size
== 1 && dynamic_array_at( VAR_PARSE
*,
2832 group
->elems
, 0 )->type
== VAR_PARSE_TYPE_STRING
)
2834 int const name
= compile_emit_constant( c
, (
2835 (VAR_PARSE_STRING
*)dynamic_array_at( VAR_PARSE
*,
2836 group
->elems
, 0 ) )->s
);
2837 var_parse_group_free( group
);
2838 compile_parse( parse
->right
, c
, RESULT_STACK
);
2839 compile_emit_debug(c
, parse
->line
);
2840 if ( result_location
!= RESULT_NONE
)
2842 compile_emit( c
, INSTR_SET_RESULT
, 1 );
2844 compile_emit( c
, op_code
, name
);
2848 var_parse_group_compile( group
, c
);
2849 var_parse_group_free( group
);
2850 compile_parse( parse
->right
, c
, RESULT_STACK
);
2851 compile_emit_debug(c
, parse
->line
);
2852 if ( result_location
!= RESULT_NONE
)
2854 compile_emit( c
, INSTR_SET_RESULT
, 1 );
2856 compile_emit( c
, op_code_group
, 0 );
2861 compile_parse( parse
->left
, c
, RESULT_STACK
);
2862 compile_parse( parse
->right
, c
, RESULT_STACK
);
2863 compile_emit_debug(c
, parse
->line
);
2864 if ( result_location
!= RESULT_NONE
)
2866 compile_emit( c
, INSTR_SET_RESULT
, 1 );
2868 compile_emit( c
, op_code_group
, 0 );
2870 if ( result_location
!= RESULT_NONE
)
2872 adjust_result( c
, RESULT_RETURN
, result_location
);
2875 else if ( parse
->type
== PARSE_SETCOMP
)
2878 struct arg_list
* args
= arg_list_compile( parse
->right
, &n_args
);
2879 int const rule_id
= compile_emit_rule( c
, parse
->string
, parse
->left
,
2880 n_args
, args
, parse
->num
);
2881 compile_emit( c
, INSTR_RULE
, rule_id
);
2882 adjust_result( c
, RESULT_NONE
, result_location
);
2884 else if ( parse
->type
== PARSE_SETEXEC
)
2886 int const actions_id
= compile_emit_actions( c
, parse
);
2887 compile_parse( parse
->left
, c
, RESULT_STACK
);
2888 compile_emit( c
, INSTR_ACTIONS
, actions_id
);
2889 adjust_result( c
, RESULT_NONE
, result_location
);
2891 else if ( parse
->type
== PARSE_SETTINGS
)
2893 compile_parse( parse
->left
, c
, RESULT_STACK
);
2894 compile_parse( parse
->third
, c
, RESULT_STACK
);
2895 compile_parse( parse
->right
, c
, RESULT_STACK
);
2897 compile_emit_debug(c
, parse
->line
);
2898 switch ( parse
->num
)
2900 case ASSIGN_APPEND
: compile_emit( c
, INSTR_APPEND_ON
, 0 ); break;
2901 case ASSIGN_DEFAULT
: compile_emit( c
, INSTR_DEFAULT_ON
, 0 ); break;
2902 default: compile_emit( c
, INSTR_SET_ON
, 0 ); break;
2905 adjust_result( c
, RESULT_STACK
, result_location
);
2907 else if ( parse
->type
== PARSE_SWITCH
)
2909 int const switch_end
= compile_new_label( c
);
2910 compile_parse( parse
->left
, c
, RESULT_STACK
);
2912 for ( parse
= parse
->right
; parse
; parse
= parse
->right
)
2914 int const id
= compile_emit_constant( c
, parse
->left
->string
);
2915 int const next_case
= compile_new_label( c
);
2916 compile_emit( c
, INSTR_PUSH_CONSTANT
, id
);
2917 compile_emit_branch( c
, INSTR_JUMP_NOT_GLOB
, next_case
);
2918 compile_parse( parse
->left
->left
, c
, result_location
);
2919 compile_emit_branch( c
, INSTR_JUMP
, switch_end
);
2920 compile_set_label( c
, next_case
);
2922 compile_emit( c
, INSTR_POP
, 0 );
2923 adjust_result( c
, RESULT_NONE
, result_location
);
2924 compile_set_label( c
, switch_end
);
2926 else if ( parse
->type
== PARSE_RETURN
)
2928 compile_parse( parse
->left
, c
, RESULT_RETURN
);
2929 compile_emit_cleanups( c
, 0 );
2930 compile_emit( c
, INSTR_RETURN
, 0 ); /* 0 for return in the middle of a function. */
2932 else if ( parse
->type
== PARSE_BREAK
)
2934 compile_emit_loop_jump( c
, LOOP_INFO_BREAK
);
2936 else if ( parse
->type
== PARSE_CONTINUE
)
2938 compile_emit_loop_jump( c
, LOOP_INFO_CONTINUE
);
2940 else if ( parse
->type
== PARSE_NULL
)
2941 adjust_result( c
, RESULT_NONE
, result_location
);
2943 assert( !"unknown PARSE type." );
2946 OBJECT
* function_rulename( FUNCTION
* function
)
2948 return function
->rulename
;
2951 void function_set_rulename( FUNCTION
* function
, OBJECT
* rulename
)
2953 function
->rulename
= rulename
;
2956 void function_location( FUNCTION
* function_
, OBJECT
* * file
, int * line
)
2958 if ( function_
->type
== FUNCTION_BUILTIN
)
2960 *file
= constant_builtin
;
2964 if ( function_
->type
== FUNCTION_PYTHON
)
2966 *file
= constant_builtin
;
2972 JAM_FUNCTION
* function
= (JAM_FUNCTION
*)function_
;
2973 assert( function_
->type
== FUNCTION_JAM
);
2974 *file
= function
->file
;
2975 *line
= function
->line
;
2979 static struct arg_list
* arg_list_compile_builtin( char const * * args
,
2980 int * num_arguments
);
2982 FUNCTION
* function_builtin( LIST
* ( * func
)( FRAME
* frame
, int flags
),
2983 int flags
, char const * * args
)
2985 BUILTIN_FUNCTION
* result
= (BUILTIN_FUNCTION
*)BJAM_MALLOC( sizeof( BUILTIN_FUNCTION
) );
2986 result
->base
.type
= FUNCTION_BUILTIN
;
2987 result
->base
.reference_count
= 1;
2988 result
->base
.rulename
= 0;
2989 result
->base
.formal_arguments
= arg_list_compile_builtin( args
,
2990 &result
->base
.num_formal_arguments
);
2991 result
->func
= func
;
2992 result
->flags
= flags
;
2993 return (FUNCTION
*)result
;
2996 FUNCTION
* function_compile( PARSE
* parse
)
2999 JAM_FUNCTION
* result
;
3001 compile_parse( parse
, c
, RESULT_RETURN
);
3002 compile_emit( c
, INSTR_RETURN
, 1 );
3003 result
= compile_to_function( c
);
3005 result
->file
= object_copy( parse
->file
);
3006 result
->line
= parse
->line
;
3007 return (FUNCTION
*)result
;
3010 FUNCTION
* function_compile_actions( char const * actions
, OBJECT
* file
,
3014 JAM_FUNCTION
* result
;
3015 VAR_PARSE_ACTIONS
* parse
;
3016 current_file
= object_str( file
);
3017 current_line
= line
;
3018 parse
= parse_actions( actions
);
3020 var_parse_actions_compile( parse
, c
);
3021 var_parse_actions_free( parse
);
3022 compile_emit( c
, INSTR_RETURN
, 1 );
3023 result
= compile_to_function( c
);
3025 result
->file
= object_copy( file
);
3026 result
->line
= line
;
3027 return (FUNCTION
*)result
;
3030 static void argument_list_print( struct arg_list
* args
, int num_args
);
3033 /* Define delimiters for type check elements in argument lists (and return type
3034 * specifications, eventually).
3036 # define TYPE_OPEN_DELIM '['
3037 # define TYPE_CLOSE_DELIM ']'
3040 * is_type_name() - true iff the given string represents a type check
3044 int is_type_name( char const * s
)
3046 return s
[ 0 ] == TYPE_OPEN_DELIM
&& s
[ strlen( s
) - 1 ] ==
3050 static void argument_error( char const * message
, FUNCTION
* procedure
,
3051 FRAME
* frame
, OBJECT
* arg
)
3053 extern void print_source_line( FRAME
* );
3054 LOL
* actual
= frame
->args
;
3055 backtrace_line( frame
->prev
);
3056 out_printf( "*** argument error\n* rule %s ( ", frame
->rulename
);
3057 argument_list_print( procedure
->formal_arguments
,
3058 procedure
->num_formal_arguments
);
3059 out_printf( " )\n* called with: ( " );
3060 lol_print( actual
);
3061 out_printf( " )\n* %s %s\n", message
, arg
? object_str ( arg
) : "" );
3062 function_location( procedure
, &frame
->file
, &frame
->line
);
3063 print_source_line( frame
);
3064 out_printf( "see definition of rule '%s' being called\n", frame
->rulename
);
3065 backtrace( frame
->prev
);
3069 static void type_check_range( OBJECT
* type_name
, LISTITER iter
, LISTITER end
,
3070 FRAME
* caller
, FUNCTION
* called
, OBJECT
* arg_name
)
3072 static module_t
* typecheck
= 0;
3074 /* If nothing to check, bail now. */
3075 if ( iter
== end
|| !type_name
)
3079 typecheck
= bindmodule( constant_typecheck
);
3081 /* If the checking rule can not be found, also bail. */
3082 if ( !typecheck
->rules
|| !hash_find( typecheck
->rules
, type_name
) )
3085 for ( ; iter
!= end
; iter
= list_next( iter
) )
3089 frame_init( frame
);
3090 frame
->module
= typecheck
;
3091 frame
->prev
= caller
;
3092 frame
->prev_user
= caller
->module
->user_module
3094 : caller
->prev_user
;
3096 /* Prepare the argument list */
3097 lol_add( frame
->args
, list_new( object_copy( list_item( iter
) ) ) );
3098 error
= evaluate_rule( bindrule( type_name
, frame
->module
), type_name
, frame
);
3100 if ( !list_empty( error
) )
3101 argument_error( object_str( list_front( error
) ), called
, caller
,
3104 frame_free( frame
);
3108 static void type_check( OBJECT
* type_name
, LIST
* values
, FRAME
* caller
,
3109 FUNCTION
* called
, OBJECT
* arg_name
)
3111 type_check_range( type_name
, list_begin( values
), list_end( values
),
3112 caller
, called
, arg_name
);
3115 void argument_list_check( struct arg_list
* formal
, int formal_count
,
3116 FUNCTION
* function
, FRAME
* frame
)
3118 LOL
* all_actual
= frame
->args
;
3121 for ( i
= 0; i
< formal_count
; ++i
)
3123 LIST
* actual
= lol_get( all_actual
, i
);
3124 LISTITER actual_iter
= list_begin( actual
);
3125 LISTITER
const actual_end
= list_end( actual
);
3127 for ( j
= 0; j
< formal
[ i
].size
; ++j
)
3129 struct argument
* formal_arg
= &formal
[ i
].args
[ j
];
3131 switch ( formal_arg
->flags
)
3134 if ( actual_iter
== actual_end
)
3135 argument_error( "missing argument", function
, frame
,
3136 formal_arg
->arg_name
);
3137 type_check_range( formal_arg
->type_name
, actual_iter
,
3138 list_next( actual_iter
), frame
, function
,
3139 formal_arg
->arg_name
);
3140 actual_iter
= list_next( actual_iter
);
3143 if ( actual_iter
!= actual_end
)
3145 type_check_range( formal_arg
->type_name
, actual_iter
,
3146 list_next( actual_iter
), frame
, function
,
3147 formal_arg
->arg_name
);
3148 actual_iter
= list_next( actual_iter
);
3152 if ( actual_iter
== actual_end
)
3153 argument_error( "missing argument", function
, frame
,
3154 formal_arg
->arg_name
);
3157 type_check_range( formal_arg
->type_name
, actual_iter
,
3158 actual_end
, frame
, function
, formal_arg
->arg_name
);
3159 actual_iter
= actual_end
;
3166 if ( actual_iter
!= actual_end
)
3167 argument_error( "extra argument", function
, frame
, list_item(
3171 for ( ; i
< all_actual
->count
; ++i
)
3173 LIST
* actual
= lol_get( all_actual
, i
);
3174 if ( !list_empty( actual
) )
3175 argument_error( "extra argument", function
, frame
, list_front(
3180 void argument_list_push( struct arg_list
* formal
, int formal_count
,
3181 FUNCTION
* function
, FRAME
* frame
, STACK
* s
)
3183 LOL
* all_actual
= frame
->args
;
3186 for ( i
= 0; i
< formal_count
; ++i
)
3188 LIST
* actual
= lol_get( all_actual
, i
);
3189 LISTITER actual_iter
= list_begin( actual
);
3190 LISTITER
const actual_end
= list_end( actual
);
3192 for ( j
= 0; j
< formal
[ i
].size
; ++j
)
3194 struct argument
* formal_arg
= &formal
[ i
].args
[ j
];
3197 switch ( formal_arg
->flags
)
3200 if ( actual_iter
== actual_end
)
3201 argument_error( "missing argument", function
, frame
,
3202 formal_arg
->arg_name
);
3203 value
= list_new( object_copy( list_item( actual_iter
) ) );
3204 actual_iter
= list_next( actual_iter
);
3207 if ( actual_iter
== actual_end
)
3211 value
= list_new( object_copy( list_item( actual_iter
) ) );
3212 actual_iter
= list_next( actual_iter
);
3216 if ( actual_iter
== actual_end
)
3217 argument_error( "missing argument", function
, frame
,
3218 formal_arg
->arg_name
);
3221 value
= list_copy_range( actual
, actual_iter
, actual_end
);
3222 actual_iter
= actual_end
;
3228 type_check( formal_arg
->type_name
, value
, frame
, function
,
3229 formal_arg
->arg_name
);
3231 if ( formal_arg
->index
!= -1 )
3233 LIST
* * const old
= &frame
->module
->fixed_variables
[
3234 formal_arg
->index
];
3235 stack_push( s
, *old
);
3239 stack_push( s
, var_swap( frame
->module
, formal_arg
->arg_name
,
3243 if ( actual_iter
!= actual_end
)
3244 argument_error( "extra argument", function
, frame
, list_item(
3248 for ( ; i
< all_actual
->count
; ++i
)
3250 LIST
* const actual
= lol_get( all_actual
, i
);
3251 if ( !list_empty( actual
) )
3252 argument_error( "extra argument", function
, frame
, list_front(
3257 void argument_list_pop( struct arg_list
* formal
, int formal_count
,
3258 FRAME
* frame
, STACK
* s
)
3261 for ( i
= formal_count
- 1; i
>= 0; --i
)
3264 for ( j
= formal
[ i
].size
- 1; j
>= 0 ; --j
)
3266 struct argument
* formal_arg
= &formal
[ i
].args
[ j
];
3268 if ( formal_arg
->flags
== ARG_VARIADIC
)
3270 if ( formal_arg
->index
!= -1 )
3272 LIST
* const old
= stack_pop( s
);
3273 LIST
* * const pos
= &frame
->module
->fixed_variables
[
3274 formal_arg
->index
];
3279 var_set( frame
->module
, formal_arg
->arg_name
, stack_pop( s
),
3286 struct argument_compiler
3288 struct dynamic_array args
[ 1 ];
3289 struct argument arg
;
3291 #define ARGUMENT_COMPILER_START 0
3292 #define ARGUMENT_COMPILER_FOUND_TYPE 1
3293 #define ARGUMENT_COMPILER_FOUND_OBJECT 2
3294 #define ARGUMENT_COMPILER_DONE 3
3298 static void argument_compiler_init( struct argument_compiler
* c
)
3300 dynamic_array_init( c
->args
);
3301 c
->state
= ARGUMENT_COMPILER_START
;
3304 static void argument_compiler_free( struct argument_compiler
* c
)
3306 dynamic_array_free( c
->args
);
3309 static void argument_compiler_add( struct argument_compiler
* c
, OBJECT
* arg
,
3310 OBJECT
* file
, int line
)
3314 case ARGUMENT_COMPILER_FOUND_OBJECT
:
3316 if ( object_equal( arg
, constant_question_mark
) )
3318 c
->arg
.flags
= ARG_OPTIONAL
;
3320 else if ( object_equal( arg
, constant_plus
) )
3322 c
->arg
.flags
= ARG_PLUS
;
3324 else if ( object_equal( arg
, constant_star
) )
3326 c
->arg
.flags
= ARG_STAR
;
3329 dynamic_array_push( c
->args
, c
->arg
);
3330 c
->state
= ARGUMENT_COMPILER_START
;
3332 if ( c
->arg
.flags
!= ARG_ONE
)
3336 case ARGUMENT_COMPILER_START
:
3338 c
->arg
.type_name
= 0;
3340 c
->arg
.flags
= ARG_ONE
;
3342 if ( is_type_name( object_str( arg
) ) )
3344 c
->arg
.type_name
= object_copy( arg
);
3345 c
->state
= ARGUMENT_COMPILER_FOUND_TYPE
;
3350 case ARGUMENT_COMPILER_FOUND_TYPE
:
3352 if ( is_type_name( object_str( arg
) ) )
3354 err_printf( "%s:%d: missing argument name before type name: %s\n",
3355 object_str( file
), line
, object_str( arg
) );
3359 c
->arg
.arg_name
= object_copy( arg
);
3360 if ( object_equal( arg
, constant_star
) )
3362 c
->arg
.flags
= ARG_VARIADIC
;
3363 dynamic_array_push( c
->args
, c
->arg
);
3364 c
->state
= ARGUMENT_COMPILER_DONE
;
3368 c
->state
= ARGUMENT_COMPILER_FOUND_OBJECT
;
3372 case ARGUMENT_COMPILER_DONE
:
3377 static void argument_compiler_recurse( struct argument_compiler
* c
,
3380 if ( parse
->type
== PARSE_APPEND
)
3382 argument_compiler_recurse( c
, parse
->left
);
3383 argument_compiler_recurse( c
, parse
->right
);
3385 else if ( parse
->type
!= PARSE_NULL
)
3387 assert( parse
->type
== PARSE_LIST
);
3388 argument_compiler_add( c
, parse
->string
, parse
->file
, parse
->line
);
3392 static struct arg_list
arg_compile_impl( struct argument_compiler
* c
,
3393 OBJECT
* file
, int line
)
3395 struct arg_list result
;
3398 case ARGUMENT_COMPILER_START
:
3399 case ARGUMENT_COMPILER_DONE
:
3401 case ARGUMENT_COMPILER_FOUND_TYPE
:
3402 err_printf( "%s:%d: missing argument name after type name: %s\n",
3403 object_str( file
), line
, object_str( c
->arg
.type_name
) );
3405 case ARGUMENT_COMPILER_FOUND_OBJECT
:
3406 dynamic_array_push( c
->args
, c
->arg
);
3409 result
.size
= c
->args
->size
;
3410 result
.args
= (struct argument
*)BJAM_MALLOC( c
->args
->size
* sizeof( struct argument
) );
3411 if ( c
->args
->size
!= 0 )
3412 memcpy( result
.args
, c
->args
->data
,
3413 c
->args
->size
* sizeof( struct argument
) );
3417 static struct arg_list
arg_compile( PARSE
* parse
)
3419 struct argument_compiler c
[ 1 ];
3420 struct arg_list result
;
3421 argument_compiler_init( c
);
3422 argument_compiler_recurse( c
, parse
);
3423 result
= arg_compile_impl( c
, parse
->file
, parse
->line
);
3424 argument_compiler_free( c
);
3428 struct argument_list_compiler
3430 struct dynamic_array args
[ 1 ];
3433 static void argument_list_compiler_init( struct argument_list_compiler
* c
)
3435 dynamic_array_init( c
->args
);
3438 static void argument_list_compiler_free( struct argument_list_compiler
* c
)
3440 dynamic_array_free( c
->args
);
3443 static void argument_list_compiler_add( struct argument_list_compiler
* c
,
3446 struct arg_list args
= arg_compile( parse
);
3447 dynamic_array_push( c
->args
, args
);
3450 static void argument_list_compiler_recurse( struct argument_list_compiler
* c
,
3455 argument_list_compiler_add( c
, parse
->right
);
3456 argument_list_compiler_recurse( c
, parse
->left
);
3460 static struct arg_list
* arg_list_compile( PARSE
* parse
, int * num_arguments
)
3464 struct argument_list_compiler c
[ 1 ];
3465 struct arg_list
* result
;
3466 argument_list_compiler_init( c
);
3467 argument_list_compiler_recurse( c
, parse
);
3468 *num_arguments
= c
->args
->size
;
3469 result
= (struct arg_list
*)BJAM_MALLOC( c
->args
->size
* sizeof( struct arg_list
) );
3470 memcpy( result
, c
->args
->data
, c
->args
->size
* sizeof( struct arg_list
)
3472 argument_list_compiler_free( c
);
3479 static struct arg_list
* arg_list_compile_builtin( char const * * args
,
3480 int * num_arguments
)
3484 struct argument_list_compiler c
[ 1 ];
3485 struct arg_list
* result
;
3486 argument_list_compiler_init( c
);
3489 struct argument_compiler arg_comp
[ 1 ];
3490 struct arg_list arg
;
3491 argument_compiler_init( arg_comp
);
3492 for ( ; *args
; ++args
)
3495 if ( strcmp( *args
, ":" ) == 0 )
3500 token
= object_new( *args
);
3501 argument_compiler_add( arg_comp
, token
, constant_builtin
, -1 );
3502 object_free( token
);
3504 arg
= arg_compile_impl( arg_comp
, constant_builtin
, -1 );
3505 dynamic_array_push( c
->args
, arg
);
3506 argument_compiler_free( arg_comp
);
3508 *num_arguments
= c
->args
->size
;
3509 result
= (struct arg_list
*)BJAM_MALLOC( c
->args
->size
* sizeof( struct arg_list
) );
3510 if ( c
->args
->size
!= 0 )
3511 memcpy( result
, c
->args
->data
,
3512 c
->args
->size
* sizeof( struct arg_list
) );
3513 argument_list_compiler_free( c
);
3520 static void argument_list_print( struct arg_list
* args
, int num_args
)
3525 for ( i
= 0; i
< num_args
; ++i
)
3528 if ( i
) out_printf( " : " );
3529 for ( j
= 0; j
< args
[ i
].size
; ++j
)
3531 struct argument
* formal_arg
= &args
[ i
].args
[ j
];
3532 if ( j
) out_printf( " " );
3533 if ( formal_arg
->type_name
)
3534 out_printf( "%s ", object_str( formal_arg
->type_name
) );
3535 out_printf( "%s", object_str( formal_arg
->arg_name
) );
3536 switch ( formal_arg
->flags
)
3538 case ARG_OPTIONAL
: out_printf( " ?" ); break;
3539 case ARG_PLUS
: out_printf( " +" ); break;
3540 case ARG_STAR
: out_printf( " *" ); break;
3548 struct arg_list
* argument_list_bind_variables( struct arg_list
* formal
,
3549 int formal_count
, module_t
* module
, int * counter
)
3553 struct arg_list
* result
= (struct arg_list
*)BJAM_MALLOC( sizeof(
3554 struct arg_list
) * formal_count
);
3557 for ( i
= 0; i
< formal_count
; ++i
)
3560 struct argument
* args
= (struct argument
*)BJAM_MALLOC( sizeof(
3561 struct argument
) * formal
[ i
].size
);
3562 for ( j
= 0; j
< formal
[ i
].size
; ++j
)
3564 args
[ j
] = formal
[ i
].args
[ j
];
3565 if ( args
[ j
].type_name
)
3566 args
[ j
].type_name
= object_copy( args
[ j
].type_name
);
3567 args
[ j
].arg_name
= object_copy( args
[ j
].arg_name
);
3568 if ( args
[ j
].flags
!= ARG_VARIADIC
)
3569 args
[ j
].index
= module_add_fixed_var( module
,
3570 args
[ j
].arg_name
, counter
);
3572 result
[ i
].args
= args
;
3573 result
[ i
].size
= formal
[ i
].size
;
3582 void argument_list_free( struct arg_list
* args
, int args_count
)
3585 for ( i
= 0; i
< args_count
; ++i
)
3588 for ( j
= 0; j
< args
[ i
].size
; ++j
)
3590 if ( args
[ i
].args
[ j
].type_name
)
3591 object_free( args
[ i
].args
[ j
].type_name
);
3592 object_free( args
[ i
].args
[ j
].arg_name
);
3594 BJAM_FREE( args
[ i
].args
);
3600 FUNCTION
* function_unbind_variables( FUNCTION
* f
)
3602 if ( f
->type
== FUNCTION_JAM
)
3604 JAM_FUNCTION
* const func
= (JAM_FUNCTION
*)f
;
3605 return func
->generic
? func
->generic
: f
;
3608 if ( f
->type
== FUNCTION_PYTHON
)
3611 assert( f
->type
== FUNCTION_BUILTIN
);
3615 FUNCTION
* function_bind_variables( FUNCTION
* f
, module_t
* module
,
3618 if ( f
->type
== FUNCTION_BUILTIN
)
3621 if ( f
->type
== FUNCTION_PYTHON
)
3625 JAM_FUNCTION
* func
= (JAM_FUNCTION
*)f
;
3626 JAM_FUNCTION
* new_func
= (JAM_FUNCTION
*)BJAM_MALLOC( sizeof( JAM_FUNCTION
) );
3629 assert( f
->type
== FUNCTION_JAM
);
3630 memcpy( new_func
, func
, sizeof( JAM_FUNCTION
) );
3631 new_func
->base
.reference_count
= 1;
3632 new_func
->base
.formal_arguments
= argument_list_bind_variables(
3633 f
->formal_arguments
, f
->num_formal_arguments
, module
, counter
);
3634 new_func
->code
= (instruction
*)BJAM_MALLOC( func
->code_size
* sizeof( instruction
) );
3635 memcpy( new_func
->code
, func
->code
, func
->code_size
* sizeof(
3637 new_func
->generic
= (FUNCTION
*)func
;
3639 for ( i
= 0; ; ++i
)
3643 code
= func
->code
+ i
;
3644 switch ( code
->op_code
)
3646 case INSTR_PUSH_VAR
: op_code
= INSTR_PUSH_VAR_FIXED
; break;
3647 case INSTR_PUSH_LOCAL
: op_code
= INSTR_PUSH_LOCAL_FIXED
; break;
3648 case INSTR_POP_LOCAL
: op_code
= INSTR_POP_LOCAL_FIXED
; break;
3649 case INSTR_SET
: op_code
= INSTR_SET_FIXED
; break;
3650 case INSTR_APPEND
: op_code
= INSTR_APPEND_FIXED
; break;
3651 case INSTR_DEFAULT
: op_code
= INSTR_DEFAULT_FIXED
; break;
3653 if( code
->arg
== 1 ) return (FUNCTION
*)new_func
;
3655 case INSTR_CALL_MEMBER_RULE
:
3656 case INSTR_CALL_RULE
: ++i
; continue;
3657 case INSTR_PUSH_MODULE
:
3663 code
= func
->code
+ i
;
3664 switch ( code
->op_code
)
3666 case INSTR_PUSH_MODULE
:
3670 case INSTR_POP_MODULE
:
3673 case INSTR_CALL_RULE
:
3683 key
= func
->constants
[ code
->arg
];
3684 if ( !( object_equal( key
, constant_TMPDIR
) ||
3685 object_equal( key
, constant_TMPNAME
) ||
3686 object_equal( key
, constant_TMPFILE
) ||
3687 object_equal( key
, constant_STDOUT
) ||
3688 object_equal( key
, constant_STDERR
) ) )
3690 code
->op_code
= op_code
;
3691 code
->arg
= module_add_fixed_var( module
, key
, counter
);
3697 LIST
* function_get_variables( FUNCTION
* f
)
3699 if ( f
->type
== FUNCTION_BUILTIN
)
3702 if ( f
->type
== FUNCTION_PYTHON
)
3706 JAM_FUNCTION
* func
= (JAM_FUNCTION
*)f
;
3710 assert( f
->type
== FUNCTION_JAM
);
3711 if ( func
->generic
) func
= ( JAM_FUNCTION
* )func
->generic
;
3713 for ( i
= 0; ; ++i
)
3716 code
= func
->code
+ i
;
3717 switch ( code
->op_code
)
3719 case INSTR_PUSH_LOCAL
: break;
3720 case INSTR_RETURN
: return result
;
3721 case INSTR_CALL_MEMBER_RULE
:
3722 case INSTR_CALL_RULE
: ++i
; continue;
3723 case INSTR_PUSH_MODULE
:
3729 code
= func
->code
+ i
;
3730 switch ( code
->op_code
)
3732 case INSTR_PUSH_MODULE
:
3736 case INSTR_POP_MODULE
:
3739 case INSTR_CALL_RULE
:
3749 var
= func
->constants
[ code
->arg
];
3750 if ( !( object_equal( var
, constant_TMPDIR
) ||
3751 object_equal( var
, constant_TMPNAME
) ||
3752 object_equal( var
, constant_TMPFILE
) ||
3753 object_equal( var
, constant_STDOUT
) ||
3754 object_equal( var
, constant_STDERR
) ) )
3756 result
= list_push_back( result
, var
);
3762 void function_refer( FUNCTION
* func
)
3764 ++func
->reference_count
;
3767 void function_free( FUNCTION
* function_
)
3771 if ( --function_
->reference_count
!= 0 )
3774 if ( function_
->formal_arguments
)
3775 argument_list_free( function_
->formal_arguments
,
3776 function_
->num_formal_arguments
);
3778 if ( function_
->type
== FUNCTION_JAM
)
3780 JAM_FUNCTION
* func
= (JAM_FUNCTION
*)function_
;
3782 BJAM_FREE( func
->code
);
3784 if ( func
->generic
)
3785 function_free( func
->generic
);
3788 if ( function_
->rulename
) object_free( function_
->rulename
);
3790 for ( i
= 0; i
< func
->num_constants
; ++i
)
3791 object_free( func
->constants
[ i
] );
3792 BJAM_FREE( func
->constants
);
3794 for ( i
= 0; i
< func
->num_subfunctions
; ++i
)
3796 object_free( func
->functions
[ i
].name
);
3797 function_free( func
->functions
[ i
].code
);
3799 BJAM_FREE( func
->functions
);
3801 for ( i
= 0; i
< func
->num_subactions
; ++i
)
3803 object_free( func
->actions
[ i
].name
);
3804 function_free( func
->actions
[ i
].command
);
3806 BJAM_FREE( func
->actions
);
3808 object_free( func
->file
);
3812 else if ( function_
->type
== FUNCTION_PYTHON
)
3814 PYTHON_FUNCTION
* func
= (PYTHON_FUNCTION
*)function_
;
3815 Py_DECREF( func
->python_function
);
3816 if ( function_
->rulename
) object_free( function_
->rulename
);
3821 assert( function_
->type
== FUNCTION_BUILTIN
);
3822 if ( function_
->rulename
) object_free( function_
->rulename
);
3825 BJAM_FREE( function_
);
3829 /* Alignment check for stack */
3831 struct align_var_edits
3837 struct align_expansion_item
3844 sizeof(struct align_var_edits
) <= sizeof(VAR_EDITS
) + sizeof(void *),
3845 "sizeof(struct align_var_edits) <= sizeof(VAR_EDITS) + sizeof(void *)" );
3847 sizeof(struct align_expansion_item
) <= sizeof(expansion_item
) + sizeof(void *),
3848 "sizeof(struct align_expansion_item) <= sizeof(expansion_item) + sizeof(void *)" );
3850 static_assert( sizeof(LIST
*) <= sizeof(void *), "sizeof(LIST *) <= sizeof(void *)" );
3851 static_assert( sizeof(char *) <= sizeof(void *), "sizeof(char *) <= sizeof(void *)" );
3853 void function_run_actions( FUNCTION
* function
, FRAME
* frame
, STACK
* s
,
3856 *(string
* *)stack_allocate( s
, sizeof( string
* ) ) = out
;
3857 list_free( function_run( function
, frame
, s
) );
3858 stack_deallocate( s
, sizeof( string
* ) );
3862 * WARNING: The instruction set is tuned for Jam and is not really generic. Be
3863 * especially careful about stack push/pop.
3866 LIST
* function_run( FUNCTION
* function_
, FRAME
* frame
, STACK
* s
)
3868 JAM_FUNCTION
* function
;
3873 void * saved_stack
= s
->data
;
3875 PROFILE_ENTER_LOCAL(function_run
);
3878 frame
->function
= function_
;
3881 if ( function_
->type
== FUNCTION_BUILTIN
)
3883 PROFILE_ENTER_LOCAL(function_run_FUNCTION_BUILTIN
);
3884 BUILTIN_FUNCTION
const * const f
= (BUILTIN_FUNCTION
*)function_
;
3885 if ( function_
->formal_arguments
)
3886 argument_list_check( function_
->formal_arguments
,
3887 function_
->num_formal_arguments
, function_
, frame
);
3889 debug_on_enter_function( frame
, f
->base
.rulename
, NULL
, -1 );
3890 result
= f
->func( frame
, f
->flags
);
3891 debug_on_exit_function( f
->base
.rulename
);
3892 PROFILE_EXIT_LOCAL(function_run_FUNCTION_BUILTIN
);
3893 PROFILE_EXIT_LOCAL(function_run
);
3898 else if ( function_
->type
== FUNCTION_PYTHON
)
3900 PROFILE_ENTER_LOCAL(function_run_FUNCTION_PYTHON
);
3901 PYTHON_FUNCTION
* f
= (PYTHON_FUNCTION
*)function_
;
3902 debug_on_enter_function( frame
, f
->base
.rulename
, NULL
, -1 );
3903 result
= call_python_function( f
, frame
);
3904 debug_on_exit_function( f
->base
.rulename
);
3905 PROFILE_EXIT_LOCAL(function_run_FUNCTION_PYTHON
);
3906 PROFILE_EXIT_LOCAL(function_run
);
3911 assert( function_
->type
== FUNCTION_JAM
);
3913 if ( function_
->formal_arguments
)
3914 argument_list_push( function_
->formal_arguments
,
3915 function_
->num_formal_arguments
, function_
, frame
, s
);
3917 function
= (JAM_FUNCTION
*)function_
;
3918 debug_on_enter_function( frame
, function
->base
.rulename
, function
->file
, function
->line
);
3919 code
= function
->code
;
3922 switch ( code
->op_code
)
3926 * Basic stack manipulation
3929 case INSTR_PUSH_EMPTY
:
3931 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_EMPTY
);
3932 stack_push( s
, L0
);
3933 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_EMPTY
);
3937 case INSTR_PUSH_CONSTANT
:
3939 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_CONSTANT
);
3940 OBJECT
* value
= function_get_constant( function
, code
->arg
);
3941 stack_push( s
, list_new( object_copy( value
) ) );
3942 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_CONSTANT
);
3946 case INSTR_PUSH_ARG
:
3948 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_ARG
);
3949 stack_push( s
, frame_get_local( frame
, code
->arg
) );
3950 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_ARG
);
3954 case INSTR_PUSH_VAR
:
3956 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_VAR
);
3957 stack_push( s
, function_get_variable( function
, frame
, code
->arg
) );
3958 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_VAR
);
3962 case INSTR_PUSH_VAR_FIXED
:
3964 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_VAR_FIXED
);
3965 stack_push( s
, list_copy( frame
->module
->fixed_variables
[ code
->arg
3967 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_VAR_FIXED
);
3971 case INSTR_PUSH_GROUP
:
3973 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_GROUP
);
3978 for ( iter
= list_begin( l
), end
= list_end( l
); iter
!= end
;
3979 iter
= list_next( iter
) )
3980 value
= list_append( value
, function_get_named_variable(
3981 function
, frame
, list_item( iter
) ) );
3983 stack_push( s
, value
);
3984 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_GROUP
);
3988 case INSTR_PUSH_APPEND
:
3990 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_APPEND
);
3993 stack_push( s
, list_append( l
, r
) );
3994 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_APPEND
);
4000 PROFILE_ENTER_LOCAL(function_run_INSTR_SWAP
);
4002 stack_set( s
, 0, stack_at( s
, code
->arg
) );
4003 stack_set( s
, code
->arg
, l
);
4004 PROFILE_EXIT_LOCAL(function_run_INSTR_SWAP
);
4010 PROFILE_ENTER_LOCAL(function_run_INSTR_POP
);
4011 list_free( stack_pop( s
) );
4012 PROFILE_EXIT_LOCAL(function_run_INSTR_POP
);
4017 * Branch instructions
4022 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP
);
4024 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP
);
4028 case INSTR_JUMP_EMPTY
:
4030 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_EMPTY
);
4032 if ( !list_cmp( l
, L0
) ) code
+= code
->arg
;
4034 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_EMPTY
);
4038 case INSTR_JUMP_NOT_EMPTY
:
4040 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_NOT_EMPTY
);
4042 if ( list_cmp( l
, L0
) ) code
+= code
->arg
;
4044 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_NOT_EMPTY
);
4050 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_LT
);
4053 if ( list_cmp( l
, r
) < 0 ) code
+= code
->arg
;
4056 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_LT
);
4062 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_LE
);
4065 if ( list_cmp( l
, r
) <= 0 ) code
+= code
->arg
;
4068 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_LE
);
4074 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_GT
);
4077 if ( list_cmp( l
, r
) > 0 ) code
+= code
->arg
;
4080 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_GT
);
4086 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_GE
);
4089 if ( list_cmp( l
, r
) >= 0 ) code
+= code
->arg
;
4092 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_GE
);
4098 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_EQ
);
4101 if ( list_cmp( l
, r
) == 0 ) code
+= code
->arg
;
4104 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_EQ
);
4110 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_NE
);
4113 if ( list_cmp(l
, r
) != 0 ) code
+= code
->arg
;
4116 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_NE
);
4122 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_IN
);
4125 if ( list_is_sublist( l
, r
) ) code
+= code
->arg
;
4128 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_IN
);
4132 case INSTR_JUMP_NOT_IN
:
4134 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_NOT_IN
);
4137 if ( !list_is_sublist( l
, r
) ) code
+= code
->arg
;
4140 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_NOT_IN
);
4148 case INSTR_FOR_INIT
:
4150 PROFILE_ENTER_LOCAL(function_run_INSTR_FOR_INIT
);
4152 *(LISTITER
*)stack_allocate( s
, sizeof( LISTITER
) ) =
4154 PROFILE_EXIT_LOCAL(function_run_INSTR_FOR_INIT
);
4158 case INSTR_FOR_LOOP
:
4160 PROFILE_ENTER_LOCAL(function_run_INSTR_FOR_LOOP
);
4161 LISTITER iter
= *(LISTITER
*)stack_get( s
);
4162 stack_deallocate( s
, sizeof( LISTITER
) );
4164 if ( iter
== list_end( l
) )
4166 list_free( stack_pop( s
) );
4171 r
= list_new( object_copy( list_item( iter
) ) );
4172 iter
= list_next( iter
);
4173 *(LISTITER
*)stack_allocate( s
, sizeof( LISTITER
) ) = iter
;
4176 PROFILE_EXIT_LOCAL(function_run_INSTR_FOR_LOOP
);
4182 PROFILE_ENTER_LOCAL(function_run_INSTR_FOR_POP
);
4183 stack_deallocate( s
, sizeof( LISTITER
) );
4184 list_free( stack_pop( s
) );
4185 PROFILE_EXIT_LOCAL(function_run_INSTR_FOR_POP
);
4193 case INSTR_JUMP_NOT_GLOB
:
4195 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_NOT_GLOB
);
4196 char const * pattern
;
4200 pattern
= list_empty( l
) ? "" : object_str( list_front( l
) );
4201 match
= list_empty( r
) ? "" : object_str( list_front( r
) );
4202 if ( glob( pattern
, match
) )
4205 list_free( stack_pop( s
) );
4207 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_NOT_GLOB
);
4215 case INSTR_SET_RESULT
:
4217 PROFILE_ENTER_LOCAL(function_run_INSTR_SET_RESULT
);
4218 list_free( result
);
4220 result
= stack_pop( s
);
4222 result
= list_copy( stack_top( s
) );
4223 PROFILE_EXIT_LOCAL(function_run_INSTR_SET_RESULT
);
4227 case INSTR_PUSH_RESULT
:
4229 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_RESULT
);
4230 stack_push( s
, result
);
4232 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_RESULT
);
4238 PROFILE_ENTER_LOCAL(function_run_INSTR_RETURN
);
4239 if ( function_
->formal_arguments
)
4240 argument_list_pop( function_
->formal_arguments
,
4241 function_
->num_formal_arguments
, frame
, s
);
4243 if ( !( saved_stack
== s
->data
) )
4245 frame
->file
= function
->file
;
4246 frame
->line
= function
->line
;
4247 backtrace_line( frame
);
4248 out_printf( "error: stack check failed.\n" );
4250 assert( saved_stack
== s
->data
);
4253 assert( saved_stack
== s
->data
);
4254 debug_on_exit_function( function
->base
.rulename
);
4255 PROFILE_EXIT_LOCAL(function_run_INSTR_RETURN
);
4256 PROFILE_EXIT_LOCAL(function_run
);
4264 case INSTR_PUSH_LOCAL
:
4266 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_LOCAL
);
4267 LIST
* value
= stack_pop( s
);
4268 stack_push( s
, function_swap_variable( function
, frame
, code
->arg
,
4270 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_LOCAL
);
4274 case INSTR_POP_LOCAL
:
4276 PROFILE_ENTER_LOCAL(function_run_INSTR_POP_LOCAL
);
4277 function_set_variable( function
, frame
, code
->arg
, stack_pop( s
) );
4278 PROFILE_EXIT_LOCAL(function_run_INSTR_POP_LOCAL
);
4282 case INSTR_PUSH_LOCAL_FIXED
:
4284 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_LOCAL_FIXED
);
4285 LIST
* value
= stack_pop( s
);
4286 LIST
* * ptr
= &frame
->module
->fixed_variables
[ code
->arg
];
4287 assert( code
->arg
< frame
->module
->num_fixed_variables
);
4288 stack_push( s
, *ptr
);
4290 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_LOCAL_FIXED
);
4294 case INSTR_POP_LOCAL_FIXED
:
4296 PROFILE_ENTER_LOCAL(function_run_INSTR_POP_LOCAL_FIXED
);
4297 LIST
* value
= stack_pop( s
);
4298 LIST
* * ptr
= &frame
->module
->fixed_variables
[ code
->arg
];
4299 assert( code
->arg
< frame
->module
->num_fixed_variables
);
4302 PROFILE_EXIT_LOCAL(function_run_INSTR_POP_LOCAL_FIXED
);
4306 case INSTR_PUSH_LOCAL_GROUP
:
4308 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_LOCAL_GROUP
);
4309 LIST
* const value
= stack_pop( s
);
4313 for ( iter
= list_begin( l
), end
= list_end( l
); iter
!= end
;
4314 iter
= list_next( iter
) )
4315 stack_push( s
, function_swap_named_variable( function
, frame
,
4316 list_item( iter
), list_copy( value
) ) );
4319 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_LOCAL_GROUP
);
4323 case INSTR_POP_LOCAL_GROUP
:
4325 PROFILE_ENTER_LOCAL(function_run_INSTR_POP_LOCAL_GROUP
);
4329 l
= list_reverse( r
);
4331 for ( iter
= list_begin( l
), end
= list_end( l
); iter
!= end
;
4332 iter
= list_next( iter
) )
4333 function_set_named_variable( function
, frame
, list_item( iter
),
4336 PROFILE_EXIT_LOCAL(function_run_INSTR_POP_LOCAL_GROUP
);
4341 * on $(TARGET) variables
4346 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_ON
);
4347 LIST
* targets
= stack_top( s
);
4348 if ( !list_empty( targets
) )
4350 /* FIXME: push the state onto the stack instead of using
4353 TARGET
* t
= bindtarget( list_front( targets
) );
4354 pushsettings( frame
->module
, t
->settings
);
4358 /* [ on $(TARGET) ... ] is ignored if $(TARGET) is empty. */
4359 list_free( stack_pop( s
) );
4360 stack_push( s
, L0
);
4363 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_ON
);
4369 PROFILE_ENTER_LOCAL(function_run_INSTR_POP_ON
);
4370 LIST
* result
= stack_pop( s
);
4371 LIST
* targets
= stack_pop( s
);
4372 if ( !list_empty( targets
) )
4374 TARGET
* t
= bindtarget( list_front( targets
) );
4375 popsettings( frame
->module
, t
->settings
);
4377 list_free( targets
);
4378 stack_push( s
, result
);
4379 PROFILE_EXIT_LOCAL(function_run_INSTR_POP_ON
);
4385 PROFILE_ENTER_LOCAL(function_run_INSTR_SET_ON
);
4386 LIST
* targets
= stack_pop( s
);
4387 LIST
* value
= stack_pop( s
);
4388 LIST
* vars
= stack_pop( s
);
4389 LISTITER iter
= list_begin( targets
);
4390 LISTITER
const end
= list_end( targets
);
4391 for ( ; iter
!= end
; iter
= list_next( iter
) )
4393 TARGET
* t
= bindtarget( list_item( iter
) );
4394 LISTITER vars_iter
= list_begin( vars
);
4395 LISTITER
const vars_end
= list_end( vars
);
4396 for ( ; vars_iter
!= vars_end
; vars_iter
= list_next( vars_iter
4398 t
->settings
= addsettings( t
->settings
, VAR_SET
, list_item(
4399 vars_iter
), list_copy( value
) );
4402 list_free( targets
);
4403 stack_push( s
, value
);
4404 PROFILE_EXIT_LOCAL(function_run_INSTR_SET_ON
);
4408 case INSTR_APPEND_ON
:
4410 PROFILE_ENTER_LOCAL(function_run_INSTR_APPEND_ON
);
4411 LIST
* targets
= stack_pop( s
);
4412 LIST
* value
= stack_pop( s
);
4413 LIST
* vars
= stack_pop( s
);
4414 LISTITER iter
= list_begin( targets
);
4415 LISTITER
const end
= list_end( targets
);
4416 for ( ; iter
!= end
; iter
= list_next( iter
) )
4418 TARGET
* const t
= bindtarget( list_item( iter
) );
4419 LISTITER vars_iter
= list_begin( vars
);
4420 LISTITER
const vars_end
= list_end( vars
);
4421 for ( ; vars_iter
!= vars_end
; vars_iter
= list_next( vars_iter
4423 t
->settings
= addsettings( t
->settings
, VAR_APPEND
,
4424 list_item( vars_iter
), list_copy( value
) );
4427 list_free( targets
);
4428 stack_push( s
, value
);
4429 PROFILE_EXIT_LOCAL(function_run_INSTR_APPEND_ON
);
4433 case INSTR_DEFAULT_ON
:
4435 PROFILE_ENTER_LOCAL(function_run_INSTR_DEFAULT_ON
);
4436 LIST
* targets
= stack_pop( s
);
4437 LIST
* value
= stack_pop( s
);
4438 LIST
* vars
= stack_pop( s
);
4439 LISTITER iter
= list_begin( targets
);
4440 LISTITER
const end
= list_end( targets
);
4441 for ( ; iter
!= end
; iter
= list_next( iter
) )
4443 TARGET
* t
= bindtarget( list_item( iter
) );
4444 LISTITER vars_iter
= list_begin( vars
);
4445 LISTITER
const vars_end
= list_end( vars
);
4446 for ( ; vars_iter
!= vars_end
; vars_iter
= list_next( vars_iter
4448 t
->settings
= addsettings( t
->settings
, VAR_DEFAULT
,
4449 list_item( vars_iter
), list_copy( value
) );
4452 list_free( targets
);
4453 stack_push( s
, value
);
4454 PROFILE_EXIT_LOCAL(function_run_INSTR_DEFAULT_ON
);
4458 /* [ on $(target) return $(variable) ] */
4461 PROFILE_ENTER_LOCAL(function_run_INSTR_GET_ON
);
4462 LIST
* targets
= stack_pop( s
);
4464 if ( !list_empty( targets
) )
4466 OBJECT
* varname
= function
->constants
[ code
->arg
];
4467 TARGET
* t
= bindtarget( list_front( targets
) );
4468 SETTINGS
* s
= t
->settings
;
4470 for ( ; s
!= 0; s
= s
->next
)
4472 if ( object_equal( s
->symbol
, varname
) )
4481 result
= var_get( frame
->module
, varname
) ;
4484 list_free( targets
);
4485 stack_push( s
, list_copy( result
) );
4486 PROFILE_EXIT_LOCAL(function_run_INSTR_GET_ON
);
4496 PROFILE_ENTER_LOCAL(function_run_INSTR_SET
);
4497 function_set_variable( function
, frame
, code
->arg
,
4499 PROFILE_EXIT_LOCAL(function_run_INSTR_SET
);
4505 PROFILE_ENTER_LOCAL(function_run_INSTR_APPEND
);
4506 function_append_variable( function
, frame
, code
->arg
,
4508 PROFILE_EXIT_LOCAL(function_run_INSTR_APPEND
);
4514 PROFILE_ENTER_LOCAL(function_run_INSTR_DEFAULT
);
4515 function_default_variable( function
, frame
, code
->arg
,
4517 PROFILE_EXIT_LOCAL(function_run_INSTR_DEFAULT
);
4521 case INSTR_SET_FIXED
:
4523 PROFILE_ENTER_LOCAL(function_run_INSTR_SET_FIXED
);
4524 LIST
* * ptr
= &frame
->module
->fixed_variables
[ code
->arg
];
4525 assert( code
->arg
< frame
->module
->num_fixed_variables
);
4527 *ptr
= stack_pop( s
);
4528 PROFILE_EXIT_LOCAL(function_run_INSTR_SET_FIXED
);
4532 case INSTR_APPEND_FIXED
:
4534 PROFILE_ENTER_LOCAL(function_run_INSTR_APPEND_FIXED
);
4535 LIST
* * ptr
= &frame
->module
->fixed_variables
[ code
->arg
];
4536 assert( code
->arg
< frame
->module
->num_fixed_variables
);
4537 *ptr
= list_append( *ptr
, stack_pop( s
) );
4538 PROFILE_EXIT_LOCAL(function_run_INSTR_APPEND_FIXED
);
4542 case INSTR_DEFAULT_FIXED
:
4544 PROFILE_ENTER_LOCAL(function_run_INSTR_DEFAULT_FIXED
);
4545 LIST
* * ptr
= &frame
->module
->fixed_variables
[ code
->arg
];
4546 LIST
* value
= stack_pop( s
);
4547 assert( code
->arg
< frame
->module
->num_fixed_variables
);
4548 if ( list_empty( *ptr
) )
4552 PROFILE_EXIT_LOCAL(function_run_INSTR_DEFAULT_FIXED
);
4556 case INSTR_SET_GROUP
:
4558 PROFILE_ENTER_LOCAL(function_run_INSTR_SET_GROUP
);
4559 LIST
* value
= stack_pop( s
);
4560 LIST
* vars
= stack_pop( s
);
4561 LISTITER iter
= list_begin( vars
);
4562 LISTITER
const end
= list_end( vars
);
4563 for ( ; iter
!= end
; iter
= list_next( iter
) )
4564 function_set_named_variable( function
, frame
, list_item( iter
),
4565 list_copy( value
) );
4568 PROFILE_EXIT_LOCAL(function_run_INSTR_SET_GROUP
);
4572 case INSTR_APPEND_GROUP
:
4574 PROFILE_ENTER_LOCAL(function_run_INSTR_APPEND_GROUP
);
4575 LIST
* value
= stack_pop( s
);
4576 LIST
* vars
= stack_pop( s
);
4577 LISTITER iter
= list_begin( vars
);
4578 LISTITER
const end
= list_end( vars
);
4579 for ( ; iter
!= end
; iter
= list_next( iter
) )
4580 function_append_named_variable( function
, frame
, list_item( iter
4581 ), list_copy( value
) );
4584 PROFILE_EXIT_LOCAL(function_run_INSTR_APPEND_GROUP
);
4588 case INSTR_DEFAULT_GROUP
:
4590 PROFILE_ENTER_LOCAL(function_run_INSTR_DEFAULT_GROUP
);
4591 LIST
* value
= stack_pop( s
);
4592 LIST
* vars
= stack_pop( s
);
4593 LISTITER iter
= list_begin( vars
);
4594 LISTITER
const end
= list_end( vars
);
4595 for ( ; iter
!= end
; iter
= list_next( iter
) )
4596 function_default_named_variable( function
, frame
, list_item(
4597 iter
), list_copy( value
) );
4600 PROFILE_EXIT_LOCAL(function_run_INSTR_DEFAULT_GROUP
);
4608 case INSTR_CALL_RULE
:
4610 PROFILE_ENTER_LOCAL(function_run_INSTR_CALL_RULE
);
4611 char const * unexpanded
= object_str( function_get_constant(
4612 function
, code
[ 1 ].op_code
) );
4613 LIST
* result
= function_call_rule( function
, frame
, s
, code
->arg
,
4614 unexpanded
, function
->file
, code
[ 1 ].arg
);
4615 stack_push( s
, result
);
4617 PROFILE_EXIT_LOCAL(function_run_INSTR_CALL_RULE
);
4621 case INSTR_CALL_MEMBER_RULE
:
4623 PROFILE_ENTER_LOCAL(function_run_INSTR_CALL_MEMBER_RULE
);
4624 OBJECT
* rule_name
= function_get_constant( function
, code
[1].op_code
);
4625 LIST
* result
= function_call_member_rule( function
, frame
, s
, code
->arg
, rule_name
, function
->file
, code
[1].arg
);
4626 stack_push( s
, result
);
4628 PROFILE_EXIT_LOCAL(function_run_INSTR_CALL_MEMBER_RULE
);
4634 PROFILE_ENTER_LOCAL(function_run_INSTR_RULE
);
4635 function_set_rule( function
, frame
, s
, code
->arg
);
4636 PROFILE_EXIT_LOCAL(function_run_INSTR_RULE
);
4642 PROFILE_ENTER_LOCAL(function_run_INSTR_ACTIONS
);
4643 function_set_actions( function
, frame
, s
, code
->arg
);
4644 PROFILE_EXIT_LOCAL(function_run_INSTR_ACTIONS
);
4649 * Variable expansion
4652 case INSTR_APPLY_MODIFIERS
:
4654 PROFILE_ENTER_LOCAL(function_run_INSTR_APPLY_MODIFIERS
);
4658 n
= expand_modifiers( s
, code
->arg
);
4660 l
= apply_modifiers( s
, n
);
4661 list_free( stack_pop( s
) );
4662 stack_deallocate( s
, n
* sizeof( VAR_EDITS
) );
4663 for ( i
= 0; i
< code
->arg
; ++i
)
4664 list_free( stack_pop( s
) ); /* pop modifiers */
4666 PROFILE_EXIT_LOCAL(function_run_INSTR_APPLY_MODIFIERS
);
4670 case INSTR_APPLY_INDEX
:
4672 PROFILE_ENTER_LOCAL(function_run_INSTR_APPLY_INDEX
);
4673 l
= apply_subscript( s
);
4674 list_free( stack_pop( s
) );
4675 list_free( stack_pop( s
) );
4677 PROFILE_EXIT_LOCAL(function_run_INSTR_APPLY_INDEX
);
4681 case INSTR_APPLY_INDEX_MODIFIERS
:
4683 PROFILE_ENTER_LOCAL(function_run_INSTR_APPLY_INDEX_MODIFIERS
);
4688 n
= expand_modifiers( s
, code
->arg
);
4691 l
= apply_subscript_and_modifiers( s
, n
);
4692 list_free( stack_pop( s
) );
4693 list_free( stack_pop( s
) );
4694 stack_deallocate( s
, n
* sizeof( VAR_EDITS
) );
4695 for ( i
= 0; i
< code
->arg
; ++i
)
4696 list_free( stack_pop( s
) ); /* pop modifiers */
4698 PROFILE_EXIT_LOCAL(function_run_INSTR_APPLY_INDEX_MODIFIERS
);
4702 case INSTR_APPLY_MODIFIERS_GROUP
:
4704 PROFILE_ENTER_LOCAL(function_run_INSTR_APPLY_MODIFIERS_GROUP
);
4706 LIST
* const vars
= stack_pop( s
);
4707 int const n
= expand_modifiers( s
, code
->arg
);
4709 LISTITER iter
= list_begin( vars
);
4710 LISTITER
const end
= list_end( vars
);
4711 for ( ; iter
!= end
; iter
= list_next( iter
) )
4713 stack_push( s
, function_get_named_variable( function
, frame
,
4714 list_item( iter
) ) );
4715 result
= list_append( result
, apply_modifiers( s
, n
) );
4716 list_free( stack_pop( s
) );
4719 stack_deallocate( s
, n
* sizeof( VAR_EDITS
) );
4720 for ( i
= 0; i
< code
->arg
; ++i
)
4721 list_free( stack_pop( s
) ); /* pop modifiers */
4722 stack_push( s
, result
);
4723 PROFILE_EXIT_LOCAL(function_run_INSTR_APPLY_MODIFIERS_GROUP
);
4727 case INSTR_APPLY_INDEX_GROUP
:
4729 PROFILE_ENTER_LOCAL(function_run_INSTR_APPLY_INDEX_GROUP
);
4730 LIST
* vars
= stack_pop( s
);
4732 LISTITER iter
= list_begin( vars
);
4733 LISTITER
const end
= list_end( vars
);
4734 for ( ; iter
!= end
; iter
= list_next( iter
) )
4736 stack_push( s
, function_get_named_variable( function
, frame
,
4737 list_item( iter
) ) );
4738 result
= list_append( result
, apply_subscript( s
) );
4739 list_free( stack_pop( s
) );
4742 list_free( stack_pop( s
) );
4743 stack_push( s
, result
);
4744 PROFILE_EXIT_LOCAL(function_run_INSTR_APPLY_INDEX_GROUP
);
4748 case INSTR_APPLY_INDEX_MODIFIERS_GROUP
:
4750 PROFILE_ENTER_LOCAL(function_run_INSTR_APPLY_INDEX_MODIFIERS_GROUP
);
4752 LIST
* const vars
= stack_pop( s
);
4753 LIST
* const r
= stack_pop( s
);
4754 int const n
= expand_modifiers( s
, code
->arg
);
4756 LISTITER iter
= list_begin( vars
);
4757 LISTITER
const end
= list_end( vars
);
4759 for ( ; iter
!= end
; iter
= list_next( iter
) )
4761 stack_push( s
, function_get_named_variable( function
, frame
,
4762 list_item( iter
) ) );
4763 result
= list_append( result
, apply_subscript_and_modifiers( s
,
4765 list_free( stack_pop( s
) );
4767 list_free( stack_pop( s
) );
4769 stack_deallocate( s
, n
* sizeof( VAR_EDITS
) );
4770 for ( i
= 0; i
< code
->arg
; ++i
)
4771 list_free( stack_pop( s
) ); /* pop modifiers */
4772 stack_push( s
, result
);
4773 PROFILE_EXIT_LOCAL(function_run_INSTR_APPLY_INDEX_MODIFIERS_GROUP
);
4777 case INSTR_COMBINE_STRINGS
:
4779 PROFILE_ENTER_LOCAL(function_run_INSTR_COMBINE_STRINGS
);
4780 size_t const buffer_size
= code
->arg
* sizeof( expansion_item
);
4781 LIST
* * const stack_pos
= (LIST
* * const)stack_get( s
);
4782 expansion_item
* items
= (expansion_item
*)stack_allocate( s
, buffer_size
);
4785 for ( i
= 0; i
< code
->arg
; ++i
)
4786 items
[ i
].values
= stack_pos
[ i
];
4787 result
= expand( items
, code
->arg
);
4788 stack_deallocate( s
, buffer_size
);
4789 for ( i
= 0; i
< code
->arg
; ++i
)
4790 list_free( stack_pop( s
) );
4791 stack_push( s
, result
);
4792 PROFILE_EXIT_LOCAL(function_run_INSTR_COMBINE_STRINGS
);
4796 case INSTR_GET_GRIST
:
4798 PROFILE_ENTER_LOCAL(function_run_INSTR_GET_GRIST
);
4799 LIST
* vals
= stack_pop( s
);
4803 for ( iter
= list_begin( vals
), end
= list_end( vals
); iter
!= end
; ++iter
)
4805 OBJECT
* new_object
;
4806 const char * value
= object_str( list_item( iter
) );
4808 if ( value
[ 0 ] == '<' && ( p
= strchr( value
, '>' ) ) )
4811 new_object
= object_new_range( value
, p
- value
+ 1 );
4813 new_object
= object_copy( list_item( iter
) );
4817 new_object
= object_copy( constant_empty
);
4819 result
= list_push_back( result
, new_object
);
4823 stack_push( s
, result
);
4824 PROFILE_EXIT_LOCAL(function_run_INSTR_GET_GRIST
);
4830 PROFILE_ENTER_LOCAL(function_run_INSTR_INCLUDE
);
4831 LIST
* nt
= stack_pop( s
);
4832 if ( !list_empty( nt
) )
4834 TARGET
* const t
= bindtarget( list_front( nt
) );
4837 /* DWA 2001/10/22 - Perforce Jam cleared the arguments here,
4838 * which prevented an included file from being treated as part
4839 * of the body of a rule. I did not see any reason to do that,
4840 * so I lifted the restriction.
4843 /* Bind the include file under the influence of "on-target"
4844 * variables. Though they are targets, include files are not
4845 * built with make().
4848 pushsettings( root_module(), t
->settings
);
4849 /* We do not expect that a file to be included is generated by
4850 * some action. Therefore, pass 0 as third argument. If the name
4851 * resolves to a directory, let it error out.
4853 object_free( t
->boundname
);
4854 t
->boundname
= search( t
->name
, &t
->time
, 0, 0 );
4855 popsettings( root_module(), t
->settings
);
4857 parse_file( t
->boundname
, frame
);
4859 frame
->function
= function_
;
4862 PROFILE_EXIT_LOCAL(function_run_INSTR_INCLUDE
);
4867 * Classes and modules
4870 case INSTR_PUSH_MODULE
:
4872 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_MODULE
);
4873 LIST
* const module_name
= stack_pop( s
);
4874 module_t
* const outer_module
= frame
->module
;
4875 frame
->module
= !list_empty( module_name
)
4876 ? bindmodule( list_front( module_name
) )
4878 list_free( module_name
);
4879 *(module_t
* *)stack_allocate( s
, sizeof( module_t
* ) ) =
4881 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_MODULE
);
4885 case INSTR_POP_MODULE
:
4887 PROFILE_ENTER_LOCAL(function_run_INSTR_POP_MODULE
);
4888 module_t
* const outer_module
= *(module_t
* *)stack_get( s
);
4889 stack_deallocate( s
, sizeof( module_t
* ) );
4890 frame
->module
= outer_module
;
4891 PROFILE_EXIT_LOCAL(function_run_INSTR_POP_MODULE
);
4897 PROFILE_ENTER_LOCAL(function_run_INSTR_CLASS
);
4898 LIST
* bases
= stack_pop( s
);
4899 LIST
* name
= stack_pop( s
);
4900 OBJECT
* class_module
= make_class_module( name
, bases
, frame
);
4902 module_t
* const outer_module
= frame
->module
;
4903 frame
->module
= bindmodule( class_module
);
4904 object_free( class_module
);
4906 *(module_t
* *)stack_allocate( s
, sizeof( module_t
* ) ) =
4908 PROFILE_EXIT_LOCAL(function_run_INSTR_CLASS
);
4912 case INSTR_BIND_MODULE_VARIABLES
:
4914 PROFILE_ENTER_LOCAL(function_run_INSTR_BIND_MODULE_VARIABLES
);
4915 module_bind_variables( frame
->module
);
4916 PROFILE_EXIT_LOCAL(function_run_INSTR_BIND_MODULE_VARIABLES
);
4920 case INSTR_APPEND_STRINGS
:
4922 PROFILE_ENTER_LOCAL(function_run_INSTR_APPEND_STRINGS
);
4925 combine_strings( s
, code
->arg
, buf
);
4926 stack_push( s
, list_new( object_new( buf
->value
) ) );
4928 PROFILE_EXIT_LOCAL(function_run_INSTR_APPEND_STRINGS
);
4932 case INSTR_WRITE_FILE
:
4934 PROFILE_ENTER_LOCAL(function_run_INSTR_WRITE_FILE
);
4937 OBJECT
* tmp_filename
= 0;
4938 int out_debug
= DEBUG_EXEC
? 1 : 0;
4939 FILE * out_file
= 0;
4941 combine_strings( s
, code
->arg
, buf
);
4942 out
= object_str( list_front( stack_top( s
) ) );
4944 /* For stdout/stderr we will create a temp file and generate a
4945 * command that outputs the content as needed.
4947 if ( ( strcmp( "STDOUT", out
) == 0 ) ||
4948 ( strcmp( "STDERR", out
) == 0 ) )
4950 int err_redir
= strcmp( "STDERR", out
) == 0;
4953 tmp_filename
= path_tmpfile();
4955 /* Construct os-specific cat command. */
4957 const char * command
= "cat";
4958 const char * quote
= "\"";
4959 const char * redirect
= "1>&2";
4964 #elif defined( OS_VMS )
4965 command
= "pipe type";
4968 /* Get tmp file name is os-format. */
4970 string os_filename
[ 1 ];
4972 string_new( os_filename
);
4973 path_translate_to_os( object_str( tmp_filename
), os_filename
);
4974 object_free( tmp_filename
);
4975 tmp_filename
= object_new( os_filename
->value
);
4976 string_free( os_filename
);
4980 string_new( result
);
4981 string_append( result
, command
);
4982 string_append( result
, " " );
4983 string_append( result
, quote
);
4984 string_append( result
, object_str( tmp_filename
) );
4985 string_append( result
, quote
);
4988 string_append( result
, " " );
4989 string_append( result
, redirect
);
4993 /* Replace STDXXX with the temporary file. */
4994 list_free( stack_pop( s
) );
4995 stack_push( s
, list_new( object_new( result
->value
) ) );
4996 out
= object_str( tmp_filename
);
4998 string_free( result
);
5000 /* Make sure temp files created by this get nuked eventually. */
5001 file_remove_atexit( tmp_filename
);
5004 if ( !globs
.noexec
)
5006 string out_name
[ 1 ];
5007 /* Handle "path to file" filenames. */
5008 if ( ( out
[ 0 ] == '"' ) && ( out
[ strlen( out
) - 1 ] == '"' )
5011 string_copy( out_name
, out
+ 1 );
5012 string_truncate( out_name
, out_name
->size
- 1 );
5015 string_copy( out_name
, out
);
5016 out_file
= fopen( out_name
->value
, "w" );
5020 err_printf( "failed to write output file '%s'!\n",
5024 string_free( out_name
);
5027 if ( out_debug
) out_printf( "\nfile %s\n", out
);
5028 if ( out_file
) fputs( buf
->value
, out_file
);
5029 if ( out_debug
) out_puts( buf
->value
);
5037 object_free( tmp_filename
);
5039 if ( out_debug
) out_putc( '\n' );
5040 PROFILE_EXIT_LOCAL(function_run_INSTR_WRITE_FILE
);
5044 case INSTR_OUTPUT_STRINGS
:
5046 PROFILE_ENTER_LOCAL(function_run_INSTR_OUTPUT_STRINGS
);
5047 string
* const buf
= *(string
* *)( (char *)stack_get( s
) + (
5048 code
->arg
* sizeof( LIST
* ) ) );
5049 combine_strings( s
, code
->arg
, buf
);
5050 PROFILE_EXIT_LOCAL(function_run_INSTR_OUTPUT_STRINGS
);
5054 case INSTR_DEBUG_LINE
:
5056 debug_on_instruction( frame
, function
->file
, code
->arg
);
5064 PROFILE_EXIT_LOCAL(function_run
);
5070 static struct arg_list
* arg_list_compile_python( PyObject
* bjam_signature
,
5071 int * num_arguments
)
5073 if ( bjam_signature
)
5075 struct argument_list_compiler c
[ 1 ];
5076 struct arg_list
* result
;
5079 argument_list_compiler_init( c
);
5081 s
= PySequence_Size( bjam_signature
);
5082 for ( i
= 0; i
< s
; ++i
)
5084 struct argument_compiler arg_comp
[ 1 ];
5085 struct arg_list arg
;
5086 PyObject
* v
= PySequence_GetItem( bjam_signature
, i
);
5089 argument_compiler_init( arg_comp
);
5091 inner
= PySequence_Size( v
);
5092 for ( j
= 0; j
< inner
; ++j
)
5093 argument_compiler_add( arg_comp
, object_new( PyString_AsString(
5094 PySequence_GetItem( v
, j
) ) ), constant_builtin
, -1 );
5096 arg
= arg_compile_impl( arg_comp
, constant_builtin
, -1 );
5097 dynamic_array_push( c
->args
, arg
);
5098 argument_compiler_free( arg_comp
);
5102 *num_arguments
= c
->args
->size
;
5103 result
= (struct arg_list
*)BJAM_MALLOC( c
->args
->size
* sizeof( struct arg_list
) );
5104 memcpy( result
, c
->args
->data
, c
->args
->size
* sizeof( struct arg_list
)
5106 argument_list_compiler_free( c
);
5113 FUNCTION
* function_python( PyObject
* function
, PyObject
* bjam_signature
)
5115 PYTHON_FUNCTION
* result
= (PYTHON_FUNCTION
*)BJAM_MALLOC( sizeof( PYTHON_FUNCTION
) );
5117 result
->base
.type
= FUNCTION_PYTHON
;
5118 result
->base
.reference_count
= 1;
5119 result
->base
.rulename
= 0;
5120 result
->base
.formal_arguments
= arg_list_compile_python( bjam_signature
,
5121 &result
->base
.num_formal_arguments
);
5122 Py_INCREF( function
);
5123 result
->python_function
= function
;
5125 return (FUNCTION
*)result
;
5129 static void argument_list_to_python( struct arg_list
* formal
, int formal_count
,
5130 FUNCTION
* function
, FRAME
* frame
, PyObject
* kw
)
5132 LOL
* all_actual
= frame
->args
;
5135 for ( i
= 0; i
< formal_count
; ++i
)
5137 LIST
* actual
= lol_get( all_actual
, i
);
5138 LISTITER actual_iter
= list_begin( actual
);
5139 LISTITER
const actual_end
= list_end( actual
);
5141 for ( j
= 0; j
< formal
[ i
].size
; ++j
)
5143 struct argument
* formal_arg
= &formal
[ i
].args
[ j
];
5147 switch ( formal_arg
->flags
)
5150 if ( actual_iter
== actual_end
)
5151 argument_error( "missing argument", function
, frame
,
5152 formal_arg
->arg_name
);
5153 type_check_range( formal_arg
->type_name
, actual_iter
, list_next(
5154 actual_iter
), frame
, function
, formal_arg
->arg_name
);
5155 value
= PyString_FromString( object_str( list_item( actual_iter
5157 actual_iter
= list_next( actual_iter
);
5160 if ( actual_iter
== actual_end
)
5164 type_check_range( formal_arg
->type_name
, actual_iter
,
5165 list_next( actual_iter
), frame
, function
,
5166 formal_arg
->arg_name
);
5167 value
= PyString_FromString( object_str( list_item(
5169 actual_iter
= list_next( actual_iter
);
5173 if ( actual_iter
== actual_end
)
5174 argument_error( "missing argument", function
, frame
,
5175 formal_arg
->arg_name
);
5178 type_check_range( formal_arg
->type_name
, actual_iter
,
5179 actual_end
, frame
, function
, formal_arg
->arg_name
);
5180 l
= list_copy_range( actual
, actual_iter
, actual_end
);
5181 value
= list_to_python( l
);
5183 actual_iter
= actual_end
;
5191 PyObject
* key
= PyString_FromString( object_str(
5192 formal_arg
->arg_name
) );
5193 PyDict_SetItem( kw
, key
, value
);
5199 if ( actual_iter
!= actual_end
)
5200 argument_error( "extra argument", function
, frame
, list_item(
5204 for ( ; i
< all_actual
->count
; ++i
)
5206 LIST
* const actual
= lol_get( all_actual
, i
);
5207 if ( !list_empty( actual
) )
5208 argument_error( "extra argument", function
, frame
, list_front(
5214 /* Given a Python object, return a string to use in Jam code instead of the said
5217 * If the object is a string, use the string value.
5218 * If the object implemenets __jam_repr__ method, use that.
5219 * Otherwise return 0.
5222 OBJECT
* python_to_string( PyObject
* value
)
5224 if ( PyString_Check( value
) )
5225 return object_new( PyString_AS_STRING( value
) );
5227 /* See if this instance defines the special __jam_repr__ method. */
5228 if ( PyInstance_Check( value
)
5229 && PyObject_HasAttrString( value
, "__jam_repr__" ) )
5231 PyObject
* repr
= PyObject_GetAttrString( value
, "__jam_repr__" );
5234 PyObject
* arguments2
= PyTuple_New( 0 );
5235 PyObject
* value2
= PyObject_Call( repr
, arguments2
, 0 );
5237 Py_DECREF( arguments2
);
5238 if ( PyString_Check( value2
) )
5239 return object_new( PyString_AS_STRING( value2
) );
5240 Py_DECREF( value2
);
5247 static module_t
* python_module()
5249 static module_t
* python
= 0;
5251 python
= bindmodule( constant_python
);
5256 static LIST
* call_python_function( PYTHON_FUNCTION
* function
, FRAME
* frame
)
5259 PyObject
* arguments
= 0;
5260 PyObject
* kw
= NULL
;
5262 PyObject
* py_result
;
5263 FRAME
* prev_frame_before_python_call
;
5265 if ( function
->base
.formal_arguments
)
5267 arguments
= PyTuple_New( 0 );
5269 argument_list_to_python( function
->base
.formal_arguments
,
5270 function
->base
.num_formal_arguments
, &function
->base
, frame
, kw
);
5274 arguments
= PyTuple_New( frame
->args
->count
);
5275 for ( i
= 0; i
< frame
->args
->count
; ++i
)
5276 PyTuple_SetItem( arguments
, i
, list_to_python( lol_get( frame
->args
,
5280 frame
->module
= python_module();
5282 prev_frame_before_python_call
= frame_before_python_call
;
5283 frame_before_python_call
= frame
;
5284 py_result
= PyObject_Call( function
->python_function
, arguments
, kw
);
5285 frame_before_python_call
= prev_frame_before_python_call
;
5286 Py_DECREF( arguments
);
5288 if ( py_result
!= NULL
)
5290 if ( PyList_Check( py_result
) )
5292 int size
= PyList_Size( py_result
);
5294 for ( i
= 0; i
< size
; ++i
)
5296 OBJECT
* s
= python_to_string( PyList_GetItem( py_result
, i
) );
5299 "Non-string object returned by Python call.\n" );
5301 result
= list_push_back( result
, s
);
5304 else if ( py_result
== Py_None
)
5310 OBJECT
* const s
= python_to_string( py_result
);
5312 result
= list_new( s
);
5314 /* We have tried all we could. Return empty list. There are
5315 * cases, e.g. feature.feature function that should return a
5316 * value for the benefit of Python code and which also can be
5317 * called by Jam code, where no sensible value can be returned.
5318 * We cannot even emit a warning, since there would be a pile of
5324 Py_DECREF( py_result
);
5329 err_printf( "Call failed\n" );
5338 void function_done( void )