aontu 0.4.0 → 0.4.2
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/dist/lib/common.d.ts +1 -1
- package/dist/lib/op/op.d.ts +1 -1
- package/dist/lib/unify.d.ts +1 -1
- package/dist/lib/val.d.ts +3 -3
- package/lib/val/RefVal.ts~ +319 -0
- package/package.json +6 -6
package/dist/lib/common.d.ts
CHANGED
package/dist/lib/op/op.d.ts
CHANGED
|
@@ -2,5 +2,5 @@ import { Context } from '../unify';
|
|
|
2
2
|
import { Val } from '../val';
|
|
3
3
|
import { disjunct } from './disjunct';
|
|
4
4
|
import { unite } from './unite';
|
|
5
|
-
|
|
5
|
+
type Operation = (ctx: Context, a?: Val, b?: Val, whence?: string) => Val;
|
|
6
6
|
export { Operation, disjunct, unite, };
|
package/dist/lib/unify.d.ts
CHANGED
package/dist/lib/val.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Context } from './unify';
|
|
2
2
|
import { Site } from './lang';
|
|
3
|
-
|
|
3
|
+
type ValMap = {
|
|
4
4
|
[key: string]: Val;
|
|
5
5
|
};
|
|
6
|
-
|
|
6
|
+
type ValList = Val[];
|
|
7
7
|
declare const DONE = -1;
|
|
8
8
|
declare const TOP: Val;
|
|
9
9
|
declare abstract class Val {
|
|
@@ -37,7 +37,7 @@ declare class Nil extends Val {
|
|
|
37
37
|
}
|
|
38
38
|
declare class Integer {
|
|
39
39
|
}
|
|
40
|
-
|
|
40
|
+
type ScalarConstructor = StringConstructor | NumberConstructor | BooleanConstructor | (typeof Integer.constructor);
|
|
41
41
|
declare class ScalarTypeVal extends Val {
|
|
42
42
|
constructor(peg: ScalarConstructor, ctx?: Context);
|
|
43
43
|
unify(peer: Val, ctx: Context): Val;
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
/* Copyright (c) 2021 Richard Rodger, MIT License */
|
|
2
|
+
|
|
3
|
+
// TODO: infinite recursion protection
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
// NOTES
|
|
7
|
+
// - Vals are immutable
|
|
8
|
+
// - each Val must handle all parent and child unifications explicitly
|
|
9
|
+
// - performance is not considered yet
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
/*
|
|
14
|
+
|
|
15
|
+
TOP -> Scalar/Boolean -> BooleanVal
|
|
16
|
+
-> Scalar/String -> StringVal
|
|
17
|
+
-> Scalar/Number -> NumberVal -> IntegerVal
|
|
18
|
+
-> Scalar/Integer
|
|
19
|
+
-> Scalar/Integer -> IntegerVal
|
|
20
|
+
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
import type {
|
|
25
|
+
Val,
|
|
26
|
+
ValMap,
|
|
27
|
+
ValList,
|
|
28
|
+
} from './type'
|
|
29
|
+
|
|
30
|
+
import {
|
|
31
|
+
DONE,
|
|
32
|
+
TOP,
|
|
33
|
+
} from './type'
|
|
34
|
+
|
|
35
|
+
import {
|
|
36
|
+
Context,
|
|
37
|
+
} from './unify'
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
import {
|
|
41
|
+
Site
|
|
42
|
+
} from './lang'
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
import {
|
|
46
|
+
unite
|
|
47
|
+
} from './op/op'
|
|
48
|
+
|
|
49
|
+
import { Nil } from './val/Nil'
|
|
50
|
+
|
|
51
|
+
import {
|
|
52
|
+
ValBase,
|
|
53
|
+
} from './val/ValBase'
|
|
54
|
+
|
|
55
|
+
import { ConjunctVal } from './val/ConjunctVal'
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
// A ScalarType for integers. Number includes floats.
|
|
63
|
+
class Integer { }
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
type ScalarConstructor =
|
|
68
|
+
StringConstructor |
|
|
69
|
+
NumberConstructor |
|
|
70
|
+
BooleanConstructor |
|
|
71
|
+
(typeof Integer.constructor)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class ScalarTypeVal extends ValBase {
|
|
75
|
+
constructor(peg: ScalarConstructor, ctx?: Context) {
|
|
76
|
+
super(peg, ctx)
|
|
77
|
+
this.done = DONE
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
unify(peer: Val, ctx: Context): Val {
|
|
81
|
+
if (peer instanceof ScalarVal) {
|
|
82
|
+
if (peer.type === this.peg) {
|
|
83
|
+
return peer
|
|
84
|
+
}
|
|
85
|
+
else if (Number === this.peg && Integer === peer.type) {
|
|
86
|
+
return peer
|
|
87
|
+
}
|
|
88
|
+
return Nil.make(ctx, 'no-scalar-unify', this, peer)
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
if (peer instanceof ScalarTypeVal) {
|
|
92
|
+
if (Number === this.peg && Integer === peer.peg) {
|
|
93
|
+
return peer
|
|
94
|
+
}
|
|
95
|
+
else if (Number === peer.peg && Integer === this.peg) {
|
|
96
|
+
return this
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return Nil.make(ctx, 'scalar-type', this, peer)
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
get canon() {
|
|
104
|
+
let ctor = (this.peg as any)
|
|
105
|
+
return ctor.name.toLowerCase()
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
same(peer: Val): boolean {
|
|
109
|
+
return peer instanceof ScalarTypeVal ? this.peg === peer.peg : super.same(peer)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
gen(_ctx?: Context) {
|
|
113
|
+
return undefined
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
class ScalarVal<T> extends ValBase {
|
|
120
|
+
type: any
|
|
121
|
+
constructor(peg: T, type: ScalarConstructor, ctx?: Context) {
|
|
122
|
+
super(peg, ctx)
|
|
123
|
+
this.type = type
|
|
124
|
+
this.done = DONE
|
|
125
|
+
}
|
|
126
|
+
unify(peer: Val, ctx: Context): Val {
|
|
127
|
+
// Exactly equal scalars are handled in op/unite
|
|
128
|
+
if (peer instanceof ScalarTypeVal) {
|
|
129
|
+
return peer.unify(this, ctx)
|
|
130
|
+
}
|
|
131
|
+
return Nil.make(ctx, 'scalar', this, peer)
|
|
132
|
+
}
|
|
133
|
+
get canon() {
|
|
134
|
+
return (this.peg as any).toString()
|
|
135
|
+
}
|
|
136
|
+
same(peer: Val): boolean {
|
|
137
|
+
return peer instanceof ScalarVal ? peer.peg === this.peg : super.same(peer)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
gen(_ctx?: Context) {
|
|
141
|
+
return this.peg
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
class NumberVal extends ScalarVal<number> {
|
|
147
|
+
constructor(peg: number, ctx?: Context) {
|
|
148
|
+
super(peg, Number, ctx)
|
|
149
|
+
}
|
|
150
|
+
unify(peer: Val, ctx: Context): Val {
|
|
151
|
+
if (peer instanceof ScalarVal && peer.type === Integer) {
|
|
152
|
+
return peer
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
return super.unify(peer, ctx)
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
class IntegerVal extends ScalarVal<number> {
|
|
162
|
+
constructor(peg: number, ctx?: Context) {
|
|
163
|
+
if (!Number.isInteger(peg)) {
|
|
164
|
+
// TODO: use Nil?
|
|
165
|
+
throw new Error('not-integer')
|
|
166
|
+
}
|
|
167
|
+
super(peg, Integer, ctx)
|
|
168
|
+
}
|
|
169
|
+
unify(peer: Val, ctx: Context): Val {
|
|
170
|
+
if (peer instanceof ScalarTypeVal && peer.peg === Number) {
|
|
171
|
+
return this
|
|
172
|
+
}
|
|
173
|
+
else if (peer instanceof ScalarVal &&
|
|
174
|
+
peer.type === Number &&
|
|
175
|
+
this.peg === peer.peg) {
|
|
176
|
+
return this
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
return super.unify(peer, ctx)
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
class StringVal extends ScalarVal<string> {
|
|
186
|
+
constructor(peg: string, ctx?: Context) {
|
|
187
|
+
super(peg, String, ctx)
|
|
188
|
+
}
|
|
189
|
+
unify(peer: Val, ctx: Context): Val {
|
|
190
|
+
return super.unify(peer, ctx)
|
|
191
|
+
}
|
|
192
|
+
get canon() {
|
|
193
|
+
return JSON.stringify(this.peg)
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
class BooleanVal extends ScalarVal<boolean> {
|
|
200
|
+
constructor(peg: boolean, ctx?: Context) {
|
|
201
|
+
super(peg, Boolean, ctx)
|
|
202
|
+
}
|
|
203
|
+
unify(peer: Val, ctx: Context): Val {
|
|
204
|
+
return super.unify(peer, ctx)
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
static TRUE = new BooleanVal(true, new Context({ vc: 1, root: TOP }))
|
|
208
|
+
static FALSE = new BooleanVal(false, new Context({ vc: 2, root: TOP }))
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
class RefVal extends ValBase {
|
|
226
|
+
parts: string[]
|
|
227
|
+
absolute: boolean
|
|
228
|
+
sep = '.'
|
|
229
|
+
|
|
230
|
+
constructor(peg: any[], abs?: boolean) {
|
|
231
|
+
super('')
|
|
232
|
+
this.absolute = true === abs
|
|
233
|
+
this.parts = []
|
|
234
|
+
|
|
235
|
+
for (let part of peg) {
|
|
236
|
+
this.append(part)
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
append(part: any) {
|
|
242
|
+
//console.log('APPEND 0', part)
|
|
243
|
+
|
|
244
|
+
if ('string' === typeof part) {
|
|
245
|
+
this.parts.push(part)
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
else if (part instanceof StringVal) {
|
|
249
|
+
this.parts.push(part.peg)
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
else if (part instanceof RefVal) {
|
|
253
|
+
this.parts.push(...part.parts)
|
|
254
|
+
|
|
255
|
+
if (part.absolute) {
|
|
256
|
+
this.absolute = true
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
this.peg = (this.absolute ? this.sep : '') + this.parts.join(this.sep)
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
unify(peer: Val, ctx: Context): Val {
|
|
264
|
+
let resolved: Val | undefined = null == ctx ? this : ctx.find(this)
|
|
265
|
+
|
|
266
|
+
// TODO: large amount of reruns needed? why?
|
|
267
|
+
resolved = null == resolved && 999 < this.done ?
|
|
268
|
+
Nil.make(ctx, 'no-path', this, peer) : (resolved || this)
|
|
269
|
+
let out: Val
|
|
270
|
+
|
|
271
|
+
if (resolved instanceof RefVal) {
|
|
272
|
+
if (TOP === peer) {
|
|
273
|
+
out = this
|
|
274
|
+
}
|
|
275
|
+
else if (peer instanceof Nil) {
|
|
276
|
+
out = Nil.make(ctx, 'ref[' + this.peg + ']', this, peer)
|
|
277
|
+
}
|
|
278
|
+
else {
|
|
279
|
+
// Ensure RefVal done is incremented
|
|
280
|
+
this.done = DONE === this.done ? DONE : this.done + 1
|
|
281
|
+
out = new ConjunctVal([this, peer], ctx)
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
out = unite(ctx, resolved, peer)
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
out.done = DONE === out.done ? DONE : this.done + 1
|
|
289
|
+
|
|
290
|
+
return out
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
same(peer: Val): boolean {
|
|
295
|
+
return null == peer ? false : this.peg === peer.peg
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
get canon() {
|
|
300
|
+
return this.peg
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
gen(_ctx?: Context) {
|
|
305
|
+
return undefined
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
export {
|
|
311
|
+
Integer,
|
|
312
|
+
TOP,
|
|
313
|
+
ScalarTypeVal,
|
|
314
|
+
NumberVal,
|
|
315
|
+
StringVal,
|
|
316
|
+
BooleanVal,
|
|
317
|
+
IntegerVal,
|
|
318
|
+
RefVal,
|
|
319
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aontu",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"main": "dist/aontu.js",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"browser": "dist/aontu.min.js",
|
|
@@ -39,11 +39,11 @@
|
|
|
39
39
|
"LICENSE"
|
|
40
40
|
],
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@jsonic/directive": "
|
|
43
|
-
"@jsonic/expr": "
|
|
44
|
-
"@jsonic/jsonic-next": "
|
|
45
|
-
"@jsonic/multisource": "
|
|
46
|
-
"@jsonic/path": "
|
|
42
|
+
"@jsonic/directive": "0.8.0",
|
|
43
|
+
"@jsonic/expr": "0.5.0",
|
|
44
|
+
"@jsonic/jsonic-next": "2.3.0",
|
|
45
|
+
"@jsonic/multisource": "0.7.0",
|
|
46
|
+
"@jsonic/path": "0.2.0",
|
|
47
47
|
"@types/node": "^18.0.3"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|