eyeprolog 1.1.27 → 1.1.28
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.
- package/package.json +1 -1
- package/src/iso.js +1 -1
- package/src/repl.js +9 -37
- package/test/run-regression.mjs +17 -2
- package/the-art-of-eyeprolog.md +8 -5
package/package.json
CHANGED
package/src/iso.js
CHANGED
|
@@ -1783,7 +1783,7 @@ function* phraseBuiltin({ solver, goal, env }) {
|
|
|
1783
1783
|
solver.absorbStatsFrom(child);
|
|
1784
1784
|
}
|
|
1785
1785
|
}
|
|
1786
|
-
function formalErrorTerm(error) {
|
|
1786
|
+
export function formalErrorTerm(error) {
|
|
1787
1787
|
const context = error.contextTerm ?? atom('eyeprolog');
|
|
1788
1788
|
if (error.formalTerm != null) return compound('error', [error.formalTerm, context]);
|
|
1789
1789
|
const parse = (text) => {
|
package/src/repl.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import fs from 'node:fs/promises';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { createInterface } from 'node:readline';
|
|
5
|
+
import { formalErrorTerm } from './iso.js';
|
|
5
6
|
|
|
6
7
|
const ANSWER_HELP = `
|
|
7
8
|
SPACE, "n" or ";": next solution, if any
|
|
@@ -425,46 +426,17 @@ function formatError(engine, state, error) {
|
|
|
425
426
|
const env = new engine.Env();
|
|
426
427
|
const variableNames = new Map();
|
|
427
428
|
let generated = 0;
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
operators: [...state.program.operators.values()],
|
|
436
|
-
variableNames,
|
|
437
|
-
});
|
|
438
|
-
if (error.contextTerm != null) {
|
|
439
|
-
const context = engine.formatTermForWrite(error.contextTerm, env, {
|
|
440
|
-
quoted: true,
|
|
441
|
-
operators: [...state.program.operators.values()],
|
|
442
|
-
variableNames,
|
|
443
|
-
});
|
|
444
|
-
return `error(${formal}, ${context}).`;
|
|
445
|
-
}
|
|
446
|
-
return `error(${formal}).`;
|
|
447
|
-
}
|
|
448
|
-
if (error.culprit != null) {
|
|
449
|
-
collectUnboundVariables(engine, error.culprit, env, variableNames, () => `_${letterName(generated++)}`);
|
|
450
|
-
}
|
|
451
|
-
if (error.contextTerm != null) {
|
|
452
|
-
collectUnboundVariables(engine, error.contextTerm, env, variableNames, () => `_${letterName(generated++)}`);
|
|
453
|
-
}
|
|
454
|
-
const culprit = error.culprit == null ? '' : `, ${engine.formatTermForWrite(error.culprit, env, {
|
|
429
|
+
// ISO 7.12.1 represents processor errors as error(ErrorTerm, ImpDef).
|
|
430
|
+
// Reuse the same conversion as catch/3 so uncaught errors at the top
|
|
431
|
+
// level cannot lose the implementation-defined context or misplace a
|
|
432
|
+
// culprit as the second argument of error/2.
|
|
433
|
+
const term = formalErrorTerm(error);
|
|
434
|
+
collectUnboundVariables(engine, term, env, variableNames, () => `_${letterName(generated++)}`);
|
|
435
|
+
return `${engine.formatTermForWrite(term, env, {
|
|
455
436
|
quoted: true,
|
|
456
437
|
operators: [...state.program.operators.values()],
|
|
457
438
|
variableNames,
|
|
458
|
-
})}
|
|
459
|
-
if (error.contextTerm != null) {
|
|
460
|
-
const context = engine.formatTermForWrite(error.contextTerm, env, {
|
|
461
|
-
quoted: true,
|
|
462
|
-
operators: [...state.program.operators.values()],
|
|
463
|
-
variableNames,
|
|
464
|
-
});
|
|
465
|
-
return `error(${error.formal}${culprit}, ${context}).`;
|
|
466
|
-
}
|
|
467
|
-
return `error(${error.formal}${culprit}).`;
|
|
439
|
+
})}.`;
|
|
468
440
|
}
|
|
469
441
|
const message = error?.message ?? String(error);
|
|
470
442
|
return message.endsWith('.') ? message : `${message}.`;
|
package/test/run-regression.mjs
CHANGED
|
@@ -533,8 +533,23 @@ c4 ?- call((!;1)).
|
|
|
533
533
|
});
|
|
534
534
|
assertEqual(result.status, 0, 'exit status');
|
|
535
535
|
assertEqual(result.stdout,
|
|
536
|
-
'?- error(type_error(list
|
|
537
|
-
'?- error(type_error(list
|
|
536
|
+
'?- error(type_error(list, [1, [], _A | 2]), eyeprolog).\n' +
|
|
537
|
+
'?- error(type_error(list, [1, [], _A | 2]), eyeprolog).\n' +
|
|
538
|
+
'?- ',
|
|
539
|
+
'stdout');
|
|
540
|
+
assertEqual(result.stderr, '', 'stderr');
|
|
541
|
+
},
|
|
542
|
+
},
|
|
543
|
+
{
|
|
544
|
+
name: 'REPL uncaught ISO errors retain the error/2 implementation context',
|
|
545
|
+
run: () => {
|
|
546
|
+
const result = runCli([], {
|
|
547
|
+
input: '_ is _.\ncatch(_ is _, error(Error, Imp_def), true).\nhalt.\n',
|
|
548
|
+
});
|
|
549
|
+
assertEqual(result.status, 0, 'exit status');
|
|
550
|
+
assertEqual(result.stdout,
|
|
551
|
+
'?- error(instantiation_error, eyeprolog).\n' +
|
|
552
|
+
'?- Error = instantiation_error, Imp_def = eyeprolog.\n' +
|
|
538
553
|
'?- ',
|
|
539
554
|
'stdout');
|
|
540
555
|
assertEqual(result.stderr, '', 'stderr');
|
package/the-art-of-eyeprolog.md
CHANGED
|
@@ -5803,11 +5803,14 @@ instances whose message contains the corresponding Prolog error term.
|
|
|
5803
5803
|
`error(Formal,eyeprolog)` term. `throw/1` copies its ball before unwinding: bound
|
|
5804
5804
|
parts are preserved, repeated variables remain shared within the copied ball,
|
|
5805
5805
|
and unbound variables are fresh with respect to the protected goal and catcher.
|
|
5806
|
-
Catchable error terms follow the same variable-freshening rule.
|
|
5807
|
-
top level
|
|
5808
|
-
|
|
5809
|
-
|
|
5810
|
-
|
|
5806
|
+
Catchable error terms follow the same variable-freshening rule. The interactive
|
|
5807
|
+
top level uses the same ISO error envelope for uncaught processor errors, so an
|
|
5808
|
+
ordinary runtime error is displayed as `error(Formal,eyeprolog)` rather than
|
|
5809
|
+
dropping the implementation-defined second argument. Variables that occur in an
|
|
5810
|
+
uncaught ISO error are rendered with fresh answer names such as `_A` rather than
|
|
5811
|
+
reusing query-variable spellings such as `X` or `Xx`; this keeps the displayed
|
|
5812
|
+
error consistent with the copied exception term. An unmatched ball or error
|
|
5813
|
+
continues outward.
|
|
5811
5814
|
|
|
5812
5815
|
Streams belong to one solver run and are shared by nested calls, exceptions,
|
|
5813
5816
|
and solution collectors. `user_input` and `user_output` are always present.
|