[Up] [Contents] [Index] [Summary]
The predicates of this
section form a tightly related set for realising premature successfull
or failing exits from a block. These predicates are first of
all useful for error-recovery. They were primarily implemented for
compatibility reasons.
- block(+Label, +Goal,
-ExitValue)
-
Execute Goal in a block. Label is the
name of the block. Label is normally an atom, but the system
imposes no type constraints and may even be a variable. ExitValue
is normally unified to the second argument of an exit/2
call invoked by Goal.
- exit(+Label, +Value)
-
Calling exit/2
makes the innermost block which Label unifies
exit. The block's ExitValue is unified with Value.
If this unification fails the block fails.
- fail(+Label)
-
Calling fail/1
makes the innermost block which Label unifies fail
immediately. Implemented as
fail(Label) :- !(Label), fail.
- !(+Label)
-
Cut all choice-points created since the entry of the innermost
block which Label unifies.
The example below illustrate these constructs to immediately report a
syntax-error from a `deep-down' procedure to the outside world without
passing it as an argument `all-over-the-place'.
parse(RuleSet, InputList, Rest) :-
block(syntaxerror, phrase(RuleSet, InputList, Rest), Error),
( var(Error)
-> true
; format('Syntax-error: ~w~n', Error),
fail
).
integer(N) -->
digit(D1), !, digits(Ds),
{ name(N, [D1|Ds]) }.
digits([D|R]) --> digit(D), digits(R).
digits(_) --> letter(_), !, { exit(syntaxerror, 'Illegal number') }.
digits([]) --> [].
digit(D, [D|R], R) :- between(0'0, 0'9, D).
letter(D, [D|R], R) :- between(0'a, 0'z, D).