| Cobra | Inline Programs | keywords | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| NAMEcontrol-flow keywordsDESCRIPTIONThe following ten words are keywords used for definint the control-flow of an inline program.if else elif (Version 4.8) while break continue goto for foreach in function returnWe illustrate the typical use of each keyword with a small example. Note that the body of every if, else, elif, while, and for statement must be enclosed in curly braces, even if it contains just a single statement. Also, every basic statement (not compound statements) must be terminated with a semi-colon. 
 
 The destination of a goto can either follow or precede the location of the goto itself, but it must appear within the same program fragment, or within the same function definition as the goto. The for keyword can be used to loop over the indices of an associative arrays, as in: 
	for ( varname in arrayname ) { ... }
See assiociative arrays for examples.
Break and continue statements can be used to alter the control flow in
the usual way (version 4.7 and later).For statements can only be used for browsing the contents of associative arrays. The foreach statement can be used to loop over either the patterns in an existing pattern set, or over the tokens from a given pattern set (version 4.7 and later). The pattern set must exist before the inline program containing the foreach statement is started, i.e., it cannot be created first as part of the same inline program fragment. An example of a foreach statement, illustrating also the use of a continue statement (break and continue are supported in foreach statements), is as follows. 
	: requires 4.7
	: pe S: while ( .* )
	%{
           foreach (p in S)
           {       print p.fnm ":" p.lnr ": ";
                   if (p.lnr == 760)
                   {       print " skipped!\n";
                           continue;
                   }
                   foreach (t in p)
                   {       print t " ";
                   }
                   print "\n";
           }
           Stop; # don't repeat the same program for all tokens in the input
	%}
A second example shows a case where the type of the argument S cannot be
predicted at compile time. In that case, we can make clear that a pattern
set is explored by adding the qualifier pattern after foreach.
(The default exploration type is a token sequence for a single pattern match.)
	pe A: while ( . ) { .* }
	%{
		function list2set(nm, y)
		{
			while (y.seq != 0)
			{	add_pattern(nm, y.p_start, y.p_end);
				y = y.nxt;
			}
		}
		function set_summary(nm)
		{	# the type of nm cannot be determined
			# at compile time, so we use the
			# qualifier 'pattern' after 'foreach'
			print "summary of " nm  "\n";
			foreach pattern (i in nm)
			{	print " " i.fnm ":" i.lnr ": " i.txt "\n";
			}
		}
	
		x = pset(A);
		z = pset(A) with (.lnr % 2);
			# using a constraint, see pset
			# in fct_index.html
		list2set("copy_of_A", x);
		list2set("subset_of_A", z);
		set_summary("A");
	
		Stop;
	%}
	ps list
Here we also used a constraint on the 
pset
command to extract a subset of the target pattern set A.
General Loops
 
	%{
		. = Begin;
		while (. != End)
		{	# do something useful
			. = .nxt;	# dont forget this
		}
		Stop;
	%}
Technically, both the first and last statement here are redundant, because
when the inline program is invoked for the first time the current token will
be the first token in the input sequence, and in this case when the while
loop terminates we also know that we have reached the final token, so the
Cobra will not advance the token any further and stop executing, even if
the Stop command was not there. Typically though it is not wise to count
on these two things being true.We could use the above loop to reverse the order of traversal, if that made sense in some context, and then we definitely need the two extra statements: 
	%{
		. = End;
		while (. != Begin)
		{	# do something
			. = .prv;
		}
		Stop;
	%}
This time, if we were to forget the Stop command, the program execution would
never finish: it would continued to execute because after each execution the
current token position is back at the beginning of the input sequence.The function keyword can be used to define new functions, e.g. as in: 
	function name(par1, par2)
	{	. = .nxt;
		if (.txt == par1)
		{	return par2;
		}
		return 0;
	}
where parameters are always passed by value. One exception is that the basename of
an associative array cannot be passed as a parameter, since that would require copying
its entire contents. When needed, it is better to make the array global in this case.There are only two levels of scope in the scripting language: global or function local. See also variables. | ||||||||||||||||
| Inline Programs Manual Tutorial | (Last Updated: 18 June 2024) | |||