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) static int unused_LOCAL_##x = 0
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
);
508 OBJECT
* real_rulename
= 0;
513 if ( list_empty( first
) )
515 backtrace_line( frame
);
516 out_printf( "warning: object is empty\n" );
521 for( i
= 0; i
< n_args
; ++i
)
523 list_free( stack_pop( s
) );
529 /* FIXME: handle generic case */
530 assert( list_length( first
) == 1 );
532 module
= bindmodule( list_front( first
) );
533 if ( module
->class_module
)
535 rule
= bindrule( rulename
, module
);
536 if ( rule
->procedure
)
538 real_rulename
= object_copy( function_rulename( rule
->procedure
) );
544 string_append( buf
, object_str( module
->name
) );
545 string_push_back( buf
, '.' );
546 string_append( buf
, object_str( rulename
) );
547 real_rulename
= object_new( buf
->value
);
555 string_append( buf
, object_str( list_front( first
) ) );
556 string_push_back( buf
, '.' );
557 string_append( buf
, object_str( rulename
) );
558 real_rulename
= object_new( buf
->value
);
560 rule
= bindrule( real_rulename
, frame
->module
);
566 inner
->prev_user
= frame
->module
->user_module
? frame
: frame
->prev_user
;
567 inner
->module
= frame
->module
; /* This gets fixed up in evaluate_rule(), below. */
569 for( i
= 0; i
< n_args
; ++i
)
571 lol_add( inner
->args
, stack_at( s
, n_args
- i
- 1 ) );
574 for( i
= 0; i
< n_args
; ++i
)
579 if ( list_length( first
) > 1 )
582 LIST
* trailing
= L0
;
583 LISTITER iter
= list_begin( first
), end
= list_end( first
);
584 iter
= list_next( iter
);
586 for ( ; iter
!= end
; iter
= list_next( iter
) )
588 string_append( buf
, object_str( list_item( iter
) ) );
589 string_push_back( buf
, '.' );
590 string_append( buf
, object_str( rulename
) );
591 trailing
= list_push_back( trailing
, object_new( buf
->value
) );
592 string_truncate( buf
, 0 );
595 if ( inner
->args
->count
== 0 )
596 lol_add( inner
->args
, trailing
);
599 LIST
* * const l
= &inner
->args
->list
[ 0 ];
600 *l
= list_append( trailing
, *l
);
605 result
= evaluate_rule( rule
, real_rulename
, inner
);
607 object_free( real_rulename
);
612 /* Variable expansion */
622 PATHNAME f
; /* :GDBSMR -- pieces */
623 char parent
; /* :P -- go to parent directory */
624 char filemods
; /* one of the above applied */
625 char downshift
; /* :L -- downshift result */
626 char upshift
; /* :U -- upshift result */
627 char to_slashes
; /* :T -- convert "\" to "/" */
628 char to_windows
; /* :W -- convert cygwin to native paths */
629 PATHPART empty
; /* :E -- default for empties */
630 PATHPART join
; /* :J -- join list with char */
633 static LIST
* apply_modifiers_impl( LIST
* result
, string
* buf
,
634 VAR_EDITS
* edits
, int n
, LISTITER iter
, LISTITER end
);
635 static void get_iters( subscript_t
const subscript
, LISTITER
* const first
,
636 LISTITER
* const last
, int const length
);
640 * var_edit_parse() - parse : modifiers into PATHNAME structure
642 * The : modifiers in a $(varname:modifier) currently support replacing or
643 * omitting elements of a filename, and so they are parsed into a PATHNAME
644 * structure (which contains pointers into the original string).
646 * Modifiers of the form "X=value" replace the component X with the given value.
647 * Modifiers without the "=value" cause everything but the component X to be
648 * omitted. X is one of:
655 * R root directory - prepended to whole path
661 * -> leave the original component xxx
663 * f->f_xxx.ptr = string
664 * f->f_xxx.len = strlen( string )
665 * -> replace component xxx with string
669 * -> omit component xxx
671 * var_edit_file() below and path_build() obligingly follow this convention.
674 static int var_edit_parse( char const * mods
, VAR_EDITS
* edits
, int havezeroed
683 case 'L': edits
->downshift
= 1; continue;
684 case 'U': edits
->upshift
= 1; continue;
685 case 'P': edits
->parent
= edits
->filemods
= 1; continue;
686 case 'E': fp
= &edits
->empty
; goto strval
;
687 case 'J': fp
= &edits
->join
; goto strval
;
688 case 'G': fp
= &edits
->f
.f_grist
; goto fileval
;
689 case 'R': fp
= &edits
->f
.f_root
; goto fileval
;
690 case 'D': fp
= &edits
->f
.f_dir
; goto fileval
;
691 case 'B': fp
= &edits
->f
.f_base
; goto fileval
;
692 case 'S': fp
= &edits
->f
.f_suffix
; goto fileval
;
693 case 'M': fp
= &edits
->f
.f_member
; goto fileval
;
694 case 'T': edits
->to_slashes
= 1; continue;
695 case 'W': edits
->to_windows
= 1; continue;
697 continue; /* Should complain, but so what... */
701 /* Handle :CHARS, where each char (without a following =) selects a
702 * particular file path element. On the first such char, we deselect all
703 * others (by setting ptr = "", len = 0) and for each char we select
704 * that element (by setting ptr = 0).
713 for ( i
= 0; i
< 6; ++i
)
715 edits
->f
.part
[ i
].len
= 0;
716 edits
->f
.part
[ i
].ptr
= "";
725 /* Handle :X=value, or :X */
734 fp
->len
= strlen( mods
);
744 * var_edit_file() - copy input target name to output, modifying filename.
747 static void var_edit_file( char const * in
, string
* out
, VAR_EDITS
* edits
)
749 if ( edits
->filemods
)
753 /* Parse apart original filename, putting parts into "pathname". */
754 path_parse( in
, &pathname
);
756 /* Replace any pathname with edits->f */
757 if ( edits
->f
.f_grist
.ptr
) pathname
.f_grist
= edits
->f
.f_grist
;
758 if ( edits
->f
.f_root
.ptr
) pathname
.f_root
= edits
->f
.f_root
;
759 if ( edits
->f
.f_dir
.ptr
) pathname
.f_dir
= edits
->f
.f_dir
;
760 if ( edits
->f
.f_base
.ptr
) pathname
.f_base
= edits
->f
.f_base
;
761 if ( edits
->f
.f_suffix
.ptr
) pathname
.f_suffix
= edits
->f
.f_suffix
;
762 if ( edits
->f
.f_member
.ptr
) pathname
.f_member
= edits
->f
.f_member
;
764 /* If requested, modify pathname to point to parent. */
766 path_parent( &pathname
);
768 /* Put filename back together. */
769 path_build( &pathname
, out
);
772 string_append( out
, in
);
777 * var_edit_translate_path() - translate path to os native format.
780 static void var_edit_translate_path( string
* out
, size_t pos
, VAR_EDITS
* edits
)
782 if ( edits
->to_windows
)
787 /* Translate path to os native format. */
788 translated
= path_translate_to_os( out
->value
+ pos
, result
);
791 string_truncate( out
, pos
);
792 string_append( out
, result
->value
);
793 edits
->to_slashes
= 0;
796 string_free( result
);
802 * var_edit_shift() - do upshift/downshift & other mods.
805 static void var_edit_shift( string
* out
, size_t pos
, VAR_EDITS
* edits
)
807 #if defined( OS_CYGWIN ) || defined( OS_VMS )
808 var_edit_translate_path( out
, pos
, edits
);
811 if ( edits
->upshift
|| edits
->downshift
|| edits
->to_slashes
)
813 /* Handle upshifting, downshifting and slash translation now. */
815 for ( p
= out
->value
+ pos
; *p
; ++p
)
817 if ( edits
->upshift
)
819 else if ( edits
->downshift
)
821 if ( edits
->to_slashes
&& ( *p
== '\\' ) )
829 * Reads n LISTs from the top of the STACK and combines them to form VAR_EDITS.
830 * Returns the number of VAR_EDITS pushed onto the STACK.
833 static int expand_modifiers( STACK
* s
, int n
)
837 LIST
* * args
= (LIST
**)stack_get( s
);
838 for ( i
= 0; i
< n
; ++i
)
839 total
*= list_length( args
[ i
] );
843 VAR_EDITS
* out
= (VAR_EDITS
*)stack_allocate( s
, total
* sizeof( VAR_EDITS
) );
844 LISTITER
* iter
= (LISTITER
*)stack_allocate( s
, n
* sizeof( LIST
* ) );
845 for ( i
= 0; i
< n
; ++i
)
846 iter
[ i
] = list_begin( args
[ i
] );
851 memset( out
, 0, sizeof( *out
) );
853 for ( i
= 0; i
< n
; ++i
)
854 havezeroed
= var_edit_parse( object_str( list_item( iter
[ i
] )
855 ), out
, havezeroed
);
859 if ( list_next( iter
[ i
] ) != list_end( args
[ i
] ) )
861 iter
[ i
] = list_next( iter
[ i
] );
864 iter
[ i
] = list_begin( args
[ i
] );
867 stack_deallocate( s
, n
* sizeof( LIST
* ) );
872 static LIST
* apply_modifiers( STACK
* s
, int n
)
874 LIST
* value
= stack_top( s
);
876 VAR_EDITS
* const edits
= (VAR_EDITS
*)( (LIST
* *)stack_get( s
) + 1 );
879 result
= apply_modifiers_impl( result
, buf
, edits
, n
, list_begin( value
),
887 * Parse a string of the form "1-2", "-2--1", "2-" and return the two
891 subscript_t
parse_subscript( char const * s
)
896 do /* so we can use "break" */
898 /* Allow negative subscripts. */
899 if ( !isdigit( *s
) && ( *s
!= '-' ) )
904 result
.sub1
= atoi( s
);
906 /* Skip over the first symbol, which is either a digit or dash. */
908 while ( isdigit( *s
) ) ++s
;
912 result
.sub2
= result
.sub1
;
930 if ( !isdigit( *s
) && ( *s
!= '-' ) )
936 /* First, compute the index of the last element. */
937 result
.sub2
= atoi( s
);
938 while ( isdigit( *++s
) );
947 static LIST
* apply_subscript( STACK
* s
)
949 LIST
* value
= stack_top( s
);
950 LIST
* indices
= stack_at( s
, 1 );
952 int length
= list_length( value
);
954 LISTITER indices_iter
= list_begin( indices
);
955 LISTITER
const indices_end
= list_end( indices
);
957 for ( ; indices_iter
!= indices_end
; indices_iter
= list_next( indices_iter
960 LISTITER iter
= list_begin( value
);
961 LISTITER end
= list_end( value
);
962 subscript_t
const subscript
= parse_subscript( object_str( list_item(
964 get_iters( subscript
, &iter
, &end
, length
);
965 for ( ; iter
!= end
; iter
= list_next( iter
) )
966 result
= list_push_back( result
, object_copy( list_item( iter
) ) );
974 * Reads the LIST from first and applies subscript to it. The results are
975 * written to *first and *last.
978 static void get_iters( subscript_t
const subscript
, LISTITER
* const first
,
979 LISTITER
* const last
, int const length
)
987 if ( subscript
.sub1
< 0 )
988 start
= length
+ subscript
.sub1
;
989 else if ( subscript
.sub1
> length
)
992 start
= subscript
.sub1
- 1;
994 size
= subscript
.sub2
< 0
995 ? length
+ 1 + subscript
.sub2
- start
996 : subscript
.sub2
- start
;
999 * HACK: When the first subscript is before the start of the list, it
1000 * magically becomes the beginning of the list. This is inconsistent,
1001 * but needed for backwards compatibility.
1006 /* The "sub2 < 0" test handles the semantic error of sub2 < sub1. */
1010 if ( start
+ size
> length
)
1011 size
= length
- start
;
1015 while ( start
-- > 0 )
1016 iter
= list_next( iter
);
1019 while ( size
-- > 0 )
1020 end
= list_next( end
);
1026 static LIST
* apply_modifiers_empty( LIST
* result
, string
* buf
,
1027 VAR_EDITS
* edits
, int n
)
1030 for ( i
= 0; i
< n
; ++i
)
1032 if ( edits
[ i
].empty
.ptr
)
1034 /** FIXME: is empty.ptr always null-terminated? */
1035 var_edit_file( edits
[ i
].empty
.ptr
, buf
, edits
+ i
);
1036 var_edit_shift( buf
, 0, edits
+ i
);
1037 result
= list_push_back( result
, object_new( buf
->value
) );
1038 string_truncate( buf
, 0 );
1044 static LIST
* apply_modifiers_non_empty( LIST
* result
, string
* buf
,
1045 VAR_EDITS
* edits
, int n
, LISTITER begin
, LISTITER end
)
1049 for ( i
= 0; i
< n
; ++i
)
1051 if ( edits
[ i
].join
.ptr
)
1053 var_edit_file( object_str( list_item( begin
) ), buf
, edits
+ i
);
1054 var_edit_shift( buf
, 0, edits
+ i
);
1055 for ( iter
= list_next( begin
); iter
!= end
; iter
= list_next( iter
1059 string_append( buf
, edits
[ i
].join
.ptr
);
1061 var_edit_file( object_str( list_item( iter
) ), buf
, edits
+ i
1063 var_edit_shift( buf
, size
, edits
+ i
);
1065 result
= list_push_back( result
, object_new( buf
->value
) );
1066 string_truncate( buf
, 0 );
1070 for ( iter
= begin
; iter
!= end
; iter
= list_next( iter
) )
1072 var_edit_file( object_str( list_item( iter
) ), buf
, edits
+ i
);
1073 var_edit_shift( buf
, 0, edits
+ i
);
1074 result
= list_push_back( result
, object_new( buf
->value
) );
1075 string_truncate( buf
, 0 );
1082 static LIST
* apply_modifiers_impl( LIST
* result
, string
* buf
,
1083 VAR_EDITS
* edits
, int n
, LISTITER iter
, LISTITER end
)
1086 ? apply_modifiers_empty( result
, buf
, edits
, n
)
1087 : apply_modifiers_non_empty( result
, buf
, edits
, n
, iter
, end
);
1090 static LIST
* apply_subscript_and_modifiers( STACK
* s
, int n
)
1092 LIST
* const value
= stack_top( s
);
1093 LIST
* const indices
= stack_at( s
, 1 );
1095 VAR_EDITS
* const edits
= (VAR_EDITS
*)((LIST
* *)stack_get( s
) + 2);
1096 int const length
= list_length( value
);
1098 LISTITER indices_iter
= list_begin( indices
);
1099 LISTITER
const indices_end
= list_end( indices
);
1101 for ( ; indices_iter
!= indices_end
; indices_iter
= list_next( indices_iter
1104 LISTITER iter
= list_begin( value
);
1105 LISTITER end
= list_end( value
);
1106 subscript_t
const sub
= parse_subscript( object_str( list_item(
1108 get_iters( sub
, &iter
, &end
, length
);
1109 result
= apply_modifiers_impl( result
, buf
, edits
, n
, iter
, end
);
1117 * expand() - expands a list of concatenated strings and variable references
1119 * Takes a list of expansion items - each representing one element to be
1120 * concatenated and each containing a list of its values. Returns a list of all
1121 * possible values constructed by selecting a single value from each of the
1122 * elements and concatenating them together.
1124 * For example, in the following code:
1126 * local a = one two three four ;
1127 * local b = foo bar ;
1128 * ECHO /$(a)/$(b)/$(a)/ ;
1130 * When constructing the result of /$(a)/$(b)/ this function would get called
1131 * with the following 7 expansion items:
1133 * 2. one two three four
1137 * 6. one two three four
1140 * And would result in a list containing 32 values:
1143 * 3. /one/foo/three/
1150 typedef struct expansion_item
1152 /* Item's value list initialized prior to calling expand(). */
1155 /* Internal data initialized and used inside expand(). */
1156 LISTITER current
; /* Currently used value. */
1157 int size
; /* Concatenated string length prior to concatenating the
1158 * item's current value.
1162 static LIST
* expand( expansion_item
* items
, int const length
)
1169 assert( length
> 0 );
1170 for ( i
= 0; i
< length
; ++i
)
1172 LISTITER iter
= list_begin( items
[ i
].values
);
1173 LISTITER
const end
= list_end( items
[ i
].values
);
1175 /* If any of the items has no values - the result is an empty list. */
1176 if ( iter
== end
) return L0
;
1178 /* Set each item's 'current' to its first listed value. This indicates
1179 * each item's next value to be used when constructing the list of all
1180 * possible concatenated values.
1182 items
[ i
].current
= iter
;
1184 /* Calculate the longest concatenated string length - to know how much
1185 * memory we need to allocate as a buffer for holding the concatenated
1190 for ( ; iter
!= end
; iter
= list_next( iter
) )
1192 int const len
= strlen( object_str( list_item( iter
) ) );
1193 if ( len
> max
) max
= len
;
1200 string_reserve( buf
, size
);
1205 for ( ; i
< length
; ++i
)
1207 items
[ i
].size
= buf
->size
;
1208 string_append( buf
, object_str( list_item( items
[ i
].current
) ) );
1210 result
= list_push_back( result
, object_new( buf
->value
) );
1213 if ( list_next( items
[ i
].current
) != list_end( items
[ i
].values
1216 items
[ i
].current
= list_next( items
[ i
].current
);
1217 string_truncate( buf
, items
[ i
].size
);
1221 items
[ i
].current
= list_begin( items
[ i
].values
);
1229 static void combine_strings( STACK
* s
, int n
, string
* out
)
1232 for ( i
= 0; i
< n
; ++i
)
1234 LIST
* const values
= stack_pop( s
);
1235 LISTITER iter
= list_begin( values
);
1236 LISTITER
const end
= list_end( values
);
1239 string_append( out
, object_str( list_item( iter
) ) );
1240 for ( iter
= list_next( iter
); iter
!= end
; iter
= list_next( iter
1243 string_push_back( out
, ' ' );
1244 string_append( out
, object_str( list_item( iter
) ) );
1246 list_free( values
);
1251 struct dynamic_array
1258 static void dynamic_array_init( struct dynamic_array
* array
)
1261 array
->capacity
= 0;
1265 static void dynamic_array_free( struct dynamic_array
* array
)
1267 BJAM_FREE( array
->data
);
1270 static void dynamic_array_push_impl( struct dynamic_array
* const array
,
1271 void const * const value
, int const unit_size
)
1273 if ( array
->capacity
== 0 )
1275 array
->capacity
= 2;
1276 array
->data
= BJAM_MALLOC( array
->capacity
* unit_size
);
1278 else if ( array
->capacity
== array
->size
)
1281 array
->capacity
*= 2;
1282 new_data
= BJAM_MALLOC( array
->capacity
* unit_size
);
1283 memcpy( new_data
, array
->data
, array
->size
* unit_size
);
1284 BJAM_FREE( array
->data
);
1285 array
->data
= new_data
;
1287 memcpy( (char *)array
->data
+ array
->size
* unit_size
, value
, unit_size
);
1291 #define dynamic_array_push( array, value ) (dynamic_array_push_impl(array, &value, sizeof(value)))
1292 #define dynamic_array_at( type, array, idx ) (((type *)(array)->data)[idx])
1293 #define dynamic_array_pop( array ) (--(array)->size)
1301 int absolute_position
;
1302 struct dynamic_array uses
[ 1 ];
1305 #define LOOP_INFO_BREAK 0
1306 #define LOOP_INFO_CONTINUE 1
1320 struct arg_list
* arguments
;
1324 typedef struct compiler
1326 struct dynamic_array code
[ 1 ];
1327 struct dynamic_array constants
[ 1 ];
1328 struct dynamic_array labels
[ 1 ];
1329 struct dynamic_array rules
[ 1 ];
1330 struct dynamic_array actions
[ 1 ];
1331 struct dynamic_array cleanups
[ 1 ];
1332 struct dynamic_array loop_scopes
[ 1 ];
1335 static void compiler_init( compiler
* c
)
1337 dynamic_array_init( c
->code
);
1338 dynamic_array_init( c
->constants
);
1339 dynamic_array_init( c
->labels
);
1340 dynamic_array_init( c
->rules
);
1341 dynamic_array_init( c
->actions
);
1342 dynamic_array_init( c
->cleanups
);
1343 dynamic_array_init( c
->loop_scopes
);
1346 static void compiler_free( compiler
* c
)
1349 dynamic_array_free( c
->actions
);
1350 dynamic_array_free( c
->rules
);
1351 for ( i
= 0; i
< c
->labels
->size
; ++i
)
1352 dynamic_array_free( dynamic_array_at( struct label_info
, c
->labels
, i
1354 dynamic_array_free( c
->labels
);
1355 dynamic_array_free( c
->constants
);
1356 dynamic_array_free( c
->code
);
1357 dynamic_array_free( c
->cleanups
);
1358 dynamic_array_free( c
->loop_scopes
);
1361 static void compile_emit_instruction( compiler
* c
, instruction instr
)
1363 dynamic_array_push( c
->code
, instr
);
1366 static int compile_new_label( compiler
* c
)
1368 int result
= c
->labels
->size
;
1369 struct label_info info
;
1370 info
.absolute_position
= -1;
1371 dynamic_array_init( info
.uses
);
1372 dynamic_array_push( c
->labels
, info
);
1376 static void compile_set_label( compiler
* c
, int label
)
1378 struct label_info
* const l
= &dynamic_array_at( struct label_info
,
1380 int const pos
= c
->code
->size
;
1382 assert( l
->absolute_position
== -1 );
1383 l
->absolute_position
= pos
;
1384 for ( i
= 0; i
< l
->uses
->size
; ++i
)
1386 int id
= dynamic_array_at( int, l
->uses
, i
);
1387 int offset
= (int)( pos
- id
- 1 );
1388 dynamic_array_at( instruction
, c
->code
, id
).arg
= offset
;
1392 static void compile_emit( compiler
* c
, unsigned int op_code
, int arg
)
1395 instr
.op_code
= op_code
;
1397 compile_emit_instruction( c
, instr
);
1400 static void compile_emit_branch( compiler
* c
, unsigned int op_code
, int label
)
1402 struct label_info
* const l
= &dynamic_array_at( struct label_info
,
1404 int const pos
= c
->code
->size
;
1406 instr
.op_code
= op_code
;
1407 if ( l
->absolute_position
== -1 )
1410 dynamic_array_push( l
->uses
, pos
);
1413 instr
.arg
= (int)( l
->absolute_position
- pos
- 1 );
1414 compile_emit_instruction( c
, instr
);
1417 static int compile_emit_constant( compiler
* c
, OBJECT
* value
)
1419 OBJECT
* copy
= object_copy( value
);
1420 dynamic_array_push( c
->constants
, copy
);
1421 return c
->constants
->size
- 1;
1424 static void compile_push_cleanup( compiler
* c
, unsigned int op_code
, int arg
)
1427 instr
.op_code
= op_code
;
1429 dynamic_array_push( c
->cleanups
, instr
);
1432 static void compile_pop_cleanup( compiler
* c
)
1434 dynamic_array_pop( c
->cleanups
);
1437 static void compile_emit_cleanups( compiler
* c
, int end
)
1440 for ( i
= c
->cleanups
->size
; --i
>= end
; )
1442 compile_emit_instruction( c
, dynamic_array_at( instruction
, c
->cleanups
, i
) );
1446 static void compile_emit_loop_jump( compiler
* c
, int type
)
1448 struct loop_info
* info
= NULL
;
1450 for ( i
= c
->loop_scopes
->size
; --i
>= 0; )
1452 struct loop_info
* elem
= &dynamic_array_at( struct loop_info
, c
->loop_scopes
, i
);
1453 if ( elem
->type
== type
)
1461 printf( "warning: ignoring break statement used outside of loop\n" );
1464 compile_emit_cleanups( c
, info
->cleanup_depth
);
1465 compile_emit_branch( c
, INSTR_JUMP
, info
->label
);
1468 static void compile_push_break_scope( compiler
* c
, int label
)
1470 struct loop_info info
;
1471 info
.type
= LOOP_INFO_BREAK
;
1473 info
.cleanup_depth
= c
->cleanups
->size
;
1474 dynamic_array_push( c
->loop_scopes
, info
);
1477 static void compile_push_continue_scope( compiler
* c
, int label
)
1479 struct loop_info info
;
1480 info
.type
= LOOP_INFO_CONTINUE
;
1482 info
.cleanup_depth
= c
->cleanups
->size
;
1483 dynamic_array_push( c
->loop_scopes
, info
);
1486 static void compile_pop_break_scope( compiler
* c
)
1488 assert( c
->loop_scopes
->size
> 0 );
1489 assert( dynamic_array_at( struct loop_info
, c
->loop_scopes
, c
->loop_scopes
->size
- 1 ).type
== LOOP_INFO_BREAK
);
1490 dynamic_array_pop( c
->loop_scopes
);
1493 static void compile_pop_continue_scope( compiler
* c
)
1495 assert( c
->loop_scopes
->size
> 0 );
1496 assert( dynamic_array_at( struct loop_info
, c
->loop_scopes
, c
->loop_scopes
->size
- 1 ).type
== LOOP_INFO_CONTINUE
);
1497 dynamic_array_pop( c
->loop_scopes
);
1500 static int compile_emit_rule( compiler
* c
, OBJECT
* name
, PARSE
* parse
,
1501 int num_arguments
, struct arg_list
* arguments
, int local
)
1503 struct stored_rule rule
;
1504 rule
.name
= object_copy( name
);
1506 rule
.num_arguments
= num_arguments
;
1507 rule
.arguments
= arguments
;
1509 dynamic_array_push( c
->rules
, rule
);
1510 return (int)( c
->rules
->size
- 1 );
1513 static int compile_emit_actions( compiler
* c
, PARSE
* parse
)
1516 a
.name
= object_copy( parse
->string
);
1517 a
.command
= function_compile_actions( object_str( parse
->string1
),
1518 parse
->file
, parse
->line
);
1519 a
.flags
= parse
->num
;
1520 dynamic_array_push( c
->actions
, a
);
1521 return (int)( c
->actions
->size
- 1 );
1524 static JAM_FUNCTION
* compile_to_function( compiler
* c
)
1526 JAM_FUNCTION
* const result
= (JAM_FUNCTION
*)BJAM_MALLOC( sizeof( JAM_FUNCTION
) );
1528 result
->base
.type
= FUNCTION_JAM
;
1529 result
->base
.reference_count
= 1;
1530 result
->base
.formal_arguments
= 0;
1531 result
->base
.num_formal_arguments
= 0;
1533 result
->base
.rulename
= 0;
1535 result
->code_size
= c
->code
->size
;
1536 result
->code
= (instruction
*)BJAM_MALLOC( c
->code
->size
* sizeof( instruction
) );
1537 memcpy( result
->code
, c
->code
->data
, c
->code
->size
* sizeof( instruction
) );
1539 result
->constants
= (OBJECT
**)BJAM_MALLOC( c
->constants
->size
* sizeof( OBJECT
* ) );
1540 if ( c
->constants
->size
!= 0 )
1541 memcpy( result
->constants
, c
->constants
->data
,
1542 c
->constants
->size
* sizeof( OBJECT
* ) );
1543 result
->num_constants
= c
->constants
->size
;
1545 result
->num_subfunctions
= c
->rules
->size
;
1546 result
->functions
= (SUBFUNCTION
*)BJAM_MALLOC( c
->rules
->size
* sizeof( SUBFUNCTION
) );
1547 for ( i
= 0; i
< c
->rules
->size
; ++i
)
1549 struct stored_rule
* const rule
= &dynamic_array_at( struct stored_rule
,
1551 result
->functions
[ i
].name
= rule
->name
;
1552 result
->functions
[ i
].code
= function_compile( rule
->parse
);
1553 result
->functions
[ i
].code
->num_formal_arguments
= rule
->num_arguments
;
1554 result
->functions
[ i
].code
->formal_arguments
= rule
->arguments
;
1555 result
->functions
[ i
].local
= rule
->local
;
1558 result
->actions
= (SUBACTION
*)BJAM_MALLOC( c
->actions
->size
* sizeof( SUBACTION
) );
1559 if ( c
->actions
->size
!= 0 )
1560 memcpy( result
->actions
, c
->actions
->data
,
1561 c
->actions
->size
* sizeof( SUBACTION
) );
1562 result
->num_subactions
= c
->actions
->size
;
1564 result
->generic
= 0;
1574 * Parsing of variable expansions
1577 typedef struct VAR_PARSE_GROUP
1579 struct dynamic_array elems
[ 1 ];
1582 typedef struct VAR_PARSE_ACTIONS
1584 struct dynamic_array elems
[ 1 ];
1585 } VAR_PARSE_ACTIONS
;
1587 #define VAR_PARSE_TYPE_VAR 0
1588 #define VAR_PARSE_TYPE_STRING 1
1589 #define VAR_PARSE_TYPE_FILE 2
1591 typedef struct _var_parse
1593 int type
; /* string, variable or file */
1599 VAR_PARSE_GROUP
* name
;
1600 VAR_PARSE_GROUP
* subscript
;
1601 struct dynamic_array modifiers
[ 1 ];
1613 struct dynamic_array filename
[ 1 ];
1614 struct dynamic_array contents
[ 1 ];
1617 static void var_parse_free( VAR_PARSE
* );
1624 static VAR_PARSE_GROUP
* var_parse_group_new()
1626 VAR_PARSE_GROUP
* const result
= (VAR_PARSE_GROUP
*)BJAM_MALLOC( sizeof( VAR_PARSE_GROUP
) );
1627 dynamic_array_init( result
->elems
);
1631 static void var_parse_group_free( VAR_PARSE_GROUP
* group
)
1634 for ( i
= 0; i
< group
->elems
->size
; ++i
)
1635 var_parse_free( dynamic_array_at( VAR_PARSE
*, group
->elems
, i
) );
1636 dynamic_array_free( group
->elems
);
1640 static void var_parse_group_add( VAR_PARSE_GROUP
* group
, VAR_PARSE
* elem
)
1642 dynamic_array_push( group
->elems
, elem
);
1645 static void var_parse_group_maybe_add_constant( VAR_PARSE_GROUP
* group
,
1646 char const * start
, char const * end
)
1651 VAR_PARSE_STRING
* const value
= (VAR_PARSE_STRING
*)BJAM_MALLOC(
1652 sizeof(VAR_PARSE_STRING
) );
1653 value
->base
.type
= VAR_PARSE_TYPE_STRING
;
1655 string_append_range( buf
, start
, end
);
1656 value
->s
= object_new( buf
->value
);
1658 var_parse_group_add( group
, (VAR_PARSE
*)value
);
1662 VAR_PARSE_STRING
* var_parse_group_as_literal( VAR_PARSE_GROUP
* group
)
1664 if ( group
->elems
->size
== 1 )
1666 VAR_PARSE
* result
= dynamic_array_at( VAR_PARSE
*, group
->elems
, 0 );
1667 if ( result
->type
== VAR_PARSE_TYPE_STRING
)
1668 return (VAR_PARSE_STRING
*)result
;
1678 static VAR_PARSE_ACTIONS
* var_parse_actions_new()
1680 VAR_PARSE_ACTIONS
* const result
= (VAR_PARSE_ACTIONS
*)BJAM_MALLOC(
1681 sizeof(VAR_PARSE_ACTIONS
) );
1682 dynamic_array_init( result
->elems
);
1686 static void var_parse_actions_free( VAR_PARSE_ACTIONS
* actions
)
1689 for ( i
= 0; i
< actions
->elems
->size
; ++i
)
1690 var_parse_group_free( dynamic_array_at( VAR_PARSE_GROUP
*,
1691 actions
->elems
, i
) );
1692 dynamic_array_free( actions
->elems
);
1693 BJAM_FREE( actions
);
1701 static VAR_PARSE_VAR
* var_parse_var_new()
1703 VAR_PARSE_VAR
* result
= (VAR_PARSE_VAR
*)BJAM_MALLOC( sizeof( VAR_PARSE_VAR
) );
1704 result
->base
.type
= VAR_PARSE_TYPE_VAR
;
1705 result
->name
= var_parse_group_new();
1706 result
->subscript
= 0;
1707 dynamic_array_init( result
->modifiers
);
1711 static void var_parse_var_free( VAR_PARSE_VAR
* var
)
1714 var_parse_group_free( var
->name
);
1715 if ( var
->subscript
)
1716 var_parse_group_free( var
->subscript
);
1717 for ( i
= 0; i
< var
->modifiers
->size
; ++i
)
1718 var_parse_group_free( dynamic_array_at( VAR_PARSE_GROUP
*,
1719 var
->modifiers
, i
) );
1720 dynamic_array_free( var
->modifiers
);
1724 static VAR_PARSE_GROUP
* var_parse_var_new_modifier( VAR_PARSE_VAR
* var
)
1726 VAR_PARSE_GROUP
* result
= var_parse_group_new();
1727 dynamic_array_push( var
->modifiers
, result
);
1736 static void var_parse_string_free( VAR_PARSE_STRING
* string
)
1738 object_free( string
->s
);
1739 BJAM_FREE( string
);
1747 static VAR_PARSE_FILE
* var_parse_file_new( void )
1749 VAR_PARSE_FILE
* const result
= (VAR_PARSE_FILE
*)BJAM_MALLOC( sizeof(
1751 result
->base
.type
= VAR_PARSE_TYPE_FILE
;
1752 dynamic_array_init( result
->filename
);
1753 dynamic_array_init( result
->contents
);
1757 static void var_parse_file_free( VAR_PARSE_FILE
* file
)
1760 for ( i
= 0; i
< file
->filename
->size
; ++i
)
1761 var_parse_group_free( dynamic_array_at( VAR_PARSE_GROUP
*,
1762 file
->filename
, i
) );
1763 dynamic_array_free( file
->filename
);
1764 for ( i
= 0; i
< file
->contents
->size
; ++i
)
1765 var_parse_group_free( dynamic_array_at( VAR_PARSE_GROUP
*,
1766 file
->contents
, i
) );
1767 dynamic_array_free( file
->contents
);
1776 static void var_parse_free( VAR_PARSE
* parse
)
1778 switch ( parse
->type
)
1780 case VAR_PARSE_TYPE_VAR
:
1781 var_parse_var_free( (VAR_PARSE_VAR
*)parse
);
1784 case VAR_PARSE_TYPE_STRING
:
1785 var_parse_string_free( (VAR_PARSE_STRING
*)parse
);
1788 case VAR_PARSE_TYPE_FILE
:
1789 var_parse_file_free( (VAR_PARSE_FILE
*)parse
);
1793 assert( !"Invalid type" );
1802 static void var_parse_group_compile( VAR_PARSE_GROUP
const * parse
,
1805 static void var_parse_var_compile( VAR_PARSE_VAR
const * parse
, compiler
* c
)
1807 int expand_name
= 0;
1808 int is_get_grist
= 0;
1809 int has_modifiers
= 0;
1810 /* Special case common modifiers */
1811 if ( parse
->modifiers
->size
== 1 )
1813 VAR_PARSE_GROUP
* mod
= dynamic_array_at( VAR_PARSE_GROUP
*, parse
->modifiers
, 0 );
1814 if ( mod
->elems
->size
== 1 )
1816 VAR_PARSE
* mod1
= dynamic_array_at( VAR_PARSE
*, mod
->elems
, 0 );
1817 if ( mod1
->type
== VAR_PARSE_TYPE_STRING
)
1819 OBJECT
* s
= ( (VAR_PARSE_STRING
*)mod1
)->s
;
1820 if ( ! strcmp ( object_str( s
), "G" ) )
1827 /* If there are modifiers, emit them in reverse order. */
1828 if ( parse
->modifiers
->size
> 0 && !is_get_grist
)
1832 for ( i
= 0; i
< parse
->modifiers
->size
; ++i
)
1833 var_parse_group_compile( dynamic_array_at( VAR_PARSE_GROUP
*,
1834 parse
->modifiers
, parse
->modifiers
->size
- i
- 1 ), c
);
1837 /* If there is a subscript, emit it. */
1838 if ( parse
->subscript
)
1839 var_parse_group_compile( parse
->subscript
, c
);
1841 /* If the variable name is empty, look it up. */
1842 if ( parse
->name
->elems
->size
== 0 )
1843 compile_emit( c
, INSTR_PUSH_VAR
, compile_emit_constant( c
,
1845 /* If the variable name does not need to be expanded, look it up. */
1846 else if ( parse
->name
->elems
->size
== 1 && dynamic_array_at( VAR_PARSE
*,
1847 parse
->name
->elems
, 0 )->type
== VAR_PARSE_TYPE_STRING
)
1849 OBJECT
* const name
= ( (VAR_PARSE_STRING
*)dynamic_array_at(
1850 VAR_PARSE
*, parse
->name
->elems
, 0 ) )->s
;
1851 int const idx
= get_argument_index( object_str( name
) );
1853 compile_emit( c
, INSTR_PUSH_ARG
, idx
);
1855 compile_emit( c
, INSTR_PUSH_VAR
, compile_emit_constant( c
, name
) );
1857 /* Otherwise, push the var names and use the group instruction. */
1860 var_parse_group_compile( parse
->name
, c
);
1864 /** Select the instruction for expanding the variable. */
1865 if ( !has_modifiers
&& !parse
->subscript
&& !expand_name
)
1867 else if ( !has_modifiers
&& !parse
->subscript
&& expand_name
)
1868 compile_emit( c
, INSTR_PUSH_GROUP
, 0 );
1869 else if ( !has_modifiers
&& parse
->subscript
&& !expand_name
)
1870 compile_emit( c
, INSTR_APPLY_INDEX
, 0 );
1871 else if ( !has_modifiers
&& parse
->subscript
&& expand_name
)
1872 compile_emit( c
, INSTR_APPLY_INDEX_GROUP
, 0 );
1873 else if ( has_modifiers
&& !parse
->subscript
&& !expand_name
)
1874 compile_emit( c
, INSTR_APPLY_MODIFIERS
, parse
->modifiers
->size
);
1875 else if ( has_modifiers
&& !parse
->subscript
&& expand_name
)
1876 compile_emit( c
, INSTR_APPLY_MODIFIERS_GROUP
, parse
->modifiers
->size
);
1877 else if ( has_modifiers
&& parse
->subscript
&& !expand_name
)
1878 compile_emit( c
, INSTR_APPLY_INDEX_MODIFIERS
, parse
->modifiers
->size
);
1879 else if ( has_modifiers
&& parse
->subscript
&& expand_name
)
1880 compile_emit( c
, INSTR_APPLY_INDEX_MODIFIERS_GROUP
,
1881 parse
->modifiers
->size
);
1883 /* Now apply any special modifiers */
1886 compile_emit( c
, INSTR_GET_GRIST
, 0 );
1890 static void var_parse_string_compile( VAR_PARSE_STRING
const * parse
,
1893 compile_emit( c
, INSTR_PUSH_CONSTANT
, compile_emit_constant( c
, parse
->s
)
1897 static void var_parse_file_compile( VAR_PARSE_FILE
const * parse
, compiler
* c
)
1900 for ( i
= 0; i
< parse
->filename
->size
; ++i
)
1901 var_parse_group_compile( dynamic_array_at( VAR_PARSE_GROUP
*,
1902 parse
->filename
, parse
->filename
->size
- i
- 1 ), c
);
1903 compile_emit( c
, INSTR_APPEND_STRINGS
, parse
->filename
->size
);
1904 for ( i
= 0; i
< parse
->contents
->size
; ++i
)
1905 var_parse_group_compile( dynamic_array_at( VAR_PARSE_GROUP
*,
1906 parse
->contents
, parse
->contents
->size
- i
- 1 ), c
);
1907 compile_emit( c
, INSTR_WRITE_FILE
, parse
->contents
->size
);
1910 static void var_parse_compile( VAR_PARSE
const * parse
, compiler
* c
)
1912 switch ( parse
->type
)
1914 case VAR_PARSE_TYPE_VAR
:
1915 var_parse_var_compile( (VAR_PARSE_VAR
const *)parse
, c
);
1918 case VAR_PARSE_TYPE_STRING
:
1919 var_parse_string_compile( (VAR_PARSE_STRING
const *)parse
, c
);
1922 case VAR_PARSE_TYPE_FILE
:
1923 var_parse_file_compile( (VAR_PARSE_FILE
const *)parse
, c
);
1927 assert( !"Unknown var parse type." );
1931 static void var_parse_group_compile( VAR_PARSE_GROUP
const * parse
, compiler
* c
1934 /* Emit the elements in reverse order. */
1936 for ( i
= 0; i
< parse
->elems
->size
; ++i
)
1937 var_parse_compile( dynamic_array_at( VAR_PARSE
*, parse
->elems
,
1938 parse
->elems
->size
- i
- 1 ), c
);
1939 /* If there are no elements, emit an empty string. */
1940 if ( parse
->elems
->size
== 0 )
1941 compile_emit( c
, INSTR_PUSH_CONSTANT
, compile_emit_constant( c
,
1943 /* If there is more than one element, combine them. */
1944 if ( parse
->elems
->size
> 1 )
1945 compile_emit( c
, INSTR_COMBINE_STRINGS
, parse
->elems
->size
);
1948 static void var_parse_actions_compile( VAR_PARSE_ACTIONS
const * actions
,
1952 for ( i
= 0; i
< actions
->elems
->size
; ++i
)
1953 var_parse_group_compile( dynamic_array_at( VAR_PARSE_GROUP
*,
1954 actions
->elems
, actions
->elems
->size
- i
- 1 ), c
);
1955 compile_emit( c
, INSTR_OUTPUT_STRINGS
, actions
->elems
->size
);
1960 * Parse VAR_PARSE_VAR
1963 static VAR_PARSE
* parse_at_file( char const * start
, char const * mid
,
1965 static VAR_PARSE
* parse_variable( char const * * string
);
1966 static int try_parse_variable( char const * * s_
, char const * * string
,
1967 VAR_PARSE_GROUP
* out
);
1968 static void balance_parentheses( char const * * s_
, char const * * string
,
1969 VAR_PARSE_GROUP
* out
);
1970 static void parse_var_string( char const * first
, char const * last
,
1971 struct dynamic_array
* out
);
1975 * Parses a string that can contain variables to expand.
1978 static VAR_PARSE_GROUP
* parse_expansion( char const * * string
)
1980 VAR_PARSE_GROUP
* result
= var_parse_group_new();
1981 char const * s
= *string
;
1984 if ( try_parse_variable( &s
, string
, result
) ) {}
1985 else if ( s
[ 0 ] == '\0' )
1987 var_parse_group_maybe_add_constant( result
, *string
, s
);
1995 static VAR_PARSE_ACTIONS
* parse_actions( char const * string
)
1997 VAR_PARSE_ACTIONS
* const result
= var_parse_actions_new();
1998 parse_var_string( string
, string
+ strlen( string
), result
->elems
);
2003 * Checks whether the string a *s_ starts with a variable expansion "$(".
2004 * *string should point to the first unemitted character before *s. If *s_
2005 * starts with variable expansion, appends elements to out up to the closing
2006 * ")", and adjusts *s_ and *string to point to next character. Returns 1 if s_
2007 * starts with a variable, 0 otherwise.
2010 static int try_parse_variable( char const * * s_
, char const * * string
,
2011 VAR_PARSE_GROUP
* out
)
2013 char const * s
= *s_
;
2014 if ( s
[ 0 ] == '$' && s
[ 1 ] == '(' )
2016 var_parse_group_maybe_add_constant( out
, *string
, s
);
2018 var_parse_group_add( out
, parse_variable( &s
) );
2023 if ( s
[ 0 ] == '@' && s
[ 1 ] == '(' )
2027 char const * split
= 0;
2028 var_parse_group_maybe_add_constant( out
, *string
, s
);
2032 /* Scan the content of the response file @() section. */
2033 while ( *ine
&& ( depth
> 0 ) )
2037 case '(': ++depth
; break;
2038 case ')': --depth
; break;
2040 if ( ( depth
== 1 ) && ( ine
[ 1 ] == 'E' ) && ( ine
[ 2 ] == '='
2048 if ( !split
|| depth
)
2051 var_parse_group_add( out
, parse_at_file( s
, split
, ine
- 1 ) );
2060 static char const * current_file
= "";
2061 static int current_line
;
2063 static void parse_error( char const * message
)
2065 out_printf( "%s:%d: %s\n", current_file
, current_line
, message
);
2070 * Parses a single variable up to the closing ")" and adjusts *string to point
2071 * to the next character. *string should point to the character immediately
2072 * after the initial "$(".
2075 static VAR_PARSE
* parse_variable( char const * * string
)
2077 VAR_PARSE_VAR
* const result
= var_parse_var_new();
2078 VAR_PARSE_GROUP
* const name
= result
->name
;
2079 char const * s
= *string
;
2082 if ( try_parse_variable( &s
, string
, name
) ) {}
2083 else if ( s
[ 0 ] == ':' )
2085 VAR_PARSE_GROUP
* mod
;
2086 var_parse_group_maybe_add_constant( name
, *string
, s
);
2089 mod
= var_parse_var_new_modifier( result
);
2092 if ( try_parse_variable( &s
, string
, mod
) ) {}
2093 else if ( s
[ 0 ] == ')' )
2095 var_parse_group_maybe_add_constant( mod
, *string
, s
);
2097 return (VAR_PARSE
*)result
;
2099 else if ( s
[ 0 ] == '(' )
2102 balance_parentheses( &s
, string
, mod
);
2104 else if ( s
[ 0 ] == ':' )
2106 var_parse_group_maybe_add_constant( mod
, *string
, s
);
2108 mod
= var_parse_var_new_modifier( result
);
2110 else if ( s
[ 0 ] == '[' )
2112 parse_error("unexpected subscript");
2115 else if ( s
[ 0 ] == '\0' )
2117 parse_error( "unbalanced parentheses" );
2118 var_parse_group_maybe_add_constant( mod
, *string
, s
);
2120 return (VAR_PARSE
*)result
;
2126 else if ( s
[ 0 ] == '[' )
2128 VAR_PARSE_GROUP
* subscript
= var_parse_group_new();
2129 result
->subscript
= subscript
;
2130 var_parse_group_maybe_add_constant( name
, *string
, s
);
2134 if ( try_parse_variable( &s
, string
, subscript
) ) {}
2135 else if ( s
[ 0 ] == ']' )
2137 var_parse_group_maybe_add_constant( subscript
, *string
, s
);
2139 if ( s
[ 0 ] != ')' && s
[ 0 ] != ':' && s
[ 0 ] != '\0' )
2140 parse_error( "unexpected text following []" );
2143 else if ( isdigit( s
[ 0 ] ) || s
[ 0 ] == '-' )
2147 else if ( s
[ 0 ] == '\0' )
2149 parse_error( "malformed subscript" );
2154 parse_error( "malformed subscript" );
2159 else if ( s
[ 0 ] == ')' )
2161 var_parse_group_maybe_add_constant( name
, *string
, s
);
2163 return (VAR_PARSE
*)result
;
2165 else if ( s
[ 0 ] == '(' )
2168 balance_parentheses( &s
, string
, name
);
2170 else if ( s
[ 0 ] == '\0' )
2172 parse_error( "unbalanced parentheses" );
2173 var_parse_group_maybe_add_constant( name
, *string
, s
);
2175 return (VAR_PARSE
*)result
;
2182 static void parse_var_string( char const * first
, char const * last
,
2183 struct dynamic_array
* out
)
2185 char const * saved
= first
;
2186 while ( first
!= last
)
2188 /* Handle whitespace. */
2189 while ( first
!= last
&& isspace( *first
) ) ++first
;
2190 if ( saved
!= first
)
2192 VAR_PARSE_GROUP
* const group
= var_parse_group_new();
2193 var_parse_group_maybe_add_constant( group
, saved
, first
);
2195 dynamic_array_push( out
, group
);
2197 if ( first
== last
) break;
2199 /* Handle non-whitespace */
2201 VAR_PARSE_GROUP
* group
= var_parse_group_new();
2204 if ( first
== last
|| isspace( *first
) )
2206 var_parse_group_maybe_add_constant( group
, saved
, first
);
2210 if ( try_parse_variable( &first
, &saved
, group
) )
2211 assert( first
<= last
);
2215 dynamic_array_push( out
, group
);
2221 * start should point to the character immediately following the opening "@(",
2222 * mid should point to the ":E=", and end should point to the closing ")".
2225 static VAR_PARSE
* parse_at_file( char const * start
, char const * mid
,
2228 VAR_PARSE_FILE
* result
= var_parse_file_new();
2229 parse_var_string( start
, mid
, result
->filename
);
2230 parse_var_string( mid
+ 3, end
, result
->contents
);
2231 return (VAR_PARSE
*)result
;
2235 * Given that *s_ points to the character after a "(", parses up to the matching
2236 * ")". *string should point to the first unemitted character before *s_.
2238 * When the function returns, *s_ will point to the character after the ")", and
2239 * *string will point to the first unemitted character before *s_. The range
2240 * from *string to *s_ does not contain any variables that need to be expanded.
2243 void balance_parentheses( char const * * s_
, char const * * string
,
2244 VAR_PARSE_GROUP
* out
)
2247 char const * s
= *s_
;
2250 if ( try_parse_variable( &s
, string
, out
) ) { }
2251 else if ( s
[ 0 ] == ':' || s
[ 0 ] == '[' )
2253 parse_error( "unbalanced parentheses" );
2256 else if ( s
[ 0 ] == '\0' )
2258 parse_error( "unbalanced parentheses" );
2261 else if ( s
[ 0 ] == ')' )
2264 if ( --depth
== 0 ) break;
2266 else if ( s
[ 0 ] == '(' )
2282 #define RESULT_STACK 0
2283 #define RESULT_RETURN 1
2284 #define RESULT_NONE 2
2286 static void compile_parse( PARSE
* parse
, compiler
* c
, int result_location
);
2287 static struct arg_list
* arg_list_compile( PARSE
* parse
, int * num_arguments
);
2289 static void compile_condition( PARSE
* parse
, compiler
* c
, int branch_true
, int label
)
2291 assert( parse
->type
== PARSE_EVAL
);
2292 switch ( parse
->num
)
2295 compile_parse( parse
->left
, c
, RESULT_STACK
);
2297 compile_emit_branch( c
, INSTR_JUMP_NOT_EMPTY
, label
);
2299 compile_emit_branch( c
, INSTR_JUMP_EMPTY
, label
);
2303 compile_parse( parse
->left
, c
, RESULT_STACK
);
2304 compile_parse( parse
->right
, c
, RESULT_STACK
);
2306 compile_emit_branch( c
, INSTR_JUMP_EQ
, label
);
2308 compile_emit_branch( c
, INSTR_JUMP_NE
, label
);
2312 compile_parse( parse
->left
, c
, RESULT_STACK
);
2313 compile_parse( parse
->right
, c
, RESULT_STACK
);
2315 compile_emit_branch( c
, INSTR_JUMP_NE
, label
);
2317 compile_emit_branch( c
, INSTR_JUMP_EQ
, label
);
2321 compile_parse( parse
->left
, c
, RESULT_STACK
);
2322 compile_parse( parse
->right
, c
, RESULT_STACK
);
2324 compile_emit_branch( c
, INSTR_JUMP_LT
, label
);
2326 compile_emit_branch( c
, INSTR_JUMP_GE
, label
);
2330 compile_parse( parse
->left
, c
, RESULT_STACK
);
2331 compile_parse( parse
->right
, c
, RESULT_STACK
);
2333 compile_emit_branch( c
, INSTR_JUMP_LE
, label
);
2335 compile_emit_branch( c
, INSTR_JUMP_GT
, label
);
2339 compile_parse( parse
->left
, c
, RESULT_STACK
);
2340 compile_parse( parse
->right
, c
, RESULT_STACK
);
2342 compile_emit_branch( c
, INSTR_JUMP_GT
, label
);
2344 compile_emit_branch( c
, INSTR_JUMP_LE
, label
);
2348 compile_parse( parse
->left
, c
, RESULT_STACK
);
2349 compile_parse( parse
->right
, c
, RESULT_STACK
);
2351 compile_emit_branch( c
, INSTR_JUMP_GE
, label
);
2353 compile_emit_branch( c
, INSTR_JUMP_LT
, label
);
2357 compile_parse( parse
->left
, c
, RESULT_STACK
);
2358 compile_parse( parse
->right
, c
, RESULT_STACK
);
2360 compile_emit_branch( c
, INSTR_JUMP_IN
, label
);
2362 compile_emit_branch( c
, INSTR_JUMP_NOT_IN
, label
);
2368 int f
= compile_new_label( c
);
2369 compile_condition( parse
->left
, c
, 0, f
);
2370 compile_condition( parse
->right
, c
, 1, label
);
2371 compile_set_label( c
, f
);
2375 compile_condition( parse
->left
, c
, 0, label
);
2376 compile_condition( parse
->right
, c
, 0, label
);
2383 compile_condition( parse
->left
, c
, 1, label
);
2384 compile_condition( parse
->right
, c
, 1, label
);
2388 int t
= compile_new_label( c
);
2389 compile_condition( parse
->left
, c
, 1, t
);
2390 compile_condition( parse
->right
, c
, 0, label
);
2391 compile_set_label( c
, t
);
2396 compile_condition( parse
->left
, c
, !branch_true
, label
);
2401 static void adjust_result( compiler
* c
, int actual_location
,
2402 int desired_location
)
2404 if ( actual_location
== desired_location
)
2406 else if ( actual_location
== RESULT_STACK
&& desired_location
== RESULT_RETURN
)
2407 compile_emit( c
, INSTR_SET_RESULT
, 0 );
2408 else if ( actual_location
== RESULT_STACK
&& desired_location
== RESULT_NONE
)
2409 compile_emit( c
, INSTR_POP
, 0 );
2410 else if ( actual_location
== RESULT_RETURN
&& desired_location
== RESULT_STACK
)
2411 compile_emit( c
, INSTR_PUSH_RESULT
, 0 );
2412 else if ( actual_location
== RESULT_RETURN
&& desired_location
== RESULT_NONE
)
2414 else if ( actual_location
== RESULT_NONE
&& desired_location
== RESULT_STACK
)
2415 compile_emit( c
, INSTR_PUSH_EMPTY
, 0 );
2416 else if ( actual_location
== RESULT_NONE
&& desired_location
== RESULT_RETURN
)
2418 compile_emit( c
, INSTR_PUSH_EMPTY
, 0 );
2419 compile_emit( c
, INSTR_SET_RESULT
, 0 );
2422 assert( !"invalid result location" );
2425 static char const * parse_type( PARSE
* parse
)
2427 switch ( parse
->type
)
2429 case PARSE_APPEND
: return "append";
2430 case PARSE_EVAL
: return "eval";
2431 case PARSE_RULES
: return "rules";
2432 default: return "unknown";
2436 static void compile_append_chain( PARSE
* parse
, compiler
* c
)
2438 assert( parse
->type
== PARSE_APPEND
);
2439 if ( parse
->left
->type
== PARSE_NULL
)
2440 compile_parse( parse
->right
, c
, RESULT_STACK
);
2443 if ( parse
->left
->type
== PARSE_APPEND
)
2444 compile_append_chain( parse
->left
, c
);
2446 compile_parse( parse
->left
, c
, RESULT_STACK
);
2447 compile_parse( parse
->right
, c
, RESULT_STACK
);
2448 compile_emit( c
, INSTR_PUSH_APPEND
, 0 );
2452 static void compile_emit_debug(compiler
* c
, int line
)
2455 if ( debug_is_debugging() )
2456 compile_emit( c
, INSTR_DEBUG_LINE
, line
);
2460 static void compile_parse( PARSE
* parse
, compiler
* c
, int result_location
)
2462 compile_emit_debug(c
, parse
->line
);
2463 if ( parse
->type
== PARSE_APPEND
)
2465 compile_append_chain( parse
, c
);
2466 adjust_result( c
, RESULT_STACK
, result_location
);
2468 else if ( parse
->type
== PARSE_EVAL
)
2470 /* FIXME: This is only needed because of the bizarre parsing of
2473 if ( parse
->num
== EXPR_EXISTS
)
2474 compile_parse( parse
->left
, c
, result_location
);
2477 int f
= compile_new_label( c
);
2478 int end
= compile_new_label( c
);
2480 out_printf( "%s:%d: Conditional used as list (check operator "
2481 "precedence).\n", object_str( parse
->file
), parse
->line
);
2483 /* Emit the condition */
2484 compile_condition( parse
, c
, 0, f
);
2485 compile_emit( c
, INSTR_PUSH_CONSTANT
, compile_emit_constant( c
,
2487 compile_emit_branch( c
, INSTR_JUMP
, end
);
2488 compile_set_label( c
, f
);
2489 compile_emit( c
, INSTR_PUSH_EMPTY
, 0 );
2490 compile_set_label( c
, end
);
2491 adjust_result( c
, RESULT_STACK
, result_location
);
2494 else if ( parse
->type
== PARSE_FOREACH
)
2496 int var
= compile_emit_constant( c
, parse
->string
);
2497 int top
= compile_new_label( c
);
2498 int end
= compile_new_label( c
);
2499 int continue_
= compile_new_label( c
);
2502 * Evaluate the list.
2504 compile_parse( parse
->left
, c
, RESULT_STACK
);
2506 /* Localize the loop variable */
2509 compile_emit( c
, INSTR_PUSH_EMPTY
, 0 );
2510 compile_emit( c
, INSTR_PUSH_LOCAL
, var
);
2511 compile_emit( c
, INSTR_SWAP
, 1 );
2512 compile_push_cleanup( c
, INSTR_POP_LOCAL
, var
);
2515 compile_emit( c
, INSTR_FOR_INIT
, 0 );
2516 compile_set_label( c
, top
);
2517 compile_emit_branch( c
, INSTR_FOR_LOOP
, end
);
2518 compile_emit_debug( c
, parse
->line
);
2519 compile_emit( c
, INSTR_SET
, var
);
2521 compile_push_break_scope( c
, end
);
2522 compile_push_cleanup( c
, INSTR_FOR_POP
, 0 );
2523 compile_push_continue_scope( c
, continue_
);
2525 /* Run the loop body */
2526 compile_parse( parse
->right
, c
, RESULT_NONE
);
2528 compile_pop_continue_scope( c
);
2529 compile_pop_cleanup( c
);
2530 compile_pop_break_scope( c
);
2532 compile_set_label( c
, continue_
);
2533 compile_emit_branch( c
, INSTR_JUMP
, top
);
2534 compile_set_label( c
, end
);
2538 compile_pop_cleanup( c
);
2539 compile_emit( c
, INSTR_POP_LOCAL
, var
);
2542 adjust_result( c
, RESULT_NONE
, result_location
);
2544 else if ( parse
->type
== PARSE_IF
)
2546 int f
= compile_new_label( c
);
2547 /* Emit the condition */
2548 compile_condition( parse
->left
, c
, 0, f
);
2549 /* Emit the if block */
2550 compile_parse( parse
->right
, c
, result_location
);
2551 if ( parse
->third
->type
!= PARSE_NULL
|| result_location
!= RESULT_NONE
)
2553 /* Emit the else block */
2554 int end
= compile_new_label( c
);
2555 compile_emit_branch( c
, INSTR_JUMP
, end
);
2556 compile_set_label( c
, f
);
2557 compile_parse( parse
->third
, c
, result_location
);
2558 compile_set_label( c
, end
);
2561 compile_set_label( c
, f
);
2564 else if ( parse
->type
== PARSE_WHILE
)
2566 int nested_result
= result_location
== RESULT_NONE
2569 int test
= compile_new_label( c
);
2570 int top
= compile_new_label( c
);
2571 int end
= compile_new_label( c
);
2572 /* Make sure that we return an empty list if the loop runs zero times.
2574 adjust_result( c
, RESULT_NONE
, nested_result
);
2575 /* Jump to the loop test. */
2576 compile_emit_branch( c
, INSTR_JUMP
, test
);
2577 compile_set_label( c
, top
);
2578 /* Emit the loop body. */
2579 compile_push_break_scope( c
, end
);
2580 compile_push_continue_scope( c
, test
);
2581 compile_parse( parse
->right
, c
, nested_result
);
2582 compile_pop_continue_scope( c
);
2583 compile_pop_break_scope( c
);
2584 /* Emit the condition. */
2585 compile_set_label( c
, test
);
2586 compile_condition( parse
->left
, c
, 1, top
);
2587 compile_set_label( c
, end
);
2589 adjust_result( c
, nested_result
, result_location
);
2591 else if ( parse
->type
== PARSE_INCLUDE
)
2593 compile_parse( parse
->left
, c
, RESULT_STACK
);
2594 compile_emit( c
, INSTR_INCLUDE
, 0 );
2595 compile_emit( c
, INSTR_BIND_MODULE_VARIABLES
, 0 );
2596 adjust_result( c
, RESULT_NONE
, result_location
);
2598 else if ( parse
->type
== PARSE_MODULE
)
2600 int const nested_result
= result_location
== RESULT_NONE
2603 compile_parse( parse
->left
, c
, RESULT_STACK
);
2604 compile_emit( c
, INSTR_PUSH_MODULE
, 0 );
2605 compile_push_cleanup( c
, INSTR_POP_MODULE
, 0 );
2606 compile_parse( parse
->right
, c
, nested_result
);
2607 compile_pop_cleanup( c
);
2608 compile_emit( c
, INSTR_POP_MODULE
, 0 );
2609 adjust_result( c
, nested_result
, result_location
);
2611 else if ( parse
->type
== PARSE_CLASS
)
2613 /* Evaluate the class name. */
2614 compile_parse( parse
->left
->right
, c
, RESULT_STACK
);
2615 /* Evaluate the base classes. */
2616 if ( parse
->left
->left
)
2617 compile_parse( parse
->left
->left
->right
, c
, RESULT_STACK
);
2619 compile_emit( c
, INSTR_PUSH_EMPTY
, 0 );
2620 compile_emit( c
, INSTR_CLASS
, 0 );
2621 compile_push_cleanup( c
, INSTR_POP_MODULE
, 0 );
2622 compile_parse( parse
->right
, c
, RESULT_NONE
);
2623 compile_emit( c
, INSTR_BIND_MODULE_VARIABLES
, 0 );
2624 compile_pop_cleanup( c
);
2625 compile_emit( c
, INSTR_POP_MODULE
, 0 );
2627 adjust_result( c
, RESULT_NONE
, result_location
);
2629 else if ( parse
->type
== PARSE_LIST
)
2631 OBJECT
* const o
= parse
->string
;
2632 char const * s
= object_str( o
);
2633 VAR_PARSE_GROUP
* group
;
2634 current_file
= object_str( parse
->file
);
2635 current_line
= parse
->line
;
2636 group
= parse_expansion( &s
);
2637 var_parse_group_compile( group
, c
);
2638 var_parse_group_free( group
);
2639 adjust_result( c
, RESULT_STACK
, result_location
);
2641 else if ( parse
->type
== PARSE_LOCAL
)
2643 int nested_result
= result_location
== RESULT_NONE
2646 /* This should be left recursive group of compile_appends. */
2647 PARSE
* vars
= parse
->left
;
2649 /* Special case an empty list of vars */
2650 if ( vars
->type
== PARSE_NULL
)
2652 compile_parse( parse
->right
, c
, RESULT_NONE
);
2653 compile_parse( parse
->third
, c
, result_location
);
2654 nested_result
= result_location
;
2656 /* Check whether there is exactly one variable with a constant name. */
2657 else if ( vars
->left
->type
== PARSE_NULL
&&
2658 vars
->right
->type
== PARSE_LIST
)
2660 char const * s
= object_str( vars
->right
->string
);
2661 VAR_PARSE_GROUP
* group
;
2662 current_file
= object_str( parse
->file
);
2663 current_line
= parse
->line
;
2664 group
= parse_expansion( &s
);
2665 if ( group
->elems
->size
== 1 && dynamic_array_at( VAR_PARSE
*,
2666 group
->elems
, 0 )->type
== VAR_PARSE_TYPE_STRING
)
2668 int const name
= compile_emit_constant( c
, (
2669 (VAR_PARSE_STRING
*)dynamic_array_at( VAR_PARSE
*,
2670 group
->elems
, 0 ) )->s
);
2671 var_parse_group_free( group
);
2672 compile_parse( parse
->right
, c
, RESULT_STACK
);
2673 compile_emit_debug(c
, parse
->line
);
2674 compile_emit( c
, INSTR_PUSH_LOCAL
, name
);
2675 compile_push_cleanup( c
, INSTR_POP_LOCAL
, name
);
2676 compile_parse( parse
->third
, c
, nested_result
);
2677 compile_pop_cleanup( c
);
2678 compile_emit( c
, INSTR_POP_LOCAL
, name
);
2682 var_parse_group_compile( group
, c
);
2683 var_parse_group_free( group
);
2684 compile_parse( parse
->right
, c
, RESULT_STACK
);
2685 compile_emit_debug(c
, parse
->line
);
2686 compile_emit( c
, INSTR_PUSH_LOCAL_GROUP
, 0 );
2687 compile_push_cleanup( c
, INSTR_POP_LOCAL_GROUP
, 0 );
2688 compile_parse( parse
->third
, c
, nested_result
);
2689 compile_pop_cleanup( c
);
2690 compile_emit( c
, INSTR_POP_LOCAL_GROUP
, 0 );
2695 compile_parse( parse
->left
, c
, RESULT_STACK
);
2696 compile_parse( parse
->right
, c
, RESULT_STACK
);
2697 compile_emit_debug(c
, parse
->line
);
2698 compile_emit( c
, INSTR_PUSH_LOCAL_GROUP
, 0 );
2699 compile_push_cleanup( c
, INSTR_POP_LOCAL_GROUP
, 0 );
2700 compile_parse( parse
->third
, c
, nested_result
);
2701 compile_pop_cleanup( c
);
2702 compile_emit( c
, INSTR_POP_LOCAL_GROUP
, 0 );
2704 adjust_result( c
, nested_result
, result_location
);
2706 else if ( parse
->type
== PARSE_ON
)
2708 if ( parse
->right
->type
== PARSE_APPEND
&&
2709 parse
->right
->left
->type
== PARSE_NULL
&&
2710 parse
->right
->right
->type
== PARSE_LIST
)
2712 /* [ on $(target) return $(variable) ] */
2713 PARSE
* value
= parse
->right
->right
;
2714 OBJECT
* const o
= value
->string
;
2715 char const * s
= object_str( o
);
2716 VAR_PARSE_GROUP
* group
;
2717 OBJECT
* varname
= 0;
2718 current_file
= object_str( value
->file
);
2719 current_line
= value
->line
;
2720 group
= parse_expansion( &s
);
2721 if ( group
->elems
->size
== 1 )
2723 VAR_PARSE
* one
= dynamic_array_at( VAR_PARSE
*, group
->elems
, 0 );
2724 if ( one
->type
== VAR_PARSE_TYPE_VAR
)
2726 VAR_PARSE_VAR
* var
= ( VAR_PARSE_VAR
* )one
;
2727 if ( var
->modifiers
->size
== 0 && !var
->subscript
&& var
->name
->elems
->size
== 1 )
2729 VAR_PARSE
* name
= dynamic_array_at( VAR_PARSE
*, var
->name
->elems
, 0 );
2730 if ( name
->type
== VAR_PARSE_TYPE_STRING
)
2732 varname
= ( ( VAR_PARSE_STRING
* )name
)->s
;
2739 /* We have one variable with a fixed name and no modifiers. */
2740 compile_parse( parse
->left
, c
, RESULT_STACK
);
2741 compile_emit( c
, INSTR_GET_ON
, compile_emit_constant( c
, varname
) );
2745 /* Too complex. Fall back on push/pop. */
2746 int end
= compile_new_label( c
);
2747 compile_parse( parse
->left
, c
, RESULT_STACK
);
2748 compile_emit_branch( c
, INSTR_PUSH_ON
, end
);
2749 compile_push_cleanup( c
, INSTR_POP_ON
, 0 );
2750 var_parse_group_compile( group
, c
);
2751 compile_pop_cleanup( c
);
2752 compile_emit( c
, INSTR_POP_ON
, 0 );
2753 compile_set_label( c
, end
);
2755 var_parse_group_free( group
);
2759 int end
= compile_new_label( c
);
2760 compile_parse( parse
->left
, c
, RESULT_STACK
);
2761 compile_emit_branch( c
, INSTR_PUSH_ON
, end
);
2762 compile_push_cleanup( c
, INSTR_POP_ON
, 0 );
2763 compile_parse( parse
->right
, c
, RESULT_STACK
);
2764 compile_pop_cleanup( c
);
2765 compile_emit( c
, INSTR_POP_ON
, 0 );
2766 compile_set_label( c
, end
);
2768 adjust_result( c
, RESULT_STACK
, result_location
);
2770 else if ( parse
->type
== PARSE_RULE
)
2774 VAR_PARSE_GROUP
* group
;
2775 char const * s
= object_str( parse
->string
);
2777 if ( parse
->left
->left
|| parse
->left
->right
->type
!= PARSE_NULL
)
2778 for ( p
= parse
->left
; p
; p
= p
->left
)
2780 compile_parse( p
->right
, c
, RESULT_STACK
);
2784 current_file
= object_str( parse
->file
);
2785 current_line
= parse
->line
;
2786 group
= parse_expansion( &s
);
2788 if ( group
->elems
->size
== 2 &&
2789 dynamic_array_at( VAR_PARSE
*, group
->elems
, 0 )->type
== VAR_PARSE_TYPE_VAR
&&
2790 dynamic_array_at( VAR_PARSE
*, group
->elems
, 1 )->type
== VAR_PARSE_TYPE_STRING
&&
2791 ( object_str( ( (VAR_PARSE_STRING
*)dynamic_array_at( VAR_PARSE
*, group
->elems
, 1 ) )->s
)[ 0 ] == '.' ) )
2793 VAR_PARSE_STRING
* access
= (VAR_PARSE_STRING
*)dynamic_array_at( VAR_PARSE
*, group
->elems
, 1 );
2794 OBJECT
* member
= object_new( object_str( access
->s
) + 1 );
2795 /* Emit the object */
2796 var_parse_var_compile( (VAR_PARSE_VAR
*)dynamic_array_at( VAR_PARSE
*, group
->elems
, 0 ), c
);
2797 var_parse_group_free( group
);
2798 compile_emit( c
, INSTR_CALL_MEMBER_RULE
, n
);
2799 compile_emit( c
, compile_emit_constant( c
, member
), parse
->line
);
2800 object_free( member
);
2804 var_parse_group_compile( group
, c
);
2805 var_parse_group_free( group
);
2806 compile_emit( c
, INSTR_CALL_RULE
, n
);
2807 compile_emit( c
, compile_emit_constant( c
, parse
->string
), parse
->line
);
2810 adjust_result( c
, RESULT_STACK
, result_location
);
2812 else if ( parse
->type
== PARSE_RULES
)
2814 do compile_parse( parse
->left
, c
, RESULT_NONE
);
2815 while ( ( parse
= parse
->right
)->type
== PARSE_RULES
);
2816 compile_parse( parse
, c
, result_location
);
2818 else if ( parse
->type
== PARSE_SET
)
2820 PARSE
* vars
= parse
->left
;
2821 unsigned int op_code
;
2822 unsigned int op_code_group
;
2824 switch ( parse
->num
)
2826 case ASSIGN_APPEND
: op_code
= INSTR_APPEND
; op_code_group
= INSTR_APPEND_GROUP
; break;
2827 case ASSIGN_DEFAULT
: op_code
= INSTR_DEFAULT
; op_code_group
= INSTR_DEFAULT_GROUP
; break;
2828 default: op_code
= INSTR_SET
; op_code_group
= INSTR_SET_GROUP
; break;
2831 /* Check whether there is exactly one variable with a constant name. */
2832 if ( vars
->type
== PARSE_LIST
)
2834 char const * s
= object_str( vars
->string
);
2835 VAR_PARSE_GROUP
* group
;
2836 current_file
= object_str( parse
->file
);
2837 current_line
= parse
->line
;
2838 group
= parse_expansion( &s
);
2839 if ( group
->elems
->size
== 1 && dynamic_array_at( VAR_PARSE
*,
2840 group
->elems
, 0 )->type
== VAR_PARSE_TYPE_STRING
)
2842 int const name
= compile_emit_constant( c
, (
2843 (VAR_PARSE_STRING
*)dynamic_array_at( VAR_PARSE
*,
2844 group
->elems
, 0 ) )->s
);
2845 var_parse_group_free( group
);
2846 compile_parse( parse
->right
, c
, RESULT_STACK
);
2847 compile_emit_debug(c
, parse
->line
);
2848 if ( result_location
!= RESULT_NONE
)
2850 compile_emit( c
, INSTR_SET_RESULT
, 1 );
2852 compile_emit( c
, op_code
, name
);
2856 var_parse_group_compile( group
, c
);
2857 var_parse_group_free( group
);
2858 compile_parse( parse
->right
, c
, RESULT_STACK
);
2859 compile_emit_debug(c
, parse
->line
);
2860 if ( result_location
!= RESULT_NONE
)
2862 compile_emit( c
, INSTR_SET_RESULT
, 1 );
2864 compile_emit( c
, op_code_group
, 0 );
2869 compile_parse( parse
->left
, c
, RESULT_STACK
);
2870 compile_parse( parse
->right
, c
, RESULT_STACK
);
2871 compile_emit_debug(c
, parse
->line
);
2872 if ( result_location
!= RESULT_NONE
)
2874 compile_emit( c
, INSTR_SET_RESULT
, 1 );
2876 compile_emit( c
, op_code_group
, 0 );
2878 if ( result_location
!= RESULT_NONE
)
2880 adjust_result( c
, RESULT_RETURN
, result_location
);
2883 else if ( parse
->type
== PARSE_SETCOMP
)
2886 struct arg_list
* args
= arg_list_compile( parse
->right
, &n_args
);
2887 int const rule_id
= compile_emit_rule( c
, parse
->string
, parse
->left
,
2888 n_args
, args
, parse
->num
);
2889 compile_emit( c
, INSTR_RULE
, rule_id
);
2890 adjust_result( c
, RESULT_NONE
, result_location
);
2892 else if ( parse
->type
== PARSE_SETEXEC
)
2894 int const actions_id
= compile_emit_actions( c
, parse
);
2895 compile_parse( parse
->left
, c
, RESULT_STACK
);
2896 compile_emit( c
, INSTR_ACTIONS
, actions_id
);
2897 adjust_result( c
, RESULT_NONE
, result_location
);
2899 else if ( parse
->type
== PARSE_SETTINGS
)
2901 compile_parse( parse
->left
, c
, RESULT_STACK
);
2902 compile_parse( parse
->third
, c
, RESULT_STACK
);
2903 compile_parse( parse
->right
, c
, RESULT_STACK
);
2905 compile_emit_debug(c
, parse
->line
);
2906 switch ( parse
->num
)
2908 case ASSIGN_APPEND
: compile_emit( c
, INSTR_APPEND_ON
, 0 ); break;
2909 case ASSIGN_DEFAULT
: compile_emit( c
, INSTR_DEFAULT_ON
, 0 ); break;
2910 default: compile_emit( c
, INSTR_SET_ON
, 0 ); break;
2913 adjust_result( c
, RESULT_STACK
, result_location
);
2915 else if ( parse
->type
== PARSE_SWITCH
)
2917 int const switch_end
= compile_new_label( c
);
2918 compile_parse( parse
->left
, c
, RESULT_STACK
);
2920 for ( parse
= parse
->right
; parse
; parse
= parse
->right
)
2922 int const id
= compile_emit_constant( c
, parse
->left
->string
);
2923 int const next_case
= compile_new_label( c
);
2924 compile_emit( c
, INSTR_PUSH_CONSTANT
, id
);
2925 compile_emit_branch( c
, INSTR_JUMP_NOT_GLOB
, next_case
);
2926 compile_parse( parse
->left
->left
, c
, result_location
);
2927 compile_emit_branch( c
, INSTR_JUMP
, switch_end
);
2928 compile_set_label( c
, next_case
);
2930 compile_emit( c
, INSTR_POP
, 0 );
2931 adjust_result( c
, RESULT_NONE
, result_location
);
2932 compile_set_label( c
, switch_end
);
2934 else if ( parse
->type
== PARSE_RETURN
)
2936 compile_parse( parse
->left
, c
, RESULT_RETURN
);
2937 compile_emit_cleanups( c
, 0 );
2938 compile_emit( c
, INSTR_RETURN
, 0 ); /* 0 for return in the middle of a function. */
2940 else if ( parse
->type
== PARSE_BREAK
)
2942 compile_emit_loop_jump( c
, LOOP_INFO_BREAK
);
2944 else if ( parse
->type
== PARSE_CONTINUE
)
2946 compile_emit_loop_jump( c
, LOOP_INFO_CONTINUE
);
2948 else if ( parse
->type
== PARSE_NULL
)
2949 adjust_result( c
, RESULT_NONE
, result_location
);
2951 assert( !"unknown PARSE type." );
2954 OBJECT
* function_rulename( FUNCTION
* function
)
2956 return function
->rulename
;
2959 void function_set_rulename( FUNCTION
* function
, OBJECT
* rulename
)
2961 function
->rulename
= rulename
;
2964 void function_location( FUNCTION
* function_
, OBJECT
* * file
, int * line
)
2966 if ( function_
->type
== FUNCTION_BUILTIN
)
2968 *file
= constant_builtin
;
2972 if ( function_
->type
== FUNCTION_PYTHON
)
2974 *file
= constant_builtin
;
2980 JAM_FUNCTION
* function
= (JAM_FUNCTION
*)function_
;
2981 assert( function_
->type
== FUNCTION_JAM
);
2982 *file
= function
->file
;
2983 *line
= function
->line
;
2987 static struct arg_list
* arg_list_compile_builtin( char const * * args
,
2988 int * num_arguments
);
2990 FUNCTION
* function_builtin( LIST
* ( * func
)( FRAME
* frame
, int flags
),
2991 int flags
, char const * * args
)
2993 BUILTIN_FUNCTION
* result
= (BUILTIN_FUNCTION
*)BJAM_MALLOC( sizeof( BUILTIN_FUNCTION
) );
2994 result
->base
.type
= FUNCTION_BUILTIN
;
2995 result
->base
.reference_count
= 1;
2996 result
->base
.rulename
= 0;
2997 result
->base
.formal_arguments
= arg_list_compile_builtin( args
,
2998 &result
->base
.num_formal_arguments
);
2999 result
->func
= func
;
3000 result
->flags
= flags
;
3001 return (FUNCTION
*)result
;
3004 FUNCTION
* function_compile( PARSE
* parse
)
3007 JAM_FUNCTION
* result
;
3009 compile_parse( parse
, c
, RESULT_RETURN
);
3010 compile_emit( c
, INSTR_RETURN
, 1 );
3011 result
= compile_to_function( c
);
3013 result
->file
= object_copy( parse
->file
);
3014 result
->line
= parse
->line
;
3015 return (FUNCTION
*)result
;
3018 FUNCTION
* function_compile_actions( char const * actions
, OBJECT
* file
,
3022 JAM_FUNCTION
* result
;
3023 VAR_PARSE_ACTIONS
* parse
;
3024 current_file
= object_str( file
);
3025 current_line
= line
;
3026 parse
= parse_actions( actions
);
3028 var_parse_actions_compile( parse
, c
);
3029 var_parse_actions_free( parse
);
3030 compile_emit( c
, INSTR_RETURN
, 1 );
3031 result
= compile_to_function( c
);
3033 result
->file
= object_copy( file
);
3034 result
->line
= line
;
3035 return (FUNCTION
*)result
;
3038 static void argument_list_print( struct arg_list
* args
, int num_args
);
3041 /* Define delimiters for type check elements in argument lists (and return type
3042 * specifications, eventually).
3044 # define TYPE_OPEN_DELIM '['
3045 # define TYPE_CLOSE_DELIM ']'
3048 * is_type_name() - true iff the given string represents a type check
3052 int is_type_name( char const * s
)
3054 return s
[ 0 ] == TYPE_OPEN_DELIM
&& s
[ strlen( s
) - 1 ] ==
3058 static void argument_error( char const * message
, FUNCTION
* procedure
,
3059 FRAME
* frame
, OBJECT
* arg
)
3061 extern void print_source_line( FRAME
* );
3062 LOL
* actual
= frame
->args
;
3063 backtrace_line( frame
->prev
);
3064 out_printf( "*** argument error\n* rule %s ( ", frame
->rulename
);
3065 argument_list_print( procedure
->formal_arguments
,
3066 procedure
->num_formal_arguments
);
3067 out_printf( " )\n* called with: ( " );
3068 lol_print( actual
);
3069 out_printf( " )\n* %s %s\n", message
, arg
? object_str ( arg
) : "" );
3070 function_location( procedure
, &frame
->file
, &frame
->line
);
3071 print_source_line( frame
);
3072 out_printf( "see definition of rule '%s' being called\n", frame
->rulename
);
3073 backtrace( frame
->prev
);
3077 static void type_check_range( OBJECT
* type_name
, LISTITER iter
, LISTITER end
,
3078 FRAME
* caller
, FUNCTION
* called
, OBJECT
* arg_name
)
3080 static module_t
* typecheck
= 0;
3082 /* If nothing to check, bail now. */
3083 if ( iter
== end
|| !type_name
)
3087 typecheck
= bindmodule( constant_typecheck
);
3089 /* If the checking rule can not be found, also bail. */
3090 if ( !typecheck
->rules
|| !hash_find( typecheck
->rules
, type_name
) )
3093 for ( ; iter
!= end
; iter
= list_next( iter
) )
3097 frame_init( frame
);
3098 frame
->module
= typecheck
;
3099 frame
->prev
= caller
;
3100 frame
->prev_user
= caller
->module
->user_module
3102 : caller
->prev_user
;
3104 /* Prepare the argument list */
3105 lol_add( frame
->args
, list_new( object_copy( list_item( iter
) ) ) );
3106 error
= evaluate_rule( bindrule( type_name
, frame
->module
), type_name
, frame
);
3108 if ( !list_empty( error
) )
3109 argument_error( object_str( list_front( error
) ), called
, caller
,
3112 frame_free( frame
);
3116 static void type_check( OBJECT
* type_name
, LIST
* values
, FRAME
* caller
,
3117 FUNCTION
* called
, OBJECT
* arg_name
)
3119 type_check_range( type_name
, list_begin( values
), list_end( values
),
3120 caller
, called
, arg_name
);
3123 void argument_list_check( struct arg_list
* formal
, int formal_count
,
3124 FUNCTION
* function
, FRAME
* frame
)
3126 LOL
* all_actual
= frame
->args
;
3129 for ( i
= 0; i
< formal_count
; ++i
)
3131 LIST
* actual
= lol_get( all_actual
, i
);
3132 LISTITER actual_iter
= list_begin( actual
);
3133 LISTITER
const actual_end
= list_end( actual
);
3135 for ( j
= 0; j
< formal
[ i
].size
; ++j
)
3137 struct argument
* formal_arg
= &formal
[ i
].args
[ j
];
3140 switch ( formal_arg
->flags
)
3143 if ( actual_iter
== actual_end
)
3144 argument_error( "missing argument", function
, frame
,
3145 formal_arg
->arg_name
);
3146 type_check_range( formal_arg
->type_name
, actual_iter
,
3147 list_next( actual_iter
), frame
, function
,
3148 formal_arg
->arg_name
);
3149 actual_iter
= list_next( actual_iter
);
3152 if ( actual_iter
== actual_end
)
3156 type_check_range( formal_arg
->type_name
, actual_iter
,
3157 list_next( actual_iter
), frame
, function
,
3158 formal_arg
->arg_name
);
3159 actual_iter
= list_next( actual_iter
);
3163 if ( actual_iter
== actual_end
)
3164 argument_error( "missing argument", function
, frame
,
3165 formal_arg
->arg_name
);
3168 type_check_range( formal_arg
->type_name
, actual_iter
,
3169 actual_end
, frame
, function
, formal_arg
->arg_name
);
3170 actual_iter
= actual_end
;
3177 if ( actual_iter
!= actual_end
)
3178 argument_error( "extra argument", function
, frame
, list_item(
3182 for ( ; i
< all_actual
->count
; ++i
)
3184 LIST
* actual
= lol_get( all_actual
, i
);
3185 if ( !list_empty( actual
) )
3186 argument_error( "extra argument", function
, frame
, list_front(
3191 void argument_list_push( struct arg_list
* formal
, int formal_count
,
3192 FUNCTION
* function
, FRAME
* frame
, STACK
* s
)
3194 LOL
* all_actual
= frame
->args
;
3197 for ( i
= 0; i
< formal_count
; ++i
)
3199 LIST
* actual
= lol_get( all_actual
, i
);
3200 LISTITER actual_iter
= list_begin( actual
);
3201 LISTITER
const actual_end
= list_end( actual
);
3203 for ( j
= 0; j
< formal
[ i
].size
; ++j
)
3205 struct argument
* formal_arg
= &formal
[ i
].args
[ j
];
3208 switch ( formal_arg
->flags
)
3211 if ( actual_iter
== actual_end
)
3212 argument_error( "missing argument", function
, frame
,
3213 formal_arg
->arg_name
);
3214 value
= list_new( object_copy( list_item( actual_iter
) ) );
3215 actual_iter
= list_next( actual_iter
);
3218 if ( actual_iter
== actual_end
)
3222 value
= list_new( object_copy( list_item( actual_iter
) ) );
3223 actual_iter
= list_next( actual_iter
);
3227 if ( actual_iter
== actual_end
)
3228 argument_error( "missing argument", function
, frame
,
3229 formal_arg
->arg_name
);
3232 value
= list_copy_range( actual
, actual_iter
, actual_end
);
3233 actual_iter
= actual_end
;
3239 type_check( formal_arg
->type_name
, value
, frame
, function
,
3240 formal_arg
->arg_name
);
3242 if ( formal_arg
->index
!= -1 )
3244 LIST
* * const old
= &frame
->module
->fixed_variables
[
3245 formal_arg
->index
];
3246 stack_push( s
, *old
);
3250 stack_push( s
, var_swap( frame
->module
, formal_arg
->arg_name
,
3254 if ( actual_iter
!= actual_end
)
3255 argument_error( "extra argument", function
, frame
, list_item(
3259 for ( ; i
< all_actual
->count
; ++i
)
3261 LIST
* const actual
= lol_get( all_actual
, i
);
3262 if ( !list_empty( actual
) )
3263 argument_error( "extra argument", function
, frame
, list_front(
3268 void argument_list_pop( struct arg_list
* formal
, int formal_count
,
3269 FRAME
* frame
, STACK
* s
)
3272 for ( i
= formal_count
- 1; i
>= 0; --i
)
3275 for ( j
= formal
[ i
].size
- 1; j
>= 0 ; --j
)
3277 struct argument
* formal_arg
= &formal
[ i
].args
[ j
];
3279 if ( formal_arg
->flags
== ARG_VARIADIC
)
3281 if ( formal_arg
->index
!= -1 )
3283 LIST
* const old
= stack_pop( s
);
3284 LIST
* * const pos
= &frame
->module
->fixed_variables
[
3285 formal_arg
->index
];
3290 var_set( frame
->module
, formal_arg
->arg_name
, stack_pop( s
),
3297 struct argument_compiler
3299 struct dynamic_array args
[ 1 ];
3300 struct argument arg
;
3302 #define ARGUMENT_COMPILER_START 0
3303 #define ARGUMENT_COMPILER_FOUND_TYPE 1
3304 #define ARGUMENT_COMPILER_FOUND_OBJECT 2
3305 #define ARGUMENT_COMPILER_DONE 3
3309 static void argument_compiler_init( struct argument_compiler
* c
)
3311 dynamic_array_init( c
->args
);
3312 c
->state
= ARGUMENT_COMPILER_START
;
3315 static void argument_compiler_free( struct argument_compiler
* c
)
3317 dynamic_array_free( c
->args
);
3320 static void argument_compiler_add( struct argument_compiler
* c
, OBJECT
* arg
,
3321 OBJECT
* file
, int line
)
3325 case ARGUMENT_COMPILER_FOUND_OBJECT
:
3327 if ( object_equal( arg
, constant_question_mark
) )
3329 c
->arg
.flags
= ARG_OPTIONAL
;
3331 else if ( object_equal( arg
, constant_plus
) )
3333 c
->arg
.flags
= ARG_PLUS
;
3335 else if ( object_equal( arg
, constant_star
) )
3337 c
->arg
.flags
= ARG_STAR
;
3340 dynamic_array_push( c
->args
, c
->arg
);
3341 c
->state
= ARGUMENT_COMPILER_START
;
3343 if ( c
->arg
.flags
!= ARG_ONE
)
3347 case ARGUMENT_COMPILER_START
:
3349 c
->arg
.type_name
= 0;
3351 c
->arg
.flags
= ARG_ONE
;
3353 if ( is_type_name( object_str( arg
) ) )
3355 c
->arg
.type_name
= object_copy( arg
);
3356 c
->state
= ARGUMENT_COMPILER_FOUND_TYPE
;
3361 case ARGUMENT_COMPILER_FOUND_TYPE
:
3363 if ( is_type_name( object_str( arg
) ) )
3365 err_printf( "%s:%d: missing argument name before type name: %s\n",
3366 object_str( file
), line
, object_str( arg
) );
3370 c
->arg
.arg_name
= object_copy( arg
);
3371 if ( object_equal( arg
, constant_star
) )
3373 c
->arg
.flags
= ARG_VARIADIC
;
3374 dynamic_array_push( c
->args
, c
->arg
);
3375 c
->state
= ARGUMENT_COMPILER_DONE
;
3379 c
->state
= ARGUMENT_COMPILER_FOUND_OBJECT
;
3383 case ARGUMENT_COMPILER_DONE
:
3388 static void argument_compiler_recurse( struct argument_compiler
* c
,
3391 if ( parse
->type
== PARSE_APPEND
)
3393 argument_compiler_recurse( c
, parse
->left
);
3394 argument_compiler_recurse( c
, parse
->right
);
3396 else if ( parse
->type
!= PARSE_NULL
)
3398 assert( parse
->type
== PARSE_LIST
);
3399 argument_compiler_add( c
, parse
->string
, parse
->file
, parse
->line
);
3403 static struct arg_list
arg_compile_impl( struct argument_compiler
* c
,
3404 OBJECT
* file
, int line
)
3406 struct arg_list result
;
3409 case ARGUMENT_COMPILER_START
:
3410 case ARGUMENT_COMPILER_DONE
:
3412 case ARGUMENT_COMPILER_FOUND_TYPE
:
3413 err_printf( "%s:%d: missing argument name after type name: %s\n",
3414 object_str( file
), line
, object_str( c
->arg
.type_name
) );
3416 case ARGUMENT_COMPILER_FOUND_OBJECT
:
3417 dynamic_array_push( c
->args
, c
->arg
);
3420 result
.size
= c
->args
->size
;
3421 result
.args
= (struct argument
*)BJAM_MALLOC( c
->args
->size
* sizeof( struct argument
) );
3422 if ( c
->args
->size
!= 0 )
3423 memcpy( result
.args
, c
->args
->data
,
3424 c
->args
->size
* sizeof( struct argument
) );
3428 static struct arg_list
arg_compile( PARSE
* parse
)
3430 struct argument_compiler c
[ 1 ];
3431 struct arg_list result
;
3432 argument_compiler_init( c
);
3433 argument_compiler_recurse( c
, parse
);
3434 result
= arg_compile_impl( c
, parse
->file
, parse
->line
);
3435 argument_compiler_free( c
);
3439 struct argument_list_compiler
3441 struct dynamic_array args
[ 1 ];
3444 static void argument_list_compiler_init( struct argument_list_compiler
* c
)
3446 dynamic_array_init( c
->args
);
3449 static void argument_list_compiler_free( struct argument_list_compiler
* c
)
3451 dynamic_array_free( c
->args
);
3454 static void argument_list_compiler_add( struct argument_list_compiler
* c
,
3457 struct arg_list args
= arg_compile( parse
);
3458 dynamic_array_push( c
->args
, args
);
3461 static void argument_list_compiler_recurse( struct argument_list_compiler
* c
,
3466 argument_list_compiler_add( c
, parse
->right
);
3467 argument_list_compiler_recurse( c
, parse
->left
);
3471 static struct arg_list
* arg_list_compile( PARSE
* parse
, int * num_arguments
)
3475 struct argument_list_compiler c
[ 1 ];
3476 struct arg_list
* result
;
3477 argument_list_compiler_init( c
);
3478 argument_list_compiler_recurse( c
, parse
);
3479 *num_arguments
= c
->args
->size
;
3480 result
= (struct arg_list
*)BJAM_MALLOC( c
->args
->size
* sizeof( struct arg_list
) );
3481 memcpy( result
, c
->args
->data
, c
->args
->size
* sizeof( struct arg_list
)
3483 argument_list_compiler_free( c
);
3490 static struct arg_list
* arg_list_compile_builtin( char const * * args
,
3491 int * num_arguments
)
3495 struct argument_list_compiler c
[ 1 ];
3496 struct arg_list
* result
;
3497 argument_list_compiler_init( c
);
3500 struct argument_compiler arg_comp
[ 1 ];
3501 struct arg_list arg
;
3502 argument_compiler_init( arg_comp
);
3503 for ( ; *args
; ++args
)
3506 if ( strcmp( *args
, ":" ) == 0 )
3511 token
= object_new( *args
);
3512 argument_compiler_add( arg_comp
, token
, constant_builtin
, -1 );
3513 object_free( token
);
3515 arg
= arg_compile_impl( arg_comp
, constant_builtin
, -1 );
3516 dynamic_array_push( c
->args
, arg
);
3517 argument_compiler_free( arg_comp
);
3519 *num_arguments
= c
->args
->size
;
3520 result
= (struct arg_list
*)BJAM_MALLOC( c
->args
->size
* sizeof( struct arg_list
) );
3521 if ( c
->args
->size
!= 0 )
3522 memcpy( result
, c
->args
->data
,
3523 c
->args
->size
* sizeof( struct arg_list
) );
3524 argument_list_compiler_free( c
);
3531 static void argument_list_print( struct arg_list
* args
, int num_args
)
3536 for ( i
= 0; i
< num_args
; ++i
)
3539 if ( i
) out_printf( " : " );
3540 for ( j
= 0; j
< args
[ i
].size
; ++j
)
3542 struct argument
* formal_arg
= &args
[ i
].args
[ j
];
3543 if ( j
) out_printf( " " );
3544 if ( formal_arg
->type_name
)
3545 out_printf( "%s ", object_str( formal_arg
->type_name
) );
3546 out_printf( "%s", object_str( formal_arg
->arg_name
) );
3547 switch ( formal_arg
->flags
)
3549 case ARG_OPTIONAL
: out_printf( " ?" ); break;
3550 case ARG_PLUS
: out_printf( " +" ); break;
3551 case ARG_STAR
: out_printf( " *" ); break;
3559 struct arg_list
* argument_list_bind_variables( struct arg_list
* formal
,
3560 int formal_count
, module_t
* module
, int * counter
)
3564 struct arg_list
* result
= (struct arg_list
*)BJAM_MALLOC( sizeof(
3565 struct arg_list
) * formal_count
);
3568 for ( i
= 0; i
< formal_count
; ++i
)
3571 struct argument
* args
= (struct argument
*)BJAM_MALLOC( sizeof(
3572 struct argument
) * formal
[ i
].size
);
3573 for ( j
= 0; j
< formal
[ i
].size
; ++j
)
3575 args
[ j
] = formal
[ i
].args
[ j
];
3576 if ( args
[ j
].type_name
)
3577 args
[ j
].type_name
= object_copy( args
[ j
].type_name
);
3578 args
[ j
].arg_name
= object_copy( args
[ j
].arg_name
);
3579 if ( args
[ j
].flags
!= ARG_VARIADIC
)
3580 args
[ j
].index
= module_add_fixed_var( module
,
3581 args
[ j
].arg_name
, counter
);
3583 result
[ i
].args
= args
;
3584 result
[ i
].size
= formal
[ i
].size
;
3593 void argument_list_free( struct arg_list
* args
, int args_count
)
3596 for ( i
= 0; i
< args_count
; ++i
)
3599 for ( j
= 0; j
< args
[ i
].size
; ++j
)
3601 if ( args
[ i
].args
[ j
].type_name
)
3602 object_free( args
[ i
].args
[ j
].type_name
);
3603 object_free( args
[ i
].args
[ j
].arg_name
);
3605 BJAM_FREE( args
[ i
].args
);
3611 FUNCTION
* function_unbind_variables( FUNCTION
* f
)
3613 if ( f
->type
== FUNCTION_JAM
)
3615 JAM_FUNCTION
* const func
= (JAM_FUNCTION
*)f
;
3616 return func
->generic
? func
->generic
: f
;
3619 if ( f
->type
== FUNCTION_PYTHON
)
3622 assert( f
->type
== FUNCTION_BUILTIN
);
3626 FUNCTION
* function_bind_variables( FUNCTION
* f
, module_t
* module
,
3629 if ( f
->type
== FUNCTION_BUILTIN
)
3632 if ( f
->type
== FUNCTION_PYTHON
)
3636 JAM_FUNCTION
* func
= (JAM_FUNCTION
*)f
;
3637 JAM_FUNCTION
* new_func
= (JAM_FUNCTION
*)BJAM_MALLOC( sizeof( JAM_FUNCTION
) );
3640 assert( f
->type
== FUNCTION_JAM
);
3641 memcpy( new_func
, func
, sizeof( JAM_FUNCTION
) );
3642 new_func
->base
.reference_count
= 1;
3643 new_func
->base
.formal_arguments
= argument_list_bind_variables(
3644 f
->formal_arguments
, f
->num_formal_arguments
, module
, counter
);
3645 new_func
->code
= (instruction
*)BJAM_MALLOC( func
->code_size
* sizeof( instruction
) );
3646 memcpy( new_func
->code
, func
->code
, func
->code_size
* sizeof(
3648 new_func
->generic
= (FUNCTION
*)func
;
3650 for ( i
= 0; ; ++i
)
3654 code
= func
->code
+ i
;
3655 switch ( code
->op_code
)
3657 case INSTR_PUSH_VAR
: op_code
= INSTR_PUSH_VAR_FIXED
; break;
3658 case INSTR_PUSH_LOCAL
: op_code
= INSTR_PUSH_LOCAL_FIXED
; break;
3659 case INSTR_POP_LOCAL
: op_code
= INSTR_POP_LOCAL_FIXED
; break;
3660 case INSTR_SET
: op_code
= INSTR_SET_FIXED
; break;
3661 case INSTR_APPEND
: op_code
= INSTR_APPEND_FIXED
; break;
3662 case INSTR_DEFAULT
: op_code
= INSTR_DEFAULT_FIXED
; break;
3664 if( code
->arg
== 1 ) return (FUNCTION
*)new_func
;
3666 case INSTR_CALL_MEMBER_RULE
:
3667 case INSTR_CALL_RULE
: ++i
; continue;
3668 case INSTR_PUSH_MODULE
:
3674 code
= func
->code
+ i
;
3675 switch ( code
->op_code
)
3677 case INSTR_PUSH_MODULE
:
3681 case INSTR_POP_MODULE
:
3684 case INSTR_CALL_RULE
:
3694 key
= func
->constants
[ code
->arg
];
3695 if ( !( object_equal( key
, constant_TMPDIR
) ||
3696 object_equal( key
, constant_TMPNAME
) ||
3697 object_equal( key
, constant_TMPFILE
) ||
3698 object_equal( key
, constant_STDOUT
) ||
3699 object_equal( key
, constant_STDERR
) ) )
3701 code
->op_code
= op_code
;
3702 code
->arg
= module_add_fixed_var( module
, key
, counter
);
3708 LIST
* function_get_variables( FUNCTION
* f
)
3710 if ( f
->type
== FUNCTION_BUILTIN
)
3713 if ( f
->type
== FUNCTION_PYTHON
)
3717 JAM_FUNCTION
* func
= (JAM_FUNCTION
*)f
;
3721 assert( f
->type
== FUNCTION_JAM
);
3722 if ( func
->generic
) func
= ( JAM_FUNCTION
* )func
->generic
;
3724 for ( i
= 0; ; ++i
)
3727 code
= func
->code
+ i
;
3728 switch ( code
->op_code
)
3730 case INSTR_PUSH_LOCAL
: break;
3731 case INSTR_RETURN
: return result
;
3732 case INSTR_CALL_MEMBER_RULE
:
3733 case INSTR_CALL_RULE
: ++i
; continue;
3734 case INSTR_PUSH_MODULE
:
3740 code
= func
->code
+ i
;
3741 switch ( code
->op_code
)
3743 case INSTR_PUSH_MODULE
:
3747 case INSTR_POP_MODULE
:
3750 case INSTR_CALL_RULE
:
3760 var
= func
->constants
[ code
->arg
];
3761 if ( !( object_equal( var
, constant_TMPDIR
) ||
3762 object_equal( var
, constant_TMPNAME
) ||
3763 object_equal( var
, constant_TMPFILE
) ||
3764 object_equal( var
, constant_STDOUT
) ||
3765 object_equal( var
, constant_STDERR
) ) )
3767 result
= list_push_back( result
, var
);
3773 void function_refer( FUNCTION
* func
)
3775 ++func
->reference_count
;
3778 void function_free( FUNCTION
* function_
)
3782 if ( --function_
->reference_count
!= 0 )
3785 if ( function_
->formal_arguments
)
3786 argument_list_free( function_
->formal_arguments
,
3787 function_
->num_formal_arguments
);
3789 if ( function_
->type
== FUNCTION_JAM
)
3791 JAM_FUNCTION
* func
= (JAM_FUNCTION
*)function_
;
3793 BJAM_FREE( func
->code
);
3795 if ( func
->generic
)
3796 function_free( func
->generic
);
3799 if ( function_
->rulename
) object_free( function_
->rulename
);
3801 for ( i
= 0; i
< func
->num_constants
; ++i
)
3802 object_free( func
->constants
[ i
] );
3803 BJAM_FREE( func
->constants
);
3805 for ( i
= 0; i
< func
->num_subfunctions
; ++i
)
3807 object_free( func
->functions
[ i
].name
);
3808 function_free( func
->functions
[ i
].code
);
3810 BJAM_FREE( func
->functions
);
3812 for ( i
= 0; i
< func
->num_subactions
; ++i
)
3814 object_free( func
->actions
[ i
].name
);
3815 function_free( func
->actions
[ i
].command
);
3817 BJAM_FREE( func
->actions
);
3819 object_free( func
->file
);
3823 else if ( function_
->type
== FUNCTION_PYTHON
)
3825 PYTHON_FUNCTION
* func
= (PYTHON_FUNCTION
*)function_
;
3826 Py_DECREF( func
->python_function
);
3827 if ( function_
->rulename
) object_free( function_
->rulename
);
3832 assert( function_
->type
== FUNCTION_BUILTIN
);
3833 if ( function_
->rulename
) object_free( function_
->rulename
);
3836 BJAM_FREE( function_
);
3840 /* Alignment check for stack */
3842 struct align_var_edits
3848 struct align_expansion_item
3854 static char check_align_var_edits
[ sizeof(struct align_var_edits
) <= sizeof(VAR_EDITS
) + sizeof(void *) ? 1 : -1 ];
3855 static char check_align_expansion_item
[ sizeof(struct align_expansion_item
) <= sizeof(expansion_item
) + sizeof(void *) ? 1 : -1 ];
3857 static char check_ptr_size1
[ sizeof(LIST
*) <= sizeof(void *) ? 1 : -1 ];
3858 static char check_ptr_size2
[ sizeof(char *) <= sizeof(void *) ? 1 : -1 ];
3860 void function_run_actions( FUNCTION
* function
, FRAME
* frame
, STACK
* s
,
3863 *(string
* *)stack_allocate( s
, sizeof( string
* ) ) = out
;
3864 list_free( function_run( function
, frame
, s
) );
3865 stack_deallocate( s
, sizeof( string
* ) );
3869 * WARNING: The instruction set is tuned for Jam and is not really generic. Be
3870 * especially careful about stack push/pop.
3873 LIST
* function_run( FUNCTION
* function_
, FRAME
* frame
, STACK
* s
)
3875 JAM_FUNCTION
* function
;
3880 void * saved_stack
= s
->data
;
3882 PROFILE_ENTER_LOCAL(function_run
);
3885 frame
->function
= function_
;
3888 if ( function_
->type
== FUNCTION_BUILTIN
)
3890 PROFILE_ENTER_LOCAL(function_run_FUNCTION_BUILTIN
);
3891 BUILTIN_FUNCTION
const * const f
= (BUILTIN_FUNCTION
*)function_
;
3892 if ( function_
->formal_arguments
)
3893 argument_list_check( function_
->formal_arguments
,
3894 function_
->num_formal_arguments
, function_
, frame
);
3896 debug_on_enter_function( frame
, f
->base
.rulename
, NULL
, -1 );
3897 result
= f
->func( frame
, f
->flags
);
3898 debug_on_exit_function( f
->base
.rulename
);
3899 PROFILE_EXIT_LOCAL(function_run_FUNCTION_BUILTIN
);
3900 PROFILE_EXIT_LOCAL(function_run
);
3905 else if ( function_
->type
== FUNCTION_PYTHON
)
3907 PROFILE_ENTER_LOCAL(function_run_FUNCTION_PYTHON
);
3908 PYTHON_FUNCTION
* f
= (PYTHON_FUNCTION
*)function_
;
3909 debug_on_enter_function( frame
, f
->base
.rulename
, NULL
, -1 );
3910 result
= call_python_function( f
, frame
);
3911 debug_on_exit_function( f
->base
.rulename
);
3912 PROFILE_EXIT_LOCAL(function_run_FUNCTION_PYTHON
);
3913 PROFILE_EXIT_LOCAL(function_run
);
3918 assert( function_
->type
== FUNCTION_JAM
);
3920 if ( function_
->formal_arguments
)
3921 argument_list_push( function_
->formal_arguments
,
3922 function_
->num_formal_arguments
, function_
, frame
, s
);
3924 function
= (JAM_FUNCTION
*)function_
;
3925 debug_on_enter_function( frame
, function
->base
.rulename
, function
->file
, function
->line
);
3926 code
= function
->code
;
3929 switch ( code
->op_code
)
3933 * Basic stack manipulation
3936 case INSTR_PUSH_EMPTY
:
3938 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_EMPTY
);
3939 stack_push( s
, L0
);
3940 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_EMPTY
);
3944 case INSTR_PUSH_CONSTANT
:
3946 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_CONSTANT
);
3947 OBJECT
* value
= function_get_constant( function
, code
->arg
);
3948 stack_push( s
, list_new( object_copy( value
) ) );
3949 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_CONSTANT
);
3953 case INSTR_PUSH_ARG
:
3955 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_ARG
);
3956 stack_push( s
, frame_get_local( frame
, code
->arg
) );
3957 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_ARG
);
3961 case INSTR_PUSH_VAR
:
3963 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_VAR
);
3964 stack_push( s
, function_get_variable( function
, frame
, code
->arg
) );
3965 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_VAR
);
3969 case INSTR_PUSH_VAR_FIXED
:
3971 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_VAR_FIXED
);
3972 stack_push( s
, list_copy( frame
->module
->fixed_variables
[ code
->arg
3974 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_VAR_FIXED
);
3978 case INSTR_PUSH_GROUP
:
3980 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_GROUP
);
3985 for ( iter
= list_begin( l
), end
= list_end( l
); iter
!= end
;
3986 iter
= list_next( iter
) )
3987 value
= list_append( value
, function_get_named_variable(
3988 function
, frame
, list_item( iter
) ) );
3990 stack_push( s
, value
);
3991 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_GROUP
);
3995 case INSTR_PUSH_APPEND
:
3997 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_APPEND
);
4000 stack_push( s
, list_append( l
, r
) );
4001 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_APPEND
);
4007 PROFILE_ENTER_LOCAL(function_run_INSTR_SWAP
);
4009 stack_set( s
, 0, stack_at( s
, code
->arg
) );
4010 stack_set( s
, code
->arg
, l
);
4011 PROFILE_EXIT_LOCAL(function_run_INSTR_SWAP
);
4017 PROFILE_ENTER_LOCAL(function_run_INSTR_POP
);
4018 list_free( stack_pop( s
) );
4019 PROFILE_EXIT_LOCAL(function_run_INSTR_POP
);
4024 * Branch instructions
4029 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP
);
4031 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP
);
4035 case INSTR_JUMP_EMPTY
:
4037 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_EMPTY
);
4039 if ( !list_cmp( l
, L0
) ) code
+= code
->arg
;
4041 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_EMPTY
);
4045 case INSTR_JUMP_NOT_EMPTY
:
4047 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_NOT_EMPTY
);
4049 if ( list_cmp( l
, L0
) ) code
+= code
->arg
;
4051 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_NOT_EMPTY
);
4057 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_LT
);
4060 if ( list_cmp( l
, r
) < 0 ) code
+= code
->arg
;
4063 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_LT
);
4069 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_LE
);
4072 if ( list_cmp( l
, r
) <= 0 ) code
+= code
->arg
;
4075 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_LE
);
4081 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_GT
);
4084 if ( list_cmp( l
, r
) > 0 ) code
+= code
->arg
;
4087 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_GT
);
4093 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_GE
);
4096 if ( list_cmp( l
, r
) >= 0 ) code
+= code
->arg
;
4099 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_GE
);
4105 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_EQ
);
4108 if ( list_cmp( l
, r
) == 0 ) code
+= code
->arg
;
4111 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_EQ
);
4117 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_NE
);
4120 if ( list_cmp(l
, r
) != 0 ) code
+= code
->arg
;
4123 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_NE
);
4129 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_IN
);
4132 if ( list_is_sublist( l
, r
) ) code
+= code
->arg
;
4135 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_IN
);
4139 case INSTR_JUMP_NOT_IN
:
4141 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_NOT_IN
);
4144 if ( !list_is_sublist( l
, r
) ) code
+= code
->arg
;
4147 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_NOT_IN
);
4155 case INSTR_FOR_INIT
:
4157 PROFILE_ENTER_LOCAL(function_run_INSTR_FOR_INIT
);
4159 *(LISTITER
*)stack_allocate( s
, sizeof( LISTITER
) ) =
4161 PROFILE_EXIT_LOCAL(function_run_INSTR_FOR_INIT
);
4165 case INSTR_FOR_LOOP
:
4167 PROFILE_ENTER_LOCAL(function_run_INSTR_FOR_LOOP
);
4168 LISTITER iter
= *(LISTITER
*)stack_get( s
);
4169 stack_deallocate( s
, sizeof( LISTITER
) );
4171 if ( iter
== list_end( l
) )
4173 list_free( stack_pop( s
) );
4178 r
= list_new( object_copy( list_item( iter
) ) );
4179 iter
= list_next( iter
);
4180 *(LISTITER
*)stack_allocate( s
, sizeof( LISTITER
) ) = iter
;
4183 PROFILE_EXIT_LOCAL(function_run_INSTR_FOR_LOOP
);
4189 PROFILE_ENTER_LOCAL(function_run_INSTR_FOR_POP
);
4190 stack_deallocate( s
, sizeof( LISTITER
) );
4191 list_free( stack_pop( s
) );
4192 PROFILE_EXIT_LOCAL(function_run_INSTR_FOR_POP
);
4200 case INSTR_JUMP_NOT_GLOB
:
4202 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_NOT_GLOB
);
4203 char const * pattern
;
4207 pattern
= list_empty( l
) ? "" : object_str( list_front( l
) );
4208 match
= list_empty( r
) ? "" : object_str( list_front( r
) );
4209 if ( glob( pattern
, match
) )
4212 list_free( stack_pop( s
) );
4214 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_NOT_GLOB
);
4222 case INSTR_SET_RESULT
:
4224 PROFILE_ENTER_LOCAL(function_run_INSTR_SET_RESULT
);
4225 list_free( result
);
4227 result
= stack_pop( s
);
4229 result
= list_copy( stack_top( s
) );
4230 PROFILE_EXIT_LOCAL(function_run_INSTR_SET_RESULT
);
4234 case INSTR_PUSH_RESULT
:
4236 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_RESULT
);
4237 stack_push( s
, result
);
4239 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_RESULT
);
4245 PROFILE_ENTER_LOCAL(function_run_INSTR_RETURN
);
4246 if ( function_
->formal_arguments
)
4247 argument_list_pop( function_
->formal_arguments
,
4248 function_
->num_formal_arguments
, frame
, s
);
4250 if ( !( saved_stack
== s
->data
) )
4252 frame
->file
= function
->file
;
4253 frame
->line
= function
->line
;
4254 backtrace_line( frame
);
4255 out_printf( "error: stack check failed.\n" );
4257 assert( saved_stack
== s
->data
);
4260 assert( saved_stack
== s
->data
);
4261 debug_on_exit_function( function
->base
.rulename
);
4262 PROFILE_EXIT_LOCAL(function_run_INSTR_RETURN
);
4263 PROFILE_EXIT_LOCAL(function_run
);
4271 case INSTR_PUSH_LOCAL
:
4273 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_LOCAL
);
4274 LIST
* value
= stack_pop( s
);
4275 stack_push( s
, function_swap_variable( function
, frame
, code
->arg
,
4277 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_LOCAL
);
4281 case INSTR_POP_LOCAL
:
4283 PROFILE_ENTER_LOCAL(function_run_INSTR_POP_LOCAL
);
4284 function_set_variable( function
, frame
, code
->arg
, stack_pop( s
) );
4285 PROFILE_EXIT_LOCAL(function_run_INSTR_POP_LOCAL
);
4289 case INSTR_PUSH_LOCAL_FIXED
:
4291 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_LOCAL_FIXED
);
4292 LIST
* value
= stack_pop( s
);
4293 LIST
* * ptr
= &frame
->module
->fixed_variables
[ code
->arg
];
4294 assert( code
->arg
< frame
->module
->num_fixed_variables
);
4295 stack_push( s
, *ptr
);
4297 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_LOCAL_FIXED
);
4301 case INSTR_POP_LOCAL_FIXED
:
4303 PROFILE_ENTER_LOCAL(function_run_INSTR_POP_LOCAL_FIXED
);
4304 LIST
* value
= stack_pop( s
);
4305 LIST
* * ptr
= &frame
->module
->fixed_variables
[ code
->arg
];
4306 assert( code
->arg
< frame
->module
->num_fixed_variables
);
4309 PROFILE_EXIT_LOCAL(function_run_INSTR_POP_LOCAL_FIXED
);
4313 case INSTR_PUSH_LOCAL_GROUP
:
4315 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_LOCAL_GROUP
);
4316 LIST
* const value
= stack_pop( s
);
4320 for ( iter
= list_begin( l
), end
= list_end( l
); iter
!= end
;
4321 iter
= list_next( iter
) )
4322 stack_push( s
, function_swap_named_variable( function
, frame
,
4323 list_item( iter
), list_copy( value
) ) );
4326 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_LOCAL_GROUP
);
4330 case INSTR_POP_LOCAL_GROUP
:
4332 PROFILE_ENTER_LOCAL(function_run_INSTR_POP_LOCAL_GROUP
);
4336 l
= list_reverse( r
);
4338 for ( iter
= list_begin( l
), end
= list_end( l
); iter
!= end
;
4339 iter
= list_next( iter
) )
4340 function_set_named_variable( function
, frame
, list_item( iter
),
4343 PROFILE_EXIT_LOCAL(function_run_INSTR_POP_LOCAL_GROUP
);
4348 * on $(TARGET) variables
4353 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_ON
);
4354 LIST
* targets
= stack_top( s
);
4355 if ( !list_empty( targets
) )
4357 /* FIXME: push the state onto the stack instead of using
4360 TARGET
* t
= bindtarget( list_front( targets
) );
4361 pushsettings( frame
->module
, t
->settings
);
4365 /* [ on $(TARGET) ... ] is ignored if $(TARGET) is empty. */
4366 list_free( stack_pop( s
) );
4367 stack_push( s
, L0
);
4370 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_ON
);
4376 PROFILE_ENTER_LOCAL(function_run_INSTR_POP_ON
);
4377 LIST
* result
= stack_pop( s
);
4378 LIST
* targets
= stack_pop( s
);
4379 if ( !list_empty( targets
) )
4381 TARGET
* t
= bindtarget( list_front( targets
) );
4382 popsettings( frame
->module
, t
->settings
);
4384 list_free( targets
);
4385 stack_push( s
, result
);
4386 PROFILE_EXIT_LOCAL(function_run_INSTR_POP_ON
);
4392 PROFILE_ENTER_LOCAL(function_run_INSTR_SET_ON
);
4393 LIST
* targets
= stack_pop( s
);
4394 LIST
* value
= stack_pop( s
);
4395 LIST
* vars
= stack_pop( s
);
4396 LISTITER iter
= list_begin( targets
);
4397 LISTITER
const end
= list_end( targets
);
4398 for ( ; iter
!= end
; iter
= list_next( iter
) )
4400 TARGET
* t
= bindtarget( list_item( iter
) );
4401 LISTITER vars_iter
= list_begin( vars
);
4402 LISTITER
const vars_end
= list_end( vars
);
4403 for ( ; vars_iter
!= vars_end
; vars_iter
= list_next( vars_iter
4405 t
->settings
= addsettings( t
->settings
, VAR_SET
, list_item(
4406 vars_iter
), list_copy( value
) );
4409 list_free( targets
);
4410 stack_push( s
, value
);
4411 PROFILE_EXIT_LOCAL(function_run_INSTR_SET_ON
);
4415 case INSTR_APPEND_ON
:
4417 PROFILE_ENTER_LOCAL(function_run_INSTR_APPEND_ON
);
4418 LIST
* targets
= stack_pop( s
);
4419 LIST
* value
= stack_pop( s
);
4420 LIST
* vars
= stack_pop( s
);
4421 LISTITER iter
= list_begin( targets
);
4422 LISTITER
const end
= list_end( targets
);
4423 for ( ; iter
!= end
; iter
= list_next( iter
) )
4425 TARGET
* const t
= bindtarget( list_item( iter
) );
4426 LISTITER vars_iter
= list_begin( vars
);
4427 LISTITER
const vars_end
= list_end( vars
);
4428 for ( ; vars_iter
!= vars_end
; vars_iter
= list_next( vars_iter
4430 t
->settings
= addsettings( t
->settings
, VAR_APPEND
,
4431 list_item( vars_iter
), list_copy( value
) );
4434 list_free( targets
);
4435 stack_push( s
, value
);
4436 PROFILE_EXIT_LOCAL(function_run_INSTR_APPEND_ON
);
4440 case INSTR_DEFAULT_ON
:
4442 PROFILE_ENTER_LOCAL(function_run_INSTR_DEFAULT_ON
);
4443 LIST
* targets
= stack_pop( s
);
4444 LIST
* value
= stack_pop( s
);
4445 LIST
* vars
= stack_pop( s
);
4446 LISTITER iter
= list_begin( targets
);
4447 LISTITER
const end
= list_end( targets
);
4448 for ( ; iter
!= end
; iter
= list_next( iter
) )
4450 TARGET
* t
= bindtarget( list_item( iter
) );
4451 LISTITER vars_iter
= list_begin( vars
);
4452 LISTITER
const vars_end
= list_end( vars
);
4453 for ( ; vars_iter
!= vars_end
; vars_iter
= list_next( vars_iter
4455 t
->settings
= addsettings( t
->settings
, VAR_DEFAULT
,
4456 list_item( vars_iter
), list_copy( value
) );
4459 list_free( targets
);
4460 stack_push( s
, value
);
4461 PROFILE_EXIT_LOCAL(function_run_INSTR_DEFAULT_ON
);
4465 /* [ on $(target) return $(variable) ] */
4468 PROFILE_ENTER_LOCAL(function_run_INSTR_GET_ON
);
4469 LIST
* targets
= stack_pop( s
);
4471 if ( !list_empty( targets
) )
4473 OBJECT
* varname
= function
->constants
[ code
->arg
];
4474 TARGET
* t
= bindtarget( list_front( targets
) );
4475 SETTINGS
* s
= t
->settings
;
4477 for ( ; s
!= 0; s
= s
->next
)
4479 if ( object_equal( s
->symbol
, varname
) )
4488 result
= var_get( frame
->module
, varname
) ;
4491 list_free( targets
);
4492 stack_push( s
, list_copy( result
) );
4493 PROFILE_EXIT_LOCAL(function_run_INSTR_GET_ON
);
4503 PROFILE_ENTER_LOCAL(function_run_INSTR_SET
);
4504 function_set_variable( function
, frame
, code
->arg
,
4506 PROFILE_EXIT_LOCAL(function_run_INSTR_SET
);
4512 PROFILE_ENTER_LOCAL(function_run_INSTR_APPEND
);
4513 function_append_variable( function
, frame
, code
->arg
,
4515 PROFILE_EXIT_LOCAL(function_run_INSTR_APPEND
);
4521 PROFILE_ENTER_LOCAL(function_run_INSTR_DEFAULT
);
4522 function_default_variable( function
, frame
, code
->arg
,
4524 PROFILE_EXIT_LOCAL(function_run_INSTR_DEFAULT
);
4528 case INSTR_SET_FIXED
:
4530 PROFILE_ENTER_LOCAL(function_run_INSTR_SET_FIXED
);
4531 LIST
* * ptr
= &frame
->module
->fixed_variables
[ code
->arg
];
4532 assert( code
->arg
< frame
->module
->num_fixed_variables
);
4534 *ptr
= stack_pop( s
);
4535 PROFILE_EXIT_LOCAL(function_run_INSTR_SET_FIXED
);
4539 case INSTR_APPEND_FIXED
:
4541 PROFILE_ENTER_LOCAL(function_run_INSTR_APPEND_FIXED
);
4542 LIST
* * ptr
= &frame
->module
->fixed_variables
[ code
->arg
];
4543 assert( code
->arg
< frame
->module
->num_fixed_variables
);
4544 *ptr
= list_append( *ptr
, stack_pop( s
) );
4545 PROFILE_EXIT_LOCAL(function_run_INSTR_APPEND_FIXED
);
4549 case INSTR_DEFAULT_FIXED
:
4551 PROFILE_ENTER_LOCAL(function_run_INSTR_DEFAULT_FIXED
);
4552 LIST
* * ptr
= &frame
->module
->fixed_variables
[ code
->arg
];
4553 LIST
* value
= stack_pop( s
);
4554 assert( code
->arg
< frame
->module
->num_fixed_variables
);
4555 if ( list_empty( *ptr
) )
4559 PROFILE_EXIT_LOCAL(function_run_INSTR_DEFAULT_FIXED
);
4563 case INSTR_SET_GROUP
:
4565 PROFILE_ENTER_LOCAL(function_run_INSTR_SET_GROUP
);
4566 LIST
* value
= stack_pop( s
);
4567 LIST
* vars
= stack_pop( s
);
4568 LISTITER iter
= list_begin( vars
);
4569 LISTITER
const end
= list_end( vars
);
4570 for ( ; iter
!= end
; iter
= list_next( iter
) )
4571 function_set_named_variable( function
, frame
, list_item( iter
),
4572 list_copy( value
) );
4575 PROFILE_EXIT_LOCAL(function_run_INSTR_SET_GROUP
);
4579 case INSTR_APPEND_GROUP
:
4581 PROFILE_ENTER_LOCAL(function_run_INSTR_APPEND_GROUP
);
4582 LIST
* value
= stack_pop( s
);
4583 LIST
* vars
= stack_pop( s
);
4584 LISTITER iter
= list_begin( vars
);
4585 LISTITER
const end
= list_end( vars
);
4586 for ( ; iter
!= end
; iter
= list_next( iter
) )
4587 function_append_named_variable( function
, frame
, list_item( iter
4588 ), list_copy( value
) );
4591 PROFILE_EXIT_LOCAL(function_run_INSTR_APPEND_GROUP
);
4595 case INSTR_DEFAULT_GROUP
:
4597 PROFILE_ENTER_LOCAL(function_run_INSTR_DEFAULT_GROUP
);
4598 LIST
* value
= stack_pop( s
);
4599 LIST
* vars
= stack_pop( s
);
4600 LISTITER iter
= list_begin( vars
);
4601 LISTITER
const end
= list_end( vars
);
4602 for ( ; iter
!= end
; iter
= list_next( iter
) )
4603 function_default_named_variable( function
, frame
, list_item(
4604 iter
), list_copy( value
) );
4607 PROFILE_EXIT_LOCAL(function_run_INSTR_DEFAULT_GROUP
);
4615 case INSTR_CALL_RULE
:
4617 PROFILE_ENTER_LOCAL(function_run_INSTR_CALL_RULE
);
4618 char const * unexpanded
= object_str( function_get_constant(
4619 function
, code
[ 1 ].op_code
) );
4620 LIST
* result
= function_call_rule( function
, frame
, s
, code
->arg
,
4621 unexpanded
, function
->file
, code
[ 1 ].arg
);
4622 stack_push( s
, result
);
4624 PROFILE_EXIT_LOCAL(function_run_INSTR_CALL_RULE
);
4628 case INSTR_CALL_MEMBER_RULE
:
4630 PROFILE_ENTER_LOCAL(function_run_INSTR_CALL_MEMBER_RULE
);
4631 OBJECT
* rule_name
= function_get_constant( function
, code
[1].op_code
);
4632 LIST
* result
= function_call_member_rule( function
, frame
, s
, code
->arg
, rule_name
, function
->file
, code
[1].arg
);
4633 stack_push( s
, result
);
4635 PROFILE_EXIT_LOCAL(function_run_INSTR_CALL_MEMBER_RULE
);
4641 PROFILE_ENTER_LOCAL(function_run_INSTR_RULE
);
4642 function_set_rule( function
, frame
, s
, code
->arg
);
4643 PROFILE_EXIT_LOCAL(function_run_INSTR_RULE
);
4649 PROFILE_ENTER_LOCAL(function_run_INSTR_ACTIONS
);
4650 function_set_actions( function
, frame
, s
, code
->arg
);
4651 PROFILE_EXIT_LOCAL(function_run_INSTR_ACTIONS
);
4656 * Variable expansion
4659 case INSTR_APPLY_MODIFIERS
:
4661 PROFILE_ENTER_LOCAL(function_run_INSTR_APPLY_MODIFIERS
);
4665 n
= expand_modifiers( s
, code
->arg
);
4667 l
= apply_modifiers( s
, n
);
4668 list_free( stack_pop( s
) );
4669 stack_deallocate( s
, n
* sizeof( VAR_EDITS
) );
4670 for ( i
= 0; i
< code
->arg
; ++i
)
4671 list_free( stack_pop( s
) ); /* pop modifiers */
4673 PROFILE_EXIT_LOCAL(function_run_INSTR_APPLY_MODIFIERS
);
4677 case INSTR_APPLY_INDEX
:
4679 PROFILE_ENTER_LOCAL(function_run_INSTR_APPLY_INDEX
);
4680 l
= apply_subscript( s
);
4681 list_free( stack_pop( s
) );
4682 list_free( stack_pop( s
) );
4684 PROFILE_EXIT_LOCAL(function_run_INSTR_APPLY_INDEX
);
4688 case INSTR_APPLY_INDEX_MODIFIERS
:
4690 PROFILE_ENTER_LOCAL(function_run_INSTR_APPLY_INDEX_MODIFIERS
);
4695 n
= expand_modifiers( s
, code
->arg
);
4698 l
= apply_subscript_and_modifiers( s
, n
);
4699 list_free( stack_pop( s
) );
4700 list_free( stack_pop( s
) );
4701 stack_deallocate( s
, n
* sizeof( VAR_EDITS
) );
4702 for ( i
= 0; i
< code
->arg
; ++i
)
4703 list_free( stack_pop( s
) ); /* pop modifiers */
4705 PROFILE_EXIT_LOCAL(function_run_INSTR_APPLY_INDEX_MODIFIERS
);
4709 case INSTR_APPLY_MODIFIERS_GROUP
:
4711 PROFILE_ENTER_LOCAL(function_run_INSTR_APPLY_MODIFIERS_GROUP
);
4713 LIST
* const vars
= stack_pop( s
);
4714 int const n
= expand_modifiers( s
, code
->arg
);
4716 LISTITER iter
= list_begin( vars
);
4717 LISTITER
const end
= list_end( vars
);
4718 for ( ; iter
!= end
; iter
= list_next( iter
) )
4720 stack_push( s
, function_get_named_variable( function
, frame
,
4721 list_item( iter
) ) );
4722 result
= list_append( result
, apply_modifiers( s
, n
) );
4723 list_free( stack_pop( s
) );
4726 stack_deallocate( s
, n
* sizeof( VAR_EDITS
) );
4727 for ( i
= 0; i
< code
->arg
; ++i
)
4728 list_free( stack_pop( s
) ); /* pop modifiers */
4729 stack_push( s
, result
);
4730 PROFILE_EXIT_LOCAL(function_run_INSTR_APPLY_MODIFIERS_GROUP
);
4734 case INSTR_APPLY_INDEX_GROUP
:
4736 PROFILE_ENTER_LOCAL(function_run_INSTR_APPLY_INDEX_GROUP
);
4737 LIST
* vars
= stack_pop( s
);
4739 LISTITER iter
= list_begin( vars
);
4740 LISTITER
const end
= list_end( vars
);
4741 for ( ; iter
!= end
; iter
= list_next( iter
) )
4743 stack_push( s
, function_get_named_variable( function
, frame
,
4744 list_item( iter
) ) );
4745 result
= list_append( result
, apply_subscript( s
) );
4746 list_free( stack_pop( s
) );
4749 list_free( stack_pop( s
) );
4750 stack_push( s
, result
);
4751 PROFILE_EXIT_LOCAL(function_run_INSTR_APPLY_INDEX_GROUP
);
4755 case INSTR_APPLY_INDEX_MODIFIERS_GROUP
:
4757 PROFILE_ENTER_LOCAL(function_run_INSTR_APPLY_INDEX_MODIFIERS_GROUP
);
4759 LIST
* const vars
= stack_pop( s
);
4760 LIST
* const r
= stack_pop( s
);
4761 int const n
= expand_modifiers( s
, code
->arg
);
4763 LISTITER iter
= list_begin( vars
);
4764 LISTITER
const end
= list_end( vars
);
4766 for ( ; iter
!= end
; iter
= list_next( iter
) )
4768 stack_push( s
, function_get_named_variable( function
, frame
,
4769 list_item( iter
) ) );
4770 result
= list_append( result
, apply_subscript_and_modifiers( s
,
4772 list_free( stack_pop( s
) );
4774 list_free( stack_pop( s
) );
4776 stack_deallocate( s
, n
* sizeof( VAR_EDITS
) );
4777 for ( i
= 0; i
< code
->arg
; ++i
)
4778 list_free( stack_pop( s
) ); /* pop modifiers */
4779 stack_push( s
, result
);
4780 PROFILE_EXIT_LOCAL(function_run_INSTR_APPLY_INDEX_MODIFIERS_GROUP
);
4784 case INSTR_COMBINE_STRINGS
:
4786 PROFILE_ENTER_LOCAL(function_run_INSTR_COMBINE_STRINGS
);
4787 size_t const buffer_size
= code
->arg
* sizeof( expansion_item
);
4788 LIST
* * const stack_pos
= (LIST
* * const)stack_get( s
);
4789 expansion_item
* items
= (expansion_item
*)stack_allocate( s
, buffer_size
);
4792 for ( i
= 0; i
< code
->arg
; ++i
)
4793 items
[ i
].values
= stack_pos
[ i
];
4794 result
= expand( items
, code
->arg
);
4795 stack_deallocate( s
, buffer_size
);
4796 for ( i
= 0; i
< code
->arg
; ++i
)
4797 list_free( stack_pop( s
) );
4798 stack_push( s
, result
);
4799 PROFILE_EXIT_LOCAL(function_run_INSTR_COMBINE_STRINGS
);
4803 case INSTR_GET_GRIST
:
4805 PROFILE_ENTER_LOCAL(function_run_INSTR_GET_GRIST
);
4806 LIST
* vals
= stack_pop( s
);
4810 for ( iter
= list_begin( vals
), end
= list_end( vals
); iter
!= end
; ++iter
)
4812 OBJECT
* new_object
;
4813 const char * value
= object_str( list_item( iter
) );
4815 if ( value
[ 0 ] == '<' && ( p
= strchr( value
, '>' ) ) )
4818 new_object
= object_new_range( value
, p
- value
+ 1 );
4820 new_object
= object_copy( list_item( iter
) );
4824 new_object
= object_copy( constant_empty
);
4826 result
= list_push_back( result
, new_object
);
4830 stack_push( s
, result
);
4831 PROFILE_EXIT_LOCAL(function_run_INSTR_GET_GRIST
);
4837 PROFILE_ENTER_LOCAL(function_run_INSTR_INCLUDE
);
4838 LIST
* nt
= stack_pop( s
);
4839 if ( !list_empty( nt
) )
4841 TARGET
* const t
= bindtarget( list_front( nt
) );
4844 /* DWA 2001/10/22 - Perforce Jam cleared the arguments here,
4845 * which prevented an included file from being treated as part
4846 * of the body of a rule. I did not see any reason to do that,
4847 * so I lifted the restriction.
4850 /* Bind the include file under the influence of "on-target"
4851 * variables. Though they are targets, include files are not
4852 * built with make().
4855 pushsettings( root_module(), t
->settings
);
4856 /* We do not expect that a file to be included is generated by
4857 * some action. Therefore, pass 0 as third argument. If the name
4858 * resolves to a directory, let it error out.
4860 object_free( t
->boundname
);
4861 t
->boundname
= search( t
->name
, &t
->time
, 0, 0 );
4862 popsettings( root_module(), t
->settings
);
4864 parse_file( t
->boundname
, frame
);
4866 frame
->function
= function_
;
4869 PROFILE_EXIT_LOCAL(function_run_INSTR_INCLUDE
);
4874 * Classes and modules
4877 case INSTR_PUSH_MODULE
:
4879 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_MODULE
);
4880 LIST
* const module_name
= stack_pop( s
);
4881 module_t
* const outer_module
= frame
->module
;
4882 frame
->module
= !list_empty( module_name
)
4883 ? bindmodule( list_front( module_name
) )
4885 list_free( module_name
);
4886 *(module_t
* *)stack_allocate( s
, sizeof( module_t
* ) ) =
4888 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_MODULE
);
4892 case INSTR_POP_MODULE
:
4894 PROFILE_ENTER_LOCAL(function_run_INSTR_POP_MODULE
);
4895 module_t
* const outer_module
= *(module_t
* *)stack_get( s
);
4896 stack_deallocate( s
, sizeof( module_t
* ) );
4897 frame
->module
= outer_module
;
4898 PROFILE_EXIT_LOCAL(function_run_INSTR_POP_MODULE
);
4904 PROFILE_ENTER_LOCAL(function_run_INSTR_CLASS
);
4905 LIST
* bases
= stack_pop( s
);
4906 LIST
* name
= stack_pop( s
);
4907 OBJECT
* class_module
= make_class_module( name
, bases
, frame
);
4909 module_t
* const outer_module
= frame
->module
;
4910 frame
->module
= bindmodule( class_module
);
4911 object_free( class_module
);
4913 *(module_t
* *)stack_allocate( s
, sizeof( module_t
* ) ) =
4915 PROFILE_EXIT_LOCAL(function_run_INSTR_CLASS
);
4919 case INSTR_BIND_MODULE_VARIABLES
:
4921 PROFILE_ENTER_LOCAL(function_run_INSTR_BIND_MODULE_VARIABLES
);
4922 module_bind_variables( frame
->module
);
4923 PROFILE_EXIT_LOCAL(function_run_INSTR_BIND_MODULE_VARIABLES
);
4927 case INSTR_APPEND_STRINGS
:
4929 PROFILE_ENTER_LOCAL(function_run_INSTR_APPEND_STRINGS
);
4932 combine_strings( s
, code
->arg
, buf
);
4933 stack_push( s
, list_new( object_new( buf
->value
) ) );
4935 PROFILE_EXIT_LOCAL(function_run_INSTR_APPEND_STRINGS
);
4939 case INSTR_WRITE_FILE
:
4941 PROFILE_ENTER_LOCAL(function_run_INSTR_WRITE_FILE
);
4944 OBJECT
* tmp_filename
= 0;
4945 int out_debug
= DEBUG_EXEC
? 1 : 0;
4946 FILE * out_file
= 0;
4948 combine_strings( s
, code
->arg
, buf
);
4949 out
= object_str( list_front( stack_top( s
) ) );
4951 /* For stdout/stderr we will create a temp file and generate a
4952 * command that outputs the content as needed.
4954 if ( ( strcmp( "STDOUT", out
) == 0 ) ||
4955 ( strcmp( "STDERR", out
) == 0 ) )
4957 int err_redir
= strcmp( "STDERR", out
) == 0;
4960 tmp_filename
= path_tmpfile();
4962 /* Construct os-specific cat command. */
4964 const char * command
= "cat";
4965 const char * quote
= "\"";
4966 const char * redirect
= "1>&2";
4971 #elif defined( OS_VMS )
4972 command
= "pipe type";
4975 /* Get tmp file name is os-format. */
4977 string os_filename
[ 1 ];
4979 string_new( os_filename
);
4980 path_translate_to_os( object_str( tmp_filename
), os_filename
);
4981 object_free( tmp_filename
);
4982 tmp_filename
= object_new( os_filename
->value
);
4983 string_free( os_filename
);
4987 string_new( result
);
4988 string_append( result
, command
);
4989 string_append( result
, " " );
4990 string_append( result
, quote
);
4991 string_append( result
, object_str( tmp_filename
) );
4992 string_append( result
, quote
);
4995 string_append( result
, " " );
4996 string_append( result
, redirect
);
5000 /* Replace STDXXX with the temporary file. */
5001 list_free( stack_pop( s
) );
5002 stack_push( s
, list_new( object_new( result
->value
) ) );
5003 out
= object_str( tmp_filename
);
5005 string_free( result
);
5007 /* Make sure temp files created by this get nuked eventually. */
5008 file_remove_atexit( tmp_filename
);
5011 if ( !globs
.noexec
)
5013 string out_name
[ 1 ];
5014 /* Handle "path to file" filenames. */
5015 if ( ( out
[ 0 ] == '"' ) && ( out
[ strlen( out
) - 1 ] == '"' )
5018 string_copy( out_name
, out
+ 1 );
5019 string_truncate( out_name
, out_name
->size
- 1 );
5022 string_copy( out_name
, out
);
5023 out_file
= fopen( out_name
->value
, "w" );
5027 err_printf( "failed to write output file '%s'!\n",
5031 string_free( out_name
);
5034 if ( out_debug
) out_printf( "\nfile %s\n", out
);
5035 if ( out_file
) fputs( buf
->value
, out_file
);
5036 if ( out_debug
) out_puts( buf
->value
);
5044 object_free( tmp_filename
);
5046 if ( out_debug
) out_putc( '\n' );
5047 PROFILE_EXIT_LOCAL(function_run_INSTR_WRITE_FILE
);
5051 case INSTR_OUTPUT_STRINGS
:
5053 PROFILE_ENTER_LOCAL(function_run_INSTR_OUTPUT_STRINGS
);
5054 string
* const buf
= *(string
* *)( (char *)stack_get( s
) + (
5055 code
->arg
* sizeof( LIST
* ) ) );
5056 combine_strings( s
, code
->arg
, buf
);
5057 PROFILE_EXIT_LOCAL(function_run_INSTR_OUTPUT_STRINGS
);
5061 case INSTR_DEBUG_LINE
:
5063 debug_on_instruction( frame
, function
->file
, code
->arg
);
5071 PROFILE_EXIT_LOCAL(function_run
);
5077 static struct arg_list
* arg_list_compile_python( PyObject
* bjam_signature
,
5078 int * num_arguments
)
5080 if ( bjam_signature
)
5082 struct argument_list_compiler c
[ 1 ];
5083 struct arg_list
* result
;
5086 argument_list_compiler_init( c
);
5088 s
= PySequence_Size( bjam_signature
);
5089 for ( i
= 0; i
< s
; ++i
)
5091 struct argument_compiler arg_comp
[ 1 ];
5092 struct arg_list arg
;
5093 PyObject
* v
= PySequence_GetItem( bjam_signature
, i
);
5096 argument_compiler_init( arg_comp
);
5098 inner
= PySequence_Size( v
);
5099 for ( j
= 0; j
< inner
; ++j
)
5100 argument_compiler_add( arg_comp
, object_new( PyString_AsString(
5101 PySequence_GetItem( v
, j
) ) ), constant_builtin
, -1 );
5103 arg
= arg_compile_impl( arg_comp
, constant_builtin
, -1 );
5104 dynamic_array_push( c
->args
, arg
);
5105 argument_compiler_free( arg_comp
);
5109 *num_arguments
= c
->args
->size
;
5110 result
= (struct arg_list
*)BJAM_MALLOC( c
->args
->size
* sizeof( struct arg_list
) );
5111 memcpy( result
, c
->args
->data
, c
->args
->size
* sizeof( struct arg_list
)
5113 argument_list_compiler_free( c
);
5120 FUNCTION
* function_python( PyObject
* function
, PyObject
* bjam_signature
)
5122 PYTHON_FUNCTION
* result
= (PYTHON_FUNCTION
*)BJAM_MALLOC( sizeof( PYTHON_FUNCTION
) );
5124 result
->base
.type
= FUNCTION_PYTHON
;
5125 result
->base
.reference_count
= 1;
5126 result
->base
.rulename
= 0;
5127 result
->base
.formal_arguments
= arg_list_compile_python( bjam_signature
,
5128 &result
->base
.num_formal_arguments
);
5129 Py_INCREF( function
);
5130 result
->python_function
= function
;
5132 return (FUNCTION
*)result
;
5136 static void argument_list_to_python( struct arg_list
* formal
, int formal_count
,
5137 FUNCTION
* function
, FRAME
* frame
, PyObject
* kw
)
5139 LOL
* all_actual
= frame
->args
;
5142 for ( i
= 0; i
< formal_count
; ++i
)
5144 LIST
* actual
= lol_get( all_actual
, i
);
5145 LISTITER actual_iter
= list_begin( actual
);
5146 LISTITER
const actual_end
= list_end( actual
);
5148 for ( j
= 0; j
< formal
[ i
].size
; ++j
)
5150 struct argument
* formal_arg
= &formal
[ i
].args
[ j
];
5154 switch ( formal_arg
->flags
)
5157 if ( actual_iter
== actual_end
)
5158 argument_error( "missing argument", function
, frame
,
5159 formal_arg
->arg_name
);
5160 type_check_range( formal_arg
->type_name
, actual_iter
, list_next(
5161 actual_iter
), frame
, function
, formal_arg
->arg_name
);
5162 value
= PyString_FromString( object_str( list_item( actual_iter
5164 actual_iter
= list_next( actual_iter
);
5167 if ( actual_iter
== actual_end
)
5171 type_check_range( formal_arg
->type_name
, actual_iter
,
5172 list_next( actual_iter
), frame
, function
,
5173 formal_arg
->arg_name
);
5174 value
= PyString_FromString( object_str( list_item(
5176 actual_iter
= list_next( actual_iter
);
5180 if ( actual_iter
== actual_end
)
5181 argument_error( "missing argument", function
, frame
,
5182 formal_arg
->arg_name
);
5185 type_check_range( formal_arg
->type_name
, actual_iter
,
5186 actual_end
, frame
, function
, formal_arg
->arg_name
);
5187 l
= list_copy_range( actual
, actual_iter
, actual_end
);
5188 value
= list_to_python( l
);
5190 actual_iter
= actual_end
;
5198 PyObject
* key
= PyString_FromString( object_str(
5199 formal_arg
->arg_name
) );
5200 PyDict_SetItem( kw
, key
, value
);
5206 if ( actual_iter
!= actual_end
)
5207 argument_error( "extra argument", function
, frame
, list_item(
5211 for ( ; i
< all_actual
->count
; ++i
)
5213 LIST
* const actual
= lol_get( all_actual
, i
);
5214 if ( !list_empty( actual
) )
5215 argument_error( "extra argument", function
, frame
, list_front(
5221 /* Given a Python object, return a string to use in Jam code instead of the said
5224 * If the object is a string, use the string value.
5225 * If the object implemenets __jam_repr__ method, use that.
5226 * Otherwise return 0.
5229 OBJECT
* python_to_string( PyObject
* value
)
5231 if ( PyString_Check( value
) )
5232 return object_new( PyString_AS_STRING( value
) );
5234 /* See if this instance defines the special __jam_repr__ method. */
5235 if ( PyInstance_Check( value
)
5236 && PyObject_HasAttrString( value
, "__jam_repr__" ) )
5238 PyObject
* repr
= PyObject_GetAttrString( value
, "__jam_repr__" );
5241 PyObject
* arguments2
= PyTuple_New( 0 );
5242 PyObject
* value2
= PyObject_Call( repr
, arguments2
, 0 );
5244 Py_DECREF( arguments2
);
5245 if ( PyString_Check( value2
) )
5246 return object_new( PyString_AS_STRING( value2
) );
5247 Py_DECREF( value2
);
5254 static module_t
* python_module()
5256 static module_t
* python
= 0;
5258 python
= bindmodule( constant_python
);
5263 static LIST
* call_python_function( PYTHON_FUNCTION
* function
, FRAME
* frame
)
5266 PyObject
* arguments
= 0;
5267 PyObject
* kw
= NULL
;
5269 PyObject
* py_result
;
5270 FRAME
* prev_frame_before_python_call
;
5272 if ( function
->base
.formal_arguments
)
5274 arguments
= PyTuple_New( 0 );
5276 argument_list_to_python( function
->base
.formal_arguments
,
5277 function
->base
.num_formal_arguments
, &function
->base
, frame
, kw
);
5281 arguments
= PyTuple_New( frame
->args
->count
);
5282 for ( i
= 0; i
< frame
->args
->count
; ++i
)
5283 PyTuple_SetItem( arguments
, i
, list_to_python( lol_get( frame
->args
,
5287 frame
->module
= python_module();
5289 prev_frame_before_python_call
= frame_before_python_call
;
5290 frame_before_python_call
= frame
;
5291 py_result
= PyObject_Call( function
->python_function
, arguments
, kw
);
5292 frame_before_python_call
= prev_frame_before_python_call
;
5293 Py_DECREF( arguments
);
5295 if ( py_result
!= NULL
)
5297 if ( PyList_Check( py_result
) )
5299 int size
= PyList_Size( py_result
);
5301 for ( i
= 0; i
< size
; ++i
)
5303 OBJECT
* s
= python_to_string( PyList_GetItem( py_result
, i
) );
5306 "Non-string object returned by Python call.\n" );
5308 result
= list_push_back( result
, s
);
5311 else if ( py_result
== Py_None
)
5317 OBJECT
* const s
= python_to_string( py_result
);
5319 result
= list_new( s
);
5321 /* We have tried all we could. Return empty list. There are
5322 * cases, e.g. feature.feature function that should return a
5323 * value for the benefit of Python code and which also can be
5324 * called by Jam code, where no sensible value can be returned.
5325 * We cannot even emit a warning, since there would be a pile of
5331 Py_DECREF( py_result
);
5336 err_printf( "Call failed\n" );
5345 void function_done( void )