eyeprolog 1.2.20 → 1.2.21

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.2.20",
6
+ "version": "1.2.21",
7
7
  "description": "EyeProlog turns facts and rules into answers and proofs.",
8
8
  "type": "module",
9
9
  "main": "./index.js",
package/src/parser.js CHANGED
@@ -436,7 +436,16 @@ class Parser {
436
436
  if (!value || (value !== ' ' && isWhitespaceCode(value.charCodeAt(0)))) {
437
437
  throw new Error(`parse line ${line}: bad character code constant`);
438
438
  }
439
- if (value === '\\') value = this.readEscape(line, { allowContinuation: false });
439
+ if (value === "'") {
440
+ // In the single-quoted-character notation used after 0', an
441
+ // apostrophe is doubled just as it is inside a quoted atom. Thus
442
+ // 0''' is one numeric token denoting character code 39, while the
443
+ // undoubled 0'' is not a complete single quoted character.
444
+ if (this.peek() !== "'") throw new Error(`parse line ${line}: bad character code constant`);
445
+ this.take();
446
+ } else if (value === '\\') {
447
+ value = this.readEscape(line, { allowContinuation: false });
448
+ }
440
449
  const code = value.codePointAt(0);
441
450
  return { type: TOK.NUMBER, text: String(negative ? -code : code), line };
442
451
  }
@@ -538,6 +538,35 @@ c4 ?- call((!;1)).
538
538
  }
539
539
  },
540
540
  },
541
+ {
542
+ name: 'apostrophe character-code constants parse in source and number conversion',
543
+ run: () => {
544
+ const source = String.raw`
545
+ ?- N = 0'''.
546
+ N = 39.
547
+ ?- number_chars(N,"0'''").
548
+ N = 39.
549
+ ?- number_chars(N,"0'\\'").
550
+ N = 39.
551
+ ?- number_codes(N,[48,39,39,39]).
552
+ N = 39.
553
+ `;
554
+ const result = publicApi.runQuads(source);
555
+ assertEqual(result.total, 4, 'quad total');
556
+ assertEqual(result.passed, 4, 'quad passed');
557
+ assertEqual(result.stdout, 'quads: 4 run, 4 passed, 0 failed.\n', 'quad report');
558
+
559
+ for (const goal of ["N = 0''", 'number_chars(N,"0\'\'")']) {
560
+ let caught = null;
561
+ try {
562
+ publicApi.run('', { goal });
563
+ } catch (error) {
564
+ caught = error;
565
+ }
566
+ if (caught == null) throw new Error(`${goal} should reject an undoubled apostrophe`);
567
+ }
568
+ },
569
+ },
541
570
  {
542
571
  name: 'number conversion rejects parenthesized numeric terms',
543
572
  run: () => {
@@ -5776,8 +5776,9 @@ minus token and the following numeric token. A single-line `%...` comment may
5776
5776
  therefore follow `-` directly because `%` cannot continue a graphic token; an
5777
5777
  adjacent bracketed comment in `-/**/1` remains a syntax error under the eager
5778
5778
  token-consumer rule. Decimal fractions and decimal exponents are supported;
5779
- trailing material and non-finite values are rejected. The regression gate
5780
- vendors all 74 numbered cases from Ulrich Neumerkel's contemporary
5779
+ the apostrophe character code is written with a doubled apostrophe as `0'''`
5780
+ and has value 39. Trailing material and non-finite values are rejected. The
5781
+ regression gate vendors all 74 numbered cases from Ulrich Neumerkel's contemporary
5781
5782
  `number_chars/2` comparison, including the Cor.2 error-precedence cases;
5782
5783
  `number_codes/2` shares the same numeric parser and has mirrored coverage for
5783
5784
  the recent numeric-syntax regressions.