Cobra Inline Programs keywords

NAME

control-flow keywords

DESCRIPTION

The 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
	return
We 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.

if, else if ( expr ) { prog }
if ( expr ) { prog1 } else { prog2 }
if ( expr ) { prog1 } elif ( expr ) { prog2 }
while, break, continue while ( expr ) { prog }
where prog can contain break and/or continue statements
goto goto label; prog1
label: prog2
for, in for (i in A) { prog } see assiociative arrays
break or continue statements are supported in for statements starting with version 4.7.
foreach, in, break, continue foreach [pattern] (p in S) { prog }
where S is either an existing pattern set, or the starting token from a pattern. Break and continue can be used to break from the loop or to continue with the next element to be visited in the iteration (version 4.7 and later).

To force the choice, when the type of S cannot be determined at compile time, the qualifier pattern can be added. By default, if the type of S cannot be determined, the loop will assume a token sequence, rather than a pattern set.

function, return see user-defined functions

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
There is only one fully general loop statement, and that is the while-loop, where the break and continue statements also have the usual effect (respectively to break from the innermost loop, or to shortcut the current iteration and jump back to the loop condition to start a new iteration). For instance, we can make an inline program take over the complete traversal of all tokens in the input sequence as follows:

	%{
		. = 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)