summaryrefslogtreecommitdiff
path: root/module.c
diff options
context:
space:
mode:
authorPeter Mikkelsen <peter@pmikkelsen.com>2021-07-23 00:50:18 +0000
committerPeter Mikkelsen <peter@pmikkelsen.com>2021-07-23 00:50:18 +0000
commitc85de58a2047c4858825d03977e490db6168fbe3 (patch)
tree8856e5d3e8ac67ca9404bd6b0541d3652f37973d /module.c
parent43f65cbe02b3a2512c3a797862196d693b3a9f11 (diff)
Simplify parsing a bit, and make sure the prolog loader calls read_term with the correct module to pick up the correct operators
Diffstat (limited to 'module.c')
-rw-r--r--module.c62
1 files changed, 53 insertions, 9 deletions
diff --git a/module.c b/module.c
index 48c2978..e255483 100644
--- 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 @@ initmodules(void)
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 @@ addtousermod(char *file)
currentpred->clauses = appendclause(currentpred->clauses, cl);
}
usermodule->predicates = appendpredicate(currentpred, usermodule->predicates);
+
+ Bterm(bio);
return 1;
}
@@ -185,4 +190,43 @@ addoperator(int level, int type, Rune *spelling, Module *mod)
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