aontu 0.51.0 → 0.52.0
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/bin/aontu-lsp.js +6 -0
- package/bin/aontu.js +7 -0
- package/dist/aontu.d.ts +1 -1
- package/dist/aontu.js +4 -7
- package/dist/aontu.js.map +1 -1
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +10 -46
- package/dist/cli.js.map +1 -1
- package/dist/ctx.js +1 -1
- package/dist/ctx.js.map +1 -1
- package/dist/err.js +3 -2
- package/dist/err.js.map +1 -1
- package/dist/exactjson.js +1 -1
- package/dist/exactjson.js.map +1 -1
- package/dist/hints.d.ts +3 -1
- package/dist/hints.js +126 -1
- package/dist/hints.js.map +1 -1
- package/dist/keyorder.js +1 -1
- package/dist/keyorder.js.map +1 -1
- package/dist/lang.js +64 -27
- package/dist/lang.js.map +1 -1
- package/dist/lsp-server.d.ts +2 -2
- package/dist/lsp-server.js +10 -10
- package/dist/lsp-server.js.map +1 -1
- package/dist/lsp.js +27 -19
- package/dist/lsp.js.map +1 -1
- package/dist/site.js +1 -1
- package/dist/site.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/unify.js +48 -1
- package/dist/unify.js.map +1 -1
- package/dist/utility.js +3 -8
- package/dist/utility.js.map +1 -1
- package/dist/val/BagVal.js +1 -1
- package/dist/val/BagVal.js.map +1 -1
- package/dist/val/BigDecimalVal.js +2 -2
- package/dist/val/BigDecimalVal.js.map +1 -1
- package/dist/val/BigIntegerVal.js +2 -2
- package/dist/val/BigIntegerVal.js.map +1 -1
- package/dist/val/BooleanVal.js +1 -1
- package/dist/val/BooleanVal.js.map +1 -1
- package/dist/val/CloseFuncVal.js +1 -1
- package/dist/val/CloseFuncVal.js.map +1 -1
- package/dist/val/ConjunctVal.js +1 -1
- package/dist/val/ConjunctVal.js.map +1 -1
- package/dist/val/ConstraintVal.d.ts +56 -0
- package/dist/val/ConstraintVal.js +407 -0
- package/dist/val/ConstraintVal.js.map +1 -0
- package/dist/val/CopyFuncVal.js +1 -1
- package/dist/val/CopyFuncVal.js.map +1 -1
- package/dist/val/Decimal.js +1 -1
- package/dist/val/Decimal.js.map +1 -1
- package/dist/val/DisjunctVal.js +1 -29
- package/dist/val/DisjunctVal.js.map +1 -1
- package/dist/val/ExpectVal.js +1 -1
- package/dist/val/ExpectVal.js.map +1 -1
- package/dist/val/FeatureVal.js +1 -1
- package/dist/val/FeatureVal.js.map +1 -1
- package/dist/val/FuncBaseVal.js +1 -1
- package/dist/val/FuncBaseVal.js.map +1 -1
- package/dist/val/HideFuncVal.js +1 -1
- package/dist/val/HideFuncVal.js.map +1 -1
- package/dist/val/IntegerVal.js +2 -2
- package/dist/val/IntegerVal.js.map +1 -1
- package/dist/val/JunctionVal.js +1 -1
- package/dist/val/JunctionVal.js.map +1 -1
- package/dist/val/KeyFuncVal.js +1 -1
- package/dist/val/KeyFuncVal.js.map +1 -1
- package/dist/val/ListVal.js +7 -7
- package/dist/val/ListVal.js.map +1 -1
- package/dist/val/LowerFuncVal.js +1 -1
- package/dist/val/LowerFuncVal.js.map +1 -1
- package/dist/val/MapVal.js +11 -9
- package/dist/val/MapVal.js.map +1 -1
- package/dist/val/MoveFuncVal.js +1 -1
- package/dist/val/MoveFuncVal.js.map +1 -1
- package/dist/val/NilVal.d.ts +1 -0
- package/dist/val/NilVal.js +10 -3
- package/dist/val/NilVal.js.map +1 -1
- package/dist/val/NullVal.js +1 -1
- package/dist/val/NullVal.js.map +1 -1
- package/dist/val/NumberVal.js +2 -2
- package/dist/val/NumberVal.js.map +1 -1
- package/dist/val/OpBaseVal.js +10 -8
- package/dist/val/OpBaseVal.js.map +1 -1
- package/dist/val/OpenFuncVal.js +1 -1
- package/dist/val/OpenFuncVal.js.map +1 -1
- package/dist/val/PathFuncVal.js +1 -1
- package/dist/val/PathFuncVal.js.map +1 -1
- package/dist/val/PlusOpVal.js +1 -1
- package/dist/val/PlusOpVal.js.map +1 -1
- package/dist/val/PrefFuncVal.js +1 -1
- package/dist/val/PrefFuncVal.js.map +1 -1
- package/dist/val/PrefVal.js +4 -3
- package/dist/val/PrefVal.js.map +1 -1
- package/dist/val/RefVal.d.ts +2 -0
- package/dist/val/RefVal.js +78 -9
- package/dist/val/RefVal.js.map +1 -1
- package/dist/val/ScalarKindVal.js +8 -2
- package/dist/val/ScalarKindVal.js.map +1 -1
- package/dist/val/ScalarVal.js +2 -2
- package/dist/val/ScalarVal.js.map +1 -1
- package/dist/val/StringVal.js +1 -1
- package/dist/val/StringVal.js.map +1 -1
- package/dist/val/SuperFuncVal.js +1 -1
- package/dist/val/SuperFuncVal.js.map +1 -1
- package/dist/val/TopVal.js +1 -1
- package/dist/val/TopVal.js.map +1 -1
- package/dist/val/TypeFuncVal.js +1 -1
- package/dist/val/TypeFuncVal.js.map +1 -1
- package/dist/val/UpperFuncVal.js +1 -1
- package/dist/val/UpperFuncVal.js.map +1 -1
- package/dist/val/Val.d.ts +1 -1
- package/dist/val/Val.js +11 -21
- package/dist/val/Val.js.map +1 -1
- package/dist/val/VarVal.js +1 -1
- package/dist/val/VarVal.js.map +1 -1
- package/dist/val/numcmp.d.ts +14 -0
- package/dist/val/numcmp.js +134 -0
- package/dist/val/numcmp.js.map +1 -0
- package/dist/val/numkind.js +1 -1
- package/dist/val/numkind.js.map +1 -1
- package/package.json +6 -4
- package/src/aontu.ts +4 -8
- package/src/cli.ts +12 -13
- package/src/ctx.ts +1 -1
- package/src/err.ts +3 -2
- package/src/exactjson.ts +1 -1
- package/src/hints.ts +140 -0
- package/src/keyorder.ts +1 -1
- package/src/lang.ts +75 -27
- package/src/lsp-server.ts +17 -15
- package/src/lsp.ts +27 -12
- package/src/site.ts +1 -1
- package/src/type.ts +1 -1
- package/src/unify.ts +52 -1
- package/src/utility.ts +3 -9
- package/src/val/BagVal.ts +1 -1
- package/src/val/BigDecimalVal.ts +2 -2
- package/src/val/BigIntegerVal.ts +2 -2
- package/src/val/BooleanVal.ts +1 -1
- package/src/val/CloseFuncVal.ts +1 -1
- package/src/val/ConjunctVal.ts +1 -1
- package/src/val/ConstraintVal.ts +561 -0
- package/src/val/CopyFuncVal.ts +1 -1
- package/src/val/Decimal.ts +1 -1
- package/src/val/DisjunctVal.ts +1 -37
- package/src/val/ExpectVal.ts +1 -1
- package/src/val/FeatureVal.ts +1 -1
- package/src/val/FuncBaseVal.ts +1 -1
- package/src/val/HideFuncVal.ts +1 -1
- package/src/val/IntegerVal.ts +2 -2
- package/src/val/JunctionVal.ts +1 -1
- package/src/val/KeyFuncVal.ts +1 -1
- package/src/val/ListVal.ts +3 -5
- package/src/val/LowerFuncVal.ts +1 -1
- package/src/val/MapVal.ts +7 -5
- package/src/val/MoveFuncVal.ts +1 -1
- package/src/val/NilVal.ts +13 -3
- package/src/val/NullVal.ts +1 -1
- package/src/val/NumberVal.ts +2 -2
- package/src/val/OpBaseVal.ts +10 -10
- package/src/val/OpenFuncVal.ts +1 -1
- package/src/val/PathFuncVal.ts +1 -1
- package/src/val/PlusOpVal.ts +1 -1
- package/src/val/PrefFuncVal.ts +1 -1
- package/src/val/PrefVal.ts +4 -3
- package/src/val/RefVal.ts +82 -9
- package/src/val/ScalarKindVal.ts +8 -2
- package/src/val/ScalarVal.ts +2 -2
- package/src/val/StringVal.ts +1 -1
- package/src/val/SuperFuncVal.ts +1 -1
- package/src/val/TopVal.ts +1 -1
- package/src/val/TypeFuncVal.ts +1 -1
- package/src/val/UpperFuncVal.ts +1 -1
- package/src/val/Val.ts +13 -8
- package/src/val/VarVal.ts +1 -1
- package/src/val/numcmp.ts +189 -0
- package/src/val/numkind.ts +1 -1
package/src/val/ListVal.ts
CHANGED
|
@@ -20,7 +20,6 @@ import {
|
|
|
20
20
|
explainOpen,
|
|
21
21
|
ec,
|
|
22
22
|
explainClose,
|
|
23
|
-
items,
|
|
24
23
|
} from '../utility'
|
|
25
24
|
|
|
26
25
|
import { makeNilErr, AontuError } from '../err'
|
|
@@ -33,7 +32,6 @@ import {
|
|
|
33
32
|
import { ConjunctVal } from './ConjunctVal'
|
|
34
33
|
import { NilVal } from './NilVal'
|
|
35
34
|
import { BagVal } from './BagVal'
|
|
36
|
-
import { empty } from './Val'
|
|
37
35
|
|
|
38
36
|
|
|
39
37
|
class ListVal extends BagVal {
|
|
@@ -121,9 +119,9 @@ class ListVal extends BagVal {
|
|
|
121
119
|
|
|
122
120
|
propagateMarks(this, child)
|
|
123
121
|
|
|
122
|
+
// child is non-nullish: propagateMarks above dereferences it.
|
|
124
123
|
out.peg[key] =
|
|
125
|
-
|
|
126
|
-
child.isNil ? child :
|
|
124
|
+
child.isNil ? child :
|
|
127
125
|
key_spread_cj.isNil ? key_spread_cj :
|
|
128
126
|
key_spread_cj.isTop && child.done ? child :
|
|
129
127
|
child.isTop && key_spread_cj.done ? key_spread_cj :
|
|
@@ -271,7 +269,7 @@ class ListVal extends BagVal {
|
|
|
271
269
|
this.peg[k].canon).join(',') +
|
|
272
270
|
']'
|
|
273
271
|
}
|
|
274
|
-
}
|
|
272
|
+
} /* node:coverage ignore next 8 */
|
|
275
273
|
|
|
276
274
|
|
|
277
275
|
|
package/src/val/LowerFuncVal.ts
CHANGED
package/src/val/MapVal.ts
CHANGED
|
@@ -42,7 +42,7 @@ import { cmpCodePoint } from '../keyorder'
|
|
|
42
42
|
// pass. The map lives on the unify root ctx (see Unify), so it persists
|
|
43
43
|
// across fixpoint passes and is GC'd with the run.
|
|
44
44
|
function spreadSnapKey(cj: any): string {
|
|
45
|
-
return cj.canon + '~' +
|
|
45
|
+
return cj.canon + '~' + cj.site.row + ':' + cj.site.col
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
// Snapshot a path-dependent ref spread to its structural target once,
|
|
@@ -229,7 +229,9 @@ class MapVal extends BagVal {
|
|
|
229
229
|
// but costs O(keys) deep template clones per pass on large
|
|
230
230
|
// models — the dominant cost on generated-SDK model trees.
|
|
231
231
|
let oval: Val
|
|
232
|
-
|
|
232
|
+
// No `undefined !== child` here: propagateMarks above already
|
|
233
|
+
// dereferenced it, so a missing child would have thrown there.
|
|
234
|
+
if (!spread_cj.isTop
|
|
233
235
|
&& (child as any)._spr === (spread_cj as any).id) {
|
|
234
236
|
oval = child.done ? child :
|
|
235
237
|
unite(te ? keyctx.clone({ explain: ec(te, 'KEY:' + key) }) : keyctx,
|
|
@@ -239,9 +241,9 @@ class MapVal extends BagVal {
|
|
|
239
241
|
else {
|
|
240
242
|
const key_spread_cj = spread_cj.spreadClone(keyctx)
|
|
241
243
|
|
|
244
|
+
// child is non-nullish: propagateMarks above dereferences it.
|
|
242
245
|
oval =
|
|
243
|
-
|
|
244
|
-
child.isNil ? child :
|
|
246
|
+
child.isNil ? child :
|
|
245
247
|
key_spread_cj.isNil ? key_spread_cj :
|
|
246
248
|
key_spread_cj.isTop && child.done ? child :
|
|
247
249
|
child.isTop && key_spread_cj.done ? key_spread_cj :
|
|
@@ -449,7 +451,7 @@ class MapVal extends BagVal {
|
|
|
449
451
|
return this.spread.cj ? '&:' + this.spread.cj.inspect(null == d ? 0 : d + 1) : ''
|
|
450
452
|
}
|
|
451
453
|
|
|
452
|
-
}
|
|
454
|
+
} /* node:coverage ignore next 6 */
|
|
453
455
|
|
|
454
456
|
|
|
455
457
|
export {
|
package/src/val/MoveFuncVal.ts
CHANGED
package/src/val/NilVal.ts
CHANGED
|
@@ -18,6 +18,8 @@ import { Val, EMPTY_ERR } from './Val'
|
|
|
18
18
|
|
|
19
19
|
import { AontuError, descErr } from '../err'
|
|
20
20
|
|
|
21
|
+
import { codeClass } from '../hints'
|
|
22
|
+
|
|
21
23
|
|
|
22
24
|
class NilVal extends Val {
|
|
23
25
|
isNil = true
|
|
@@ -98,10 +100,10 @@ class NilVal extends Val {
|
|
|
98
100
|
if (spec && 'object' === typeof spec) {
|
|
99
101
|
this.why = spec?.why
|
|
100
102
|
this.msg = 'string' === typeof spec?.msg ? spec.msg : this.msg
|
|
101
|
-
this.err =
|
|
103
|
+
this.err =
|
|
102
104
|
Array.isArray(spec.err) ? [...spec.err] :
|
|
103
105
|
null != spec.err ? [spec.err] :
|
|
104
|
-
EMPTY_ERR
|
|
106
|
+
EMPTY_ERR
|
|
105
107
|
}
|
|
106
108
|
|
|
107
109
|
// Nil is always DONE, by definition.
|
|
@@ -135,6 +137,14 @@ class NilVal extends Val {
|
|
|
135
137
|
}
|
|
136
138
|
|
|
137
139
|
|
|
140
|
+
// The code's class from the shared registry (test/spec/errcodes.tsv):
|
|
141
|
+
// conflict | incomplete | reference | parse | budget | internal.
|
|
142
|
+
// A why-less nil classifies as its eventual gen-time code, nil_gen.
|
|
143
|
+
get class(): string {
|
|
144
|
+
return codeClass(null == this.why ? 'nil_gen' : String(this.why))
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
|
|
138
148
|
gen(ctx: AontuContext) {
|
|
139
149
|
// Unresolved nil cannot be generated, so always an error.
|
|
140
150
|
|
|
@@ -174,7 +184,7 @@ class NilVal extends Val {
|
|
|
174
184
|
//
|
|
175
185
|
// Do NOT use this sentinel for errors that may surface: those need
|
|
176
186
|
// real NilVals with proper site/path info for descErr formatting.
|
|
177
|
-
const TRIAL_NIL = new NilVal({ why: '|:trial-nil' })
|
|
187
|
+
const TRIAL_NIL = new NilVal({ why: '|:trial-nil' }) /* node:coverage ignore next 7 */
|
|
178
188
|
|
|
179
189
|
|
|
180
190
|
export {
|
package/src/val/NullVal.ts
CHANGED
package/src/val/NumberVal.ts
CHANGED
|
@@ -49,7 +49,7 @@ class NumberVal extends ScalarVal {
|
|
|
49
49
|
let out: Val = this
|
|
50
50
|
|
|
51
51
|
if (null != peer) {
|
|
52
|
-
if (peer.isScalarKind) {
|
|
52
|
+
if (peer.isScalarKind || (peer as any).isConstraint) {
|
|
53
53
|
out = peer.unify(this, ctx)
|
|
54
54
|
}
|
|
55
55
|
else if (
|
|
@@ -95,7 +95,7 @@ class NumberVal extends ScalarVal {
|
|
|
95
95
|
s.includes('N') ||
|
|
96
96
|
s.includes('I')) ? s : s + '.0'
|
|
97
97
|
}
|
|
98
|
-
}
|
|
98
|
+
} /* node:coverage ignore next 6 */
|
|
99
99
|
|
|
100
100
|
|
|
101
101
|
export {
|
package/src/val/OpBaseVal.ts
CHANGED
|
@@ -67,7 +67,11 @@ class OpBaseVal extends FeatureVal {
|
|
|
67
67
|
|
|
68
68
|
unify(peer: Val, ctx: AontuContext): Val {
|
|
69
69
|
const te = ctx.explain && explainOpen(ctx, ctx.explain, 'Op:' + this.opname(), this, peer)
|
|
70
|
-
|
|
70
|
+
// Declared without an initial value: every arm below assigns it, and
|
|
71
|
+
// seeding it with `this` made the two arms that stand the op read as
|
|
72
|
+
// redundant self-assignments. The arms themselves stay as they are —
|
|
73
|
+
// they mirror the dispatch switch in go/op.go arm for arm (ADR-001).
|
|
74
|
+
let out: Val
|
|
71
75
|
|
|
72
76
|
if (this.id == peer.id) {
|
|
73
77
|
return this
|
|
@@ -88,16 +92,12 @@ class OpBaseVal extends FeatureVal {
|
|
|
88
92
|
// console.log('OPVAL', this.id, this.opname(), pegdone, newpeg.map(p => p.canon))
|
|
89
93
|
|
|
90
94
|
if (pegdone) {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
result =
|
|
94
|
-
|
|
95
|
-
if (null == result && this.canon === peer.canon) {
|
|
96
|
-
out = this
|
|
97
|
-
}
|
|
95
|
+
// `|| this` makes result truthy, so an op that cannot compute yet
|
|
96
|
+
// takes the OpBaseVal arm below rather than a separate null arm.
|
|
97
|
+
let result: Val = this.operate(ctx, newpeg) || this
|
|
98
98
|
|
|
99
99
|
// TODO: should be result.isOp
|
|
100
|
-
|
|
100
|
+
if (result instanceof OpBaseVal) {
|
|
101
101
|
if (peer.isTop) {
|
|
102
102
|
out = this
|
|
103
103
|
}
|
|
@@ -223,7 +223,7 @@ class OpBaseVal extends FeatureVal {
|
|
|
223
223
|
|
|
224
224
|
return undefined
|
|
225
225
|
}
|
|
226
|
-
}
|
|
226
|
+
} /* node:coverage ignore next 6 */
|
|
227
227
|
|
|
228
228
|
|
|
229
229
|
export {
|
package/src/val/OpenFuncVal.ts
CHANGED
package/src/val/PathFuncVal.ts
CHANGED
package/src/val/PlusOpVal.ts
CHANGED
|
@@ -237,7 +237,7 @@ function integer(v: any, k: OpKind): bigint {
|
|
|
237
237
|
// Scale 0 normalises to the one decimal place the leaf keeps.
|
|
238
238
|
function decimal(v: any, k: OpKind): Decimal {
|
|
239
239
|
return 'bigdecimal' === k ? v.peg : new Decimal(integer(v, k), 0)
|
|
240
|
-
}
|
|
240
|
+
} /* node:coverage ignore next 6 */
|
|
241
241
|
|
|
242
242
|
|
|
243
243
|
export {
|
package/src/val/PrefFuncVal.ts
CHANGED
package/src/val/PrefVal.ts
CHANGED
|
@@ -114,7 +114,6 @@ class PrefVal extends FeatureVal {
|
|
|
114
114
|
peer = peer ?? top()
|
|
115
115
|
|
|
116
116
|
const te = ctx.explain && explainOpen(ctx, ctx.explain, 'Pref', this, peer)
|
|
117
|
-
let done = true
|
|
118
117
|
let out: Val = this
|
|
119
118
|
let why = ''
|
|
120
119
|
|
|
@@ -180,7 +179,9 @@ class PrefVal extends FeatureVal {
|
|
|
180
179
|
why += 'none'
|
|
181
180
|
}
|
|
182
181
|
|
|
183
|
-
|
|
182
|
+
// Every pref result is DONE, including a stuck conjunct from the
|
|
183
|
+
// superior-unify (mirrored by PrefVal.Unify in go/pref.go).
|
|
184
|
+
out.dc = DONE
|
|
184
185
|
|
|
185
186
|
// console.log('PREFVAL-OUT', why, this.canon, peer.canon, '->', out.canon, out.done)
|
|
186
187
|
|
|
@@ -226,7 +227,7 @@ class PrefVal extends FeatureVal {
|
|
|
226
227
|
|
|
227
228
|
return val.gen(ctx)
|
|
228
229
|
}
|
|
229
|
-
}
|
|
230
|
+
} /* node:coverage ignore next 6 */
|
|
230
231
|
|
|
231
232
|
|
|
232
233
|
export {
|
package/src/val/RefVal.ts
CHANGED
|
@@ -68,8 +68,9 @@ class RefVal extends FeatureVal {
|
|
|
68
68
|
super(spec, ctx)
|
|
69
69
|
this.peg = []
|
|
70
70
|
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
// The field initialiser (absolute = false) has just run, so only
|
|
72
|
+
// the spec can carry absoluteness in (RefVal.clone re-passes it).
|
|
73
|
+
this.absolute = true === spec.absolute
|
|
73
74
|
|
|
74
75
|
this.prefix = true === spec.prefix
|
|
75
76
|
|
|
@@ -181,14 +182,13 @@ class RefVal extends FeatureVal {
|
|
|
181
182
|
// TODO: not resolved when all Vals in path are done is an error
|
|
182
183
|
// as path cannot be found
|
|
183
184
|
// let resolved: Val | undefined = null == ctx ? this : ctx.find(this)
|
|
184
|
-
let found: Val | undefined =
|
|
185
|
+
let found: Val | undefined = this.find(ctx)
|
|
185
186
|
|
|
187
|
+
// `?? this` makes resolved non-nullish, so an unresolved reference
|
|
188
|
+
// takes the RefVal arm below rather than a separate null arm.
|
|
186
189
|
const resolved = found ?? this
|
|
187
190
|
|
|
188
|
-
if (
|
|
189
|
-
out = this
|
|
190
|
-
}
|
|
191
|
-
else if (resolved instanceof RefVal) {
|
|
191
|
+
if (resolved instanceof RefVal) {
|
|
192
192
|
if (peer.isTop) {
|
|
193
193
|
out = this
|
|
194
194
|
why = 'pt'
|
|
@@ -413,8 +413,16 @@ class RefVal extends FeatureVal {
|
|
|
413
413
|
else if (pI === refpath.length) {
|
|
414
414
|
out = node
|
|
415
415
|
|
|
416
|
+
// A reference landing on another reference may be a PROVEN
|
|
417
|
+
// mutual cycle (a: $.b, b: $.a) -- follow the plain-ref chain
|
|
418
|
+
// and, if it revisits a node, report path_cycle now instead of
|
|
419
|
+
// deferring every pass and dying later as a generic ref error.
|
|
420
|
+
// No proof (chain leaves plain refs, or ends) defers as before.
|
|
421
|
+
if (null != out && (out as any).isRef && this.detectRefCycle(ctx)) {
|
|
422
|
+
out = makeNilErr(ctx, 'path_cycle', this)
|
|
423
|
+
}
|
|
416
424
|
// Types and hidden values are cloned and made concrete
|
|
417
|
-
if (null != out) { // && (out.mark.type || out.mark.hide)) {
|
|
425
|
+
else if (null != out) { // && (out.mark.type || out.mark.hide)) {
|
|
418
426
|
|
|
419
427
|
// console.log('FOUND-A', out)
|
|
420
428
|
|
|
@@ -456,6 +464,71 @@ class RefVal extends FeatureVal {
|
|
|
456
464
|
}
|
|
457
465
|
|
|
458
466
|
|
|
467
|
+
// Follow the chain of plain references from this node; true iff the
|
|
468
|
+
// chain revisits a node -- a PROVEN reference cycle, distinct from a
|
|
469
|
+
// merely unresolved reference. Detection is only on the resolution
|
|
470
|
+
// chain revisiting a node, never on syntactic shape: a chain that
|
|
471
|
+
// passes through a variable segment, a conjunct, a function, or any
|
|
472
|
+
// non-ref value yields no proof and the ref defers as before.
|
|
473
|
+
detectRefCycle(ctx: AontuContext): boolean {
|
|
474
|
+
const seen = new Set<number>()
|
|
475
|
+
let cur: RefVal = this
|
|
476
|
+
// No hop cap: every iteration either returns or adds a NEW ref to
|
|
477
|
+
// `seen`, and the tree holds finitely many refs, so the chase
|
|
478
|
+
// terminates at the first repetition or the first non-ref — a cap
|
|
479
|
+
// would just make cycles longer than it invisible.
|
|
480
|
+
for (; ;) {
|
|
481
|
+
if (seen.has(cur.id)) {
|
|
482
|
+
return true
|
|
483
|
+
}
|
|
484
|
+
seen.add(cur.id)
|
|
485
|
+
const rp = cur.plainRefPath()
|
|
486
|
+
if (null == rp) {
|
|
487
|
+
return false
|
|
488
|
+
}
|
|
489
|
+
let node: any = ctx.root
|
|
490
|
+
for (let i = 0; i < rp.length && null != node; i++) {
|
|
491
|
+
node = (node.isMap || node.isList) ? node.peg[rp[i]] : undefined
|
|
492
|
+
}
|
|
493
|
+
if (null == node || !node.isRef) {
|
|
494
|
+
return false
|
|
495
|
+
}
|
|
496
|
+
cur = node
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
|
|
501
|
+
// The resolved absolute path of a reference whose segments are all
|
|
502
|
+
// plain strings; undefined when the ref has variable segments (no
|
|
503
|
+
// cycle proof is attempted for those). Mirrors find's refpath
|
|
504
|
+
// computation for the plain case, including the `.` prefix reduction.
|
|
505
|
+
plainRefPath(): string[] | undefined {
|
|
506
|
+
const parts: string[] = []
|
|
507
|
+
for (const p of this.peg) {
|
|
508
|
+
if ('string' !== typeof p) {
|
|
509
|
+
return undefined
|
|
510
|
+
}
|
|
511
|
+
parts.push(p)
|
|
512
|
+
}
|
|
513
|
+
const refpath = this.absolute ? parts :
|
|
514
|
+
this.path.slice(0, -1).concat(parts)
|
|
515
|
+
const reduced: string[] = []
|
|
516
|
+
for (const p of refpath) {
|
|
517
|
+
if ('.' === p) {
|
|
518
|
+
// A parent step off the top of the path proves nothing.
|
|
519
|
+
if (0 === reduced.length) {
|
|
520
|
+
return undefined
|
|
521
|
+
}
|
|
522
|
+
reduced.length = reduced.length - 1
|
|
523
|
+
}
|
|
524
|
+
else {
|
|
525
|
+
reduced.push(p)
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
return reduced
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
|
|
459
532
|
same(peer: Val): boolean {
|
|
460
533
|
return null == peer ? false : this.peg === peer.peg
|
|
461
534
|
}
|
|
@@ -509,7 +582,7 @@ class RefVal extends FeatureVal {
|
|
|
509
582
|
].filter(p => '' != p).join(',')
|
|
510
583
|
}
|
|
511
584
|
|
|
512
|
-
}
|
|
585
|
+
} /* node:coverage ignore next 6 */
|
|
513
586
|
|
|
514
587
|
|
|
515
588
|
export {
|
package/src/val/ScalarKindVal.ts
CHANGED
|
@@ -148,7 +148,13 @@ class ScalarKindVal extends FeatureVal {
|
|
|
148
148
|
|
|
149
149
|
let out: Val = this
|
|
150
150
|
|
|
151
|
-
if (
|
|
151
|
+
if ((peer as any).isConstraint) {
|
|
152
|
+
// The constraint algebra owns the kind-meets-constraint rules
|
|
153
|
+
// (narrowing, domain checks) -- delegate, so disjunct trials and
|
|
154
|
+
// direct drives agree with the sorted conjunct fold.
|
|
155
|
+
out = (peer as any).unify(this, ctx)
|
|
156
|
+
}
|
|
157
|
+
else if (peerIsScalarVal) {
|
|
152
158
|
let peerKind = (peer as any).kind
|
|
153
159
|
|
|
154
160
|
// A kind admits a concrete value of that kind, or of any kind
|
|
@@ -213,7 +219,7 @@ class ScalarKindVal extends FeatureVal {
|
|
|
213
219
|
}
|
|
214
220
|
|
|
215
221
|
|
|
216
|
-
}
|
|
222
|
+
} /* node:coverage ignore next 15 */
|
|
217
223
|
|
|
218
224
|
|
|
219
225
|
export {
|
package/src/val/ScalarVal.ts
CHANGED
|
@@ -60,7 +60,7 @@ class ScalarVal extends Val {
|
|
|
60
60
|
let out: Val
|
|
61
61
|
|
|
62
62
|
// Exactly equal scalars are handled in unify.unite
|
|
63
|
-
if (peer.isScalarKind) {
|
|
63
|
+
if (peer.isScalarKind || (peer as any).isConstraint) {
|
|
64
64
|
out = peer.unify(this, ctx)
|
|
65
65
|
}
|
|
66
66
|
else if (peer.isTop) {
|
|
@@ -121,7 +121,7 @@ class ScalarVal extends Val {
|
|
|
121
121
|
}))
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
}
|
|
124
|
+
} /* node:coverage ignore next 6 */
|
|
125
125
|
|
|
126
126
|
|
|
127
127
|
export {
|
package/src/val/StringVal.ts
CHANGED
package/src/val/SuperFuncVal.ts
CHANGED
package/src/val/TopVal.ts
CHANGED
package/src/val/TypeFuncVal.ts
CHANGED
package/src/val/UpperFuncVal.ts
CHANGED
package/src/val/Val.ts
CHANGED
|
@@ -148,11 +148,13 @@ abstract class Val {
|
|
|
148
148
|
|
|
149
149
|
deps?: any
|
|
150
150
|
|
|
151
|
-
|
|
151
|
+
// TS-private (as _site above): the `#` form emits downlevel helper
|
|
152
|
+
// functions whose branches no supported Node can execute.
|
|
153
|
+
private _ctx: any
|
|
152
154
|
|
|
153
155
|
// TODO: Site needed in ctor
|
|
154
156
|
constructor(spec: ValSpec, ctx?: AontuContext) {
|
|
155
|
-
this
|
|
157
|
+
this._ctx = ctx
|
|
156
158
|
|
|
157
159
|
this.peg = spec?.peg
|
|
158
160
|
|
|
@@ -179,7 +181,7 @@ abstract class Val {
|
|
|
179
181
|
|
|
180
182
|
|
|
181
183
|
ctx() {
|
|
182
|
-
return this
|
|
184
|
+
return this._ctx
|
|
183
185
|
}
|
|
184
186
|
|
|
185
187
|
|
|
@@ -217,9 +219,12 @@ abstract class Val {
|
|
|
217
219
|
|
|
218
220
|
out.dc = this.done ? DONE : out.dc
|
|
219
221
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
222
|
+
// this.site is a lazy getter that always yields a Site, and Site's
|
|
223
|
+
// constructor coerces row/col to numbers and url to a string, so the
|
|
224
|
+
// spec value is the only one that can be absent.
|
|
225
|
+
out.site.row = spec?.row ?? this.site.row
|
|
226
|
+
out.site.col = spec?.col ?? this.site.col
|
|
227
|
+
out.site.url = spec?.url ?? this.site.url
|
|
223
228
|
|
|
224
229
|
out.mark = Object.assign({}, this.mark, fullspec.mark ?? {})
|
|
225
230
|
out.mark.type = this.mark.type && (fullspec.mark?.type ?? true)
|
|
@@ -427,7 +432,7 @@ function inspectpeg(peg: any, d: number) {
|
|
|
427
432
|
('{' +
|
|
428
433
|
Object.entries(peg).map((n: any) =>
|
|
429
434
|
'\n ' + indent + n[0] + ': ' + // n[1].inspect(d)
|
|
430
|
-
|
|
435
|
+
n[1].inspect(d)
|
|
431
436
|
).join(',') +
|
|
432
437
|
'\n' + indent + '}')
|
|
433
438
|
)
|
|
@@ -448,7 +453,7 @@ function empty(o: any) {
|
|
|
448
453
|
|| (null != o && 'object' === typeof o && 0 === Object.keys(o).length)
|
|
449
454
|
|| false
|
|
450
455
|
)
|
|
451
|
-
}
|
|
456
|
+
} /* node:coverage ignore next 16 */
|
|
452
457
|
|
|
453
458
|
|
|
454
459
|
|