forked from jansegre/node-swipl
-
Notifications
You must be signed in to change notification settings - Fork 4
/
index.js
98 lines (82 loc) · 2.16 KB
/
index.js
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
const fs = require('fs');
const path = require('path');
const assert = require('assert');
const term = require('./lib/term');
const swipl = require('./build/Release/libswipl');
// Set SWI_HOME_DIR based on install-time value.
const filename = path.join(__dirname, 'plbase.conf');
const plbase = fs.readFileSync(filename, 'utf8').trim();
process.env.SWI_HOME_DIR = plbase;
let initialised = false;
let auto = true;
// Allows to disable autoinitialization of
// the SWI-Prolog engine.
const autoInitialise = (initialise) => {
auto = !!initialise;
};
let current = null;
class Query {
constructor(query) {
assert.equal(typeof query, 'string',
'Query must be set as a string.');
assert.ok(current === null,
'There can be only one open query at a time.');
if (!initialised) {
if (auto) {
if (!swipl.initialise('node')) {
throw new Error('SWI-Prolog engine initialization failed.');
}
initialised = true;
} else {
throw new Error('SWI-Prolog is not initialised.');
}
}
this.internal = new swipl.InternalQuery(query);
current = this;
}
next() {
const bindings = this.internal.next();
if (!bindings) {
return false;
} else {
return extractBindings(bindings);
}
}
close() {
this.internal.close();
current = null;
}
};
// Helper to call single query.
const call = (query) => {
const instance = new Query(query);
try {
const bindings = instance.next();
return bindings;
} finally {
instance.close();
}
};
// Extracts bindings from the option list.
const extractBindings = (list) => {
const bindings = {};
while (list !== '[]') {
bindings[list.head.args[0]] = list.head.args[1];
list = list.tail;
}
return bindings;
};
const initialise = () => {
return swipl.initialise('node');
};
const cleanup = () => {
return swipl.cleanup();
};
module.exports = {
autoInitialise,
Query,
call,
term,
initialise,
cleanup
};