eyeprolog 1.3.2 → 1.3.3
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 +2 -5
- package/src/parser.js +14 -0
- package/test/run-regression.mjs +21 -0
package/package.json
CHANGED
package/src/iso.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
properListItems, termIsGround, termToString, unify, variable, variantTerms,
|
|
7
7
|
} from './term.js';
|
|
8
8
|
import { sameNumberValue } from './number-value.js';
|
|
9
|
-
import { createParserOperatorState,
|
|
9
|
+
import { createParserOperatorState, parseGoalText, parseNumberTokenText, parseTermText } from './parser.js';
|
|
10
10
|
import { formatTermForWrite } from './write.js';
|
|
11
11
|
import { emptyTerminalSequence, expandDcgBody, isListOrPartialList, validateDcgEmbeddedGoals } from './dcg.js';
|
|
12
12
|
import {
|
|
@@ -1199,8 +1199,7 @@ function scopeReadTerm(term) {
|
|
|
1199
1199
|
function parseReadTermText(text, solver) {
|
|
1200
1200
|
const converted = convertedTermText(text, solver);
|
|
1201
1201
|
const operatorState = createParserOperatorState(solver.program.operators.values(), false);
|
|
1202
|
-
|
|
1203
|
-
sourceMetadata: false,
|
|
1202
|
+
return parseTermText(converted, {
|
|
1204
1203
|
operatorState,
|
|
1205
1204
|
isoStrict: solver.isoStrict,
|
|
1206
1205
|
doubleQuotes: solver.prologFlags.get('double_quotes')?.value?.name ?? 'chars',
|
|
@@ -1208,8 +1207,6 @@ function parseReadTermText(text, solver) {
|
|
|
1208
1207
|
// Earlier ambiguous dots must remain available to maximal graphic tokens.
|
|
1209
1208
|
readTermEnd: converted.length - 1,
|
|
1210
1209
|
});
|
|
1211
|
-
if (clauses.length !== 1 || clauses[0].body.length) throw new Error('bad term');
|
|
1212
|
-
return clauses[0].head;
|
|
1213
1210
|
}
|
|
1214
1211
|
|
|
1215
1212
|
export function isCompleteReadTermText(text, solver) {
|
package/src/parser.js
CHANGED
|
@@ -819,6 +819,16 @@ class Parser {
|
|
|
819
819
|
}
|
|
820
820
|
throw new Error(`parse line ${this.token.line}: bad term`);
|
|
821
821
|
}
|
|
822
|
+
parseStandaloneTerm() {
|
|
823
|
+
// read/1 and read_term/* consume one ordinary Prolog term, not a program
|
|
824
|
+
// clause. In particular, commas and operators such as :- and ?- belong to
|
|
825
|
+
// the term itself and must not be reinterpreted by parseProgram().
|
|
826
|
+
const term = this.parseTerm(0, true, true, true);
|
|
827
|
+
this.expect(TOK.DOT, '.');
|
|
828
|
+
this.advance();
|
|
829
|
+
this.expect(TOK.EOF, 'end of input');
|
|
830
|
+
return term;
|
|
831
|
+
}
|
|
822
832
|
sourceLineIsIndented(line) {
|
|
823
833
|
let start = 0;
|
|
824
834
|
for (let current = 1; current < line; current++) {
|
|
@@ -1504,6 +1514,10 @@ export function parseNumberTokenText(text) {
|
|
|
1504
1514
|
return numberTerm(source);
|
|
1505
1515
|
}
|
|
1506
1516
|
|
|
1517
|
+
export function parseTermText(text, options = {}) {
|
|
1518
|
+
return new Parser(text, options).parseStandaloneTerm();
|
|
1519
|
+
}
|
|
1520
|
+
|
|
1507
1521
|
export function parseGoalText(text, options = {}) {
|
|
1508
1522
|
const clauses = parseClauses(`zz_goal((${text})).`, options);
|
|
1509
1523
|
const head = clauses[0]?.head;
|
package/test/run-regression.mjs
CHANGED
|
@@ -819,6 +819,27 @@ c4 ?- call((!;1)).
|
|
|
819
819
|
});
|
|
820
820
|
assertEqual(consecutive.stdout, "answer(./*., ok).\n", 'following read starts after the complete term');
|
|
821
821
|
|
|
822
|
+
// Issue #41 follow-up: read/1 consumes an ordinary term, not a program
|
|
823
|
+
// clause head. A comma chain therefore has no program-level two-comma
|
|
824
|
+
// limit, and source operators such as :- and ?- remain term data.
|
|
825
|
+
const commaChain = runEyeProlog('', {
|
|
826
|
+
goal: 'read(T)',
|
|
827
|
+
ioOptions: { input: '!,!,! .\n' },
|
|
828
|
+
});
|
|
829
|
+
assertEqual(commaChain.stdout, 'read((!, !, !)).\n', 'three-element comma term');
|
|
830
|
+
|
|
831
|
+
const ruleAsData = runEyeProlog('', {
|
|
832
|
+
goal: 'read(T)',
|
|
833
|
+
ioOptions: { input: 'a :- b.\n' },
|
|
834
|
+
});
|
|
835
|
+
assertEqual(ruleAsData.stdout, 'read((a :- b)).\n', 'rule operator remains term data');
|
|
836
|
+
|
|
837
|
+
const queryAsData = runEyeProlog('', {
|
|
838
|
+
goal: 'read(T)',
|
|
839
|
+
ioOptions: { input: '?- foo.\n' },
|
|
840
|
+
});
|
|
841
|
+
assertEqual(queryAsData.stdout, 'read((?- foo)).\n', 'query operator remains term data');
|
|
842
|
+
|
|
822
843
|
// A possible full stop can fail to complete the term while still
|
|
823
844
|
// extending a current graphic operator into an ordinary atom. The
|
|
824
845
|
// later standalone full stop then completes the read term. Exercise
|