summaryrefslogtreecommitdiff
path: root/module.c
diff options
context:
space:
mode:
authorPeter Mikkelsen <peter@pmikkelsen.com>2021-07-05 16:27:38 +0000
committerPeter Mikkelsen <peter@pmikkelsen.com>2021-07-05 16:27:38 +0000
commit44ab8a339c78bcc3460d44b2f435116f21faa60a (patch)
treefa512c143c5df81c0c333a187b9083cbac9636f6 /module.c
parent3f26a0f2a1f699e628136ec5be6178b5ab40fc44 (diff)
First step on modules. Still very very rough.
Diffstat (limited to 'module.c')
-rw-r--r--module.c116
1 files changed, 116 insertions, 0 deletions
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 <u.h>
+#include <libc.h>
+#include <bio.h>
+
+#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