]> Repositorios git - scryer-prolog.git/commitdiff
ISO: Implement the include/1 directive
authorMarkus Triska <[email protected]>
Sat, 28 Feb 2026 13:23:44 +0000 (14:23 +0100)
committerMarkus Triska <[email protected]>
Sat, 28 Feb 2026 13:49:13 +0000 (14:49 +0100)
Quoting from the standard:

    7.4.2.7 include/1

    If F is an implementation defined ground term designating
    a Prolog text unit, then Prolog text P1 which contains
    a directive include(F) is identical to a Prolog text P2
    obtained by replacing the directive include(F) in P1 by
    the Prolog text denoted by F.

Example:

    :- include("hello.pl").

This addresses #583 and #634.

src/toplevel.pl

index ce0190c737fd0eae38cfdd44d872b88bb4aac2ec..9c0ad643b0144473ad84e17b0431b90f06aaa1a0 100644 (file)
@@ -220,6 +220,46 @@ expand_op_list([Op | OtherOps], Pri, Spec, [(:- op(Pri, Spec, Op)) | OtherResult
     expand_op_list(OtherOps, Pri, Spec, OtherResults).
 
 
+% Implement the include/1 directive via term expansion.
+
+user:term_expansion((:- include(File0)), Clauses) :-
+        (   si:atom_si(File0) ->
+            atom_chars(File0, File),
+            format("% Warning: include/1: atom arguments are deprecated. Use chars for file paths:~n", []),
+            format("% :- include(\"~s\").~n", [File])
+        ;   error:must_be(chars, File0),
+            File = File0
+        ),
+        '$toplevel':gather_clauses_from_file(File, Clauses).
+
+
+gather_clauses_from_file(File, Clauses) :-
+        (   file_exists(File) ->
+            setup_call_cleanup(open(File, read, Stream),
+                               gather_clauses_(Stream, File, Clauses),
+                               close(Stream))
+        ;   format("include/1: ~s does not exist.", [File]),
+            Clauses = []
+        ).
+
+
+gather_clauses_(Stream, _, []) :- at_end_of_stream(Stream), !.
+gather_clauses_(Stream, File, Clauses) :-
+        catch((read(Stream, Clause),
+               Continue = true),
+              Error,
+              (   Error = error(syntax_error(incomplete_reduction),_),
+                  at_end_of_stream(Stream) ->
+                  true
+              ;   format("~s: ~q", [File,Error])
+              )),
+        (   Continue == true ->
+            Clauses = [Clause|Rest],
+            gather_clauses_(Stream, File, Rest)
+        ;   Clauses = []
+        ).
+
+
 read_and_match :-
     '$read_query_term'(_, Term, _, _, VarList),
     instruction_match(Term, VarList).