Jam语法解析,on的用法

使用Jam语法的时候, 由于文档的缺失,以及on语法的用法多样,我经常被on这个 关键字给搞糊涂。

看了一下源码, 感觉需要整理记录一下on相关的内容。

使用on给变量赋值

首先是用on给变量赋值。 这会在Target的专属Variable集合中添加或删除修改变量。

variable on targets = elements ;  The = operator replaces any previous elements of variable with elements directly on targets  
variable on targets += elements ;  The += operator directly adds elements to targets's variable's list of elements  
variable on targets -= elements ;  The -= operator directly removes elements from targets's variable's list of elements  
variable on targets ?= elements ;  The ?= operator sets variable on targets only if it was previously unset  

    # If myvar hasn't been assigned yet, assign the string list ab and cd.
    myvar ?= ab cd ;

    # Replace myvar's contents with ef and gh.
    myvar = ef gh ;

    # Add some additional elements to myvar.
    myvar += ij kl ;        # myvar = ef gh ij kl

    # Remove some elements from myvar.
    myvar -= gh kl ;        # myvar = ef ij

    # sometarget.myvar = zx cv
    myvar on sometarget = zx cv ;

    # This prints zx cv.
    on sometarget Echo $(myvar) ;

对应的语法定义

rule : arg ON_t list assign list _SEMIC_t
		{ $$.parse = CreateParse_AddTargetVariables( $1.parse, $3.parse, $5.parse, $4.number ); }

最终会调用 interpret_AddTargetVariables函数

	for( targetStr = targets; targetStr; targetStr = list_next( targetStr ) )
	{
	    TARGET 	*target = GetOrCreateTargetByName( targetStr->string );
	    StringListEntry	*tempVariableName;

	    for( tempVariableName = tempVariableNames; tempVariableName; tempVariableName = list_next( tempVariableName ) )
		{

			target->targetVariables = SetTempVariableWithFlag( target->targetVariables, parse->num,
				tempVariableName->string, list_copy( (StringListEntry*)0, variableStrValues ) );
		}
	}

使用on执行操作

语法相关的定义有3处

rule : ON_t arg rule
		{ $$.parse = CreateParse_InvokeUsingTargetVariable( $2.parse, $3.parse ); }

// func - a function call (inside [])
// func 定义 出现在[] 函数调用中
func	: arg lol
		{ $$.parse = parseInvokeRule( $1.parse, $2.parse ); }
	| ON_t arg arg lol
		{ $$.parse = CreateParse_InvokeUsingTargetVariable( $2.parse, parseInvokeRule( $3.parse, $4.parse ) ); }
	| ON_t arg RETURN_t list
		{ $$.parse = CreateParse_InvokeUsingTargetVariable( $2.parse, $4.parse ); }
	;

这里的意思其实很简单, 就是基于当前的Variables,新增on后面这个target里面的专属Variable,然后再执行对应的操作。

SwapVariableValuesWithTemp函数就是用 target专属的variable去替换当前variable里面的。

操作结束后,再把变量切换回来

	if( targetStr )
	{
	    TARGET *target = GetOrCreateTargetByName( targetStr->string );
	    TempVariableListEntry *s = CopyTempVariables( target->targetVariables );

	    SwapVariableValuesWithTemp( s );
	    result = (*actionParse->func)( actionParse, args, jmp );
	    SwapVariableValuesWithTemp( s );
	    DeleteTempVariableList( s );
	}
posted @ 2026-03-04 22:50  dewxin  阅读(3)  评论(0)    收藏  举报