⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 compile.c

📁 jam源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	 */	if( nt )	{	    TARGET *t = bindtarget( nt->string );	    SETTINGS *s = copysettings( t->settings );	    pushsettings( s );	    result = (*parse->right->func)( parse->right, args, jmp );	    popsettings( s );	    freesettings( s );	}	list_free( nt );	return result;}/* * compile_rule() - compile a single user defined rule * *	parse->left	list of rules to run *	parse->right	parameters (list of lists) to rule, recursing left * * Wrapped around evaluate_rule() so that headers() can share it. */LIST *compile_rule(	PARSE	*parse,	LOL	*args,	int	*jmp ){	LOL	nargs[1];	LIST	*result = 0;	LIST	*ll, *l;	PARSE	*p;	/* list of rules to run -- normally 1! */	ll = (*parse->left->func)( parse->left, args, jmp );	/* Build up the list of arg lists */	lol_init( nargs );	for( p = parse->right; p; p = p->left )	    lol_add( nargs, (*p->right->func)( p->right, args, jmp ) );	/* Run rules, appending results from each */	for( l = ll; l; l = list_next( l ) )	    result = evaluate_rule( l->string, nargs, result );	list_free( ll );	lol_free( nargs );	return result;}/* * evaluate_rule() - execute a rule invocation */LIST *evaluate_rule(	const char *rulename,	LOL	*args, 	LIST	*result ){	RULE	*rule = bindrule( rulename );	if( DEBUG_COMPILE )	{	    debug_compile( 1, rulename );	    lol_print( args );	    printf( "\n" );	}	/* Check traditional targets $(<) and sources $(>) */	if( !rule->actions && !rule->procedure )	    printf( "warning: unknown rule %s\n", rule->name );	/* If this rule will be executed for updating the targets */	/* then construct the action for make(). */	if( rule->actions )	{	    TARGETS	*t;	    ACTION	*action;	    /* The action is associated with this instance of this rule */	    action = (ACTION *)malloc( sizeof( ACTION ) );	    memset( (char *)action, '\0', sizeof( *action ) );	    action->rule = rule;	    action->targets = targetlist( (TARGETS *)0, lol_get( args, 0 ) );	    action->sources = targetlist( (TARGETS *)0, lol_get( args, 1 ) );	    /* Append this action to the actions of each target */	    for( t = action->targets; t; t = t->next )		t->target->actions = actionlist( t->target->actions, action );	}	/* Now recursively compile any parse tree associated with this rule */	if( rule->procedure )	{	    PARSE *parse = rule->procedure;	    SETTINGS *s = 0;	    int jmp = JMP_NONE;	    LIST *l;	    int i;	    /* build parameters as local vars */	    for( l = rule->params, i = 0; l; l = l->next, i++ )		s = addsettings( s, 0, l->string, 		    list_copy( L0, lol_get( args, i ) ) );	    /* Run rule. */	    /* Bring in local params. */	    /* refer/free to ensure rule not freed during use. */	    parse_refer( parse );	    pushsettings( s );	    result = list_append( result, (*parse->func)( parse, args, &jmp ) );	    popsettings( s );	    freesettings( s );	    parse_free( parse );	}	if( DEBUG_COMPILE )	    debug_compile( -1, 0 );	return result;}/* * compile_rules() - compile a chain of rules * *	parse->left	single rule *	parse->right	more compile_rules() by right-recursion */LIST *compile_rules(	PARSE	*parse,	LOL	*args,	int	*jmp ){	/* Ignore result from first statement; return the 2nd. */	/* Optimize recursion on the right by looping. */	LIST 	*result = 0;	while( *jmp == JMP_NONE && parse->func == compile_rules )	{	    list_free( result );	    result = (*parse->left->func)( parse->left, args, jmp );	    parse = parse->right;	}	if( *jmp == JMP_NONE )	{	    list_free( result );	    result = (*parse->func)( parse, args, jmp );	}	return result;}/* * compile_set() - compile the "set variable" statement * *	parse->left	variable names *	parse->right	variable values  *	parse->num	VAR_SET/APPEND/DEFAULT */LIST *compile_set(	PARSE	*parse,	LOL	*args,	int	*jmp ){	LIST	*nt = (*parse->left->func)( parse->left, args, jmp );	LIST	*ns = (*parse->right->func)( parse->right, args, jmp );	LIST	*l;	if( DEBUG_COMPILE )	{	    debug_compile( 0, "set" );	    list_print( nt );	    printf( " %s ", set_names[ parse->num ] );	    list_print( ns );	    printf( "\n" );	}	/* Call var_set to set variable */	/* var_set keeps ns, so need to copy it */	for( l = nt; l; l = list_next( l ) )	    var_set( l->string, list_copy( L0, ns ), parse->num );	list_free( nt );	return ns;}/* * compile_setcomp() - support for `rule` - save parse tree  * *	parse->string	rule name *	parse->left	list of argument names *	parse->right	rules for rule */LIST *compile_setcomp(	PARSE	*parse,	LOL	*args,	int	*jmp ){	RULE	*rule = bindrule( parse->string );	LIST	*params = 0;	PARSE	*p;	/* Build param list */	for( p = parse->left; p; p = p->left )	    params = list_new( params, p->string, 1 );	if( DEBUG_COMPILE )	{	    debug_compile( 0, "rule" );	    printf( "%s ", parse->string );	    list_print( params );	    printf( "\n" );	}	/* Free old one, if present */	if( rule->procedure )	    parse_free( rule->procedure );	if( rule->params )	    list_free( rule->params );	rule->procedure = parse->right;	rule->params = params;	/* we now own this parse tree */	/* don't let parse_free() release it */	parse_refer( parse->right );	return L0;}/* * compile_setexec() - support for `actions` - save execution string  * *	parse->string	rule name *	parse->string1	OS command string *	parse->num	flags *	parse->left	`bind` variables * * Note that the parse flags (as defined in compile.h) are transfered * directly to the rule flags (as defined in rules.h). */LIST *compile_setexec(	PARSE	*parse,	LOL	*args,	int	*jmp ){	RULE	*rule = bindrule( parse->string );	LIST	*bindlist = (*parse->left->func)( parse->left, args, jmp );		/* Free old one, if present */	if( rule->actions )	{	    freestr( rule->actions );	    list_free( rule->bindlist );	}	rule->actions = copystr( parse->string1 );	rule->bindlist = bindlist;	rule->flags = parse->num;	return L0;}/* * compile_settings() - compile the "on =" (set variable on exec) statement * *	parse->left	variable names *	parse->right	target name  *	parse->third	variable value  *	parse->num	VAR_SET/APPEND/DEFAULT */LIST *compile_settings(	PARSE	*parse,	LOL	*args,	int	*jmp ){	LIST	*nt = (*parse->left->func)( parse->left, args, jmp );	LIST	*ns = (*parse->third->func)( parse->third, args, jmp );	LIST	*targets = (*parse->right->func)( parse->right, args, jmp );	LIST	*ts;	if( DEBUG_COMPILE )	{	    debug_compile( 0, "set" );	    list_print( nt );	    printf( "on " );	    list_print( targets );	    printf( " %s ", set_names[ parse->num ] );	    list_print( ns );	    printf( "\n" );	}	/* Call addsettings to save variable setting */	/* addsettings keeps ns, so need to copy it */	/* Pass append flag to addsettings() */	for( ts = targets; ts; ts = list_next( ts ) )	{	    TARGET 	*t = bindtarget( ts->string );	    LIST	*l;	    for( l = nt; l; l = list_next( l ) )		t->settings = addsettings( t->settings, parse->num,				l->string, list_copy( (LIST*)0, ns ) );	}	list_free( nt );	list_free( targets );	return ns;}/* * compile_switch() - compile 'switch' rule * *	parse->left	switch value (only 1st used) *	parse->right	cases * *	cases->left	1st case *	cases->right	next cases * *	case->string	argument to match *	case->left	parse tree to execute */LIST *compile_switch(	PARSE	*parse,	LOL	*args,	int	*jmp ){	LIST	*nt = (*parse->left->func)( parse->left, args, jmp );	LIST	*result = 0;	if( DEBUG_COMPILE )	{	    debug_compile( 0, "switch" );	    list_print( nt );	    printf( "\n" );	}	/* Step through cases */	for( parse = parse->right; parse; parse = parse->right )	{	    if( !glob( parse->left->string, nt ? nt->string : "" ) )	    {		/* Get & exec parse tree for this case */		parse = parse->left->left;		result = (*parse->func)( parse, args, jmp );		break;	    }	}	list_free( nt );	return result;}/* * compile_while() - compile 'while' rule * *	parse->left		condition tree *	parse->right		execution tree */LIST *compile_while(	PARSE	*p,	LOL	*args,	int	*jmp ){	LIST *result = 0;	LIST *l;	/* Returns the value from the last execution of the block */	while( ( *jmp == JMP_NONE ) && 	       ( l = (*p->left->func)( p->left, args, jmp ) ) )	{	    /* Always toss while's expression */	    list_free( l );	    /* Keep only last result. */	    list_free( result );	    result = (*p->right->func)( p->right, args, jmp );	    /* continue loop? */	    if( *jmp == JMP_CONTINUE )		*jmp = JMP_NONE;	}	/* Here by break/continue? */	if( *jmp == JMP_BREAK || *jmp == JMP_CONTINUE )	    *jmp = JMP_NONE;	/* Returns result of last loop */	return result;}/* * debug_compile() - printf with indent to show rule expansion. */static voiddebug_compile( int which, const char *s ){	static int level = 0;	static char indent[36] = ">>>>|>>>>|>>>>|>>>>|>>>>|>>>>|>>>>|";	int i = ((1+level) * 2) % 35;	if( which >= 0 )	    printf( "%*.*s ", i, i, indent );	if( s )	    printf( "%s ", s );	level += which;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -