eyeling 1.15.0 → 1.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,18 +1,95 @@
|
|
|
1
1
|
#include <stdio.h>
|
|
2
2
|
#include <stdlib.h>
|
|
3
|
+
#include <string.h>
|
|
4
|
+
|
|
5
|
+
enum { DEPTH = 100000 };
|
|
6
|
+
|
|
7
|
+
static int emit(const char *s) {
|
|
8
|
+
return fputs(s, stdout) != EOF;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
static int emit_type(const char *kind, int index) {
|
|
12
|
+
return printf(":ind a :%s%d .\n", kind, index) >= 0;
|
|
13
|
+
}
|
|
3
14
|
|
|
4
15
|
int main(void) {
|
|
5
|
-
|
|
16
|
+
unsigned char hasN[DEPTH + 1];
|
|
17
|
+
unsigned char hasI[DEPTH + 1];
|
|
18
|
+
unsigned char hasJ[DEPTH + 1];
|
|
19
|
+
unsigned char hasA2 = 0;
|
|
20
|
+
unsigned char hasTest = 0;
|
|
21
|
+
int changed = 1;
|
|
22
|
+
|
|
23
|
+
memset(hasN, 0, sizeof(hasN));
|
|
24
|
+
memset(hasI, 0, sizeof(hasI));
|
|
25
|
+
memset(hasJ, 0, sizeof(hasJ));
|
|
26
|
+
|
|
27
|
+
/* fact: :ind a :N0. */
|
|
28
|
+
hasN[0] = 1;
|
|
29
|
+
|
|
30
|
+
/*
|
|
31
|
+
* Forward-chain the rules to a fixpoint.
|
|
32
|
+
*
|
|
33
|
+
* {?X a :N0} => {?X a :N1, :I1, :J1}.
|
|
34
|
+
* {?X a :N1} => {?X a :N2, :I2, :J2}.
|
|
35
|
+
* ...
|
|
36
|
+
* {?X a :N99999} => {?X a :N100000, :I100000, :J100000}.
|
|
37
|
+
* {?X a :N100000} => {?X a :A2}.
|
|
38
|
+
* {:ind a :A2} => {:test :is true}.
|
|
39
|
+
*/
|
|
40
|
+
while (changed) {
|
|
41
|
+
changed = 0;
|
|
42
|
+
|
|
43
|
+
for (int i = 0; i < DEPTH; i++) {
|
|
44
|
+
if (!hasN[i]) {
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (!hasN[i + 1]) {
|
|
49
|
+
hasN[i + 1] = 1;
|
|
50
|
+
changed = 1;
|
|
51
|
+
}
|
|
52
|
+
if (!hasI[i + 1]) {
|
|
53
|
+
hasI[i + 1] = 1;
|
|
54
|
+
changed = 1;
|
|
55
|
+
}
|
|
56
|
+
if (!hasJ[i + 1]) {
|
|
57
|
+
hasJ[i + 1] = 1;
|
|
58
|
+
changed = 1;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (hasN[DEPTH] && !hasA2) {
|
|
63
|
+
hasA2 = 1;
|
|
64
|
+
changed = 1;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (hasA2 && !hasTest) {
|
|
68
|
+
hasTest = 1;
|
|
69
|
+
changed = 1;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (!emit("@prefix : <http://eulersharp.sourceforge.net/2009/12dtb/test#> .\n\n")) {
|
|
6
74
|
return EXIT_FAILURE;
|
|
7
75
|
}
|
|
8
76
|
|
|
9
|
-
for (int i = 1; i <=
|
|
10
|
-
if (
|
|
77
|
+
for (int i = 1; i <= DEPTH; i++) {
|
|
78
|
+
if (!hasN[i] || !hasI[i] || !hasJ[i]) {
|
|
79
|
+
fprintf(stderr, "incomplete closure at depth %d\n", i);
|
|
11
80
|
return EXIT_FAILURE;
|
|
12
81
|
}
|
|
82
|
+
if (!emit_type("N", i) || !emit_type("I", i) || !emit_type("J", i)) {
|
|
83
|
+
return EXIT_FAILURE;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (!hasA2 || !hasTest) {
|
|
88
|
+
fputs("expected conclusions were not derived\n", stderr);
|
|
89
|
+
return EXIT_FAILURE;
|
|
13
90
|
}
|
|
14
91
|
|
|
15
|
-
if (
|
|
92
|
+
if (!emit(":ind a :A2 .\n:test :is true .\n")) {
|
|
16
93
|
return EXIT_FAILURE;
|
|
17
94
|
}
|
|
18
95
|
|
package/package.json
CHANGED
package/test/check.test.js
CHANGED
|
@@ -6,20 +6,36 @@ const os = require('node:os');
|
|
|
6
6
|
const path = require('node:path');
|
|
7
7
|
const cp = require('node:child_process');
|
|
8
8
|
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
const C = process.stdout.isTTY
|
|
10
|
+
? {
|
|
11
|
+
red: '\x1b[31m',
|
|
12
|
+
green: '\x1b[32m',
|
|
13
|
+
yellow: '\x1b[33m',
|
|
14
|
+
dim: '\x1b[2m',
|
|
15
|
+
reset: '\x1b[0m',
|
|
16
|
+
}
|
|
17
|
+
: {
|
|
18
|
+
red: '',
|
|
19
|
+
green: '',
|
|
20
|
+
yellow: '',
|
|
21
|
+
dim: '',
|
|
22
|
+
reset: '',
|
|
23
|
+
};
|
|
14
24
|
|
|
15
25
|
function ok(msg) {
|
|
16
|
-
console.log(`${C.
|
|
26
|
+
console.log(`${C.green}OK${C.reset} ${msg}`);
|
|
17
27
|
}
|
|
28
|
+
|
|
18
29
|
function fail(msg) {
|
|
19
|
-
console.
|
|
30
|
+
console.log(`${C.red}FAIL${C.reset} ${msg}`);
|
|
20
31
|
}
|
|
32
|
+
|
|
21
33
|
function info(msg) {
|
|
22
|
-
console.log(`${C.
|
|
34
|
+
console.log(`${C.yellow}==${C.reset} ${msg}`);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function msTag(ms) {
|
|
38
|
+
return `(${ms} ms)`;
|
|
23
39
|
}
|
|
24
40
|
|
|
25
41
|
function run(cmd, args, opts = {}) {
|
|
@@ -33,8 +49,8 @@ function run(cmd, args, opts = {}) {
|
|
|
33
49
|
function normalizeForCompare(n3Text) {
|
|
34
50
|
return String(n3Text)
|
|
35
51
|
.split(/\r?\n/)
|
|
36
|
-
.map((
|
|
37
|
-
.filter((
|
|
52
|
+
.map((line) => line.replace(/[ \t]+$/g, ''))
|
|
53
|
+
.filter((line) => line.length > 0)
|
|
38
54
|
.sort((a, b) => a.localeCompare(b))
|
|
39
55
|
.join('\n');
|
|
40
56
|
}
|
|
@@ -77,7 +93,7 @@ function main() {
|
|
|
77
93
|
.sort((a, b) => a.localeCompare(b));
|
|
78
94
|
|
|
79
95
|
info(`Running ${files.length} C check tests`);
|
|
80
|
-
console.log(`${C.dim}compiler ${compiler}; node ${process.version}${C.
|
|
96
|
+
console.log(`${C.dim}compiler ${compiler}; node ${process.version}${C.reset}`);
|
|
81
97
|
|
|
82
98
|
if (files.length === 0) {
|
|
83
99
|
ok('No .c files found in examples/check/input/');
|
|
@@ -100,6 +116,8 @@ function main() {
|
|
|
100
116
|
const tmpDir = mkTmpDir();
|
|
101
117
|
const executablePath = path.join(tmpDir, stem + (process.platform === 'win32' ? '.exe' : ''));
|
|
102
118
|
|
|
119
|
+
let outFd = null;
|
|
120
|
+
|
|
103
121
|
try {
|
|
104
122
|
if (!fs.existsSync(expectedPath)) {
|
|
105
123
|
throw new Error(`Missing expected output: ${path.relative(root, expectedPath)}`);
|
|
@@ -120,23 +138,32 @@ function main() {
|
|
|
120
138
|
throw new Error(`Cannot run compiler '${compiler}': ${compile.error.message}`);
|
|
121
139
|
}
|
|
122
140
|
if (compile.status !== 0) {
|
|
123
|
-
throw new Error(`Compilation failed\n${compile.stderr || compile.stdout || ''
|
|
141
|
+
throw new Error(`Compilation failed\n${(compile.stderr || compile.stdout || '').trim()}`);
|
|
124
142
|
}
|
|
125
143
|
|
|
126
|
-
|
|
144
|
+
outFd = fs.openSync(generatedPath, 'w');
|
|
145
|
+
|
|
146
|
+
const execResult = cp.spawnSync(executablePath, [], {
|
|
147
|
+
cwd: root,
|
|
148
|
+
stdio: ['ignore', outFd, 'pipe'],
|
|
149
|
+
encoding: 'utf8',
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
fs.closeSync(outFd);
|
|
153
|
+
outFd = null;
|
|
154
|
+
|
|
127
155
|
if (execResult.error) {
|
|
128
156
|
throw new Error(`Cannot run executable: ${execResult.error.message}`);
|
|
129
157
|
}
|
|
130
|
-
|
|
131
|
-
fs.writeFileSync(generatedPath, execResult.stdout || '', 'utf8');
|
|
132
|
-
|
|
133
158
|
if (execResult.status !== 0) {
|
|
134
|
-
|
|
159
|
+
const why = execResult.signal ? `signal ${execResult.signal}` : `code ${execResult.status}`;
|
|
160
|
+
throw new Error(`Executable exited with ${why}\n${(execResult.stderr || '').trim()}`);
|
|
135
161
|
}
|
|
136
162
|
|
|
137
163
|
const expectedText = fs.readFileSync(expectedPath, 'utf8');
|
|
138
164
|
const generatedText = fs.readFileSync(generatedPath, 'utf8');
|
|
139
165
|
const same = normalizeForCompare(expectedText) === normalizeForCompare(generatedText);
|
|
166
|
+
|
|
140
167
|
const ms = Date.now() - start;
|
|
141
168
|
|
|
142
169
|
if (same) {
|
|
@@ -151,9 +178,14 @@ function main() {
|
|
|
151
178
|
} catch (err) {
|
|
152
179
|
const ms = Date.now() - start;
|
|
153
180
|
fail(`${idx} ${file} ${msTag(ms)}`);
|
|
154
|
-
fail(err.message);
|
|
181
|
+
fail(err && err.message ? err.message : String(err));
|
|
155
182
|
failed++;
|
|
156
183
|
} finally {
|
|
184
|
+
if (outFd !== null) {
|
|
185
|
+
try {
|
|
186
|
+
fs.closeSync(outFd);
|
|
187
|
+
} catch {}
|
|
188
|
+
}
|
|
157
189
|
rmrf(tmpDir);
|
|
158
190
|
}
|
|
159
191
|
}
|