|
The match-bind expression performs a pattern match, and tests whether
it succeeds. It evaluates the left hand expression to a value -- the specimen.
It then matches the specimen against the pattern. The match-bind expression
as a whole evaluates to a boolean indicating whether the match succeeded.
In either case, the variable bound by pattern are available in the succeeding
scope.
|
eExpr "=~" pattern
|
|
<!ELEMENT matchBindExpr (%eExpr;, %pattern;)>
|
|
The pattern is expanded to produce a boolean saying whether we
have a match. Only when we succeed do we bind the variable in the
pattern to extracts of the specimen. If we fail, all these variable
must be broken in the following scope. Therefore, we use temporary
standins for these variable during the match. |
|
list =~ [car] + cdr
|
|
list =~ [car :any] + cdr :any
|
|
<matchBindExpr>
<Noun>list</Noun>
<cdrPattern>
<listPattern>
<finalPattern>
<Noun>car</Noun>
<Noun>any</Noun>
</finalPattern>
</listPattern>
<finalPattern>
<Noun>cdr</Noun>
<Noun>any</Noun>
</finalPattern>
</cdrPattern>
</matchBindExpr>
|
|
boolean result_4 = false;
Object car = Ref.broken(...);
Object cdr = Ref.broken(...);
fail_4: {
if (! isTuple(list)) { break fail_4; }
Integer len = E.toInteger(E.call(list, "size"));
if (len.intValue() < 1) { break fail_4; }
final Object car_tmp = E.call(list, "get", 0);
final Object cdr_tmp = E.call(list, "run", 1, len);
//commit
result_4 = true;
car = car_tmp;
cdr = cdr_tmp;
}
//
|
If the match succeeded, then these variables will bound to the values they
extracted from the specimen. If the match fails, then, in the succeeding
scope, all these variables will be bound to broken references (XXX need
to specify the problem). If a variable was part of an earlier sub-pattern
than succeeded before the match as a whole failed, then this variable will
be seen to bound to the value it extracted from the specimen by later code
within the overall pattern, but will be seen to by bound to the broken reference
by code after the match-bind expression as a whole. This "change"
in binding happens even if the variable is declared ":final".
Effectively, the variables defined within the pattern are redefined following
the pattern and initialized accordingly. |
|