ref: 24cdc7adf5611d536403ae625414bb10f3bc4f93
parent: 90664173e5c72d0b31bdfd2c467134b3cfb3623a
author: Peter Mikkelsen <peter@pmikkelsen.com>
date: Tue Jul 20 17:58:46 EDT 2021
Add a new work in progress loader to load all user defined modules
--- a/builtins.c
+++ b/builtins.c
@@ -872,6 +872,9 @@
if(error)
Throw(realterm);
+ if(realterm == nil)
+ Throw(syntaxerror(L"end of stream"));
+
Term *singlevars = nil;
Term *uniquevars = nil;
Term *varsnames = nil;
--- /dev/null
+++ b/loader.pl
@@ -1,0 +1,76 @@
+:- module(loader, []).
+
+load_module_from_file(File) :-
+ write('Loading file: '),
+ write(File),
+ nl,
+ ( atom_concat(_, '.pl', File)
+ -> open(File, read, Stream)
+ ; atom_concat(File, '.pl', File1),
+ open(File1, read, Stream)
+ ),
+ read_and_handle_terms(Stream, user, _),
+ close(Stream),
+ write('Loaded file: '),
+ write(File),
+ nl.
+
+read_and_handle_terms(Stream, Module0, Module) :-
+ ( read_one_term(Stream, Term)
+ -> handle_term(Term, Module0, Module1),
+ read_and_handle_terms(Stream, Module1, Module)
+ ; Module = Module0
+ ).
+
+read_one_term(Stream, Term) :-
+ consume_whitespace(Stream),
+ peek_char(Stream, NextCh),
+ NextCh \= end_of_file,
+ read_term(Stream, Term, []).
+
+whitespace(' ').
+whitespace(' ').
+whitespace('
+').
+
+consume_whitespace(S) :-
+ peek_char(S, Ch),
+ ( whitespace(Ch)
+ -> get_char(S, _), consume_whitespace(S)
+ ; true
+ ).
+
+handle_term(:- Directive, Module, NewModule) :-
+ !,
+ handle_directive(Directive, Module, NewModule).
+handle_term(Head :- Body, Module, Module) :-
+ !,
+ Module:assertz(Head :- Body).
+handle_term(Head --> Body, Module, Module) :-
+ !,
+ write('DCG RULE: '),
+ write(Head --> Body),
+ nl.
+handle_term(Head, Module, Module) :-
+ Module:assertz(Head).
+
+handle_directive(op(Priority, Specifier, Operator), Module, Module) :-
+ Module:op(Priority, Specifier, Operator).
+handle_directive(include(F), Module, NewModule) :-
+ open(F, read, S),
+ read_and_handle_terms(S, Module, NewModule),
+ close(S).
+handle_directive(ensure_loaded(F), Module, Module) :-
+ ensure_load(F).
+handle_directive(D, Module, Module) :-
+ write('Cannot handle directive: '),
+ write(D),
+ nl.
+
+ensure_loads(_) :- fail.
+
+ensure_load(F) :-
+ ( ensure_loads(F)
+ -> true
+ ; asserta(ensure_loads(F)), load_module_from_file(F)
+ ).
--- a/mkfile
+++ b/mkfile
@@ -23,7 +23,8 @@
PROLOGFILES=\
stdlib.pl\
- repl.pl
+ repl.pl\
+ loader.pl
default:V: all
--- a/module.c
+++ b/module.c
@@ -22,6 +22,7 @@
usermodule = addemptymodule(L"user");
parsemodule("/sys/lib/prolog/repl.pl");
+ parsemodule("/sys/lib/prolog/loader.pl");
}
Module *
--- a/parser.c
+++ b/parser.c
@@ -73,7 +73,7 @@
currentmod = usermodule;
Term *result = prologtext(querymode);
- if(querymode){
+ if(querymode && result){
uvlong id = 1;
result = copyterm(result, &id);
}
--- a/repl.pl
+++ b/repl.pl
@@ -1,11 +1,12 @@
:- module(repl, []).
repl([ProgName|Args]) :-
- write('Welcome to p-prolog version 1'),
+ write('Welcome to p-prolog version 1.'),
nl,
write('Started with args: '),
write(Args),
nl,
+ flush_output,
handle_args(Args),
repl_loop.
@@ -12,14 +13,14 @@
handle_arg('-d') :-
set_prolog_flag(debug, on).
handle_arg(Arg) :-
- ( '$load_module_from_file'(Arg)
- -> write('Loaded module from file: ')
- ; write('Failed to load module from file: ')
- ),
- write(Arg), nl.
+ loader:load_module_from_file(Arg).
-handle_args([Arg|Rest]) :- handle_arg(Arg), !, handle_args(Rest).
+handle_args([Arg|Rest]) :- catch(handle_arg(Arg), E, handle_arg_error(E)), !, handle_args(Rest).
handle_args([]).
+
+handle_arg_error(E) :-
+ write('Could not handle arg: '),
+ print_exception(E).
repl_loop :-
catch(read_eval_print, E, print_exception(E)),
--- a/stdlib.pl
+++ b/stdlib.pl
@@ -122,7 +122,8 @@
current_input(S),
stream_property(S, end_of_stream(E)),
!,
- (E = at ; E = past).
+ (E = at ; E = past),
+ !.
at_end_of_stream(S_or_a) :-
( atom(S_or_a)
@@ -131,7 +132,8 @@
),
stream_property(S, end_of_stream(E)),
!,
- (E = at; E = past).
+ (E = at; E = past),
+ !.
% Standard exceptions
@@ -677,4 +679,9 @@
),
is_atom_or_var(Operator),
current_ops(Operators),
- member(op(Priority, Op_specifier, Operator), Operators).
\ No newline at end of file
+ member(op(Priority, Op_specifier, Operator), Operators).
+
+% Loading prolog text
+
+consult(File) :-
+ loader:load_module_from_file(File).
--- a/streams.c
+++ b/streams.c
@@ -323,7 +323,8 @@
{
Stream *s = getstream(t);
Rune r = Bgetrune(s->bio);
- Bungetrune(s->bio);
+ if(r != Beof)
+ Bungetrune(s->bio);
return r;
}
@@ -412,11 +413,12 @@
/* end_of_stream(E) */
if(s->mode == ReadStream){
Rune r = Bgetrune(s->bio);
- Bungetrune(s->bio);
if(r == Beof)
arg = mkatom(L"at");
- else
+ else{
+ Bungetrune(s->bio);
arg = mkatom(L"not");
+ }
data = copyterm(stream, nil);
data->next = mkcompound(L"end_of_stream", 1, arg);
prop = mkcompound(L"prop", 2, data);