1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
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;
}
|