eyeprolog 1.1.22 → 1.1.23
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/parser.js +15 -8
- package/src/program.js +5 -2
- package/test/conformance/cases/iso/operator_atoms_as_arguments.pl +7 -0
- package/test/conformance/expected/iso/operator_atoms_as_arguments.pl +1 -0
- package/test/run-regression.mjs +26 -0
- package/the-art-of-eyeprolog.md +10 -2
package/package.json
CHANGED
package/src/parser.js
CHANGED
|
@@ -39,6 +39,7 @@ const graphicAtomChars = '#$&*+-./<=>@^~\\:';
|
|
|
39
39
|
// canonical notation. Commas remain separators except inside parentheses.
|
|
40
40
|
const INFIX_OPERATORS = new Map([
|
|
41
41
|
[':-', { precedence: 1, associativity: 'none' }],
|
|
42
|
+
['?-', { precedence: 1, associativity: 'none' }], // quad label extension
|
|
42
43
|
['-->', { precedence: 1, associativity: 'none' }],
|
|
43
44
|
['|', { precedence: 96, associativity: 'right' }],
|
|
44
45
|
[';', { precedence: 101, associativity: 'right' }],
|
|
@@ -77,14 +78,15 @@ const INFIX_OPERATORS = new Map([
|
|
|
77
78
|
['^', { precedence: 1001, associativity: 'right' }],
|
|
78
79
|
]);
|
|
79
80
|
const PREFIX_OPERATORS = new Map([
|
|
80
|
-
['
|
|
81
|
-
['
|
|
82
|
-
['
|
|
83
|
-
['
|
|
81
|
+
['?-', { precedence: 1, strict: true }],
|
|
82
|
+
['\\+', { precedence: 301, strict: false }],
|
|
83
|
+
['+', { precedence: 1001, strict: false }],
|
|
84
|
+
['-', { precedence: 1001, strict: false }],
|
|
85
|
+
['\\', { precedence: 1001, strict: false }],
|
|
84
86
|
]);
|
|
85
87
|
|
|
86
88
|
export const ISO_OPERATOR_DEFINITIONS = [
|
|
87
|
-
[1200, 'xfx', ':-'], [1200, 'fx', ':-'], [1200, 'xfx', '-->'],
|
|
89
|
+
[1200, 'xfx', ':-'], [1200, 'fx', ':-'], [1200, 'fx', '?-'], [1200, 'xfx', '-->'],
|
|
88
90
|
[1105, 'xfy', '|'],
|
|
89
91
|
[1100, 'xfy', ';'], [1050, 'xfy', '->'], [1000, 'xfy', ','],
|
|
90
92
|
[900, 'fy', '\\+'],
|
|
@@ -97,6 +99,13 @@ export const ISO_OPERATOR_DEFINITIONS = [
|
|
|
97
99
|
[200, 'fy', '+'], [200, 'fy', '-'], [200, 'fy', '\\'],
|
|
98
100
|
];
|
|
99
101
|
|
|
102
|
+
// EyeProlog's embedded quad syntax permits an optional label before `?-`.
|
|
103
|
+
// That makes `?-` an implementation-specific xfx operator in addition to its
|
|
104
|
+
// ISO 1200 fx definition.
|
|
105
|
+
export const QUAD_OPERATOR_DEFINITIONS = [
|
|
106
|
+
[1200, 'xfx', '?-'],
|
|
107
|
+
];
|
|
108
|
+
|
|
100
109
|
const CLPZ_OPERATOR_DEFINITIONS = [
|
|
101
110
|
[760, 'yfx', '#<==>'], [750, 'xfy', '#==>'], [750, 'yfx', '#<=='],
|
|
102
111
|
[740, 'yfx', '#\\/'], [730, 'yfx', '#\\'], [720, 'yfx', '#/\\'],
|
|
@@ -133,9 +142,7 @@ function defineParserOperator(state, priority, specifier, name) {
|
|
|
133
142
|
export function createParserOperatorState(definitions = [], includeDefaults = true) {
|
|
134
143
|
const state = {
|
|
135
144
|
infixOperators: includeDefaults ? new Map(INFIX_OPERATORS) : new Map(),
|
|
136
|
-
prefixOperators: includeDefaults
|
|
137
|
-
? new Map([...PREFIX_OPERATORS].map(([name, precedence]) => [name, { precedence, strict: false }]))
|
|
138
|
-
: new Map(),
|
|
145
|
+
prefixOperators: includeDefaults ? new Map(PREFIX_OPERATORS) : new Map(),
|
|
139
146
|
postfixOperators: new Map(),
|
|
140
147
|
};
|
|
141
148
|
for (const definition of definitions) {
|
package/src/program.js
CHANGED
|
@@ -4,6 +4,7 @@ import { ATOM, COMPOUND, VAR, Env, atom, compound, deref, flattenConjunction, is
|
|
|
4
4
|
import { formatTermForWrite } from './write.js';
|
|
5
5
|
import {
|
|
6
6
|
ISO_OPERATOR_DEFINITIONS,
|
|
7
|
+
QUAD_OPERATOR_DEFINITIONS,
|
|
7
8
|
createParserOperatorState,
|
|
8
9
|
parseClauses,
|
|
9
10
|
parseClausesInto,
|
|
@@ -101,8 +102,10 @@ export class Program {
|
|
|
101
102
|
this.moduleMetaPredicates = new Map();
|
|
102
103
|
this.dynamicPredicates = new Set();
|
|
103
104
|
this.operators = new Map();
|
|
104
|
-
for (const [
|
|
105
|
-
|
|
105
|
+
for (const definitions of [ISO_OPERATOR_DEFINITIONS, QUAD_OPERATOR_DEFINITIONS]) {
|
|
106
|
+
for (const [priority, specifier, name] of definitions) {
|
|
107
|
+
this.defineOperator(priority, specifier, name);
|
|
108
|
+
}
|
|
106
109
|
}
|
|
107
110
|
this.initializations = [];
|
|
108
111
|
this.quads = [];
|
|
@@ -5,3 +5,10 @@
|
|
|
5
5
|
operator_atoms(Priority, Specifier, List) :-
|
|
6
6
|
current_op(Priority, Specifier, :-),
|
|
7
7
|
List = [:-,-].
|
|
8
|
+
|
|
9
|
+
% ISO 6.3.4.4, Table 7: ?- is a predefined 1200 fx operator.
|
|
10
|
+
|
|
11
|
+
%% goal: query_prefix_operator(ok)
|
|
12
|
+
|
|
13
|
+
query_prefix_operator(ok) :-
|
|
14
|
+
current_op(1200, fx, ?-).
|
package/test/run-regression.mjs
CHANGED
|
@@ -950,6 +950,32 @@ c4 ?- call((!;1)).
|
|
|
950
950
|
assertEqual(run(source, { goal: 'operator_argument(ok)' }).stdout, 'operator_argument(ok).\n', 'operator argument syntax');
|
|
951
951
|
},
|
|
952
952
|
},
|
|
953
|
+
{
|
|
954
|
+
name: 'ISO query operator and quad infix extension are visible through current_op/3',
|
|
955
|
+
run: () => {
|
|
956
|
+
assertEqual(
|
|
957
|
+
run('', { goal: 'current_op(Priority, Specifier, ?-)' }).stdout,
|
|
958
|
+
"current_op(1200, fx, '?-').\ncurrent_op(1200, xfx, '?-').\n",
|
|
959
|
+
'query operator definitions',
|
|
960
|
+
);
|
|
961
|
+
assertEqual(
|
|
962
|
+
run('', { goal: 'current_op(1200, fx, ?-)' }).stdout,
|
|
963
|
+
"current_op(1200, fx, '?-').\n",
|
|
964
|
+
'ISO query prefix operator',
|
|
965
|
+
);
|
|
966
|
+
assertEqual(
|
|
967
|
+
run('', { goal: 'current_op(1200, xfx, ?-)' }).stdout,
|
|
968
|
+
"current_op(1200, xfx, '?-').\n",
|
|
969
|
+
'quad query infix operator',
|
|
970
|
+
);
|
|
971
|
+
const prefix = parseGoalText('(?- true)');
|
|
972
|
+
assertEqual(prefix.name, '?-', 'prefix query functor');
|
|
973
|
+
assertEqual(prefix.arity, 1, 'prefix query arity');
|
|
974
|
+
const infix = parseGoalText('(label ?- true)');
|
|
975
|
+
assertEqual(infix.name, '?-', 'quad query functor');
|
|
976
|
+
assertEqual(infix.arity, 2, 'quad query arity');
|
|
977
|
+
},
|
|
978
|
+
},
|
|
953
979
|
{
|
|
954
980
|
name: 'term input keeps dotted operators intact and uses program operators',
|
|
955
981
|
run: () => {
|
package/the-art-of-eyeprolog.md
CHANGED
|
@@ -5124,7 +5124,13 @@ parsing of subsequent text, place them before their first use. ISO argument
|
|
|
5124
5124
|
syntax also permits an atom that is currently an operator to appear directly
|
|
5125
5125
|
as a functional argument or list element, so forms such as
|
|
5126
5126
|
`current_op(Priority, Specifier, :-)` and `[:-,-]` are valid without quoting
|
|
5127
|
-
or parenthesizing those operator atoms.
|
|
5127
|
+
or parenthesizing those operator atoms. The ISO initial operator table also
|
|
5128
|
+
contains `?-` at priority 1200 with specifier `fx`, so
|
|
5129
|
+
`current_op(1200, fx, ?-)` succeeds. EyeProlog's embedded quad syntax permits
|
|
5130
|
+
an optional label before the query marker (`Label ?- Query.`), so while quad
|
|
5131
|
+
syntax is supported it additionally exposes `?-` at priority 1200 with
|
|
5132
|
+
specifier `xfx` as an implementation-specific operator. Consequently
|
|
5133
|
+
`current_op(Priority, Specifier, ?-)` enumerates both definitions.
|
|
5128
5134
|
|
|
5129
5135
|
Run [`iso-dynamic-database.pl`](https://github.com/eyereasoner/eyeprolog/blob/main/examples/iso-dynamic-database.pl)
|
|
5130
5136
|
for an explicitly stateful queue and
|
|
@@ -5290,8 +5296,10 @@ clause ends in a period. The grammar above gives the canonical term shapes.
|
|
|
5290
5296
|
The initial operator table contains the following ISO-style operators, all
|
|
5291
5297
|
lowered to ordinary compound terms:
|
|
5292
5298
|
|
|
5293
|
-
- prefix: `\+`, unary `+`, unary `-`, and `\`;
|
|
5299
|
+
- prefix: ISO `?-`, `\+`, unary `+`, unary `-`, and `\`;
|
|
5294
5300
|
- control: `,`, `;`, and `->`;
|
|
5301
|
+
- quad syntax extension: `?-` is also a priority-1200 `xfx` operator so a
|
|
5302
|
+
label may precede a quad query;
|
|
5295
5303
|
- grammar rules: `-->` and the Part 3 alternative `|`;
|
|
5296
5304
|
- unification and comparison: `=`, `\=`, `==`, `\==`, `@<`, `@=<`, `@>`,
|
|
5297
5305
|
`@>=`, `is`, `=:=`, `=\=`, `<`, `=<`, `>`, and `>=`;
|