ref: c85de58a2047c4858825d03977e490db6168fbe3
parent: 43f65cbe02b3a2512c3a797862196d693b3a9f11
author: Peter Mikkelsen <peter@pmikkelsen.com>
date: Thu Jul 22 20:50:18 EDT 2021
Simplify parsing a bit, and make sure the prolog loader calls read_term with the correct module to pick up the correct operators
--- a/builtins.c
+++ b/builtins.c
@@ -893,7 +893,6 @@
builtinreadterm(Term *goal, Binding **bindings, Module *module)
{
USED(bindings);
- USED(module);
Term *stream = goal->children;
Term *term = stream->next;
@@ -911,7 +910,7 @@
Throw(permissionerror(L"input", L"binary_stream", stream));
Term *realterm;
- int error = readterm(stream, &realterm);
+ int error = readterm(stream, &realterm, module);
if(error)
Throw(realterm);
@@ -942,7 +941,7 @@
varsnames = varsandnames(uniquevars);
singlevars = singletons(allvars);
}
-
+
Term *op;
for(op = options; op->tag == CompoundTerm; op = op->children->next){
Term *opkey = op->children->children;
--- a/eval.c
+++ b/eval.c
@@ -66,6 +66,17 @@
name = prettyprint(goal, 0, 0, 0, nil);
arity = 0;
}
+ print("Didn't find predicate %S in module %S\n", prettyprint(goal, 0, 0, 0, nil), module->name);
+ Predicate *p;
+ for(p = module->predicates; p != nil; p = p->next)
+ print("Available in %S: %S/%d\n", module->name, p->name, p->arity);
+ Module *sysmod;
+ if(systemmoduleloaded)
+ sysmod = getmodule(L"system");
+ else
+ sysmod = getmodule(L"user");
+ for(p = sysmod->predicates; p != nil; p = p->next)
+ print("Available in %S: %S/%d\n", sysmod->name, p->name, p->arity);
switch(flagunknown){
case UnknownError:
procedure = mkatom(name);
--- a/fns.h
+++ b/fns.h
@@ -1,5 +1,5 @@
/* parser.c */
-Term *parse(int, Biobuf *, int);
+Term *parse(Biobuf *, Module *);
/* prettyprint.c */
Rune *prettyprint(Term *, int, int, int, Module *);
@@ -58,7 +58,7 @@
int istextstream(Term *);
int isbinarystream(Term *);
int canreposition(Term *);
-int readterm(Term *, Term **);
+int readterm(Term *, Term **, Module *);
void writeterm(Term *, Term *, Term *, Module *);
Rune getchar(Term *);
Rune peekchar(Term *);
--- a/loader.pl
+++ b/loader.pl
@@ -55,17 +55,21 @@
read_and_handle_terms(Stream, Module0, Module) :-
- ( read_one_term(Stream, Term, Singles)
+ ( read_one_term(Stream, Term, Module0, Singles)
-> handle_term(Term, Singles, Module0, Module1),
read_and_handle_terms(Stream, Module1, Module)
; Module = Module0
).
-read_one_term(Stream, Term, Singles) :-
+read_one_term(Stream, Term, Module0, Singles) :-
consume_whitespace(Stream),
peek_char(Stream, NextCh),
NextCh \= end_of_file,
- read_term(Stream, Term, [singletons(Singletons)]),
+ ( Module0 == system
+ -> read_term(Stream, Term, [singletons(Singletons)])
+ ; Module0:read_term(Stream, Term, [singletons(Singletons)])
+ % For all other modules than system use Mod:read_term, to use the correct operators
+ ),
singleton_names(Singletons, Singles).
whitespace(' ').
--- a/module.c
+++ b/module.c
@@ -5,6 +5,8 @@
#include "dat.h"
#include "fns.h"
+void handleopdirective(Term *, Module *);
+
void
initmodules(void)
{
@@ -22,24 +24,25 @@
int
addtousermod(char *file)
{
- int fd = open(file, OREAD);
- if(fd < 0)
+ Biobuf *bio = Bopen(file, OREAD);
+ if(bio == nil)
return 0;
Module *usermodule = getmodule(L"user");
- Term *terms = parse(fd, nil, 0);
-
- if(terms == nil)
- return 0;
-
Predicate *currentpred = nil;
+
Term *t;
- for(t = terms; t != nil; t = t->next){
+ while(t = parse(bio, usermodule)){
Clause *cl = gmalloc(sizeof(Clause));
int arity;
cl->clausenr = 0;
cl->next = nil;
- if(t->tag == CompoundTerm && runestrcmp(t->text, L":-") == 0 && t->arity == 2){
+ if(t->tag == CompoundTerm && runestrcmp(t->text, L":-") == 0 && t->arity == 1){
+ Term *body = t->children;
+ if(runestrcmp(body->text, L"op") == 0 && body->arity == 3)
+ handleopdirective(body->children, usermodule);
+ continue;
+ }else if(t->tag == CompoundTerm && runestrcmp(t->text, L":-") == 0 && t->arity == 2){
cl->head = t->children;
cl->body = t->children->next;
}else{
@@ -66,6 +69,8 @@
currentpred->clauses = appendclause(currentpred->clauses, cl);
}
usermodule->predicates = appendpredicate(currentpred, usermodule->predicates);
+
+ Bterm(bio);
return 1;
}
@@ -185,4 +190,43 @@
op->spelling = spelling;
op->next = mod->operators[level-1];
mod->operators[level-1] = op;
+}
+
+void
+handleopdirective(Term *args, Module *mod)
+{
+ Term *levelt = args;
+ Term *typet = levelt->next;
+ Term *opt = typet->next;
+ if(levelt->tag == IntegerTerm
+ && levelt->ival >= 0
+ && levelt->ival <= PrecedenceLevels
+ && typet->tag == AtomTerm
+ && opt->tag == AtomTerm){
+ int level = levelt->ival;
+ Rune *spelling = opt->text;
+ int type = 0;
+ if(runestrcmp(typet->text, L"xf") == 0)
+ type = Xf;
+ else if(runestrcmp(typet->text, L"yf") == 0)
+ type = Yf;
+ else if(runestrcmp(typet->text, L"xfx") == 0)
+ type = Xfx;
+ else if(runestrcmp(typet->text, L"xfy") == 0)
+ type = Xfy;
+ else if(runestrcmp(typet->text, L"yfx") == 0)
+ type = Yfx;
+ else if(runestrcmp(typet->text, L"fy") == 0)
+ type = Fy;
+ else if(runestrcmp(typet->text, L"fx") == 0)
+ type = Fx;
+ if(type != 0){
+ addoperator(level, type, spelling, mod);
+ return;
+ }
+ }
+ print("Malformed op directive with level=%S, type=%S, op=%S\n",
+ prettyprint(levelt, 0, 0, 0, mod),
+ prettyprint(typet, 0, 0, 0, mod),
+ prettyprint(opt, 0, 0, 0, mod));
}
\ No newline at end of file
--- a/parser.c
+++ b/parser.c
@@ -52,68 +52,33 @@
Term *parseoperators(Term *);
void match(int);
void syntaxerror_parser(char *);
-Term *prologtext(int);
-void handlemoduledirective(Term *);
-void handleopdirective(Term *);
+Term *parseterm(void);
Term *
-parse(int fd, Biobuf *bio, int querymode)
+parse(Biobuf *bio, Module *mod)
{
- if(bio == nil){
- fd = dup(fd, -1);
- parsein = Bfdopen(fd, OREAD);
- if(parsein == nil){
- print("Could not open file\n");
- return nil;
- }
- }else
- parsein = bio;
-
+ parsein = bio;
+ currentmod = mod;
nexttoken();
- currentmod = getmodule(L"user");
- Term *result = prologtext(querymode);
- if(querymode && result){
+ Term *result = parseterm();
+ if(result){
result = copyterm(result, &clausenr);
clausenr++;
}
- if(!bio)
- Bterm(parsein);
-
return result;
}
Term *
-prologtext(int querymode)
+parseterm(void)
{
if(lookahead.tag == EofTok)
return nil;
Term *t = fullterm(AtomTok, L".", nil);
- if(lookahead.tag == AtomTok && runestrcmp(lookahead.text, L".") == 0){
- if(!querymode)
- match(AtomTok);
- }else
- syntaxerror_parser("prologtext");
+ if(lookahead.tag != AtomTok || runestrcmp(lookahead.text, L".") != 0)
+ syntaxerror_parser("parseterm");
- if(querymode)
- return t;
-
- if(t->tag == CompoundTerm && runestrcmp(t->text, L":-") == 0 && t->arity == 1){
- Term *body = t->children;
- if(runestrcmp(body->text, L"op") == 0 && body->arity == 3)
- handleopdirective(body->children);
-
- t = prologtext(querymode);
- }else if(t->tag == CompoundTerm && runestrcmp(t->text, L":-") == 0 && t->arity == 2){
- t->next = prologtext(querymode);
- }else if(t->tag == AtomTerm || t->tag == CompoundTerm){
- t->next = prologtext(querymode);
- }else{
- print("Expected directive or clause as toplevel\n");
- syntaxerror_parser("prologtext");
- }
-
return t;
}
@@ -572,42 +537,3 @@
print("Syntax error: Unexpected %d (%S) token in %s\n", lookahead.tag, lookahead.text, where);
exits("syntax error");
}
-
-void
-handleopdirective(Term *args)
-{
- Term *levelt = args;
- Term *typet = levelt->next;
- Term *opt = typet->next;
- if(levelt->tag == IntegerTerm
- && levelt->ival >= 0
- && levelt->ival <= PrecedenceLevels
- && typet->tag == AtomTerm
- && opt->tag == AtomTerm){
- int level = levelt->ival;
- Rune *spelling = opt->text;
- int type = 0;
- if(runestrcmp(typet->text, L"xf") == 0)
- type = Xf;
- else if(runestrcmp(typet->text, L"yf") == 0)
- type = Yf;
- else if(runestrcmp(typet->text, L"xfx") == 0)
- type = Xfx;
- else if(runestrcmp(typet->text, L"xfy") == 0)
- type = Xfy;
- else if(runestrcmp(typet->text, L"yfx") == 0)
- type = Yfx;
- else if(runestrcmp(typet->text, L"fy") == 0)
- type = Fy;
- else if(runestrcmp(typet->text, L"fx") == 0)
- type = Fx;
- if(type != 0){
- addoperator(level, type, spelling, currentmod);
- return;
- }
- }
- print("Malformed op directive with level=%S, type=%S, op=%S\n",
- prettyprint(levelt, 0, 0, 0, currentmod),
- prettyprint(typet, 0, 0, 0, currentmod),
- prettyprint(opt, 0, 0, 0, currentmod));
-}
\ No newline at end of file
--- a/streams.c
+++ b/streams.c
@@ -217,7 +217,7 @@
}
int
-readterm(Term *stream, Term **term)
+readterm(Term *stream, Term **term, Module *mod)
{
Stream *s = getstream(stream);
if(s == nil){
@@ -224,7 +224,7 @@
*term = existenceerror(L"stream", stream);
return 1;
}
- *term = parse(0, s->bio, 1);
+ *term = parse(s->bio, mod);
return 0;
}