1:- module(dialect,
2	  [
3	   exists_source/1,
4	   source_exports/2
5	  ]).
6
7
8prolog:'$expects_dialect'(yap) :- !,
9	eraseall('$dialect'),
10	recorda('$dialect',yap,_).
11prolog:'$expects_dialect'(Dialect) :-
12	check_dialect(Dialect),
13	eraseall('$dialect'),
14	load_files(library(dialect/Dialect),[silent(true),if(not_loaded)]),
15	(   current_predicate(Dialect:setup_dialect/0)
16	->  Dialect:setup_dialect
17	;   true
18	),
19	recorda('$dialect',Dialect,_).
20
21check_dialect(Dialect) :-
22	var(Dialect),!,
23	'$do_error'(instantiation_error,(:- dialect(Dialect))).
24check_dialect(Dialect) :-
25	\+ atom(Dialect),!,
26	'$do_error'(type_error(Dialect),(:- dialect(Dialect))).
27check_dialect(Dialect) :-
28	exists_source(library(dialect/Dialect)), !.
29check_dialect(Dialect) :-
30	'$do_error'(domain_error(dialect,Dialect),(:- dialect(Dialect))).
31
32%%	exists_source(+Source) is semidet.
33%
34%	True if Source (a term  valid   for  load_files/2) exists. Fails
35%	without error if this is not the case. The predicate is intended
36%	to be used with  :-  if,  as   in  the  example  below. See also
37%	source_exports/2.
38%
39%	==
40%	:- if(exists_source(library(error))).
41%	:- use_module_library(error).
42%	:- endif.
43%	==
44
45exists_source(Source) :-
46	exists_source(Source, _Path).
47
48exists_source(Source, Path) :-
49	absolute_file_name(Source, Path,
50			   [ file_type(prolog),
51			     access(read),
52			     file_errors(fail)
53			   ]).
54
55%%	source_exports(+Source, +Export) is semidet.
56%%	source_exports(+Source, -Export) is nondet.
57%
58%	True if Source exports Export. Fails   without  error if this is
59%	not the case.  See also exists_source/1.
60%
61%	@tbd	Should we also allow for source_exports(-Source, +Export)?
62
63source_exports(Source, Export) :-
64	open_source(Source, In),
65	catch(call_cleanup(exports(In, Exports), close(In)), _, fail),
66	(   ground(Export)
67	->  memberchk(Export, Exports)
68	;   member(Export, Exports)
69	).
70
71%%	open_source(+Source, -In:stream) is semidet.
72%
73%	Open a source location.
74
75open_source(File, In) :-
76	exists_source(File, Path),
77	open(Path, read, In),
78	(   peek_char(In, #)
79	->  skip(In, 10)
80	;   true
81	).
82
83exports(In, Exports) :-
84	read(In, Term),
85	Term = (:- module(_Name, Exports)).
86
87