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 real_rulename
= object_copy( function_rulename( rule
->procedure
) );
542 string_append( buf
, object_str( list_front( first
) ) );
543 string_push_back( buf
, '.' );
544 string_append( buf
, object_str( rulename
) );
545 real_rulename
= object_new( buf
->value
);
547 rule
= bindrule( real_rulename
, frame
->module
);
553 inner
->prev_user
= frame
->module
->user_module
? frame
: frame
->prev_user
;
554 inner
->module
= frame
->module
; /* This gets fixed up in evaluate_rule(), below. */
556 for( i
= 0; i
< n_args
; ++i
)
558 lol_add( inner
->args
, stack_at( s
, n_args
- i
- 1 ) );
561 for( i
= 0; i
< n_args
; ++i
)
566 if ( list_length( first
) > 1 )
569 LIST
* trailing
= L0
;
570 LISTITER iter
= list_begin( first
), end
= list_end( first
);
571 iter
= list_next( iter
);
573 for ( ; iter
!= end
; iter
= list_next( iter
) )
575 string_append( buf
, object_str( list_item( iter
) ) );
576 string_push_back( buf
, '.' );
577 string_append( buf
, object_str( rulename
) );
578 trailing
= list_push_back( trailing
, object_new( buf
->value
) );
579 string_truncate( buf
, 0 );
582 if ( inner
->args
->count
== 0 )
583 lol_add( inner
->args
, trailing
);
586 LIST
* * const l
= &inner
->args
->list
[ 0 ];
587 *l
= list_append( trailing
, *l
);
592 result
= evaluate_rule( rule
, real_rulename
, inner
);
594 object_free( real_rulename
);
599 /* Variable expansion */
609 PATHNAME f
; /* :GDBSMR -- pieces */
610 char parent
; /* :P -- go to parent directory */
611 char filemods
; /* one of the above applied */
612 char downshift
; /* :L -- downshift result */
613 char upshift
; /* :U -- upshift result */
614 char to_slashes
; /* :T -- convert "\" to "/" */
615 char to_windows
; /* :W -- convert cygwin to native paths */
616 PATHPART empty
; /* :E -- default for empties */
617 PATHPART join
; /* :J -- join list with char */
620 static LIST
* apply_modifiers_impl( LIST
* result
, string
* buf
,
621 VAR_EDITS
* edits
, int n
, LISTITER iter
, LISTITER end
);
622 static void get_iters( subscript_t
const subscript
, LISTITER
* const first
,
623 LISTITER
* const last
, int const length
);
627 * var_edit_parse() - parse : modifiers into PATHNAME structure
629 * The : modifiers in a $(varname:modifier) currently support replacing or
630 * omitting elements of a filename, and so they are parsed into a PATHNAME
631 * structure (which contains pointers into the original string).
633 * Modifiers of the form "X=value" replace the component X with the given value.
634 * Modifiers without the "=value" cause everything but the component X to be
635 * omitted. X is one of:
642 * R root directory - prepended to whole path
648 * -> leave the original component xxx
650 * f->f_xxx.ptr = string
651 * f->f_xxx.len = strlen( string )
652 * -> replace component xxx with string
656 * -> omit component xxx
658 * var_edit_file() below and path_build() obligingly follow this convention.
661 static int var_edit_parse( char const * mods
, VAR_EDITS
* edits
, int havezeroed
670 case 'L': edits
->downshift
= 1; continue;
671 case 'U': edits
->upshift
= 1; continue;
672 case 'P': edits
->parent
= edits
->filemods
= 1; continue;
673 case 'E': fp
= &edits
->empty
; goto strval
;
674 case 'J': fp
= &edits
->join
; goto strval
;
675 case 'G': fp
= &edits
->f
.f_grist
; goto fileval
;
676 case 'R': fp
= &edits
->f
.f_root
; goto fileval
;
677 case 'D': fp
= &edits
->f
.f_dir
; goto fileval
;
678 case 'B': fp
= &edits
->f
.f_base
; goto fileval
;
679 case 'S': fp
= &edits
->f
.f_suffix
; goto fileval
;
680 case 'M': fp
= &edits
->f
.f_member
; goto fileval
;
681 case 'T': edits
->to_slashes
= 1; continue;
682 case 'W': edits
->to_windows
= 1; continue;
684 continue; /* Should complain, but so what... */
688 /* Handle :CHARS, where each char (without a following =) selects a
689 * particular file path element. On the first such char, we deselect all
690 * others (by setting ptr = "", len = 0) and for each char we select
691 * that element (by setting ptr = 0).
700 for ( i
= 0; i
< 6; ++i
)
702 edits
->f
.part
[ i
].len
= 0;
703 edits
->f
.part
[ i
].ptr
= "";
712 /* Handle :X=value, or :X */
721 fp
->len
= strlen( mods
);
731 * var_edit_file() - copy input target name to output, modifying filename.
734 static void var_edit_file( char const * in
, string
* out
, VAR_EDITS
* edits
)
736 if ( edits
->filemods
)
740 /* Parse apart original filename, putting parts into "pathname". */
741 path_parse( in
, &pathname
);
743 /* Replace any pathname with edits->f */
744 if ( edits
->f
.f_grist
.ptr
) pathname
.f_grist
= edits
->f
.f_grist
;
745 if ( edits
->f
.f_root
.ptr
) pathname
.f_root
= edits
->f
.f_root
;
746 if ( edits
->f
.f_dir
.ptr
) pathname
.f_dir
= edits
->f
.f_dir
;
747 if ( edits
->f
.f_base
.ptr
) pathname
.f_base
= edits
->f
.f_base
;
748 if ( edits
->f
.f_suffix
.ptr
) pathname
.f_suffix
= edits
->f
.f_suffix
;
749 if ( edits
->f
.f_member
.ptr
) pathname
.f_member
= edits
->f
.f_member
;
751 /* If requested, modify pathname to point to parent. */
753 path_parent( &pathname
);
755 /* Put filename back together. */
756 path_build( &pathname
, out
);
759 string_append( out
, in
);
764 * var_edit_translate_path() - translate path to os native format.
767 static void var_edit_translate_path( string
* out
, size_t pos
, VAR_EDITS
* edits
)
769 if ( edits
->to_windows
)
774 /* Translate path to os native format. */
775 translated
= path_translate_to_os( out
->value
+ pos
, result
);
778 string_truncate( out
, pos
);
779 string_append( out
, result
->value
);
780 edits
->to_slashes
= 0;
783 string_free( result
);
789 * var_edit_shift() - do upshift/downshift & other mods.
792 static void var_edit_shift( string
* out
, size_t pos
, VAR_EDITS
* edits
)
794 #if defined( OS_CYGWIN ) || defined( OS_VMS )
795 var_edit_translate_path( out
, pos
, edits
);
798 if ( edits
->upshift
|| edits
->downshift
|| edits
->to_slashes
)
800 /* Handle upshifting, downshifting and slash translation now. */
802 for ( p
= out
->value
+ pos
; *p
; ++p
)
804 if ( edits
->upshift
)
806 else if ( edits
->downshift
)
808 if ( edits
->to_slashes
&& ( *p
== '\\' ) )
816 * Reads n LISTs from the top of the STACK and combines them to form VAR_EDITS.
817 * Returns the number of VAR_EDITS pushed onto the STACK.
820 static int expand_modifiers( STACK
* s
, int n
)
824 LIST
* * args
= stack_get( s
);
825 for ( i
= 0; i
< n
; ++i
)
826 total
*= list_length( args
[ i
] );
830 VAR_EDITS
* out
= stack_allocate( s
, total
* sizeof( VAR_EDITS
) );
831 LISTITER
* iter
= stack_allocate( s
, n
* sizeof( LIST
* ) );
832 for ( i
= 0; i
< n
; ++i
)
833 iter
[ i
] = list_begin( args
[ i
] );
838 memset( out
, 0, sizeof( *out
) );
840 for ( i
= 0; i
< n
; ++i
)
841 havezeroed
= var_edit_parse( object_str( list_item( iter
[ i
] )
842 ), out
, havezeroed
);
846 if ( list_next( iter
[ i
] ) != list_end( args
[ i
] ) )
848 iter
[ i
] = list_next( iter
[ i
] );
851 iter
[ i
] = list_begin( args
[ i
] );
854 stack_deallocate( s
, n
* sizeof( LIST
* ) );
859 static LIST
* apply_modifiers( STACK
* s
, int n
)
861 LIST
* value
= stack_top( s
);
863 VAR_EDITS
* const edits
= (VAR_EDITS
*)( (LIST
* *)stack_get( s
) + 1 );
866 result
= apply_modifiers_impl( result
, buf
, edits
, n
, list_begin( value
),
874 * Parse a string of the form "1-2", "-2--1", "2-" and return the two
878 subscript_t
parse_subscript( char const * s
)
883 do /* so we can use "break" */
885 /* Allow negative subscripts. */
886 if ( !isdigit( *s
) && ( *s
!= '-' ) )
891 result
.sub1
= atoi( s
);
893 /* Skip over the first symbol, which is either a digit or dash. */
895 while ( isdigit( *s
) ) ++s
;
899 result
.sub2
= result
.sub1
;
917 if ( !isdigit( *s
) && ( *s
!= '-' ) )
923 /* First, compute the index of the last element. */
924 result
.sub2
= atoi( s
);
925 while ( isdigit( *++s
) );
934 static LIST
* apply_subscript( STACK
* s
)
936 LIST
* value
= stack_top( s
);
937 LIST
* indices
= stack_at( s
, 1 );
939 int length
= list_length( value
);
941 LISTITER indices_iter
= list_begin( indices
);
942 LISTITER
const indices_end
= list_end( indices
);
944 for ( ; indices_iter
!= indices_end
; indices_iter
= list_next( indices_iter
947 LISTITER iter
= list_begin( value
);
948 LISTITER end
= list_end( value
);
949 subscript_t
const subscript
= parse_subscript( object_str( list_item(
951 get_iters( subscript
, &iter
, &end
, length
);
952 for ( ; iter
!= end
; iter
= list_next( iter
) )
953 result
= list_push_back( result
, object_copy( list_item( iter
) ) );
961 * Reads the LIST from first and applies subscript to it. The results are
962 * written to *first and *last.
965 static void get_iters( subscript_t
const subscript
, LISTITER
* const first
,
966 LISTITER
* const last
, int const length
)
974 if ( subscript
.sub1
< 0 )
975 start
= length
+ subscript
.sub1
;
976 else if ( subscript
.sub1
> length
)
979 start
= subscript
.sub1
- 1;
981 size
= subscript
.sub2
< 0
982 ? length
+ 1 + subscript
.sub2
- start
983 : subscript
.sub2
- start
;
986 * HACK: When the first subscript is before the start of the list, it
987 * magically becomes the beginning of the list. This is inconsistent,
988 * but needed for backwards compatibility.
993 /* The "sub2 < 0" test handles the semantic error of sub2 < sub1. */
997 if ( start
+ size
> length
)
998 size
= length
- start
;
1002 while ( start
-- > 0 )
1003 iter
= list_next( iter
);
1006 while ( size
-- > 0 )
1007 end
= list_next( end
);
1013 static LIST
* apply_modifiers_empty( LIST
* result
, string
* buf
,
1014 VAR_EDITS
* edits
, int n
)
1017 for ( i
= 0; i
< n
; ++i
)
1019 if ( edits
[ i
].empty
.ptr
)
1021 /** FIXME: is empty.ptr always null-terminated? */
1022 var_edit_file( edits
[ i
].empty
.ptr
, buf
, edits
+ i
);
1023 var_edit_shift( buf
, 0, edits
+ i
);
1024 result
= list_push_back( result
, object_new( buf
->value
) );
1025 string_truncate( buf
, 0 );
1031 static LIST
* apply_modifiers_non_empty( LIST
* result
, string
* buf
,
1032 VAR_EDITS
* edits
, int n
, LISTITER begin
, LISTITER end
)
1036 for ( i
= 0; i
< n
; ++i
)
1038 if ( edits
[ i
].join
.ptr
)
1040 var_edit_file( object_str( list_item( begin
) ), buf
, edits
+ i
);
1041 var_edit_shift( buf
, 0, edits
+ i
);
1042 for ( iter
= list_next( begin
); iter
!= end
; iter
= list_next( iter
1046 string_append( buf
, edits
[ i
].join
.ptr
);
1048 var_edit_file( object_str( list_item( iter
) ), buf
, edits
+ i
1050 var_edit_shift( buf
, size
, edits
+ i
);
1052 result
= list_push_back( result
, object_new( buf
->value
) );
1053 string_truncate( buf
, 0 );
1057 for ( iter
= begin
; iter
!= end
; iter
= list_next( iter
) )
1059 var_edit_file( object_str( list_item( iter
) ), buf
, edits
+ i
);
1060 var_edit_shift( buf
, 0, edits
+ i
);
1061 result
= list_push_back( result
, object_new( buf
->value
) );
1062 string_truncate( buf
, 0 );
1069 static LIST
* apply_modifiers_impl( LIST
* result
, string
* buf
,
1070 VAR_EDITS
* edits
, int n
, LISTITER iter
, LISTITER end
)
1073 ? apply_modifiers_empty( result
, buf
, edits
, n
)
1074 : apply_modifiers_non_empty( result
, buf
, edits
, n
, iter
, end
);
1077 static LIST
* apply_subscript_and_modifiers( STACK
* s
, int n
)
1079 LIST
* const value
= stack_top( s
);
1080 LIST
* const indices
= stack_at( s
, 1 );
1082 VAR_EDITS
* const edits
= (VAR_EDITS
*)((LIST
* *)stack_get( s
) + 2);
1083 int const length
= list_length( value
);
1085 LISTITER indices_iter
= list_begin( indices
);
1086 LISTITER
const indices_end
= list_end( indices
);
1088 for ( ; indices_iter
!= indices_end
; indices_iter
= list_next( indices_iter
1091 LISTITER iter
= list_begin( value
);
1092 LISTITER end
= list_end( value
);
1093 subscript_t
const sub
= parse_subscript( object_str( list_item(
1095 get_iters( sub
, &iter
, &end
, length
);
1096 result
= apply_modifiers_impl( result
, buf
, edits
, n
, iter
, end
);
1104 * expand() - expands a list of concatenated strings and variable refereces
1106 * Takes a list of expansion items - each representing one element to be
1107 * concatenated and each containing a list of its values. Returns a list of all
1108 * possible values constructed by selecting a single value from each of the
1109 * elements and concatenating them together.
1111 * For example, in the following code:
1113 * local a = one two three four ;
1114 * local b = foo bar ;
1115 * ECHO /$(a)/$(b)/$(a)/ ;
1117 * When constructing the result of /$(a)/$(b)/ this function would get called
1118 * with the following 7 expansion items:
1120 * 2. one two three four
1124 * 6. one two three four
1127 * And would result in a list containing 32 values:
1130 * 3. /one/foo/three/
1137 typedef struct expansion_item
1139 /* Item's value list initialized prior to calling expand(). */
1142 /* Internal data initialized and used inside expand(). */
1143 LISTITER current
; /* Currently used value. */
1144 int size
; /* Concatenated string length prior to concatenating the
1145 * item's current value.
1149 static LIST
* expand( expansion_item
* items
, int const length
)
1156 assert( length
> 0 );
1157 for ( i
= 0; i
< length
; ++i
)
1159 LISTITER iter
= list_begin( items
[ i
].values
);
1160 LISTITER
const end
= list_end( items
[ i
].values
);
1162 /* If any of the items has no values - the result is an empty list. */
1163 if ( iter
== end
) return L0
;
1165 /* Set each item's 'current' to its first listed value. This indicates
1166 * each item's next value to be used when constructing the list of all
1167 * possible concatenated values.
1169 items
[ i
].current
= iter
;
1171 /* Calculate the longest concatenated string length - to know how much
1172 * memory we need to allocate as a buffer for holding the concatenated
1177 for ( ; iter
!= end
; iter
= list_next( iter
) )
1179 int const len
= strlen( object_str( list_item( iter
) ) );
1180 if ( len
> max
) max
= len
;
1187 string_reserve( buf
, size
);
1192 for ( ; i
< length
; ++i
)
1194 items
[ i
].size
= buf
->size
;
1195 string_append( buf
, object_str( list_item( items
[ i
].current
) ) );
1197 result
= list_push_back( result
, object_new( buf
->value
) );
1200 if ( list_next( items
[ i
].current
) != list_end( items
[ i
].values
1203 items
[ i
].current
= list_next( items
[ i
].current
);
1204 string_truncate( buf
, items
[ i
].size
);
1208 items
[ i
].current
= list_begin( items
[ i
].values
);
1216 static void combine_strings( STACK
* s
, int n
, string
* out
)
1219 for ( i
= 0; i
< n
; ++i
)
1221 LIST
* const values
= stack_pop( s
);
1222 LISTITER iter
= list_begin( values
);
1223 LISTITER
const end
= list_end( values
);
1226 string_append( out
, object_str( list_item( iter
) ) );
1227 for ( iter
= list_next( iter
); iter
!= end
; iter
= list_next( iter
1230 string_push_back( out
, ' ' );
1231 string_append( out
, object_str( list_item( iter
) ) );
1233 list_free( values
);
1238 struct dynamic_array
1245 static void dynamic_array_init( struct dynamic_array
* array
)
1248 array
->capacity
= 0;
1252 static void dynamic_array_free( struct dynamic_array
* array
)
1254 BJAM_FREE( array
->data
);
1257 static void dynamic_array_push_impl( struct dynamic_array
* const array
,
1258 void const * const value
, int const unit_size
)
1260 if ( array
->capacity
== 0 )
1262 array
->capacity
= 2;
1263 array
->data
= BJAM_MALLOC( array
->capacity
* unit_size
);
1265 else if ( array
->capacity
== array
->size
)
1268 array
->capacity
*= 2;
1269 new_data
= BJAM_MALLOC( array
->capacity
* unit_size
);
1270 memcpy( new_data
, array
->data
, array
->size
* unit_size
);
1271 BJAM_FREE( array
->data
);
1272 array
->data
= new_data
;
1274 memcpy( (char *)array
->data
+ array
->size
* unit_size
, value
, unit_size
);
1278 #define dynamic_array_push( array, value ) (dynamic_array_push_impl(array, &value, sizeof(value)))
1279 #define dynamic_array_at( type, array, idx ) (((type *)(array)->data)[idx])
1280 #define dynamic_array_pop( array ) (--(array)->size)
1288 int absolute_position
;
1289 struct dynamic_array uses
[ 1 ];
1292 #define LOOP_INFO_BREAK 0
1293 #define LOOP_INFO_CONTINUE 1
1307 struct arg_list
* arguments
;
1311 typedef struct compiler
1313 struct dynamic_array code
[ 1 ];
1314 struct dynamic_array constants
[ 1 ];
1315 struct dynamic_array labels
[ 1 ];
1316 struct dynamic_array rules
[ 1 ];
1317 struct dynamic_array actions
[ 1 ];
1318 struct dynamic_array cleanups
[ 1 ];
1319 struct dynamic_array loop_scopes
[ 1 ];
1322 static void compiler_init( compiler
* c
)
1324 dynamic_array_init( c
->code
);
1325 dynamic_array_init( c
->constants
);
1326 dynamic_array_init( c
->labels
);
1327 dynamic_array_init( c
->rules
);
1328 dynamic_array_init( c
->actions
);
1329 dynamic_array_init( c
->cleanups
);
1330 dynamic_array_init( c
->loop_scopes
);
1333 static void compiler_free( compiler
* c
)
1336 dynamic_array_free( c
->actions
);
1337 dynamic_array_free( c
->rules
);
1338 for ( i
= 0; i
< c
->labels
->size
; ++i
)
1339 dynamic_array_free( dynamic_array_at( struct label_info
, c
->labels
, i
1341 dynamic_array_free( c
->labels
);
1342 dynamic_array_free( c
->constants
);
1343 dynamic_array_free( c
->code
);
1344 dynamic_array_free( c
->cleanups
);
1345 dynamic_array_free( c
->loop_scopes
);
1348 static void compile_emit_instruction( compiler
* c
, instruction instr
)
1350 dynamic_array_push( c
->code
, instr
);
1353 static int compile_new_label( compiler
* c
)
1355 int result
= c
->labels
->size
;
1356 struct label_info info
;
1357 info
.absolute_position
= -1;
1358 dynamic_array_init( info
.uses
);
1359 dynamic_array_push( c
->labels
, info
);
1363 static void compile_set_label( compiler
* c
, int label
)
1365 struct label_info
* const l
= &dynamic_array_at( struct label_info
,
1367 int const pos
= c
->code
->size
;
1369 assert( l
->absolute_position
== -1 );
1370 l
->absolute_position
= pos
;
1371 for ( i
= 0; i
< l
->uses
->size
; ++i
)
1373 int id
= dynamic_array_at( int, l
->uses
, i
);
1374 int offset
= (int)( pos
- id
- 1 );
1375 dynamic_array_at( instruction
, c
->code
, id
).arg
= offset
;
1379 static void compile_emit( compiler
* c
, unsigned int op_code
, int arg
)
1382 instr
.op_code
= op_code
;
1384 compile_emit_instruction( c
, instr
);
1387 static void compile_emit_branch( compiler
* c
, unsigned int op_code
, int label
)
1389 struct label_info
* const l
= &dynamic_array_at( struct label_info
,
1391 int const pos
= c
->code
->size
;
1393 instr
.op_code
= op_code
;
1394 if ( l
->absolute_position
== -1 )
1397 dynamic_array_push( l
->uses
, pos
);
1400 instr
.arg
= (int)( l
->absolute_position
- pos
- 1 );
1401 compile_emit_instruction( c
, instr
);
1404 static int compile_emit_constant( compiler
* c
, OBJECT
* value
)
1406 OBJECT
* copy
= object_copy( value
);
1407 dynamic_array_push( c
->constants
, copy
);
1408 return c
->constants
->size
- 1;
1411 static void compile_push_cleanup( compiler
* c
, unsigned int op_code
, int arg
)
1414 instr
.op_code
= op_code
;
1416 dynamic_array_push( c
->cleanups
, instr
);
1419 static void compile_pop_cleanup( compiler
* c
)
1421 dynamic_array_pop( c
->cleanups
);
1424 static void compile_emit_cleanups( compiler
* c
, int end
)
1427 for ( i
= c
->cleanups
->size
; --i
>= end
; )
1429 compile_emit_instruction( c
, dynamic_array_at( instruction
, c
->cleanups
, i
) );
1433 static void compile_emit_loop_jump( compiler
* c
, int type
)
1435 struct loop_info
* info
= NULL
;
1437 for ( i
= c
->loop_scopes
->size
; --i
>= 0; )
1439 struct loop_info
* elem
= &dynamic_array_at( struct loop_info
, c
->loop_scopes
, i
);
1440 if ( elem
->type
== type
)
1448 printf( "warning: ignoring break statement used outside of loop\n" );
1451 compile_emit_cleanups( c
, info
->cleanup_depth
);
1452 compile_emit_branch( c
, INSTR_JUMP
, info
->label
);
1455 static void compile_push_break_scope( compiler
* c
, int label
)
1457 struct loop_info info
;
1458 info
.type
= LOOP_INFO_BREAK
;
1460 info
.cleanup_depth
= c
->cleanups
->size
;
1461 dynamic_array_push( c
->loop_scopes
, info
);
1464 static void compile_push_continue_scope( compiler
* c
, int label
)
1466 struct loop_info info
;
1467 info
.type
= LOOP_INFO_CONTINUE
;
1469 info
.cleanup_depth
= c
->cleanups
->size
;
1470 dynamic_array_push( c
->loop_scopes
, info
);
1473 static void compile_pop_break_scope( compiler
* c
)
1475 assert( c
->loop_scopes
->size
> 0 );
1476 assert( dynamic_array_at( struct loop_info
, c
->loop_scopes
, c
->loop_scopes
->size
- 1 ).type
== LOOP_INFO_BREAK
);
1477 dynamic_array_pop( c
->loop_scopes
);
1480 static void compile_pop_continue_scope( compiler
* c
)
1482 assert( c
->loop_scopes
->size
> 0 );
1483 assert( dynamic_array_at( struct loop_info
, c
->loop_scopes
, c
->loop_scopes
->size
- 1 ).type
== LOOP_INFO_CONTINUE
);
1484 dynamic_array_pop( c
->loop_scopes
);
1487 static int compile_emit_rule( compiler
* c
, OBJECT
* name
, PARSE
* parse
,
1488 int num_arguments
, struct arg_list
* arguments
, int local
)
1490 struct stored_rule rule
;
1491 rule
.name
= object_copy( name
);
1493 rule
.num_arguments
= num_arguments
;
1494 rule
.arguments
= arguments
;
1496 dynamic_array_push( c
->rules
, rule
);
1497 return (int)( c
->rules
->size
- 1 );
1500 static int compile_emit_actions( compiler
* c
, PARSE
* parse
)
1503 a
.name
= object_copy( parse
->string
);
1504 a
.command
= function_compile_actions( object_str( parse
->string1
),
1505 parse
->file
, parse
->line
);
1506 a
.flags
= parse
->num
;
1507 dynamic_array_push( c
->actions
, a
);
1508 return (int)( c
->actions
->size
- 1 );
1511 static JAM_FUNCTION
* compile_to_function( compiler
* c
)
1513 JAM_FUNCTION
* const result
= BJAM_MALLOC( sizeof( JAM_FUNCTION
) );
1515 result
->base
.type
= FUNCTION_JAM
;
1516 result
->base
.reference_count
= 1;
1517 result
->base
.formal_arguments
= 0;
1518 result
->base
.num_formal_arguments
= 0;
1520 result
->base
.rulename
= 0;
1522 result
->code_size
= c
->code
->size
;
1523 result
->code
= BJAM_MALLOC( c
->code
->size
* sizeof( instruction
) );
1524 memcpy( result
->code
, c
->code
->data
, c
->code
->size
* sizeof( instruction
) );
1526 result
->constants
= BJAM_MALLOC( c
->constants
->size
* sizeof( OBJECT
* ) );
1527 memcpy( result
->constants
, c
->constants
->data
, c
->constants
->size
* sizeof(
1529 result
->num_constants
= c
->constants
->size
;
1531 result
->num_subfunctions
= c
->rules
->size
;
1532 result
->functions
= BJAM_MALLOC( c
->rules
->size
* sizeof( SUBFUNCTION
) );
1533 for ( i
= 0; i
< c
->rules
->size
; ++i
)
1535 struct stored_rule
* const rule
= &dynamic_array_at( struct stored_rule
,
1537 result
->functions
[ i
].name
= rule
->name
;
1538 result
->functions
[ i
].code
= function_compile( rule
->parse
);
1539 result
->functions
[ i
].code
->num_formal_arguments
= rule
->num_arguments
;
1540 result
->functions
[ i
].code
->formal_arguments
= rule
->arguments
;
1541 result
->functions
[ i
].local
= rule
->local
;
1544 result
->actions
= BJAM_MALLOC( c
->actions
->size
* sizeof( SUBACTION
) );
1545 memcpy( result
->actions
, c
->actions
->data
, c
->actions
->size
* sizeof(
1547 result
->num_subactions
= c
->actions
->size
;
1549 result
->generic
= 0;
1559 * Parsing of variable expansions
1562 typedef struct VAR_PARSE_GROUP
1564 struct dynamic_array elems
[ 1 ];
1567 typedef struct VAR_PARSE_ACTIONS
1569 struct dynamic_array elems
[ 1 ];
1570 } VAR_PARSE_ACTIONS
;
1572 #define VAR_PARSE_TYPE_VAR 0
1573 #define VAR_PARSE_TYPE_STRING 1
1574 #define VAR_PARSE_TYPE_FILE 2
1576 typedef struct _var_parse
1578 int type
; /* string, variable or file */
1584 VAR_PARSE_GROUP
* name
;
1585 VAR_PARSE_GROUP
* subscript
;
1586 struct dynamic_array modifiers
[ 1 ];
1598 struct dynamic_array filename
[ 1 ];
1599 struct dynamic_array contents
[ 1 ];
1602 static void var_parse_free( VAR_PARSE
* );
1609 static VAR_PARSE_GROUP
* var_parse_group_new()
1611 VAR_PARSE_GROUP
* const result
= BJAM_MALLOC( sizeof( VAR_PARSE_GROUP
) );
1612 dynamic_array_init( result
->elems
);
1616 static void var_parse_group_free( VAR_PARSE_GROUP
* group
)
1619 for ( i
= 0; i
< group
->elems
->size
; ++i
)
1620 var_parse_free( dynamic_array_at( VAR_PARSE
*, group
->elems
, i
) );
1621 dynamic_array_free( group
->elems
);
1625 static void var_parse_group_add( VAR_PARSE_GROUP
* group
, VAR_PARSE
* elem
)
1627 dynamic_array_push( group
->elems
, elem
);
1630 static void var_parse_group_maybe_add_constant( VAR_PARSE_GROUP
* group
,
1631 char const * start
, char const * end
)
1636 VAR_PARSE_STRING
* const value
= (VAR_PARSE_STRING
*)BJAM_MALLOC(
1637 sizeof(VAR_PARSE_STRING
) );
1638 value
->base
.type
= VAR_PARSE_TYPE_STRING
;
1640 string_append_range( buf
, start
, end
);
1641 value
->s
= object_new( buf
->value
);
1643 var_parse_group_add( group
, (VAR_PARSE
*)value
);
1647 VAR_PARSE_STRING
* var_parse_group_as_literal( VAR_PARSE_GROUP
* group
)
1649 if ( group
->elems
->size
== 1 )
1651 VAR_PARSE
* result
= dynamic_array_at( VAR_PARSE
*, group
->elems
, 0 );
1652 if ( result
->type
== VAR_PARSE_TYPE_STRING
)
1653 return (VAR_PARSE_STRING
*)result
;
1663 static VAR_PARSE_ACTIONS
* var_parse_actions_new()
1665 VAR_PARSE_ACTIONS
* const result
= (VAR_PARSE_ACTIONS
*)BJAM_MALLOC(
1666 sizeof(VAR_PARSE_ACTIONS
) );
1667 dynamic_array_init( result
->elems
);
1671 static void var_parse_actions_free( VAR_PARSE_ACTIONS
* actions
)
1674 for ( i
= 0; i
< actions
->elems
->size
; ++i
)
1675 var_parse_group_free( dynamic_array_at( VAR_PARSE_GROUP
*,
1676 actions
->elems
, i
) );
1677 dynamic_array_free( actions
->elems
);
1678 BJAM_FREE( actions
);
1686 static VAR_PARSE_VAR
* var_parse_var_new()
1688 VAR_PARSE_VAR
* result
= BJAM_MALLOC( sizeof( VAR_PARSE_VAR
) );
1689 result
->base
.type
= VAR_PARSE_TYPE_VAR
;
1690 result
->name
= var_parse_group_new();
1691 result
->subscript
= 0;
1692 dynamic_array_init( result
->modifiers
);
1696 static void var_parse_var_free( VAR_PARSE_VAR
* var
)
1699 var_parse_group_free( var
->name
);
1700 if ( var
->subscript
)
1701 var_parse_group_free( var
->subscript
);
1702 for ( i
= 0; i
< var
->modifiers
->size
; ++i
)
1703 var_parse_group_free( dynamic_array_at( VAR_PARSE_GROUP
*,
1704 var
->modifiers
, i
) );
1705 dynamic_array_free( var
->modifiers
);
1709 static VAR_PARSE_GROUP
* var_parse_var_new_modifier( VAR_PARSE_VAR
* var
)
1711 VAR_PARSE_GROUP
* result
= var_parse_group_new();
1712 dynamic_array_push( var
->modifiers
, result
);
1721 static void var_parse_string_free( VAR_PARSE_STRING
* string
)
1723 object_free( string
->s
);
1724 BJAM_FREE( string
);
1732 static VAR_PARSE_FILE
* var_parse_file_new( void )
1734 VAR_PARSE_FILE
* const result
= (VAR_PARSE_FILE
*)BJAM_MALLOC( sizeof(
1736 result
->base
.type
= VAR_PARSE_TYPE_FILE
;
1737 dynamic_array_init( result
->filename
);
1738 dynamic_array_init( result
->contents
);
1742 static void var_parse_file_free( VAR_PARSE_FILE
* file
)
1745 for ( i
= 0; i
< file
->filename
->size
; ++i
)
1746 var_parse_group_free( dynamic_array_at( VAR_PARSE_GROUP
*,
1747 file
->filename
, i
) );
1748 dynamic_array_free( file
->filename
);
1749 for ( i
= 0; i
< file
->contents
->size
; ++i
)
1750 var_parse_group_free( dynamic_array_at( VAR_PARSE_GROUP
*,
1751 file
->contents
, i
) );
1752 dynamic_array_free( file
->contents
);
1761 static void var_parse_free( VAR_PARSE
* parse
)
1763 switch ( parse
->type
)
1765 case VAR_PARSE_TYPE_VAR
:
1766 var_parse_var_free( (VAR_PARSE_VAR
*)parse
);
1769 case VAR_PARSE_TYPE_STRING
:
1770 var_parse_string_free( (VAR_PARSE_STRING
*)parse
);
1773 case VAR_PARSE_TYPE_FILE
:
1774 var_parse_file_free( (VAR_PARSE_FILE
*)parse
);
1778 assert( !"Invalid type" );
1787 static void var_parse_group_compile( VAR_PARSE_GROUP
const * parse
,
1790 static void var_parse_var_compile( VAR_PARSE_VAR
const * parse
, compiler
* c
)
1792 int expand_name
= 0;
1793 int is_get_grist
= 0;
1794 int has_modifiers
= 0;
1795 /* Special case common modifiers */
1796 if ( parse
->modifiers
->size
== 1 )
1798 VAR_PARSE_GROUP
* mod
= dynamic_array_at( VAR_PARSE_GROUP
*, parse
->modifiers
, 0 );
1799 if ( mod
->elems
->size
== 1 )
1801 VAR_PARSE
* mod1
= dynamic_array_at( VAR_PARSE
*, mod
->elems
, 0 );
1802 if ( mod1
->type
== VAR_PARSE_TYPE_STRING
)
1804 OBJECT
* s
= ( (VAR_PARSE_STRING
*)mod1
)->s
;
1805 if ( ! strcmp ( object_str( s
), "G" ) )
1812 /* If there are modifiers, emit them in reverse order. */
1813 if ( parse
->modifiers
->size
> 0 && !is_get_grist
)
1817 for ( i
= 0; i
< parse
->modifiers
->size
; ++i
)
1818 var_parse_group_compile( dynamic_array_at( VAR_PARSE_GROUP
*,
1819 parse
->modifiers
, parse
->modifiers
->size
- i
- 1 ), c
);
1822 /* If there is a subscript, emit it. */
1823 if ( parse
->subscript
)
1824 var_parse_group_compile( parse
->subscript
, c
);
1826 /* If the variable name is empty, look it up. */
1827 if ( parse
->name
->elems
->size
== 0 )
1828 compile_emit( c
, INSTR_PUSH_VAR
, compile_emit_constant( c
,
1830 /* If the variable name does not need to be expanded, look it up. */
1831 else if ( parse
->name
->elems
->size
== 1 && dynamic_array_at( VAR_PARSE
*,
1832 parse
->name
->elems
, 0 )->type
== VAR_PARSE_TYPE_STRING
)
1834 OBJECT
* const name
= ( (VAR_PARSE_STRING
*)dynamic_array_at(
1835 VAR_PARSE
*, parse
->name
->elems
, 0 ) )->s
;
1836 int const idx
= get_argument_index( object_str( name
) );
1838 compile_emit( c
, INSTR_PUSH_ARG
, idx
);
1840 compile_emit( c
, INSTR_PUSH_VAR
, compile_emit_constant( c
, name
) );
1842 /* Otherwise, push the var names and use the group instruction. */
1845 var_parse_group_compile( parse
->name
, c
);
1849 /** Select the instruction for expanding the variable. */
1850 if ( !has_modifiers
&& !parse
->subscript
&& !expand_name
)
1852 else if ( !has_modifiers
&& !parse
->subscript
&& expand_name
)
1853 compile_emit( c
, INSTR_PUSH_GROUP
, 0 );
1854 else if ( !has_modifiers
&& parse
->subscript
&& !expand_name
)
1855 compile_emit( c
, INSTR_APPLY_INDEX
, 0 );
1856 else if ( !has_modifiers
&& parse
->subscript
&& expand_name
)
1857 compile_emit( c
, INSTR_APPLY_INDEX_GROUP
, 0 );
1858 else if ( has_modifiers
&& !parse
->subscript
&& !expand_name
)
1859 compile_emit( c
, INSTR_APPLY_MODIFIERS
, parse
->modifiers
->size
);
1860 else if ( has_modifiers
&& !parse
->subscript
&& expand_name
)
1861 compile_emit( c
, INSTR_APPLY_MODIFIERS_GROUP
, parse
->modifiers
->size
);
1862 else if ( has_modifiers
&& parse
->subscript
&& !expand_name
)
1863 compile_emit( c
, INSTR_APPLY_INDEX_MODIFIERS
, parse
->modifiers
->size
);
1864 else if ( has_modifiers
&& parse
->subscript
&& expand_name
)
1865 compile_emit( c
, INSTR_APPLY_INDEX_MODIFIERS_GROUP
,
1866 parse
->modifiers
->size
);
1868 /* Now apply any special modifiers */
1871 compile_emit( c
, INSTR_GET_GRIST
, 0 );
1875 static void var_parse_string_compile( VAR_PARSE_STRING
const * parse
,
1878 compile_emit( c
, INSTR_PUSH_CONSTANT
, compile_emit_constant( c
, parse
->s
)
1882 static void var_parse_file_compile( VAR_PARSE_FILE
const * parse
, compiler
* c
)
1885 for ( i
= 0; i
< parse
->filename
->size
; ++i
)
1886 var_parse_group_compile( dynamic_array_at( VAR_PARSE_GROUP
*,
1887 parse
->filename
, parse
->filename
->size
- i
- 1 ), c
);
1888 compile_emit( c
, INSTR_APPEND_STRINGS
, parse
->filename
->size
);
1889 for ( i
= 0; i
< parse
->contents
->size
; ++i
)
1890 var_parse_group_compile( dynamic_array_at( VAR_PARSE_GROUP
*,
1891 parse
->contents
, parse
->contents
->size
- i
- 1 ), c
);
1892 compile_emit( c
, INSTR_WRITE_FILE
, parse
->contents
->size
);
1895 static void var_parse_compile( VAR_PARSE
const * parse
, compiler
* c
)
1897 switch ( parse
->type
)
1899 case VAR_PARSE_TYPE_VAR
:
1900 var_parse_var_compile( (VAR_PARSE_VAR
const *)parse
, c
);
1903 case VAR_PARSE_TYPE_STRING
:
1904 var_parse_string_compile( (VAR_PARSE_STRING
const *)parse
, c
);
1907 case VAR_PARSE_TYPE_FILE
:
1908 var_parse_file_compile( (VAR_PARSE_FILE
const *)parse
, c
);
1912 assert( !"Unknown var parse type." );
1916 static void var_parse_group_compile( VAR_PARSE_GROUP
const * parse
, compiler
* c
1919 /* Emit the elements in reverse order. */
1921 for ( i
= 0; i
< parse
->elems
->size
; ++i
)
1922 var_parse_compile( dynamic_array_at( VAR_PARSE
*, parse
->elems
,
1923 parse
->elems
->size
- i
- 1 ), c
);
1924 /* If there are no elements, emit an empty string. */
1925 if ( parse
->elems
->size
== 0 )
1926 compile_emit( c
, INSTR_PUSH_CONSTANT
, compile_emit_constant( c
,
1928 /* If there is more than one element, combine them. */
1929 if ( parse
->elems
->size
> 1 )
1930 compile_emit( c
, INSTR_COMBINE_STRINGS
, parse
->elems
->size
);
1933 static void var_parse_actions_compile( VAR_PARSE_ACTIONS
const * actions
,
1937 for ( i
= 0; i
< actions
->elems
->size
; ++i
)
1938 var_parse_group_compile( dynamic_array_at( VAR_PARSE_GROUP
*,
1939 actions
->elems
, actions
->elems
->size
- i
- 1 ), c
);
1940 compile_emit( c
, INSTR_OUTPUT_STRINGS
, actions
->elems
->size
);
1945 * Parse VAR_PARSE_VAR
1948 static VAR_PARSE
* parse_at_file( char const * start
, char const * mid
,
1950 static VAR_PARSE
* parse_variable( char const * * string
);
1951 static int try_parse_variable( char const * * s_
, char const * * string
,
1952 VAR_PARSE_GROUP
* out
);
1953 static void balance_parentheses( char const * * s_
, char const * * string
,
1954 VAR_PARSE_GROUP
* out
);
1955 static void parse_var_string( char const * first
, char const * last
,
1956 struct dynamic_array
* out
);
1960 * Parses a string that can contain variables to expand.
1963 static VAR_PARSE_GROUP
* parse_expansion( char const * * string
)
1965 VAR_PARSE_GROUP
* result
= var_parse_group_new();
1966 char const * s
= *string
;
1969 if ( try_parse_variable( &s
, string
, result
) ) {}
1970 else if ( s
[ 0 ] == '\0' )
1972 var_parse_group_maybe_add_constant( result
, *string
, s
);
1980 static VAR_PARSE_ACTIONS
* parse_actions( char const * string
)
1982 VAR_PARSE_ACTIONS
* const result
= var_parse_actions_new();
1983 parse_var_string( string
, string
+ strlen( string
), result
->elems
);
1988 * Checks whether the string a *s_ starts with a variable expansion "$(".
1989 * *string should point to the first unemitted character before *s. If *s_
1990 * starts with variable expansion, appends elements to out up to the closing
1991 * ")", and adjusts *s_ and *string to point to next character. Returns 1 if s_
1992 * starts with a variable, 0 otherwise.
1995 static int try_parse_variable( char const * * s_
, char const * * string
,
1996 VAR_PARSE_GROUP
* out
)
1998 char const * s
= *s_
;
1999 if ( s
[ 0 ] == '$' && s
[ 1 ] == '(' )
2001 var_parse_group_maybe_add_constant( out
, *string
, s
);
2003 var_parse_group_add( out
, parse_variable( &s
) );
2008 if ( s
[ 0 ] == '@' && s
[ 1 ] == '(' )
2012 char const * split
= 0;
2013 var_parse_group_maybe_add_constant( out
, *string
, s
);
2017 /* Scan the content of the response file @() section. */
2018 while ( *ine
&& ( depth
> 0 ) )
2022 case '(': ++depth
; break;
2023 case ')': --depth
; break;
2025 if ( ( depth
== 1 ) && ( ine
[ 1 ] == 'E' ) && ( ine
[ 2 ] == '='
2033 if ( !split
|| depth
)
2036 var_parse_group_add( out
, parse_at_file( s
, split
, ine
- 1 ) );
2045 static char const * current_file
= "";
2046 static int current_line
;
2048 static void parse_error( char const * message
)
2050 out_printf( "%s:%d: %s\n", current_file
, current_line
, message
);
2055 * Parses a single variable up to the closing ")" and adjusts *string to point
2056 * to the next character. *string should point to the character immediately
2057 * after the initial "$(".
2060 static VAR_PARSE
* parse_variable( char const * * string
)
2062 VAR_PARSE_VAR
* const result
= var_parse_var_new();
2063 VAR_PARSE_GROUP
* const name
= result
->name
;
2064 char const * s
= *string
;
2067 if ( try_parse_variable( &s
, string
, name
) ) {}
2068 else if ( s
[ 0 ] == ':' )
2070 VAR_PARSE_GROUP
* mod
;
2071 var_parse_group_maybe_add_constant( name
, *string
, s
);
2074 mod
= var_parse_var_new_modifier( result
);
2077 if ( try_parse_variable( &s
, string
, mod
) ) {}
2078 else if ( s
[ 0 ] == ')' )
2080 var_parse_group_maybe_add_constant( mod
, *string
, s
);
2082 return (VAR_PARSE
*)result
;
2084 else if ( s
[ 0 ] == '(' )
2087 balance_parentheses( &s
, string
, mod
);
2089 else if ( s
[ 0 ] == ':' )
2091 var_parse_group_maybe_add_constant( mod
, *string
, s
);
2093 mod
= var_parse_var_new_modifier( result
);
2095 else if ( s
[ 0 ] == '[' )
2097 parse_error("unexpected subscript");
2100 else if ( s
[ 0 ] == '\0' )
2102 parse_error( "unbalanced parentheses" );
2103 var_parse_group_maybe_add_constant( mod
, *string
, s
);
2105 return (VAR_PARSE
*)result
;
2111 else if ( s
[ 0 ] == '[' )
2113 VAR_PARSE_GROUP
* subscript
= var_parse_group_new();
2114 result
->subscript
= subscript
;
2115 var_parse_group_maybe_add_constant( name
, *string
, s
);
2119 if ( try_parse_variable( &s
, string
, subscript
) ) {}
2120 else if ( s
[ 0 ] == ']' )
2122 var_parse_group_maybe_add_constant( subscript
, *string
, s
);
2124 if ( s
[ 0 ] != ')' && s
[ 0 ] != ':' && s
[ 0 ] != '\0' )
2125 parse_error( "unexpected text following []" );
2128 else if ( isdigit( s
[ 0 ] ) || s
[ 0 ] == '-' )
2132 else if ( s
[ 0 ] == '\0' )
2134 parse_error( "malformed subscript" );
2139 parse_error( "malformed subscript" );
2144 else if ( s
[ 0 ] == ')' )
2146 var_parse_group_maybe_add_constant( name
, *string
, s
);
2148 return (VAR_PARSE
*)result
;
2150 else if ( s
[ 0 ] == '(' )
2153 balance_parentheses( &s
, string
, name
);
2155 else if ( s
[ 0 ] == '\0' )
2157 parse_error( "unbalanced parentheses" );
2158 var_parse_group_maybe_add_constant( name
, *string
, s
);
2160 return (VAR_PARSE
*)result
;
2167 static void parse_var_string( char const * first
, char const * last
,
2168 struct dynamic_array
* out
)
2170 char const * saved
= first
;
2171 while ( first
!= last
)
2173 /* Handle whitespace. */
2174 while ( first
!= last
&& isspace( *first
) ) ++first
;
2175 if ( saved
!= first
)
2177 VAR_PARSE_GROUP
* const group
= var_parse_group_new();
2178 var_parse_group_maybe_add_constant( group
, saved
, first
);
2180 dynamic_array_push( out
, group
);
2182 if ( first
== last
) break;
2184 /* Handle non-whitespace */
2186 VAR_PARSE_GROUP
* group
= var_parse_group_new();
2189 if ( first
== last
|| isspace( *first
) )
2191 var_parse_group_maybe_add_constant( group
, saved
, first
);
2195 if ( try_parse_variable( &first
, &saved
, group
) )
2196 assert( first
<= last
);
2200 dynamic_array_push( out
, group
);
2206 * start should point to the character immediately following the opening "@(",
2207 * mid should point to the ":E=", and end should point to the closing ")".
2210 static VAR_PARSE
* parse_at_file( char const * start
, char const * mid
,
2213 VAR_PARSE_FILE
* result
= var_parse_file_new();
2214 parse_var_string( start
, mid
, result
->filename
);
2215 parse_var_string( mid
+ 3, end
, result
->contents
);
2216 return (VAR_PARSE
*)result
;
2220 * Given that *s_ points to the character after a "(", parses up to the matching
2221 * ")". *string should point to the first unemitted character before *s_.
2223 * When the function returns, *s_ will point to the character after the ")", and
2224 * *string will point to the first unemitted character before *s_. The range
2225 * from *string to *s_ does not contain any variables that need to be expanded.
2228 void balance_parentheses( char const * * s_
, char const * * string
,
2229 VAR_PARSE_GROUP
* out
)
2232 char const * s
= *s_
;
2235 if ( try_parse_variable( &s
, string
, out
) ) { }
2236 else if ( s
[ 0 ] == ':' || s
[ 0 ] == '[' )
2238 parse_error( "unbalanced parentheses" );
2241 else if ( s
[ 0 ] == '\0' )
2243 parse_error( "unbalanced parentheses" );
2246 else if ( s
[ 0 ] == ')' )
2249 if ( --depth
== 0 ) break;
2251 else if ( s
[ 0 ] == '(' )
2267 #define RESULT_STACK 0
2268 #define RESULT_RETURN 1
2269 #define RESULT_NONE 2
2271 static void compile_parse( PARSE
* parse
, compiler
* c
, int result_location
);
2272 static struct arg_list
* arg_list_compile( PARSE
* parse
, int * num_arguments
);
2274 static void compile_condition( PARSE
* parse
, compiler
* c
, int branch_true
, int label
)
2276 assert( parse
->type
== PARSE_EVAL
);
2277 switch ( parse
->num
)
2280 compile_parse( parse
->left
, c
, RESULT_STACK
);
2282 compile_emit_branch( c
, INSTR_JUMP_NOT_EMPTY
, label
);
2284 compile_emit_branch( c
, INSTR_JUMP_EMPTY
, label
);
2288 compile_parse( parse
->left
, c
, RESULT_STACK
);
2289 compile_parse( parse
->right
, c
, RESULT_STACK
);
2291 compile_emit_branch( c
, INSTR_JUMP_EQ
, label
);
2293 compile_emit_branch( c
, INSTR_JUMP_NE
, label
);
2297 compile_parse( parse
->left
, c
, RESULT_STACK
);
2298 compile_parse( parse
->right
, c
, RESULT_STACK
);
2300 compile_emit_branch( c
, INSTR_JUMP_NE
, label
);
2302 compile_emit_branch( c
, INSTR_JUMP_EQ
, label
);
2306 compile_parse( parse
->left
, c
, RESULT_STACK
);
2307 compile_parse( parse
->right
, c
, RESULT_STACK
);
2309 compile_emit_branch( c
, INSTR_JUMP_LT
, label
);
2311 compile_emit_branch( c
, INSTR_JUMP_GE
, label
);
2315 compile_parse( parse
->left
, c
, RESULT_STACK
);
2316 compile_parse( parse
->right
, c
, RESULT_STACK
);
2318 compile_emit_branch( c
, INSTR_JUMP_LE
, label
);
2320 compile_emit_branch( c
, INSTR_JUMP_GT
, label
);
2324 compile_parse( parse
->left
, c
, RESULT_STACK
);
2325 compile_parse( parse
->right
, c
, RESULT_STACK
);
2327 compile_emit_branch( c
, INSTR_JUMP_GT
, label
);
2329 compile_emit_branch( c
, INSTR_JUMP_LE
, label
);
2333 compile_parse( parse
->left
, c
, RESULT_STACK
);
2334 compile_parse( parse
->right
, c
, RESULT_STACK
);
2336 compile_emit_branch( c
, INSTR_JUMP_GE
, label
);
2338 compile_emit_branch( c
, INSTR_JUMP_LT
, label
);
2342 compile_parse( parse
->left
, c
, RESULT_STACK
);
2343 compile_parse( parse
->right
, c
, RESULT_STACK
);
2345 compile_emit_branch( c
, INSTR_JUMP_IN
, label
);
2347 compile_emit_branch( c
, INSTR_JUMP_NOT_IN
, label
);
2353 int f
= compile_new_label( c
);
2354 compile_condition( parse
->left
, c
, 0, f
);
2355 compile_condition( parse
->right
, c
, 1, label
);
2356 compile_set_label( c
, f
);
2360 compile_condition( parse
->left
, c
, 0, label
);
2361 compile_condition( parse
->right
, c
, 0, label
);
2368 compile_condition( parse
->left
, c
, 1, label
);
2369 compile_condition( parse
->right
, c
, 1, label
);
2373 int t
= compile_new_label( c
);
2374 compile_condition( parse
->left
, c
, 1, t
);
2375 compile_condition( parse
->right
, c
, 0, label
);
2376 compile_set_label( c
, t
);
2381 compile_condition( parse
->left
, c
, !branch_true
, label
);
2386 static void adjust_result( compiler
* c
, int actual_location
,
2387 int desired_location
)
2389 if ( actual_location
== desired_location
)
2391 else if ( actual_location
== RESULT_STACK
&& desired_location
== RESULT_RETURN
)
2392 compile_emit( c
, INSTR_SET_RESULT
, 0 );
2393 else if ( actual_location
== RESULT_STACK
&& desired_location
== RESULT_NONE
)
2394 compile_emit( c
, INSTR_POP
, 0 );
2395 else if ( actual_location
== RESULT_RETURN
&& desired_location
== RESULT_STACK
)
2396 compile_emit( c
, INSTR_PUSH_RESULT
, 0 );
2397 else if ( actual_location
== RESULT_RETURN
&& desired_location
== RESULT_NONE
)
2399 else if ( actual_location
== RESULT_NONE
&& desired_location
== RESULT_STACK
)
2400 compile_emit( c
, INSTR_PUSH_EMPTY
, 0 );
2401 else if ( actual_location
== RESULT_NONE
&& desired_location
== RESULT_RETURN
)
2403 compile_emit( c
, INSTR_PUSH_EMPTY
, 0 );
2404 compile_emit( c
, INSTR_SET_RESULT
, 0 );
2407 assert( !"invalid result location" );
2410 static char const * parse_type( PARSE
* parse
)
2412 switch ( parse
->type
)
2414 case PARSE_APPEND
: return "append";
2415 case PARSE_EVAL
: return "eval";
2416 case PARSE_RULES
: return "rules";
2417 default: return "unknown";
2421 static void compile_append_chain( PARSE
* parse
, compiler
* c
)
2423 assert( parse
->type
== PARSE_APPEND
);
2424 if ( parse
->left
->type
== PARSE_NULL
)
2425 compile_parse( parse
->right
, c
, RESULT_STACK
);
2428 if ( parse
->left
->type
== PARSE_APPEND
)
2429 compile_append_chain( parse
->left
, c
);
2431 compile_parse( parse
->left
, c
, RESULT_STACK
);
2432 compile_parse( parse
->right
, c
, RESULT_STACK
);
2433 compile_emit( c
, INSTR_PUSH_APPEND
, 0 );
2437 static void compile_parse( PARSE
* parse
, compiler
* c
, int result_location
)
2440 if ( debug_is_debugging() )
2441 compile_emit( c
, INSTR_DEBUG_LINE
, parse
->line
);
2443 if ( parse
->type
== PARSE_APPEND
)
2445 compile_append_chain( parse
, c
);
2446 adjust_result( c
, RESULT_STACK
, result_location
);
2448 else if ( parse
->type
== PARSE_EVAL
)
2450 /* FIXME: This is only needed because of the bizarre parsing of
2453 if ( parse
->num
== EXPR_EXISTS
)
2454 compile_parse( parse
->left
, c
, result_location
);
2457 int f
= compile_new_label( c
);
2458 int end
= compile_new_label( c
);
2460 out_printf( "%s:%d: Conditional used as list (check operator "
2461 "precedence).\n", object_str( parse
->file
), parse
->line
);
2463 /* Emit the condition */
2464 compile_condition( parse
, c
, 0, f
);
2465 compile_emit( c
, INSTR_PUSH_CONSTANT
, compile_emit_constant( c
,
2467 compile_emit_branch( c
, INSTR_JUMP
, end
);
2468 compile_set_label( c
, f
);
2469 compile_emit( c
, INSTR_PUSH_EMPTY
, 0 );
2470 compile_set_label( c
, end
);
2471 adjust_result( c
, RESULT_STACK
, result_location
);
2474 else if ( parse
->type
== PARSE_FOREACH
)
2476 int var
= compile_emit_constant( c
, parse
->string
);
2477 int top
= compile_new_label( c
);
2478 int end
= compile_new_label( c
);
2479 int continue_
= compile_new_label( c
);
2482 * Evaluate the list.
2484 compile_parse( parse
->left
, c
, RESULT_STACK
);
2486 /* Localize the loop variable */
2489 compile_emit( c
, INSTR_PUSH_EMPTY
, 0 );
2490 compile_emit( c
, INSTR_PUSH_LOCAL
, var
);
2491 compile_emit( c
, INSTR_SWAP
, 1 );
2492 compile_push_cleanup( c
, INSTR_POP_LOCAL
, var
);
2495 compile_emit( c
, INSTR_FOR_INIT
, 0 );
2496 compile_set_label( c
, top
);
2497 compile_emit_branch( c
, INSTR_FOR_LOOP
, end
);
2498 compile_emit( c
, INSTR_SET
, var
);
2500 compile_push_break_scope( c
, end
);
2501 compile_push_cleanup( c
, INSTR_FOR_POP
, 0 );
2502 compile_push_continue_scope( c
, continue_
);
2504 /* Run the loop body */
2505 compile_parse( parse
->right
, c
, RESULT_NONE
);
2507 compile_pop_continue_scope( c
);
2508 compile_pop_cleanup( c
);
2509 compile_pop_break_scope( c
);
2511 compile_set_label( c
, continue_
);
2512 compile_emit_branch( c
, INSTR_JUMP
, top
);
2513 compile_set_label( c
, end
);
2517 compile_pop_cleanup( c
);
2518 compile_emit( c
, INSTR_POP_LOCAL
, var
);
2521 adjust_result( c
, RESULT_NONE
, result_location
);
2523 else if ( parse
->type
== PARSE_IF
)
2525 int f
= compile_new_label( c
);
2526 /* Emit the condition */
2527 compile_condition( parse
->left
, c
, 0, f
);
2528 /* Emit the if block */
2529 compile_parse( parse
->right
, c
, result_location
);
2530 if ( parse
->third
->type
!= PARSE_NULL
|| result_location
!= RESULT_NONE
)
2532 /* Emit the else block */
2533 int end
= compile_new_label( c
);
2534 compile_emit_branch( c
, INSTR_JUMP
, end
);
2535 compile_set_label( c
, f
);
2536 compile_parse( parse
->third
, c
, result_location
);
2537 compile_set_label( c
, end
);
2540 compile_set_label( c
, f
);
2543 else if ( parse
->type
== PARSE_WHILE
)
2545 int nested_result
= result_location
== RESULT_NONE
2548 int test
= compile_new_label( c
);
2549 int top
= compile_new_label( c
);
2550 int end
= compile_new_label( c
);
2551 /* Make sure that we return an empty list if the loop runs zero times.
2553 adjust_result( c
, RESULT_NONE
, nested_result
);
2554 /* Jump to the loop test. */
2555 compile_emit_branch( c
, INSTR_JUMP
, test
);
2556 compile_set_label( c
, top
);
2557 /* Emit the loop body. */
2558 compile_push_break_scope( c
, end
);
2559 compile_push_continue_scope( c
, test
);
2560 compile_parse( parse
->right
, c
, nested_result
);
2561 compile_pop_continue_scope( c
);
2562 compile_pop_break_scope( c
);
2563 /* Emit the condition. */
2564 compile_set_label( c
, test
);
2565 compile_condition( parse
->left
, c
, 1, top
);
2566 compile_set_label( c
, end
);
2568 adjust_result( c
, nested_result
, result_location
);
2570 else if ( parse
->type
== PARSE_INCLUDE
)
2572 compile_parse( parse
->left
, c
, RESULT_STACK
);
2573 compile_emit( c
, INSTR_INCLUDE
, 0 );
2574 compile_emit( c
, INSTR_BIND_MODULE_VARIABLES
, 0 );
2575 adjust_result( c
, RESULT_NONE
, result_location
);
2577 else if ( parse
->type
== PARSE_MODULE
)
2579 int const nested_result
= result_location
== RESULT_NONE
2582 compile_parse( parse
->left
, c
, RESULT_STACK
);
2583 compile_emit( c
, INSTR_PUSH_MODULE
, 0 );
2584 compile_push_cleanup( c
, INSTR_POP_MODULE
, 0 );
2585 compile_parse( parse
->right
, c
, nested_result
);
2586 compile_pop_cleanup( c
);
2587 compile_emit( c
, INSTR_POP_MODULE
, 0 );
2588 adjust_result( c
, nested_result
, result_location
);
2590 else if ( parse
->type
== PARSE_CLASS
)
2592 /* Evaluate the class name. */
2593 compile_parse( parse
->left
->right
, c
, RESULT_STACK
);
2594 /* Evaluate the base classes. */
2595 if ( parse
->left
->left
)
2596 compile_parse( parse
->left
->left
->right
, c
, RESULT_STACK
);
2598 compile_emit( c
, INSTR_PUSH_EMPTY
, 0 );
2599 compile_emit( c
, INSTR_CLASS
, 0 );
2600 compile_push_cleanup( c
, INSTR_POP_MODULE
, 0 );
2601 compile_parse( parse
->right
, c
, RESULT_NONE
);
2602 compile_emit( c
, INSTR_BIND_MODULE_VARIABLES
, 0 );
2603 compile_pop_cleanup( c
);
2604 compile_emit( c
, INSTR_POP_MODULE
, 0 );
2606 adjust_result( c
, RESULT_NONE
, result_location
);
2608 else if ( parse
->type
== PARSE_LIST
)
2610 OBJECT
* const o
= parse
->string
;
2611 char const * s
= object_str( o
);
2612 VAR_PARSE_GROUP
* group
;
2613 current_file
= object_str( parse
->file
);
2614 current_line
= parse
->line
;
2615 group
= parse_expansion( &s
);
2616 var_parse_group_compile( group
, c
);
2617 var_parse_group_free( group
);
2618 adjust_result( c
, RESULT_STACK
, result_location
);
2620 else if ( parse
->type
== PARSE_LOCAL
)
2622 int nested_result
= result_location
== RESULT_NONE
2625 /* This should be left recursive group of compile_appends. */
2626 PARSE
* vars
= parse
->left
;
2628 /* Special case an empty list of vars */
2629 if ( vars
->type
== PARSE_NULL
)
2631 compile_parse( parse
->right
, c
, RESULT_NONE
);
2632 compile_parse( parse
->third
, c
, result_location
);
2633 nested_result
= result_location
;
2635 /* Check whether there is exactly one variable with a constant name. */
2636 else if ( vars
->left
->type
== PARSE_NULL
&&
2637 vars
->right
->type
== PARSE_LIST
)
2639 char const * s
= object_str( vars
->right
->string
);
2640 VAR_PARSE_GROUP
* group
;
2641 current_file
= object_str( parse
->file
);
2642 current_line
= parse
->line
;
2643 group
= parse_expansion( &s
);
2644 if ( group
->elems
->size
== 1 && dynamic_array_at( VAR_PARSE
*,
2645 group
->elems
, 0 )->type
== VAR_PARSE_TYPE_STRING
)
2647 int const name
= compile_emit_constant( c
, (
2648 (VAR_PARSE_STRING
*)dynamic_array_at( VAR_PARSE
*,
2649 group
->elems
, 0 ) )->s
);
2650 var_parse_group_free( group
);
2651 compile_parse( parse
->right
, c
, RESULT_STACK
);
2652 compile_emit( c
, INSTR_PUSH_LOCAL
, name
);
2653 compile_push_cleanup( c
, INSTR_POP_LOCAL
, name
);
2654 compile_parse( parse
->third
, c
, nested_result
);
2655 compile_pop_cleanup( c
);
2656 compile_emit( c
, INSTR_POP_LOCAL
, name
);
2660 var_parse_group_compile( group
, c
);
2661 var_parse_group_free( group
);
2662 compile_parse( parse
->right
, c
, RESULT_STACK
);
2663 compile_emit( c
, INSTR_PUSH_LOCAL_GROUP
, 0 );
2664 compile_push_cleanup( c
, INSTR_POP_LOCAL_GROUP
, 0 );
2665 compile_parse( parse
->third
, c
, nested_result
);
2666 compile_pop_cleanup( c
);
2667 compile_emit( c
, INSTR_POP_LOCAL_GROUP
, 0 );
2672 compile_parse( parse
->left
, c
, RESULT_STACK
);
2673 compile_parse( parse
->right
, c
, RESULT_STACK
);
2674 compile_emit( c
, INSTR_PUSH_LOCAL_GROUP
, 0 );
2675 compile_push_cleanup( c
, INSTR_POP_LOCAL_GROUP
, 0 );
2676 compile_parse( parse
->third
, c
, nested_result
);
2677 compile_pop_cleanup( c
);
2678 compile_emit( c
, INSTR_POP_LOCAL_GROUP
, 0 );
2680 adjust_result( c
, nested_result
, result_location
);
2682 else if ( parse
->type
== PARSE_ON
)
2684 if ( parse
->right
->type
== PARSE_APPEND
&&
2685 parse
->right
->left
->type
== PARSE_NULL
&&
2686 parse
->right
->right
->type
== PARSE_LIST
)
2688 /* [ on $(target) return $(variable) ] */
2689 PARSE
* value
= parse
->right
->right
;
2690 OBJECT
* const o
= value
->string
;
2691 char const * s
= object_str( o
);
2692 VAR_PARSE_GROUP
* group
;
2693 OBJECT
* varname
= 0;
2694 current_file
= object_str( value
->file
);
2695 current_line
= value
->line
;
2696 group
= parse_expansion( &s
);
2697 if ( group
->elems
->size
== 1 )
2699 VAR_PARSE
* one
= dynamic_array_at( VAR_PARSE
*, group
->elems
, 0 );
2700 if ( one
->type
== VAR_PARSE_TYPE_VAR
)
2702 VAR_PARSE_VAR
* var
= ( VAR_PARSE_VAR
* )one
;
2703 if ( var
->modifiers
->size
== 0 && !var
->subscript
&& var
->name
->elems
->size
== 1 )
2705 VAR_PARSE
* name
= dynamic_array_at( VAR_PARSE
*, var
->name
->elems
, 0 );
2706 if ( name
->type
== VAR_PARSE_TYPE_STRING
)
2708 varname
= ( ( VAR_PARSE_STRING
* )name
)->s
;
2715 /* We have one variable with a fixed name and no modifiers. */
2716 compile_parse( parse
->left
, c
, RESULT_STACK
);
2717 compile_emit( c
, INSTR_GET_ON
, compile_emit_constant( c
, varname
) );
2721 /* Too complex. Fall back on push/pop. */
2722 int end
= compile_new_label( c
);
2723 compile_parse( parse
->left
, c
, RESULT_STACK
);
2724 compile_emit_branch( c
, INSTR_PUSH_ON
, end
);
2725 compile_push_cleanup( c
, INSTR_POP_ON
, 0 );
2726 var_parse_group_compile( group
, c
);
2727 compile_pop_cleanup( c
);
2728 compile_emit( c
, INSTR_POP_ON
, 0 );
2729 compile_set_label( c
, end
);
2731 var_parse_group_free( group
);
2735 int end
= compile_new_label( c
);
2736 compile_parse( parse
->left
, c
, RESULT_STACK
);
2737 compile_emit_branch( c
, INSTR_PUSH_ON
, end
);
2738 compile_push_cleanup( c
, INSTR_POP_ON
, 0 );
2739 compile_parse( parse
->right
, c
, RESULT_STACK
);
2740 compile_pop_cleanup( c
);
2741 compile_emit( c
, INSTR_POP_ON
, 0 );
2742 compile_set_label( c
, end
);
2744 adjust_result( c
, RESULT_STACK
, result_location
);
2746 else if ( parse
->type
== PARSE_RULE
)
2750 VAR_PARSE_GROUP
* group
;
2751 char const * s
= object_str( parse
->string
);
2753 if ( parse
->left
->left
|| parse
->left
->right
->type
!= PARSE_NULL
)
2754 for ( p
= parse
->left
; p
; p
= p
->left
)
2756 compile_parse( p
->right
, c
, RESULT_STACK
);
2760 current_file
= object_str( parse
->file
);
2761 current_line
= parse
->line
;
2762 group
= parse_expansion( &s
);
2764 if ( group
->elems
->size
== 2 &&
2765 dynamic_array_at( VAR_PARSE
*, group
->elems
, 0 )->type
== VAR_PARSE_TYPE_VAR
&&
2766 dynamic_array_at( VAR_PARSE
*, group
->elems
, 1 )->type
== VAR_PARSE_TYPE_STRING
&&
2767 ( object_str( ( (VAR_PARSE_STRING
*)dynamic_array_at( VAR_PARSE
*, group
->elems
, 1 ) )->s
)[ 0 ] == '.' ) )
2769 VAR_PARSE_STRING
* access
= (VAR_PARSE_STRING
*)dynamic_array_at( VAR_PARSE
*, group
->elems
, 1 );
2770 OBJECT
* member
= object_new( object_str( access
->s
) + 1 );
2771 /* Emit the object */
2772 var_parse_var_compile( (VAR_PARSE_VAR
*)dynamic_array_at( VAR_PARSE
*, group
->elems
, 0 ), c
);
2773 var_parse_group_free( group
);
2774 compile_emit( c
, INSTR_CALL_MEMBER_RULE
, n
);
2775 compile_emit( c
, compile_emit_constant( c
, member
), parse
->line
);
2776 object_free( member
);
2780 var_parse_group_compile( group
, c
);
2781 var_parse_group_free( group
);
2782 compile_emit( c
, INSTR_CALL_RULE
, n
);
2783 compile_emit( c
, compile_emit_constant( c
, parse
->string
), parse
->line
);
2786 adjust_result( c
, RESULT_STACK
, result_location
);
2788 else if ( parse
->type
== PARSE_RULES
)
2790 do compile_parse( parse
->left
, c
, RESULT_NONE
);
2791 while ( ( parse
= parse
->right
)->type
== PARSE_RULES
);
2792 compile_parse( parse
, c
, result_location
);
2794 else if ( parse
->type
== PARSE_SET
)
2796 PARSE
* vars
= parse
->left
;
2797 unsigned int op_code
;
2798 unsigned int op_code_group
;
2800 switch ( parse
->num
)
2802 case ASSIGN_APPEND
: op_code
= INSTR_APPEND
; op_code_group
= INSTR_APPEND_GROUP
; break;
2803 case ASSIGN_DEFAULT
: op_code
= INSTR_DEFAULT
; op_code_group
= INSTR_DEFAULT_GROUP
; break;
2804 default: op_code
= INSTR_SET
; op_code_group
= INSTR_SET_GROUP
; break;
2807 /* Check whether there is exactly one variable with a constant name. */
2808 if ( vars
->type
== PARSE_LIST
)
2810 char const * s
= object_str( vars
->string
);
2811 VAR_PARSE_GROUP
* group
;
2812 current_file
= object_str( parse
->file
);
2813 current_line
= parse
->line
;
2814 group
= parse_expansion( &s
);
2815 if ( group
->elems
->size
== 1 && dynamic_array_at( VAR_PARSE
*,
2816 group
->elems
, 0 )->type
== VAR_PARSE_TYPE_STRING
)
2818 int const name
= compile_emit_constant( c
, (
2819 (VAR_PARSE_STRING
*)dynamic_array_at( VAR_PARSE
*,
2820 group
->elems
, 0 ) )->s
);
2821 var_parse_group_free( group
);
2822 compile_parse( parse
->right
, c
, RESULT_STACK
);
2823 if ( result_location
!= RESULT_NONE
)
2825 compile_emit( c
, INSTR_SET_RESULT
, 1 );
2827 compile_emit( c
, op_code
, name
);
2831 var_parse_group_compile( group
, c
);
2832 var_parse_group_free( group
);
2833 compile_parse( parse
->right
, c
, RESULT_STACK
);
2834 if ( result_location
!= RESULT_NONE
)
2836 compile_emit( c
, INSTR_SET_RESULT
, 1 );
2838 compile_emit( c
, op_code_group
, 0 );
2843 compile_parse( parse
->left
, c
, RESULT_STACK
);
2844 compile_parse( parse
->right
, c
, RESULT_STACK
);
2845 if ( result_location
!= RESULT_NONE
)
2847 compile_emit( c
, INSTR_SET_RESULT
, 1 );
2849 compile_emit( c
, op_code_group
, 0 );
2851 if ( result_location
!= RESULT_NONE
)
2853 adjust_result( c
, RESULT_RETURN
, result_location
);
2856 else if ( parse
->type
== PARSE_SETCOMP
)
2859 struct arg_list
* args
= arg_list_compile( parse
->right
, &n_args
);
2860 int const rule_id
= compile_emit_rule( c
, parse
->string
, parse
->left
,
2861 n_args
, args
, parse
->num
);
2862 compile_emit( c
, INSTR_RULE
, rule_id
);
2863 adjust_result( c
, RESULT_NONE
, result_location
);
2865 else if ( parse
->type
== PARSE_SETEXEC
)
2867 int const actions_id
= compile_emit_actions( c
, parse
);
2868 compile_parse( parse
->left
, c
, RESULT_STACK
);
2869 compile_emit( c
, INSTR_ACTIONS
, actions_id
);
2870 adjust_result( c
, RESULT_NONE
, result_location
);
2872 else if ( parse
->type
== PARSE_SETTINGS
)
2874 compile_parse( parse
->left
, c
, RESULT_STACK
);
2875 compile_parse( parse
->third
, c
, RESULT_STACK
);
2876 compile_parse( parse
->right
, c
, RESULT_STACK
);
2878 switch ( parse
->num
)
2880 case ASSIGN_APPEND
: compile_emit( c
, INSTR_APPEND_ON
, 0 ); break;
2881 case ASSIGN_DEFAULT
: compile_emit( c
, INSTR_DEFAULT_ON
, 0 ); break;
2882 default: compile_emit( c
, INSTR_SET_ON
, 0 ); break;
2885 adjust_result( c
, RESULT_STACK
, result_location
);
2887 else if ( parse
->type
== PARSE_SWITCH
)
2889 int const switch_end
= compile_new_label( c
);
2890 compile_parse( parse
->left
, c
, RESULT_STACK
);
2892 for ( parse
= parse
->right
; parse
; parse
= parse
->right
)
2894 int const id
= compile_emit_constant( c
, parse
->left
->string
);
2895 int const next_case
= compile_new_label( c
);
2896 compile_emit( c
, INSTR_PUSH_CONSTANT
, id
);
2897 compile_emit_branch( c
, INSTR_JUMP_NOT_GLOB
, next_case
);
2898 compile_parse( parse
->left
->left
, c
, result_location
);
2899 compile_emit_branch( c
, INSTR_JUMP
, switch_end
);
2900 compile_set_label( c
, next_case
);
2902 compile_emit( c
, INSTR_POP
, 0 );
2903 adjust_result( c
, RESULT_NONE
, result_location
);
2904 compile_set_label( c
, switch_end
);
2906 else if ( parse
->type
== PARSE_RETURN
)
2908 compile_parse( parse
->left
, c
, RESULT_RETURN
);
2909 compile_emit_cleanups( c
, 0 );
2910 compile_emit( c
, INSTR_RETURN
, 0 ); /* 0 for return in the middle of a function. */
2912 else if ( parse
->type
== PARSE_BREAK
)
2914 compile_emit_loop_jump( c
, LOOP_INFO_BREAK
);
2916 else if ( parse
->type
== PARSE_CONTINUE
)
2918 compile_emit_loop_jump( c
, LOOP_INFO_CONTINUE
);
2920 else if ( parse
->type
== PARSE_NULL
)
2921 adjust_result( c
, RESULT_NONE
, result_location
);
2923 assert( !"unknown PARSE type." );
2926 OBJECT
* function_rulename( FUNCTION
* function
)
2928 return function
->rulename
;
2931 void function_set_rulename( FUNCTION
* function
, OBJECT
* rulename
)
2933 function
->rulename
= rulename
;
2936 void function_location( FUNCTION
* function_
, OBJECT
* * file
, int * line
)
2938 if ( function_
->type
== FUNCTION_BUILTIN
)
2940 *file
= constant_builtin
;
2944 if ( function_
->type
== FUNCTION_PYTHON
)
2946 *file
= constant_builtin
;
2952 JAM_FUNCTION
* function
= (JAM_FUNCTION
*)function_
;
2953 assert( function_
->type
== FUNCTION_JAM
);
2954 *file
= function
->file
;
2955 *line
= function
->line
;
2959 static struct arg_list
* arg_list_compile_builtin( char const * * args
,
2960 int * num_arguments
);
2962 FUNCTION
* function_builtin( LIST
* ( * func
)( FRAME
* frame
, int flags
),
2963 int flags
, char const * * args
)
2965 BUILTIN_FUNCTION
* result
= BJAM_MALLOC( sizeof( BUILTIN_FUNCTION
) );
2966 result
->base
.type
= FUNCTION_BUILTIN
;
2967 result
->base
.reference_count
= 1;
2968 result
->base
.rulename
= 0;
2969 result
->base
.formal_arguments
= arg_list_compile_builtin( args
,
2970 &result
->base
.num_formal_arguments
);
2971 result
->func
= func
;
2972 result
->flags
= flags
;
2973 return (FUNCTION
*)result
;
2976 FUNCTION
* function_compile( PARSE
* parse
)
2979 JAM_FUNCTION
* result
;
2981 compile_parse( parse
, c
, RESULT_RETURN
);
2982 compile_emit( c
, INSTR_RETURN
, 1 );
2983 result
= compile_to_function( c
);
2985 result
->file
= object_copy( parse
->file
);
2986 result
->line
= parse
->line
;
2987 return (FUNCTION
*)result
;
2990 FUNCTION
* function_compile_actions( char const * actions
, OBJECT
* file
,
2994 JAM_FUNCTION
* result
;
2995 VAR_PARSE_ACTIONS
* parse
;
2996 current_file
= object_str( file
);
2997 current_line
= line
;
2998 parse
= parse_actions( actions
);
3000 var_parse_actions_compile( parse
, c
);
3001 var_parse_actions_free( parse
);
3002 compile_emit( c
, INSTR_RETURN
, 1 );
3003 result
= compile_to_function( c
);
3005 result
->file
= object_copy( file
);
3006 result
->line
= line
;
3007 return (FUNCTION
*)result
;
3010 static void argument_list_print( struct arg_list
* args
, int num_args
);
3013 /* Define delimiters for type check elements in argument lists (and return type
3014 * specifications, eventually).
3016 # define TYPE_OPEN_DELIM '['
3017 # define TYPE_CLOSE_DELIM ']'
3020 * is_type_name() - true iff the given string represents a type check
3024 int is_type_name( char const * s
)
3026 return s
[ 0 ] == TYPE_OPEN_DELIM
&& s
[ strlen( s
) - 1 ] ==
3030 static void argument_error( char const * message
, FUNCTION
* procedure
,
3031 FRAME
* frame
, OBJECT
* arg
)
3033 extern void print_source_line( FRAME
* );
3034 LOL
* actual
= frame
->args
;
3035 backtrace_line( frame
->prev
);
3036 out_printf( "*** argument error\n* rule %s ( ", frame
->rulename
);
3037 argument_list_print( procedure
->formal_arguments
,
3038 procedure
->num_formal_arguments
);
3039 out_printf( " )\n* called with: ( " );
3040 lol_print( actual
);
3041 out_printf( " )\n* %s %s\n", message
, arg
? object_str ( arg
) : "" );
3042 function_location( procedure
, &frame
->file
, &frame
->line
);
3043 print_source_line( frame
);
3044 out_printf( "see definition of rule '%s' being called\n", frame
->rulename
);
3045 backtrace( frame
->prev
);
3049 static void type_check_range( OBJECT
* type_name
, LISTITER iter
, LISTITER end
,
3050 FRAME
* caller
, FUNCTION
* called
, OBJECT
* arg_name
)
3052 static module_t
* typecheck
= 0;
3054 /* If nothing to check, bail now. */
3055 if ( iter
== end
|| !type_name
)
3059 typecheck
= bindmodule( constant_typecheck
);
3061 /* If the checking rule can not be found, also bail. */
3062 if ( !typecheck
->rules
|| !hash_find( typecheck
->rules
, type_name
) )
3065 for ( ; iter
!= end
; iter
= list_next( iter
) )
3069 frame_init( frame
);
3070 frame
->module
= typecheck
;
3071 frame
->prev
= caller
;
3072 frame
->prev_user
= caller
->module
->user_module
3074 : caller
->prev_user
;
3076 /* Prepare the argument list */
3077 lol_add( frame
->args
, list_new( object_copy( list_item( iter
) ) ) );
3078 error
= evaluate_rule( bindrule( type_name
, frame
->module
), type_name
, frame
);
3080 if ( !list_empty( error
) )
3081 argument_error( object_str( list_front( error
) ), called
, caller
,
3084 frame_free( frame
);
3088 static void type_check( OBJECT
* type_name
, LIST
* values
, FRAME
* caller
,
3089 FUNCTION
* called
, OBJECT
* arg_name
)
3091 type_check_range( type_name
, list_begin( values
), list_end( values
),
3092 caller
, called
, arg_name
);
3095 void argument_list_check( struct arg_list
* formal
, int formal_count
,
3096 FUNCTION
* function
, FRAME
* frame
)
3098 LOL
* all_actual
= frame
->args
;
3101 for ( i
= 0; i
< formal_count
; ++i
)
3103 LIST
* actual
= lol_get( all_actual
, i
);
3104 LISTITER actual_iter
= list_begin( actual
);
3105 LISTITER
const actual_end
= list_end( actual
);
3107 for ( j
= 0; j
< formal
[ i
].size
; ++j
)
3109 struct argument
* formal_arg
= &formal
[ i
].args
[ j
];
3112 switch ( formal_arg
->flags
)
3115 if ( actual_iter
== actual_end
)
3116 argument_error( "missing argument", function
, frame
,
3117 formal_arg
->arg_name
);
3118 type_check_range( formal_arg
->type_name
, actual_iter
,
3119 list_next( actual_iter
), frame
, function
,
3120 formal_arg
->arg_name
);
3121 actual_iter
= list_next( actual_iter
);
3124 if ( actual_iter
== actual_end
)
3128 type_check_range( formal_arg
->type_name
, actual_iter
,
3129 list_next( actual_iter
), frame
, function
,
3130 formal_arg
->arg_name
);
3131 actual_iter
= list_next( actual_iter
);
3135 if ( actual_iter
== actual_end
)
3136 argument_error( "missing argument", function
, frame
,
3137 formal_arg
->arg_name
);
3140 type_check_range( formal_arg
->type_name
, actual_iter
,
3141 actual_end
, frame
, function
, formal_arg
->arg_name
);
3142 actual_iter
= actual_end
;
3149 if ( actual_iter
!= actual_end
)
3150 argument_error( "extra argument", function
, frame
, list_item(
3154 for ( ; i
< all_actual
->count
; ++i
)
3156 LIST
* actual
= lol_get( all_actual
, i
);
3157 if ( !list_empty( actual
) )
3158 argument_error( "extra argument", function
, frame
, list_front(
3163 void argument_list_push( struct arg_list
* formal
, int formal_count
,
3164 FUNCTION
* function
, FRAME
* frame
, STACK
* s
)
3166 LOL
* all_actual
= frame
->args
;
3169 for ( i
= 0; i
< formal_count
; ++i
)
3171 LIST
* actual
= lol_get( all_actual
, i
);
3172 LISTITER actual_iter
= list_begin( actual
);
3173 LISTITER
const actual_end
= list_end( actual
);
3175 for ( j
= 0; j
< formal
[ i
].size
; ++j
)
3177 struct argument
* formal_arg
= &formal
[ i
].args
[ j
];
3180 switch ( formal_arg
->flags
)
3183 if ( actual_iter
== actual_end
)
3184 argument_error( "missing argument", function
, frame
,
3185 formal_arg
->arg_name
);
3186 value
= list_new( object_copy( list_item( actual_iter
) ) );
3187 actual_iter
= list_next( actual_iter
);
3190 if ( actual_iter
== actual_end
)
3194 value
= list_new( object_copy( list_item( actual_iter
) ) );
3195 actual_iter
= list_next( actual_iter
);
3199 if ( actual_iter
== actual_end
)
3200 argument_error( "missing argument", function
, frame
,
3201 formal_arg
->arg_name
);
3204 value
= list_copy_range( actual
, actual_iter
, actual_end
);
3205 actual_iter
= actual_end
;
3211 type_check( formal_arg
->type_name
, value
, frame
, function
,
3212 formal_arg
->arg_name
);
3214 if ( formal_arg
->index
!= -1 )
3216 LIST
* * const old
= &frame
->module
->fixed_variables
[
3217 formal_arg
->index
];
3218 stack_push( s
, *old
);
3222 stack_push( s
, var_swap( frame
->module
, formal_arg
->arg_name
,
3226 if ( actual_iter
!= actual_end
)
3227 argument_error( "extra argument", function
, frame
, list_item(
3231 for ( ; i
< all_actual
->count
; ++i
)
3233 LIST
* const actual
= lol_get( all_actual
, i
);
3234 if ( !list_empty( actual
) )
3235 argument_error( "extra argument", function
, frame
, list_front(
3240 void argument_list_pop( struct arg_list
* formal
, int formal_count
,
3241 FRAME
* frame
, STACK
* s
)
3244 for ( i
= formal_count
- 1; i
>= 0; --i
)
3247 for ( j
= formal
[ i
].size
- 1; j
>= 0 ; --j
)
3249 struct argument
* formal_arg
= &formal
[ i
].args
[ j
];
3251 if ( formal_arg
->flags
== ARG_VARIADIC
)
3253 if ( formal_arg
->index
!= -1 )
3255 LIST
* const old
= stack_pop( s
);
3256 LIST
* * const pos
= &frame
->module
->fixed_variables
[
3257 formal_arg
->index
];
3262 var_set( frame
->module
, formal_arg
->arg_name
, stack_pop( s
),
3269 struct argument_compiler
3271 struct dynamic_array args
[ 1 ];
3272 struct argument arg
;
3274 #define ARGUMENT_COMPILER_START 0
3275 #define ARGUMENT_COMPILER_FOUND_TYPE 1
3276 #define ARGUMENT_COMPILER_FOUND_OBJECT 2
3277 #define ARGUMENT_COMPILER_DONE 3
3281 static void argument_compiler_init( struct argument_compiler
* c
)
3283 dynamic_array_init( c
->args
);
3284 c
->state
= ARGUMENT_COMPILER_START
;
3287 static void argument_compiler_free( struct argument_compiler
* c
)
3289 dynamic_array_free( c
->args
);
3292 static void argument_compiler_add( struct argument_compiler
* c
, OBJECT
* arg
,
3293 OBJECT
* file
, int line
)
3297 case ARGUMENT_COMPILER_FOUND_OBJECT
:
3299 if ( object_equal( arg
, constant_question_mark
) )
3301 c
->arg
.flags
= ARG_OPTIONAL
;
3303 else if ( object_equal( arg
, constant_plus
) )
3305 c
->arg
.flags
= ARG_PLUS
;
3307 else if ( object_equal( arg
, constant_star
) )
3309 c
->arg
.flags
= ARG_STAR
;
3312 dynamic_array_push( c
->args
, c
->arg
);
3313 c
->state
= ARGUMENT_COMPILER_START
;
3315 if ( c
->arg
.flags
!= ARG_ONE
)
3319 case ARGUMENT_COMPILER_START
:
3321 c
->arg
.type_name
= 0;
3323 c
->arg
.flags
= ARG_ONE
;
3325 if ( is_type_name( object_str( arg
) ) )
3327 c
->arg
.type_name
= object_copy( arg
);
3328 c
->state
= ARGUMENT_COMPILER_FOUND_TYPE
;
3333 case ARGUMENT_COMPILER_FOUND_TYPE
:
3335 if ( is_type_name( object_str( arg
) ) )
3337 err_printf( "%s:%d: missing argument name before type name: %s\n",
3338 object_str( file
), line
, object_str( arg
) );
3342 c
->arg
.arg_name
= object_copy( arg
);
3343 if ( object_equal( arg
, constant_star
) )
3345 c
->arg
.flags
= ARG_VARIADIC
;
3346 dynamic_array_push( c
->args
, c
->arg
);
3347 c
->state
= ARGUMENT_COMPILER_DONE
;
3351 c
->state
= ARGUMENT_COMPILER_FOUND_OBJECT
;
3355 case ARGUMENT_COMPILER_DONE
:
3360 static void argument_compiler_recurse( struct argument_compiler
* c
,
3363 if ( parse
->type
== PARSE_APPEND
)
3365 argument_compiler_recurse( c
, parse
->left
);
3366 argument_compiler_recurse( c
, parse
->right
);
3368 else if ( parse
->type
!= PARSE_NULL
)
3370 assert( parse
->type
== PARSE_LIST
);
3371 argument_compiler_add( c
, parse
->string
, parse
->file
, parse
->line
);
3375 static struct arg_list
arg_compile_impl( struct argument_compiler
* c
,
3376 OBJECT
* file
, int line
)
3378 struct arg_list result
;
3381 case ARGUMENT_COMPILER_START
:
3382 case ARGUMENT_COMPILER_DONE
:
3384 case ARGUMENT_COMPILER_FOUND_TYPE
:
3385 err_printf( "%s:%d: missing argument name after type name: %s\n",
3386 object_str( file
), line
, object_str( c
->arg
.type_name
) );
3388 case ARGUMENT_COMPILER_FOUND_OBJECT
:
3389 dynamic_array_push( c
->args
, c
->arg
);
3392 result
.size
= c
->args
->size
;
3393 result
.args
= BJAM_MALLOC( c
->args
->size
* sizeof( struct argument
) );
3394 memcpy( result
.args
, c
->args
->data
, c
->args
->size
* sizeof( struct argument
3399 static struct arg_list
arg_compile( PARSE
* parse
)
3401 struct argument_compiler c
[ 1 ];
3402 struct arg_list result
;
3403 argument_compiler_init( c
);
3404 argument_compiler_recurse( c
, parse
);
3405 result
= arg_compile_impl( c
, parse
->file
, parse
->line
);
3406 argument_compiler_free( c
);
3410 struct argument_list_compiler
3412 struct dynamic_array args
[ 1 ];
3415 static void argument_list_compiler_init( struct argument_list_compiler
* c
)
3417 dynamic_array_init( c
->args
);
3420 static void argument_list_compiler_free( struct argument_list_compiler
* c
)
3422 dynamic_array_free( c
->args
);
3425 static void argument_list_compiler_add( struct argument_list_compiler
* c
,
3428 struct arg_list args
= arg_compile( parse
);
3429 dynamic_array_push( c
->args
, args
);
3432 static void argument_list_compiler_recurse( struct argument_list_compiler
* c
,
3437 argument_list_compiler_add( c
, parse
->right
);
3438 argument_list_compiler_recurse( c
, parse
->left
);
3442 static struct arg_list
* arg_list_compile( PARSE
* parse
, int * num_arguments
)
3446 struct argument_list_compiler c
[ 1 ];
3447 struct arg_list
* result
;
3448 argument_list_compiler_init( c
);
3449 argument_list_compiler_recurse( c
, parse
);
3450 *num_arguments
= c
->args
->size
;
3451 result
= BJAM_MALLOC( c
->args
->size
* sizeof( struct arg_list
) );
3452 memcpy( result
, c
->args
->data
, c
->args
->size
* sizeof( struct arg_list
)
3454 argument_list_compiler_free( c
);
3461 static struct arg_list
* arg_list_compile_builtin( char const * * args
,
3462 int * num_arguments
)
3466 struct argument_list_compiler c
[ 1 ];
3467 struct arg_list
* result
;
3468 argument_list_compiler_init( c
);
3471 struct argument_compiler arg_comp
[ 1 ];
3472 struct arg_list arg
;
3473 argument_compiler_init( arg_comp
);
3474 for ( ; *args
; ++args
)
3477 if ( strcmp( *args
, ":" ) == 0 )
3482 token
= object_new( *args
);
3483 argument_compiler_add( arg_comp
, token
, constant_builtin
, -1 );
3484 object_free( token
);
3486 arg
= arg_compile_impl( arg_comp
, constant_builtin
, -1 );
3487 dynamic_array_push( c
->args
, arg
);
3488 argument_compiler_free( arg_comp
);
3490 *num_arguments
= c
->args
->size
;
3491 result
= BJAM_MALLOC( c
->args
->size
* sizeof( struct arg_list
) );
3492 memcpy( result
, c
->args
->data
, c
->args
->size
* sizeof( struct arg_list
)
3494 argument_list_compiler_free( c
);
3501 static void argument_list_print( struct arg_list
* args
, int num_args
)
3506 for ( i
= 0; i
< num_args
; ++i
)
3509 if ( i
) out_printf( " : " );
3510 for ( j
= 0; j
< args
[ i
].size
; ++j
)
3512 struct argument
* formal_arg
= &args
[ i
].args
[ j
];
3513 if ( j
) out_printf( " " );
3514 if ( formal_arg
->type_name
)
3515 out_printf( "%s ", object_str( formal_arg
->type_name
) );
3516 out_printf( "%s", object_str( formal_arg
->arg_name
) );
3517 switch ( formal_arg
->flags
)
3519 case ARG_OPTIONAL
: out_printf( " ?" ); break;
3520 case ARG_PLUS
: out_printf( " +" ); break;
3521 case ARG_STAR
: out_printf( " *" ); break;
3529 struct arg_list
* argument_list_bind_variables( struct arg_list
* formal
,
3530 int formal_count
, module_t
* module
, int * counter
)
3534 struct arg_list
* result
= (struct arg_list
*)BJAM_MALLOC( sizeof(
3535 struct arg_list
) * formal_count
);
3538 for ( i
= 0; i
< formal_count
; ++i
)
3541 struct argument
* args
= (struct argument
*)BJAM_MALLOC( sizeof(
3542 struct argument
) * formal
[ i
].size
);
3543 for ( j
= 0; j
< formal
[ i
].size
; ++j
)
3545 args
[ j
] = formal
[ i
].args
[ j
];
3546 if ( args
[ j
].type_name
)
3547 args
[ j
].type_name
= object_copy( args
[ j
].type_name
);
3548 args
[ j
].arg_name
= object_copy( args
[ j
].arg_name
);
3549 if ( args
[ j
].flags
!= ARG_VARIADIC
)
3550 args
[ j
].index
= module_add_fixed_var( module
,
3551 args
[ j
].arg_name
, counter
);
3553 result
[ i
].args
= args
;
3554 result
[ i
].size
= formal
[ i
].size
;
3563 void argument_list_free( struct arg_list
* args
, int args_count
)
3566 for ( i
= 0; i
< args_count
; ++i
)
3569 for ( j
= 0; j
< args
[ i
].size
; ++j
)
3571 if ( args
[ i
].args
[ j
].type_name
)
3572 object_free( args
[ i
].args
[ j
].type_name
);
3573 object_free( args
[ i
].args
[ j
].arg_name
);
3575 BJAM_FREE( args
[ i
].args
);
3581 FUNCTION
* function_unbind_variables( FUNCTION
* f
)
3583 if ( f
->type
== FUNCTION_JAM
)
3585 JAM_FUNCTION
* const func
= (JAM_FUNCTION
*)f
;
3586 return func
->generic
? func
->generic
: f
;
3589 if ( f
->type
== FUNCTION_PYTHON
)
3592 assert( f
->type
== FUNCTION_BUILTIN
);
3596 FUNCTION
* function_bind_variables( FUNCTION
* f
, module_t
* module
,
3599 if ( f
->type
== FUNCTION_BUILTIN
)
3602 if ( f
->type
== FUNCTION_PYTHON
)
3606 JAM_FUNCTION
* func
= (JAM_FUNCTION
*)f
;
3607 JAM_FUNCTION
* new_func
= BJAM_MALLOC( sizeof( JAM_FUNCTION
) );
3610 assert( f
->type
== FUNCTION_JAM
);
3611 memcpy( new_func
, func
, sizeof( JAM_FUNCTION
) );
3612 new_func
->base
.reference_count
= 1;
3613 new_func
->base
.formal_arguments
= argument_list_bind_variables(
3614 f
->formal_arguments
, f
->num_formal_arguments
, module
, counter
);
3615 new_func
->code
= BJAM_MALLOC( func
->code_size
* sizeof( instruction
) );
3616 memcpy( new_func
->code
, func
->code
, func
->code_size
* sizeof(
3618 new_func
->generic
= (FUNCTION
*)func
;
3620 for ( i
= 0; ; ++i
)
3624 code
= func
->code
+ i
;
3625 switch ( code
->op_code
)
3627 case INSTR_PUSH_VAR
: op_code
= INSTR_PUSH_VAR_FIXED
; break;
3628 case INSTR_PUSH_LOCAL
: op_code
= INSTR_PUSH_LOCAL_FIXED
; break;
3629 case INSTR_POP_LOCAL
: op_code
= INSTR_POP_LOCAL_FIXED
; break;
3630 case INSTR_SET
: op_code
= INSTR_SET_FIXED
; break;
3631 case INSTR_APPEND
: op_code
= INSTR_APPEND_FIXED
; break;
3632 case INSTR_DEFAULT
: op_code
= INSTR_DEFAULT_FIXED
; break;
3634 if( code
->arg
== 1 ) return (FUNCTION
*)new_func
;
3636 case INSTR_CALL_MEMBER_RULE
:
3637 case INSTR_CALL_RULE
: ++i
; continue;
3638 case INSTR_PUSH_MODULE
:
3644 code
= func
->code
+ i
;
3645 switch ( code
->op_code
)
3647 case INSTR_PUSH_MODULE
:
3651 case INSTR_POP_MODULE
:
3654 case INSTR_CALL_RULE
:
3664 key
= func
->constants
[ code
->arg
];
3665 if ( !( object_equal( key
, constant_TMPDIR
) ||
3666 object_equal( key
, constant_TMPNAME
) ||
3667 object_equal( key
, constant_TMPFILE
) ||
3668 object_equal( key
, constant_STDOUT
) ||
3669 object_equal( key
, constant_STDERR
) ) )
3671 code
->op_code
= op_code
;
3672 code
->arg
= module_add_fixed_var( module
, key
, counter
);
3678 LIST
* function_get_variables( FUNCTION
* f
)
3680 if ( f
->type
== FUNCTION_BUILTIN
)
3683 if ( f
->type
== FUNCTION_PYTHON
)
3687 JAM_FUNCTION
* func
= (JAM_FUNCTION
*)f
;
3691 assert( f
->type
== FUNCTION_JAM
);
3692 if ( func
->generic
) func
= ( JAM_FUNCTION
* )func
->generic
;
3694 for ( i
= 0; ; ++i
)
3697 code
= func
->code
+ i
;
3698 switch ( code
->op_code
)
3700 case INSTR_PUSH_LOCAL
: break;
3701 case INSTR_RETURN
: return result
;
3702 case INSTR_CALL_MEMBER_RULE
:
3703 case INSTR_CALL_RULE
: ++i
; continue;
3704 case INSTR_PUSH_MODULE
:
3710 code
= func
->code
+ i
;
3711 switch ( code
->op_code
)
3713 case INSTR_PUSH_MODULE
:
3717 case INSTR_POP_MODULE
:
3720 case INSTR_CALL_RULE
:
3730 var
= func
->constants
[ code
->arg
];
3731 if ( !( object_equal( var
, constant_TMPDIR
) ||
3732 object_equal( var
, constant_TMPNAME
) ||
3733 object_equal( var
, constant_TMPFILE
) ||
3734 object_equal( var
, constant_STDOUT
) ||
3735 object_equal( var
, constant_STDERR
) ) )
3737 result
= list_push_back( result
, var
);
3743 void function_refer( FUNCTION
* func
)
3745 ++func
->reference_count
;
3748 void function_free( FUNCTION
* function_
)
3752 if ( --function_
->reference_count
!= 0 )
3755 if ( function_
->formal_arguments
)
3756 argument_list_free( function_
->formal_arguments
,
3757 function_
->num_formal_arguments
);
3759 if ( function_
->type
== FUNCTION_JAM
)
3761 JAM_FUNCTION
* func
= (JAM_FUNCTION
*)function_
;
3763 BJAM_FREE( func
->code
);
3765 if ( func
->generic
)
3766 function_free( func
->generic
);
3769 if ( function_
->rulename
) object_free( function_
->rulename
);
3771 for ( i
= 0; i
< func
->num_constants
; ++i
)
3772 object_free( func
->constants
[ i
] );
3773 BJAM_FREE( func
->constants
);
3775 for ( i
= 0; i
< func
->num_subfunctions
; ++i
)
3777 object_free( func
->functions
[ i
].name
);
3778 function_free( func
->functions
[ i
].code
);
3780 BJAM_FREE( func
->functions
);
3782 for ( i
= 0; i
< func
->num_subactions
; ++i
)
3784 object_free( func
->actions
[ i
].name
);
3785 function_free( func
->actions
[ i
].command
);
3787 BJAM_FREE( func
->actions
);
3789 object_free( func
->file
);
3793 else if ( function_
->type
== FUNCTION_PYTHON
)
3795 PYTHON_FUNCTION
* func
= (PYTHON_FUNCTION
*)function_
;
3796 Py_DECREF( func
->python_function
);
3797 if ( function_
->rulename
) object_free( function_
->rulename
);
3802 assert( function_
->type
== FUNCTION_BUILTIN
);
3803 if ( function_
->rulename
) object_free( function_
->rulename
);
3806 BJAM_FREE( function_
);
3810 /* Alignment check for stack */
3812 struct align_var_edits
3818 struct align_expansion_item
3824 static char check_align_var_edits
[ sizeof(struct align_var_edits
) <= sizeof(VAR_EDITS
) + sizeof(void *) ? 1 : -1 ];
3825 static char check_align_expansion_item
[ sizeof(struct align_expansion_item
) <= sizeof(expansion_item
) + sizeof(void *) ? 1 : -1 ];
3827 static char check_ptr_size1
[ sizeof(LIST
*) <= sizeof(void *) ? 1 : -1 ];
3828 static char check_ptr_size2
[ sizeof(char *) <= sizeof(void *) ? 1 : -1 ];
3830 void function_run_actions( FUNCTION
* function
, FRAME
* frame
, STACK
* s
,
3833 *(string
* *)stack_allocate( s
, sizeof( string
* ) ) = out
;
3834 list_free( function_run( function
, frame
, s
) );
3835 stack_deallocate( s
, sizeof( string
* ) );
3839 * WARNING: The instruction set is tuned for Jam and is not really generic. Be
3840 * especially careful about stack push/pop.
3843 LIST
* function_run( FUNCTION
* function_
, FRAME
* frame
, STACK
* s
)
3845 JAM_FUNCTION
* function
;
3850 void * saved_stack
= s
->data
;
3852 PROFILE_ENTER_LOCAL(function_run
);
3855 frame
->function
= function_
;
3858 if ( function_
->type
== FUNCTION_BUILTIN
)
3860 PROFILE_ENTER_LOCAL(function_run_FUNCTION_BUILTIN
);
3861 BUILTIN_FUNCTION
const * const f
= (BUILTIN_FUNCTION
*)function_
;
3862 if ( function_
->formal_arguments
)
3863 argument_list_check( function_
->formal_arguments
,
3864 function_
->num_formal_arguments
, function_
, frame
);
3866 debug_on_enter_function( frame
, f
->base
.rulename
, NULL
, -1 );
3867 result
= f
->func( frame
, f
->flags
);
3868 debug_on_exit_function( f
->base
.rulename
);
3869 PROFILE_EXIT_LOCAL(function_run_FUNCTION_BUILTIN
);
3870 PROFILE_EXIT_LOCAL(function_run
);
3875 else if ( function_
->type
== FUNCTION_PYTHON
)
3877 PROFILE_ENTER_LOCAL(function_run_FUNCTION_PYTHON
);
3878 PYTHON_FUNCTION
* f
= (PYTHON_FUNCTION
*)function_
;
3879 debug_on_enter_function( frame
, f
->base
.rulename
, NULL
, -1 );
3880 result
= call_python_function( f
, frame
);
3881 debug_on_exit_function( f
->base
.rulename
);
3882 PROFILE_EXIT_LOCAL(function_run_FUNCTION_PYTHON
);
3883 PROFILE_EXIT_LOCAL(function_run
);
3888 assert( function_
->type
== FUNCTION_JAM
);
3890 if ( function_
->formal_arguments
)
3891 argument_list_push( function_
->formal_arguments
,
3892 function_
->num_formal_arguments
, function_
, frame
, s
);
3894 function
= (JAM_FUNCTION
*)function_
;
3895 debug_on_enter_function( frame
, function
->base
.rulename
, function
->file
, function
->line
);
3896 code
= function
->code
;
3899 switch ( code
->op_code
)
3903 * Basic stack manipulation
3906 case INSTR_PUSH_EMPTY
:
3908 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_EMPTY
);
3909 stack_push( s
, L0
);
3910 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_EMPTY
);
3914 case INSTR_PUSH_CONSTANT
:
3916 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_CONSTANT
);
3917 OBJECT
* value
= function_get_constant( function
, code
->arg
);
3918 stack_push( s
, list_new( object_copy( value
) ) );
3919 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_CONSTANT
);
3923 case INSTR_PUSH_ARG
:
3925 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_ARG
);
3926 stack_push( s
, frame_get_local( frame
, code
->arg
) );
3927 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_ARG
);
3931 case INSTR_PUSH_VAR
:
3933 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_VAR
);
3934 stack_push( s
, function_get_variable( function
, frame
, code
->arg
) );
3935 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_VAR
);
3939 case INSTR_PUSH_VAR_FIXED
:
3941 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_VAR_FIXED
);
3942 stack_push( s
, list_copy( frame
->module
->fixed_variables
[ code
->arg
3944 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_VAR_FIXED
);
3948 case INSTR_PUSH_GROUP
:
3950 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_GROUP
);
3955 for ( iter
= list_begin( l
), end
= list_end( l
); iter
!= end
;
3956 iter
= list_next( iter
) )
3957 value
= list_append( value
, function_get_named_variable(
3958 function
, frame
, list_item( iter
) ) );
3960 stack_push( s
, value
);
3961 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_GROUP
);
3965 case INSTR_PUSH_APPEND
:
3967 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_APPEND
);
3970 stack_push( s
, list_append( l
, r
) );
3971 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_APPEND
);
3977 PROFILE_ENTER_LOCAL(function_run_INSTR_SWAP
);
3979 stack_set( s
, 0, stack_at( s
, code
->arg
) );
3980 stack_set( s
, code
->arg
, l
);
3981 PROFILE_EXIT_LOCAL(function_run_INSTR_SWAP
);
3987 PROFILE_ENTER_LOCAL(function_run_INSTR_POP
);
3988 list_free( stack_pop( s
) );
3989 PROFILE_EXIT_LOCAL(function_run_INSTR_POP
);
3994 * Branch instructions
3999 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP
);
4001 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP
);
4005 case INSTR_JUMP_EMPTY
:
4007 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_EMPTY
);
4009 if ( !list_cmp( l
, L0
) ) code
+= code
->arg
;
4011 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_EMPTY
);
4015 case INSTR_JUMP_NOT_EMPTY
:
4017 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_NOT_EMPTY
);
4019 if ( list_cmp( l
, L0
) ) code
+= code
->arg
;
4021 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_NOT_EMPTY
);
4027 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_LT
);
4030 if ( list_cmp( l
, r
) < 0 ) code
+= code
->arg
;
4033 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_LT
);
4039 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_LE
);
4042 if ( list_cmp( l
, r
) <= 0 ) code
+= code
->arg
;
4045 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_LE
);
4051 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_GT
);
4054 if ( list_cmp( l
, r
) > 0 ) code
+= code
->arg
;
4057 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_GT
);
4063 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_GE
);
4066 if ( list_cmp( l
, r
) >= 0 ) code
+= code
->arg
;
4069 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_GE
);
4075 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_EQ
);
4078 if ( list_cmp( l
, r
) == 0 ) code
+= code
->arg
;
4081 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_EQ
);
4087 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_NE
);
4090 if ( list_cmp(l
, r
) != 0 ) code
+= code
->arg
;
4093 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_NE
);
4099 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_IN
);
4102 if ( list_is_sublist( l
, r
) ) code
+= code
->arg
;
4105 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_IN
);
4109 case INSTR_JUMP_NOT_IN
:
4111 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_NOT_IN
);
4114 if ( !list_is_sublist( l
, r
) ) code
+= code
->arg
;
4117 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_NOT_IN
);
4125 case INSTR_FOR_INIT
:
4127 PROFILE_ENTER_LOCAL(function_run_INSTR_FOR_INIT
);
4129 *(LISTITER
*)stack_allocate( s
, sizeof( LISTITER
) ) =
4131 PROFILE_EXIT_LOCAL(function_run_INSTR_FOR_INIT
);
4135 case INSTR_FOR_LOOP
:
4137 PROFILE_ENTER_LOCAL(function_run_INSTR_FOR_LOOP
);
4138 LISTITER iter
= *(LISTITER
*)stack_get( s
);
4139 stack_deallocate( s
, sizeof( LISTITER
) );
4141 if ( iter
== list_end( l
) )
4143 list_free( stack_pop( s
) );
4148 r
= list_new( object_copy( list_item( iter
) ) );
4149 iter
= list_next( iter
);
4150 *(LISTITER
*)stack_allocate( s
, sizeof( LISTITER
) ) = iter
;
4153 PROFILE_EXIT_LOCAL(function_run_INSTR_FOR_LOOP
);
4159 PROFILE_ENTER_LOCAL(function_run_INSTR_FOR_POP
);
4160 stack_deallocate( s
, sizeof( LISTITER
) );
4161 list_free( stack_pop( s
) );
4162 PROFILE_EXIT_LOCAL(function_run_INSTR_FOR_POP
);
4170 case INSTR_JUMP_NOT_GLOB
:
4172 PROFILE_ENTER_LOCAL(function_run_INSTR_JUMP_NOT_GLOB
);
4173 char const * pattern
;
4177 pattern
= list_empty( l
) ? "" : object_str( list_front( l
) );
4178 match
= list_empty( r
) ? "" : object_str( list_front( r
) );
4179 if ( glob( pattern
, match
) )
4182 list_free( stack_pop( s
) );
4184 PROFILE_EXIT_LOCAL(function_run_INSTR_JUMP_NOT_GLOB
);
4192 case INSTR_SET_RESULT
:
4194 PROFILE_ENTER_LOCAL(function_run_INSTR_SET_RESULT
);
4195 list_free( result
);
4197 result
= stack_pop( s
);
4199 result
= list_copy( stack_top( s
) );
4200 PROFILE_EXIT_LOCAL(function_run_INSTR_SET_RESULT
);
4204 case INSTR_PUSH_RESULT
:
4206 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_RESULT
);
4207 stack_push( s
, result
);
4209 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_RESULT
);
4215 PROFILE_ENTER_LOCAL(function_run_INSTR_RETURN
);
4216 if ( function_
->formal_arguments
)
4217 argument_list_pop( function_
->formal_arguments
,
4218 function_
->num_formal_arguments
, frame
, s
);
4220 if ( !( saved_stack
== s
->data
) )
4222 frame
->file
= function
->file
;
4223 frame
->line
= function
->line
;
4224 backtrace_line( frame
);
4225 out_printf( "error: stack check failed.\n" );
4227 assert( saved_stack
== s
->data
);
4230 assert( saved_stack
== s
->data
);
4231 debug_on_exit_function( function
->base
.rulename
);
4232 PROFILE_EXIT_LOCAL(function_run_INSTR_RETURN
);
4233 PROFILE_EXIT_LOCAL(function_run
);
4241 case INSTR_PUSH_LOCAL
:
4243 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_LOCAL
);
4244 LIST
* value
= stack_pop( s
);
4245 stack_push( s
, function_swap_variable( function
, frame
, code
->arg
,
4247 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_LOCAL
);
4251 case INSTR_POP_LOCAL
:
4253 PROFILE_ENTER_LOCAL(function_run_INSTR_POP_LOCAL
);
4254 function_set_variable( function
, frame
, code
->arg
, stack_pop( s
) );
4255 PROFILE_EXIT_LOCAL(function_run_INSTR_POP_LOCAL
);
4259 case INSTR_PUSH_LOCAL_FIXED
:
4261 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_LOCAL_FIXED
);
4262 LIST
* value
= stack_pop( s
);
4263 LIST
* * ptr
= &frame
->module
->fixed_variables
[ code
->arg
];
4264 assert( code
->arg
< frame
->module
->num_fixed_variables
);
4265 stack_push( s
, *ptr
);
4267 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_LOCAL_FIXED
);
4271 case INSTR_POP_LOCAL_FIXED
:
4273 PROFILE_ENTER_LOCAL(function_run_INSTR_POP_LOCAL_FIXED
);
4274 LIST
* value
= stack_pop( s
);
4275 LIST
* * ptr
= &frame
->module
->fixed_variables
[ code
->arg
];
4276 assert( code
->arg
< frame
->module
->num_fixed_variables
);
4279 PROFILE_EXIT_LOCAL(function_run_INSTR_POP_LOCAL_FIXED
);
4283 case INSTR_PUSH_LOCAL_GROUP
:
4285 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_LOCAL_GROUP
);
4286 LIST
* const value
= stack_pop( s
);
4290 for ( iter
= list_begin( l
), end
= list_end( l
); iter
!= end
;
4291 iter
= list_next( iter
) )
4292 stack_push( s
, function_swap_named_variable( function
, frame
,
4293 list_item( iter
), list_copy( value
) ) );
4296 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_LOCAL_GROUP
);
4300 case INSTR_POP_LOCAL_GROUP
:
4302 PROFILE_ENTER_LOCAL(function_run_INSTR_POP_LOCAL_GROUP
);
4306 l
= list_reverse( r
);
4308 for ( iter
= list_begin( l
), end
= list_end( l
); iter
!= end
;
4309 iter
= list_next( iter
) )
4310 function_set_named_variable( function
, frame
, list_item( iter
),
4313 PROFILE_EXIT_LOCAL(function_run_INSTR_POP_LOCAL_GROUP
);
4318 * on $(TARGET) variables
4323 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_ON
);
4324 LIST
* targets
= stack_top( s
);
4325 if ( !list_empty( targets
) )
4327 /* FIXME: push the state onto the stack instead of using
4330 TARGET
* t
= bindtarget( list_front( targets
) );
4331 pushsettings( frame
->module
, t
->settings
);
4335 /* [ on $(TARGET) ... ] is ignored if $(TARGET) is empty. */
4336 list_free( stack_pop( s
) );
4337 stack_push( s
, L0
);
4340 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_ON
);
4346 PROFILE_ENTER_LOCAL(function_run_INSTR_POP_ON
);
4347 LIST
* result
= stack_pop( s
);
4348 LIST
* targets
= stack_pop( s
);
4349 if ( !list_empty( targets
) )
4351 TARGET
* t
= bindtarget( list_front( targets
) );
4352 popsettings( frame
->module
, t
->settings
);
4354 list_free( targets
);
4355 stack_push( s
, result
);
4356 PROFILE_EXIT_LOCAL(function_run_INSTR_POP_ON
);
4362 PROFILE_ENTER_LOCAL(function_run_INSTR_SET_ON
);
4363 LIST
* targets
= stack_pop( s
);
4364 LIST
* value
= stack_pop( s
);
4365 LIST
* vars
= stack_pop( s
);
4366 LISTITER iter
= list_begin( targets
);
4367 LISTITER
const end
= list_end( targets
);
4368 for ( ; iter
!= end
; iter
= list_next( iter
) )
4370 TARGET
* t
= bindtarget( list_item( iter
) );
4371 LISTITER vars_iter
= list_begin( vars
);
4372 LISTITER
const vars_end
= list_end( vars
);
4373 for ( ; vars_iter
!= vars_end
; vars_iter
= list_next( vars_iter
4375 t
->settings
= addsettings( t
->settings
, VAR_SET
, list_item(
4376 vars_iter
), list_copy( value
) );
4379 list_free( targets
);
4380 stack_push( s
, value
);
4381 PROFILE_EXIT_LOCAL(function_run_INSTR_SET_ON
);
4385 case INSTR_APPEND_ON
:
4387 PROFILE_ENTER_LOCAL(function_run_INSTR_APPEND_ON
);
4388 LIST
* targets
= stack_pop( s
);
4389 LIST
* value
= stack_pop( s
);
4390 LIST
* vars
= stack_pop( s
);
4391 LISTITER iter
= list_begin( targets
);
4392 LISTITER
const end
= list_end( targets
);
4393 for ( ; iter
!= end
; iter
= list_next( iter
) )
4395 TARGET
* const t
= bindtarget( list_item( iter
) );
4396 LISTITER vars_iter
= list_begin( vars
);
4397 LISTITER
const vars_end
= list_end( vars
);
4398 for ( ; vars_iter
!= vars_end
; vars_iter
= list_next( vars_iter
4400 t
->settings
= addsettings( t
->settings
, VAR_APPEND
,
4401 list_item( vars_iter
), list_copy( value
) );
4404 list_free( targets
);
4405 stack_push( s
, value
);
4406 PROFILE_EXIT_LOCAL(function_run_INSTR_APPEND_ON
);
4410 case INSTR_DEFAULT_ON
:
4412 PROFILE_ENTER_LOCAL(function_run_INSTR_DEFAULT_ON
);
4413 LIST
* targets
= stack_pop( s
);
4414 LIST
* value
= stack_pop( s
);
4415 LIST
* vars
= stack_pop( s
);
4416 LISTITER iter
= list_begin( targets
);
4417 LISTITER
const end
= list_end( targets
);
4418 for ( ; iter
!= end
; iter
= list_next( iter
) )
4420 TARGET
* t
= bindtarget( list_item( iter
) );
4421 LISTITER vars_iter
= list_begin( vars
);
4422 LISTITER
const vars_end
= list_end( vars
);
4423 for ( ; vars_iter
!= vars_end
; vars_iter
= list_next( vars_iter
4425 t
->settings
= addsettings( t
->settings
, VAR_DEFAULT
,
4426 list_item( vars_iter
), list_copy( value
) );
4429 list_free( targets
);
4430 stack_push( s
, value
);
4431 PROFILE_EXIT_LOCAL(function_run_INSTR_DEFAULT_ON
);
4435 /* [ on $(target) return $(variable) ] */
4438 PROFILE_ENTER_LOCAL(function_run_INSTR_GET_ON
);
4439 LIST
* targets
= stack_pop( s
);
4441 if ( !list_empty( targets
) )
4443 OBJECT
* varname
= function
->constants
[ code
->arg
];
4444 TARGET
* t
= bindtarget( list_front( targets
) );
4445 SETTINGS
* s
= t
->settings
;
4447 for ( ; s
!= 0; s
= s
->next
)
4449 if ( object_equal( s
->symbol
, varname
) )
4458 result
= var_get( frame
->module
, varname
) ;
4461 list_free( targets
);
4462 stack_push( s
, list_copy( result
) );
4463 PROFILE_EXIT_LOCAL(function_run_INSTR_GET_ON
);
4473 PROFILE_ENTER_LOCAL(function_run_INSTR_SET
);
4474 function_set_variable( function
, frame
, code
->arg
,
4476 PROFILE_EXIT_LOCAL(function_run_INSTR_SET
);
4482 PROFILE_ENTER_LOCAL(function_run_INSTR_APPEND
);
4483 function_append_variable( function
, frame
, code
->arg
,
4485 PROFILE_EXIT_LOCAL(function_run_INSTR_APPEND
);
4491 PROFILE_ENTER_LOCAL(function_run_INSTR_DEFAULT
);
4492 function_default_variable( function
, frame
, code
->arg
,
4494 PROFILE_EXIT_LOCAL(function_run_INSTR_DEFAULT
);
4498 case INSTR_SET_FIXED
:
4500 PROFILE_ENTER_LOCAL(function_run_INSTR_SET_FIXED
);
4501 LIST
* * ptr
= &frame
->module
->fixed_variables
[ code
->arg
];
4502 assert( code
->arg
< frame
->module
->num_fixed_variables
);
4504 *ptr
= stack_pop( s
);
4505 PROFILE_EXIT_LOCAL(function_run_INSTR_SET_FIXED
);
4509 case INSTR_APPEND_FIXED
:
4511 PROFILE_ENTER_LOCAL(function_run_INSTR_APPEND_FIXED
);
4512 LIST
* * ptr
= &frame
->module
->fixed_variables
[ code
->arg
];
4513 assert( code
->arg
< frame
->module
->num_fixed_variables
);
4514 *ptr
= list_append( *ptr
, stack_pop( s
) );
4515 PROFILE_EXIT_LOCAL(function_run_INSTR_APPEND_FIXED
);
4519 case INSTR_DEFAULT_FIXED
:
4521 PROFILE_ENTER_LOCAL(function_run_INSTR_DEFAULT_FIXED
);
4522 LIST
* * ptr
= &frame
->module
->fixed_variables
[ code
->arg
];
4523 LIST
* value
= stack_pop( s
);
4524 assert( code
->arg
< frame
->module
->num_fixed_variables
);
4525 if ( list_empty( *ptr
) )
4529 PROFILE_EXIT_LOCAL(function_run_INSTR_DEFAULT_FIXED
);
4533 case INSTR_SET_GROUP
:
4535 PROFILE_ENTER_LOCAL(function_run_INSTR_SET_GROUP
);
4536 LIST
* value
= stack_pop( s
);
4537 LIST
* vars
= stack_pop( s
);
4538 LISTITER iter
= list_begin( vars
);
4539 LISTITER
const end
= list_end( vars
);
4540 for ( ; iter
!= end
; iter
= list_next( iter
) )
4541 function_set_named_variable( function
, frame
, list_item( iter
),
4542 list_copy( value
) );
4545 PROFILE_EXIT_LOCAL(function_run_INSTR_SET_GROUP
);
4549 case INSTR_APPEND_GROUP
:
4551 PROFILE_ENTER_LOCAL(function_run_INSTR_APPEND_GROUP
);
4552 LIST
* value
= stack_pop( s
);
4553 LIST
* vars
= stack_pop( s
);
4554 LISTITER iter
= list_begin( vars
);
4555 LISTITER
const end
= list_end( vars
);
4556 for ( ; iter
!= end
; iter
= list_next( iter
) )
4557 function_append_named_variable( function
, frame
, list_item( iter
4558 ), list_copy( value
) );
4561 PROFILE_EXIT_LOCAL(function_run_INSTR_APPEND_GROUP
);
4565 case INSTR_DEFAULT_GROUP
:
4567 PROFILE_ENTER_LOCAL(function_run_INSTR_DEFAULT_GROUP
);
4568 LIST
* value
= stack_pop( s
);
4569 LIST
* vars
= stack_pop( s
);
4570 LISTITER iter
= list_begin( vars
);
4571 LISTITER
const end
= list_end( vars
);
4572 for ( ; iter
!= end
; iter
= list_next( iter
) )
4573 function_default_named_variable( function
, frame
, list_item(
4574 iter
), list_copy( value
) );
4577 PROFILE_EXIT_LOCAL(function_run_INSTR_DEFAULT_GROUP
);
4585 case INSTR_CALL_RULE
:
4587 PROFILE_ENTER_LOCAL(function_run_INSTR_CALL_RULE
);
4588 char const * unexpanded
= object_str( function_get_constant(
4589 function
, code
[ 1 ].op_code
) );
4590 LIST
* result
= function_call_rule( function
, frame
, s
, code
->arg
,
4591 unexpanded
, function
->file
, code
[ 1 ].arg
);
4592 stack_push( s
, result
);
4594 PROFILE_EXIT_LOCAL(function_run_INSTR_CALL_RULE
);
4598 case INSTR_CALL_MEMBER_RULE
:
4600 PROFILE_ENTER_LOCAL(function_run_INSTR_CALL_MEMBER_RULE
);
4601 OBJECT
* rule_name
= function_get_constant( function
, code
[1].op_code
);
4602 LIST
* result
= function_call_member_rule( function
, frame
, s
, code
->arg
, rule_name
, function
->file
, code
[1].arg
);
4603 stack_push( s
, result
);
4605 PROFILE_EXIT_LOCAL(function_run_INSTR_CALL_MEMBER_RULE
);
4611 PROFILE_ENTER_LOCAL(function_run_INSTR_RULE
);
4612 function_set_rule( function
, frame
, s
, code
->arg
);
4613 PROFILE_EXIT_LOCAL(function_run_INSTR_RULE
);
4619 PROFILE_ENTER_LOCAL(function_run_INSTR_ACTIONS
);
4620 function_set_actions( function
, frame
, s
, code
->arg
);
4621 PROFILE_EXIT_LOCAL(function_run_INSTR_ACTIONS
);
4626 * Variable expansion
4629 case INSTR_APPLY_MODIFIERS
:
4631 PROFILE_ENTER_LOCAL(function_run_INSTR_APPLY_MODIFIERS
);
4635 n
= expand_modifiers( s
, code
->arg
);
4637 l
= apply_modifiers( s
, n
);
4638 list_free( stack_pop( s
) );
4639 stack_deallocate( s
, n
* sizeof( VAR_EDITS
) );
4640 for ( i
= 0; i
< code
->arg
; ++i
)
4641 list_free( stack_pop( s
) ); /* pop modifiers */
4643 PROFILE_EXIT_LOCAL(function_run_INSTR_APPLY_MODIFIERS
);
4647 case INSTR_APPLY_INDEX
:
4649 PROFILE_ENTER_LOCAL(function_run_INSTR_APPLY_INDEX
);
4650 l
= apply_subscript( s
);
4651 list_free( stack_pop( s
) );
4652 list_free( stack_pop( s
) );
4654 PROFILE_EXIT_LOCAL(function_run_INSTR_APPLY_INDEX
);
4658 case INSTR_APPLY_INDEX_MODIFIERS
:
4660 PROFILE_ENTER_LOCAL(function_run_INSTR_APPLY_INDEX_MODIFIERS
);
4665 n
= expand_modifiers( s
, code
->arg
);
4668 l
= apply_subscript_and_modifiers( s
, n
);
4669 list_free( stack_pop( s
) );
4670 list_free( stack_pop( s
) );
4671 stack_deallocate( s
, n
* sizeof( VAR_EDITS
) );
4672 for ( i
= 0; i
< code
->arg
; ++i
)
4673 list_free( stack_pop( s
) ); /* pop modifiers */
4675 PROFILE_EXIT_LOCAL(function_run_INSTR_APPLY_INDEX_MODIFIERS
);
4679 case INSTR_APPLY_MODIFIERS_GROUP
:
4681 PROFILE_ENTER_LOCAL(function_run_INSTR_APPLY_MODIFIERS_GROUP
);
4683 LIST
* const vars
= stack_pop( s
);
4684 int const n
= expand_modifiers( s
, code
->arg
);
4686 LISTITER iter
= list_begin( vars
);
4687 LISTITER
const end
= list_end( vars
);
4688 for ( ; iter
!= end
; iter
= list_next( iter
) )
4690 stack_push( s
, function_get_named_variable( function
, frame
,
4691 list_item( iter
) ) );
4692 result
= list_append( result
, apply_modifiers( s
, n
) );
4693 list_free( stack_pop( s
) );
4696 stack_deallocate( s
, n
* sizeof( VAR_EDITS
) );
4697 for ( i
= 0; i
< code
->arg
; ++i
)
4698 list_free( stack_pop( s
) ); /* pop modifiers */
4699 stack_push( s
, result
);
4700 PROFILE_EXIT_LOCAL(function_run_INSTR_APPLY_MODIFIERS_GROUP
);
4704 case INSTR_APPLY_INDEX_GROUP
:
4706 PROFILE_ENTER_LOCAL(function_run_INSTR_APPLY_INDEX_GROUP
);
4707 LIST
* vars
= stack_pop( s
);
4709 LISTITER iter
= list_begin( vars
);
4710 LISTITER
const end
= list_end( vars
);
4711 for ( ; iter
!= end
; iter
= list_next( iter
) )
4713 stack_push( s
, function_get_named_variable( function
, frame
,
4714 list_item( iter
) ) );
4715 result
= list_append( result
, apply_subscript( s
) );
4716 list_free( stack_pop( s
) );
4719 list_free( stack_pop( s
) );
4720 stack_push( s
, result
);
4721 PROFILE_EXIT_LOCAL(function_run_INSTR_APPLY_INDEX_GROUP
);
4725 case INSTR_APPLY_INDEX_MODIFIERS_GROUP
:
4727 PROFILE_ENTER_LOCAL(function_run_INSTR_APPLY_INDEX_MODIFIERS_GROUP
);
4729 LIST
* const vars
= stack_pop( s
);
4730 LIST
* const r
= stack_pop( s
);
4731 int const n
= expand_modifiers( s
, code
->arg
);
4733 LISTITER iter
= list_begin( vars
);
4734 LISTITER
const end
= list_end( vars
);
4736 for ( ; iter
!= end
; iter
= list_next( iter
) )
4738 stack_push( s
, function_get_named_variable( function
, frame
,
4739 list_item( iter
) ) );
4740 result
= list_append( result
, apply_subscript_and_modifiers( s
,
4742 list_free( stack_pop( s
) );
4744 list_free( stack_pop( s
) );
4746 stack_deallocate( s
, n
* sizeof( VAR_EDITS
) );
4747 for ( i
= 0; i
< code
->arg
; ++i
)
4748 list_free( stack_pop( s
) ); /* pop modifiers */
4749 stack_push( s
, result
);
4750 PROFILE_EXIT_LOCAL(function_run_INSTR_APPLY_INDEX_MODIFIERS_GROUP
);
4754 case INSTR_COMBINE_STRINGS
:
4756 PROFILE_ENTER_LOCAL(function_run_INSTR_COMBINE_STRINGS
);
4757 size_t const buffer_size
= code
->arg
* sizeof( expansion_item
);
4758 LIST
* * const stack_pos
= stack_get( s
);
4759 expansion_item
* items
= stack_allocate( s
, buffer_size
);
4762 for ( i
= 0; i
< code
->arg
; ++i
)
4763 items
[ i
].values
= stack_pos
[ i
];
4764 result
= expand( items
, code
->arg
);
4765 stack_deallocate( s
, buffer_size
);
4766 for ( i
= 0; i
< code
->arg
; ++i
)
4767 list_free( stack_pop( s
) );
4768 stack_push( s
, result
);
4769 PROFILE_EXIT_LOCAL(function_run_INSTR_COMBINE_STRINGS
);
4773 case INSTR_GET_GRIST
:
4775 PROFILE_ENTER_LOCAL(function_run_INSTR_GET_GRIST
);
4776 LIST
* vals
= stack_pop( s
);
4780 for ( iter
= list_begin( vals
), end
= list_end( vals
); iter
!= end
; ++iter
)
4782 OBJECT
* new_object
;
4783 const char * value
= object_str( list_item( iter
) );
4785 if ( value
[ 0 ] == '<' && ( p
= strchr( value
, '>' ) ) )
4788 new_object
= object_new_range( value
, p
- value
+ 1 );
4790 new_object
= object_copy( list_item( iter
) );
4794 new_object
= object_copy( constant_empty
);
4796 result
= list_push_back( result
, new_object
);
4800 stack_push( s
, result
);
4801 PROFILE_EXIT_LOCAL(function_run_INSTR_GET_GRIST
);
4807 PROFILE_ENTER_LOCAL(function_run_INSTR_INCLUDE
);
4808 LIST
* nt
= stack_pop( s
);
4809 if ( !list_empty( nt
) )
4811 TARGET
* const t
= bindtarget( list_front( nt
) );
4814 /* DWA 2001/10/22 - Perforce Jam cleared the arguments here,
4815 * which prevented an included file from being treated as part
4816 * of the body of a rule. I did not see any reason to do that,
4817 * so I lifted the restriction.
4820 /* Bind the include file under the influence of "on-target"
4821 * variables. Though they are targets, include files are not
4822 * built with make().
4825 pushsettings( root_module(), t
->settings
);
4826 /* We do not expect that a file to be included is generated by
4827 * some action. Therefore, pass 0 as third argument. If the name
4828 * resolves to a directory, let it error out.
4830 object_free( t
->boundname
);
4831 t
->boundname
= search( t
->name
, &t
->time
, 0, 0 );
4832 popsettings( root_module(), t
->settings
);
4834 parse_file( t
->boundname
, frame
);
4836 frame
->function
= function_
;
4839 PROFILE_EXIT_LOCAL(function_run_INSTR_INCLUDE
);
4844 * Classes and modules
4847 case INSTR_PUSH_MODULE
:
4849 PROFILE_ENTER_LOCAL(function_run_INSTR_PUSH_MODULE
);
4850 LIST
* const module_name
= stack_pop( s
);
4851 module_t
* const outer_module
= frame
->module
;
4852 frame
->module
= !list_empty( module_name
)
4853 ? bindmodule( list_front( module_name
) )
4855 list_free( module_name
);
4856 *(module_t
* *)stack_allocate( s
, sizeof( module_t
* ) ) =
4858 PROFILE_EXIT_LOCAL(function_run_INSTR_PUSH_MODULE
);
4862 case INSTR_POP_MODULE
:
4864 PROFILE_ENTER_LOCAL(function_run_INSTR_POP_MODULE
);
4865 module_t
* const outer_module
= *(module_t
* *)stack_get( s
);
4866 stack_deallocate( s
, sizeof( module_t
* ) );
4867 frame
->module
= outer_module
;
4868 PROFILE_EXIT_LOCAL(function_run_INSTR_POP_MODULE
);
4874 PROFILE_ENTER_LOCAL(function_run_INSTR_CLASS
);
4875 LIST
* bases
= stack_pop( s
);
4876 LIST
* name
= stack_pop( s
);
4877 OBJECT
* class_module
= make_class_module( name
, bases
, frame
);
4879 module_t
* const outer_module
= frame
->module
;
4880 frame
->module
= bindmodule( class_module
);
4881 object_free( class_module
);
4883 *(module_t
* *)stack_allocate( s
, sizeof( module_t
* ) ) =
4885 PROFILE_EXIT_LOCAL(function_run_INSTR_CLASS
);
4889 case INSTR_BIND_MODULE_VARIABLES
:
4891 PROFILE_ENTER_LOCAL(function_run_INSTR_BIND_MODULE_VARIABLES
);
4892 module_bind_variables( frame
->module
);
4893 PROFILE_EXIT_LOCAL(function_run_INSTR_BIND_MODULE_VARIABLES
);
4897 case INSTR_APPEND_STRINGS
:
4899 PROFILE_ENTER_LOCAL(function_run_INSTR_APPEND_STRINGS
);
4902 combine_strings( s
, code
->arg
, buf
);
4903 stack_push( s
, list_new( object_new( buf
->value
) ) );
4905 PROFILE_EXIT_LOCAL(function_run_INSTR_APPEND_STRINGS
);
4909 case INSTR_WRITE_FILE
:
4911 PROFILE_ENTER_LOCAL(function_run_INSTR_WRITE_FILE
);
4914 OBJECT
* tmp_filename
= 0;
4915 int out_debug
= DEBUG_EXEC
? 1 : 0;
4916 FILE * out_file
= 0;
4918 combine_strings( s
, code
->arg
, buf
);
4919 out
= object_str( list_front( stack_top( s
) ) );
4921 /* For stdout/stderr we will create a temp file and generate a
4922 * command that outputs the content as needed.
4924 if ( ( strcmp( "STDOUT", out
) == 0 ) ||
4925 ( strcmp( "STDERR", out
) == 0 ) )
4927 int err_redir
= strcmp( "STDERR", out
) == 0;
4930 tmp_filename
= path_tmpfile();
4932 /* Construct os-specific cat command. */
4934 char * command
= "cat";
4935 char * quote
= "\"";
4936 char * redirect
= "1>&2";
4941 #elif defined( OS_VMS )
4942 command
= "pipe type";
4945 /* Get tmp file name is os-format. */
4947 string os_filename
[ 1 ];
4949 string_new( os_filename
);
4950 path_translate_to_os( object_str( tmp_filename
), os_filename
);
4951 object_free( tmp_filename
);
4952 tmp_filename
= object_new( os_filename
->value
);
4953 string_free( os_filename
);
4957 string_new( result
);
4958 string_append( result
, command
);
4959 string_append( result
, " " );
4960 string_append( result
, quote
);
4961 string_append( result
, object_str( tmp_filename
) );
4962 string_append( result
, quote
);
4965 string_append( result
, " " );
4966 string_append( result
, redirect
);
4970 /* Replace STDXXX with the temporary file. */
4971 list_free( stack_pop( s
) );
4972 stack_push( s
, list_new( object_new( result
->value
) ) );
4973 out
= object_str( tmp_filename
);
4975 string_free( result
);
4977 /* Make sure temp files created by this get nuked eventually. */
4978 file_remove_atexit( tmp_filename
);
4981 if ( !globs
.noexec
)
4983 string out_name
[ 1 ];
4984 /* Handle "path to file" filenames. */
4985 if ( ( out
[ 0 ] == '"' ) && ( out
[ strlen( out
) - 1 ] == '"' )
4988 string_copy( out_name
, out
+ 1 );
4989 string_truncate( out_name
, out_name
->size
- 1 );
4992 string_copy( out_name
, out
);
4993 out_file
= fopen( out_name
->value
, "w" );
4997 err_printf( "failed to write output file '%s'!\n",
5001 string_free( out_name
);
5004 if ( out_debug
) out_printf( "\nfile %s\n", out
);
5005 if ( out_file
) fputs( buf
->value
, out_file
);
5006 if ( out_debug
) out_puts( buf
->value
);
5014 object_free( tmp_filename
);
5016 if ( out_debug
) out_putc( '\n' );
5017 PROFILE_EXIT_LOCAL(function_run_INSTR_WRITE_FILE
);
5021 case INSTR_OUTPUT_STRINGS
:
5023 PROFILE_ENTER_LOCAL(function_run_INSTR_OUTPUT_STRINGS
);
5024 string
* const buf
= *(string
* *)( (char *)stack_get( s
) + (
5025 code
->arg
* sizeof( LIST
* ) ) );
5026 combine_strings( s
, code
->arg
, buf
);
5027 PROFILE_EXIT_LOCAL(function_run_INSTR_OUTPUT_STRINGS
);
5031 case INSTR_DEBUG_LINE
:
5033 debug_on_instruction( frame
, function
->file
, code
->arg
);
5041 PROFILE_EXIT_LOCAL(function_run
);
5047 static struct arg_list
* arg_list_compile_python( PyObject
* bjam_signature
,
5048 int * num_arguments
)
5050 if ( bjam_signature
)
5052 struct argument_list_compiler c
[ 1 ];
5053 struct arg_list
* result
;
5056 argument_list_compiler_init( c
);
5058 s
= PySequence_Size( bjam_signature
);
5059 for ( i
= 0; i
< s
; ++i
)
5061 struct argument_compiler arg_comp
[ 1 ];
5062 struct arg_list arg
;
5063 PyObject
* v
= PySequence_GetItem( bjam_signature
, i
);
5066 argument_compiler_init( arg_comp
);
5068 inner
= PySequence_Size( v
);
5069 for ( j
= 0; j
< inner
; ++j
)
5070 argument_compiler_add( arg_comp
, object_new( PyString_AsString(
5071 PySequence_GetItem( v
, j
) ) ), constant_builtin
, -1 );
5073 arg
= arg_compile_impl( arg_comp
, constant_builtin
, -1 );
5074 dynamic_array_push( c
->args
, arg
);
5075 argument_compiler_free( arg_comp
);
5079 *num_arguments
= c
->args
->size
;
5080 result
= BJAM_MALLOC( c
->args
->size
* sizeof( struct arg_list
) );
5081 memcpy( result
, c
->args
->data
, c
->args
->size
* sizeof( struct arg_list
)
5083 argument_list_compiler_free( c
);
5090 FUNCTION
* function_python( PyObject
* function
, PyObject
* bjam_signature
)
5092 PYTHON_FUNCTION
* result
= BJAM_MALLOC( sizeof( PYTHON_FUNCTION
) );
5094 result
->base
.type
= FUNCTION_PYTHON
;
5095 result
->base
.reference_count
= 1;
5096 result
->base
.rulename
= 0;
5097 result
->base
.formal_arguments
= arg_list_compile_python( bjam_signature
,
5098 &result
->base
.num_formal_arguments
);
5099 Py_INCREF( function
);
5100 result
->python_function
= function
;
5102 return (FUNCTION
*)result
;
5106 static void argument_list_to_python( struct arg_list
* formal
, int formal_count
,
5107 FUNCTION
* function
, FRAME
* frame
, PyObject
* kw
)
5109 LOL
* all_actual
= frame
->args
;
5112 for ( i
= 0; i
< formal_count
; ++i
)
5114 LIST
* actual
= lol_get( all_actual
, i
);
5115 LISTITER actual_iter
= list_begin( actual
);
5116 LISTITER
const actual_end
= list_end( actual
);
5118 for ( j
= 0; j
< formal
[ i
].size
; ++j
)
5120 struct argument
* formal_arg
= &formal
[ i
].args
[ j
];
5124 switch ( formal_arg
->flags
)
5127 if ( actual_iter
== actual_end
)
5128 argument_error( "missing argument", function
, frame
,
5129 formal_arg
->arg_name
);
5130 type_check_range( formal_arg
->type_name
, actual_iter
, list_next(
5131 actual_iter
), frame
, function
, formal_arg
->arg_name
);
5132 value
= PyString_FromString( object_str( list_item( actual_iter
5134 actual_iter
= list_next( actual_iter
);
5137 if ( actual_iter
== actual_end
)
5141 type_check_range( formal_arg
->type_name
, actual_iter
,
5142 list_next( actual_iter
), frame
, function
,
5143 formal_arg
->arg_name
);
5144 value
= PyString_FromString( object_str( list_item(
5146 actual_iter
= list_next( actual_iter
);
5150 if ( actual_iter
== actual_end
)
5151 argument_error( "missing argument", function
, frame
,
5152 formal_arg
->arg_name
);
5155 type_check_range( formal_arg
->type_name
, actual_iter
,
5156 actual_end
, frame
, function
, formal_arg
->arg_name
);
5157 l
= list_copy_range( actual
, actual_iter
, actual_end
);
5158 value
= list_to_python( l
);
5160 actual_iter
= actual_end
;
5168 PyObject
* key
= PyString_FromString( object_str(
5169 formal_arg
->arg_name
) );
5170 PyDict_SetItem( kw
, key
, value
);
5176 if ( actual_iter
!= actual_end
)
5177 argument_error( "extra argument", function
, frame
, list_item(
5181 for ( ; i
< all_actual
->count
; ++i
)
5183 LIST
* const actual
= lol_get( all_actual
, i
);
5184 if ( !list_empty( actual
) )
5185 argument_error( "extra argument", function
, frame
, list_front(
5191 /* Given a Python object, return a string to use in Jam code instead of the said
5194 * If the object is a string, use the string value.
5195 * If the object implemenets __jam_repr__ method, use that.
5196 * Otherwise return 0.
5199 OBJECT
* python_to_string( PyObject
* value
)
5201 if ( PyString_Check( value
) )
5202 return object_new( PyString_AS_STRING( value
) );
5204 /* See if this instance defines the special __jam_repr__ method. */
5205 if ( PyInstance_Check( value
)
5206 && PyObject_HasAttrString( value
, "__jam_repr__" ) )
5208 PyObject
* repr
= PyObject_GetAttrString( value
, "__jam_repr__" );
5211 PyObject
* arguments2
= PyTuple_New( 0 );
5212 PyObject
* value2
= PyObject_Call( repr
, arguments2
, 0 );
5214 Py_DECREF( arguments2
);
5215 if ( PyString_Check( value2
) )
5216 return object_new( PyString_AS_STRING( value2
) );
5217 Py_DECREF( value2
);
5224 static module_t
* python_module()
5226 static module_t
* python
= 0;
5228 python
= bindmodule( constant_python
);
5233 static LIST
* call_python_function( PYTHON_FUNCTION
* function
, FRAME
* frame
)
5236 PyObject
* arguments
= 0;
5237 PyObject
* kw
= NULL
;
5239 PyObject
* py_result
;
5240 FRAME
* prev_frame_before_python_call
;
5242 if ( function
->base
.formal_arguments
)
5244 arguments
= PyTuple_New( 0 );
5246 argument_list_to_python( function
->base
.formal_arguments
,
5247 function
->base
.num_formal_arguments
, &function
->base
, frame
, kw
);
5251 arguments
= PyTuple_New( frame
->args
->count
);
5252 for ( i
= 0; i
< frame
->args
->count
; ++i
)
5253 PyTuple_SetItem( arguments
, i
, list_to_python( lol_get( frame
->args
,
5257 frame
->module
= python_module();
5259 prev_frame_before_python_call
= frame_before_python_call
;
5260 frame_before_python_call
= frame
;
5261 py_result
= PyObject_Call( function
->python_function
, arguments
, kw
);
5262 frame_before_python_call
= prev_frame_before_python_call
;
5263 Py_DECREF( arguments
);
5265 if ( py_result
!= NULL
)
5267 if ( PyList_Check( py_result
) )
5269 int size
= PyList_Size( py_result
);
5271 for ( i
= 0; i
< size
; ++i
)
5273 OBJECT
* s
= python_to_string( PyList_GetItem( py_result
, i
) );
5276 "Non-string object returned by Python call.\n" );
5278 result
= list_push_back( result
, s
);
5281 else if ( py_result
== Py_None
)
5287 OBJECT
* const s
= python_to_string( py_result
);
5289 result
= list_new( s
);
5291 /* We have tried all we could. Return empty list. There are
5292 * cases, e.g. feature.feature function that should return a
5293 * value for the benefit of Python code and which also can be
5294 * called by Jam code, where no sensible value can be returned.
5295 * We cannot even emit a warning, since there would be a pile of
5301 Py_DECREF( py_result
);
5306 err_printf( "Call failed\n" );
5315 void function_done( void )