$func Length e.Exp = s.ExpLen;
$func? Left s.Left s.Len e.Exp = e.SubExp;
$func? Right s.Right s.Len e.Exp = e.SubExp;
$func? Middle s.Left s.Right e.Exp = e.SubExp;
$func? L s.Left e.Exp = t.SubExp;
$func? R s.Right e.Exp = t.SubExp;
These functions provide direct access to the components of ground expressions. The arguments
s.Left, s.Right, and s.Len must be
non-negative integers. e.Exp may be any ground expression.
If s.Left, s.Right, and s.Len are not
non-negative integers, the functions return the error $error(Fname "Invalid
argument"), where Fname is the function's name.
Length returns the length of the expression e.Exp
measured in terms. In other words, a ground expression Ge of the form
Gt1 Gt2 ... GtN is assumed to have the
length N.
For example:
<Length > => 0
<Length A B C> => 3
<Length (A B) C (D E)> => 3
Left removes the first s.Left terms from
e.Exp, and then returns the first s.Len terms of the
remaining expression.
Right removes the last s.Right terms from
e.Exp, and then returns the last s.Len terms of the
remaining expression.
Middle removes the first s.Left and the last
s.Right terms from e.Exp, and returns the remaining
expression.
L removes the first s.Left terms from
e.Exp, and returns the first term of the remaining expression.
R removes the last s.Right terms from
e.Exp, and returns the last term of the remaining expression.
If the length of e.Exp is not sufficient for the operation to be performed,
all of the above functions return $fail(0).
For example:
<Middle 2 3 A B C D E F> => C
<Middle 2 3 A B C D> => $fail(0)
<Middle 0 0 A B C> => A B C
<Left 2 3 A B C D E F> => C D E
<Left 2 3 A B C D> => $fail(0)
<Left 0 0 A B C> =>
<Right 2 3 A B C D E F> => B C D
<Right 2 3 A B C D> => $fail(0)
<Right 0 0 A B C> =>
<L 2 A B C D E F> => C
<L 2 A B> => $fail(0)
<R 2 A B C D E F> => D
<R 2 A B> => $fail(0)
The operations Middle, Left, and
Right may be depicted in the following way:
s.Left s.Right
+-------+-------+-------+
| |XXXXXXX| | <Middle s.Left s.Right e.Exp>
+-------+-------+-------+
s.Left s.Len
+-------+-------+-------+
| |XXXXXXX| | <Left s.Left s.Len e.Exp>
+-------+-------+-------+
s.Len s.Right
+-------+-------+-------+
| |XXXXXXX| | <Right s.Right s.Len e.Exp>
+-------+-------+-------+