From 44ab8a339c78bcc3460d44b2f435116f21faa60a Mon Sep 17 00:00:00 2001 From: Peter Mikkelsen Date: Mon, 5 Jul 2021 16:27:38 +0000 Subject: First step on modules. Still very very rough. --- module.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 module.c (limited to 'module.c') diff --git a/module.c b/module.c new file mode 100644 index 0000000..f3ab01b --- /dev/null +++ b/module.c @@ -0,0 +1,116 @@ +#include +#include +#include + +#include "dat.h" +#include "fns.h" + +Module *addemptymodule(Rune *); +Clause *appendclause(Clause *, Clause *); + +void +initmodules(void) +{ + systemmodule = parsemodule("./stdlib.pl"); + if(systemmodule == nil){ + print("Can't load ./stdlib.pl\n"); + exits(nil); + } + + usermodule = addemptymodule(L"user"); +} + +Module * +parsemodule(char *file) +{ + Module *m = nil; + + int fd = open(file, OREAD); + if(fd < 0) + return nil; + Term *terms = parse(fd, nil, 0); + + if(terms == nil) + return nil; + + /* Actually look at the terms and convert ':-'/2 terms into clauses. + The only directives (terms of type ':-'/1 there should be in the list are + the module specific ones, as the other are handled by parse itself. + */ + if(terms->tag == CompoundTerm && runestrcmp(terms->text, L":-") == 0 && terms->arity == 1){ + Term *directive = terms->children; + if(directive->tag == CompoundTerm && runestrcmp(directive->text, L"module") == 0 && directive->arity == 2){ + Term *modulename = directive->children; + Term *publiclist = modulename->next; + if(modulename->tag != AtomTerm){ + print("Module name should be an atom in: %S\n", prettyprint(directive, 0, 0, 0)); + return nil; + } + print("Public list for module '%S': %S\n", modulename->text, prettyprint(publiclist, 0, 0, 0)); + m = addemptymodule(modulename->text); + } + terms = terms->next; + } + + Term *t; + for(t = terms; t != nil; t = t->next){ + Clause *cl = malloc(sizeof(Clause)); + cl->clausenr = 0; + cl->public = 1; /* everything is public for now */ + cl->next = nil; + if(t->tag == CompoundTerm && runestrcmp(t->text, L":-") == 0 && t->arity == 2){ + cl->head = t->children; + cl->body = t->children->next; + }else{ + cl->head = t; + cl->body = nil; + } + + if(m == nil) + usermodule->clauses = appendclause(usermodule->clauses, cl); + else + m->clauses = appendclause(m->clauses, cl); + } + + return m; +} + +Module * +getmodule(Rune *name) +{ + Module *m; + for(m = modules; m != nil; m = m->next){ + if(runestrcmp(m->name, name) == 0) + return m; + } + return nil; +} + +Module * +addemptymodule(Rune *name) +{ + Module *m = malloc(sizeof(Module)); + m->name = name; + m->next = modules; + + if(systemmodule == nil) + m->clauses = nil; + else + m->clauses = systemmodule->clauses; /* Direct access to system clauses for now, but when I figure out imports this will change */ + modules = m; + return m; +} + +Clause * +appendclause(Clause *clauses, Clause *new) +{ + Clause *tmp; + + if(clauses == nil) + return new; + + for(tmp = clauses; tmp->next != nil; tmp = tmp->next); + + tmp->next = new; + return clauses; +} \ No newline at end of file -- cgit v1.2.3