eyeprolog 1.3.16 → 1.3.17

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 CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.3.16",
6
+ "version": "1.3.17",
7
7
  "description": "EyeProlog turns facts and rules into answers and proofs.",
8
8
  "type": "module",
9
9
  "main": "./index.js",
package/src/repl.js CHANGED
@@ -366,7 +366,6 @@ function terminalFullStop(source, solver = null) {
366
366
  let quote = null;
367
367
  let lineComment = false;
368
368
  let blockComment = false;
369
- let depth = 0;
370
369
 
371
370
  for (let i = 0; i < source.length; i++) {
372
371
  const ch = source[i];
@@ -415,10 +414,12 @@ function terminalFullStop(source, solver = null) {
415
414
  quote = ch;
416
415
  continue;
417
416
  }
418
- if ('([{'.includes(ch)) depth++;
419
- else if (')]}'.includes(ch)) depth = Math.max(0, depth - 1);
420
- else if (depth === 0 && isTerminatingFullStop(source, i, convert) &&
421
- onlyLayoutAndComments(source.slice(i + 1))) return i;
417
+ // ISO 8.14.1.1 locates the end token lexically before read-term parsing.
418
+ // An unmatched opening bracket therefore must not make the top level wait
419
+ // for more input after a terminating full stop; parsing the collected text
420
+ // is what reports the syntax error (for example `[l.` or `{.`).
421
+ if (isTerminatingFullStop(source, i, convert) &&
422
+ onlyLayoutAndComments(source.slice(i + 1))) return i;
422
423
  }
423
424
  return -1;
424
425
  }
@@ -1410,6 +1410,27 @@ c4 ?- call((!;1)).
1410
1410
  assertEqual(result.stdout, 'ok', 'DCG hand-off benchmark result');
1411
1411
  },
1412
1412
  },
1413
+ {
1414
+ name: 'DCG state hand-off reaches the next non-terminal at 8192 cells (issue #49 comment 5347991607)',
1415
+ run: () => {
1416
+ const filename = path.join(tmp, `issue49-small-handoff-${tmpCounter++}.pl`);
1417
+ fs.writeFileSync(filename,
1418
+ ':- set_prolog_flag(occurs_check, true).\na --> ..., epsilon.\nepsilon --> [].\n');
1419
+ const result = runCli([], {
1420
+ input:
1421
+ `[${sourceAtom(filename)}].\n` +
1422
+ 'use_module(library(lists)).\n' +
1423
+ '\\+ \\+ (length(L,8192), phrase(a,L)).\n' +
1424
+ 'halt.\n',
1425
+ timeout: 3000,
1426
+ });
1427
+ if (result.error) throw result.error;
1428
+ assertEqual(result.status, 0, `small DCG hand-off status; stderr=${result.stderr}`);
1429
+ assertNotIncludes(result.stdout, 'resource_error', 'small DCG hand-off resource error');
1430
+ assertNotIncludes(result.stdout, 'depth_limit_exceeded', 'small DCG hand-off depth error');
1431
+ assertEqual(result.stderr, '', 'small DCG hand-off stderr');
1432
+ },
1433
+ },
1413
1434
  {
1414
1435
  name: 'Trealla-style DCG hand-off reaches 65536 cells without the solver depth ceiling',
1415
1436
  run: () => {
@@ -1910,6 +1931,19 @@ c4 ?- call((!;1)).
1910
1931
  assertIncludes(result.stdout, '?- repeat, fail.', 'terminal query echo');
1911
1932
  },
1912
1933
  },
1934
+ {
1935
+ name: 'REPL stops at the end token before parsing unmatched brackets (issue #51)',
1936
+ run: () => {
1937
+ const result = runCli([], { input: '[l.\ntrue.\n{.\ntrue.\nhalt.\n' });
1938
+ assertEqual(result.status, 0, 'exit status');
1939
+ assertNotIncludes(result.stdout, '| ', 'no continuation prompt after malformed end token');
1940
+ assertEqual((result.stdout.match(/\?- true\./g) ?? []).length, 2,
1941
+ 'following lines remain separate top-level queries');
1942
+ assertEqual((result.stdout.match(/parse line 1:/g) ?? []).length, 2,
1943
+ 'both malformed bracketed queries report syntax errors');
1944
+ assertEqual(result.stderr, '', 'stderr');
1945
+ },
1946
+ },
1913
1947
  {
1914
1948
  name: 'REPL accepts multiline period-terminated queries',
1915
1949
  run: () => {