diff options
-rw-r--r-- | builtins.c | 3 | ||||
-rw-r--r-- | loader.pl | 76 | ||||
-rw-r--r-- | mkfile | 3 | ||||
-rw-r--r-- | module.c | 1 | ||||
-rw-r--r-- | parser.c | 2 | ||||
-rw-r--r-- | repl.pl | 15 | ||||
-rw-r--r-- | stdlib.pl | 13 | ||||
-rw-r--r-- | streams.c | 8 |
8 files changed, 106 insertions, 15 deletions
@@ -872,6 +872,9 @@ builtinreadterm(Term *goal, Binding **bindings, Module *module) if(error) Throw(realterm); + if(realterm == nil) + Throw(syntaxerror(L"end of stream")); + Term *singlevars = nil; Term *uniquevars = nil; Term *varsnames = nil; diff --git a/loader.pl b/loader.pl new file mode 100644 index 0000000..3ba1c05 --- /dev/null +++ b/loader.pl @@ -0,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) + ). @@ -23,7 +23,8 @@ BIN=/$objtype/bin PROLOGFILES=\ stdlib.pl\ - repl.pl + repl.pl\ + loader.pl default:V: all @@ -22,6 +22,7 @@ initmodules(void) usermodule = addemptymodule(L"user"); parsemodule("/sys/lib/prolog/repl.pl"); + parsemodule("/sys/lib/prolog/loader.pl"); } Module * @@ -73,7 +73,7 @@ parse(int fd, Biobuf *bio, int querymode) currentmod = usermodule; Term *result = prologtext(querymode); - if(querymode){ + if(querymode && result){ uvlong id = 1; result = copyterm(result, &id); } @@ -1,26 +1,27 @@ :- 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. 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)), '$collect_garbage', @@ -122,7 +122,8 @@ at_end_of_stream :- 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 @@ at_end_of_stream(S_or_a) :- ), stream_property(S, end_of_stream(E)), !, - (E = at; E = past). + (E = at; E = past), + !. % Standard exceptions @@ -677,4 +679,9 @@ current_op(Priority, Op_specifier, Operator) :- ), 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). @@ -323,7 +323,8 @@ peekchar(Term *t) { Stream *s = getstream(t); Rune r = Bgetrune(s->bio); - Bungetrune(s->bio); + if(r != Beof) + Bungetrune(s->bio); return r; } @@ -412,11 +413,12 @@ Term *streamproperties(Stream *s) /* 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); |