next up previous
Next: Grammar rule interface Up: Built-In Predicates Previous: Meta-Call Predicates

Advanced control-structures: blocks

  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 compatibily 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).



Passani Luca
Tue Nov 14 08:58:33 MET 1995