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
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/* Copyright (c) 2025 Richard Rodger, MIT License */
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Exact cross-leaf numeric comparison for the constraint algebra
|
|
5
|
+
* (docs/reference-language.md, "The constraint algebra"): order is a
|
|
6
|
+
* property of the number line, not the leaf, so a bound must compare an
|
|
7
|
+
* integer, a float, a biginteger and a bigdecimal EXACTLY, with no
|
|
8
|
+
* rounding anywhere. Every finite binary64 is exactly a rational —
|
|
9
|
+
* mant * 2^exp — and 2^-k = 5^k * 10^-k, so every leaf converts
|
|
10
|
+
* losslessly to a signed scaled-decimal (unscaled / 10^scale) and
|
|
11
|
+
* comparison is bigint arithmetic. The Go mirror is numcmp.go.
|
|
12
|
+
*
|
|
13
|
+
* The scaled forms built here are comparison-internal: they are never
|
|
14
|
+
* stored, never rendered, and deliberately NOT subject to the exact
|
|
15
|
+
* leaves' 4096-digit budget (a float's exact expansion can need ~770
|
|
16
|
+
* digits and that is fine for a compare).
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { Decimal } from './Decimal'
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
// A comparison-internal exact rational with a power-of-ten denominator.
|
|
23
|
+
// `inf` marks the two binary64 infinities, which some float leaf value
|
|
24
|
+
// could in principle carry; NaN cannot reach a scalar (the parser has
|
|
25
|
+
// no spelling for it) and is rejected by the atom constructors.
|
|
26
|
+
type Scaled = {
|
|
27
|
+
inf?: 1 | -1
|
|
28
|
+
unscaled: bigint // signed
|
|
29
|
+
scale: number // value = unscaled / 10^scale, scale >= 0
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
const F64 = new DataView(new ArrayBuffer(8))
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
// The exact scaled-decimal value of a finite or infinite binary64.
|
|
37
|
+
function scaledOfFloat(f: number): Scaled {
|
|
38
|
+
if (Number.isInteger(f) && Math.abs(f) <= Number.MAX_SAFE_INTEGER) {
|
|
39
|
+
return { unscaled: BigInt(f), scale: 0 }
|
|
40
|
+
}
|
|
41
|
+
if (Infinity === f) {
|
|
42
|
+
return { inf: 1, unscaled: 0n, scale: 0 }
|
|
43
|
+
}
|
|
44
|
+
if (-Infinity === f) {
|
|
45
|
+
return { inf: -1, unscaled: 0n, scale: 0 }
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
F64.setFloat64(0, f)
|
|
49
|
+
const hi = BigInt(F64.getUint32(0))
|
|
50
|
+
const lo = BigInt(F64.getUint32(4))
|
|
51
|
+
const bits = (hi << 32n) | lo
|
|
52
|
+
|
|
53
|
+
const sign = (bits >> 63n) & 1n ? -1n : 1n
|
|
54
|
+
const expBits = Number((bits >> 52n) & 0x7ffn)
|
|
55
|
+
const frac = bits & 0xfffffffffffffn
|
|
56
|
+
|
|
57
|
+
// Normal: implicit leading bit, exponent bias 1023 plus the 52
|
|
58
|
+
// fraction bits. Subnormal: no implicit bit, fixed exponent -1074.
|
|
59
|
+
let mant: bigint
|
|
60
|
+
let exp: number
|
|
61
|
+
if (0 === expBits) {
|
|
62
|
+
mant = frac
|
|
63
|
+
exp = -1074
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
mant = frac | (1n << 52n)
|
|
67
|
+
exp = expBits - 1075
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (0 <= exp) {
|
|
71
|
+
return { unscaled: sign * (mant << BigInt(exp)), scale: 0 }
|
|
72
|
+
}
|
|
73
|
+
// mant * 2^-k == mant * 5^k / 10^k, exactly.
|
|
74
|
+
return { unscaled: sign * mant * 5n ** BigInt(-exp), scale: -exp }
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
// The exact scaled-decimal value of any numeric leaf Val.
|
|
79
|
+
function scaledOfNumeric(v: any): Scaled {
|
|
80
|
+
if (v.isBigInteger) {
|
|
81
|
+
return { unscaled: v.peg as bigint, scale: 0 }
|
|
82
|
+
}
|
|
83
|
+
if (v.isBigDecimal) {
|
|
84
|
+
const d = v.peg as Decimal
|
|
85
|
+
return { unscaled: d.unscaled, scale: d.scale }
|
|
86
|
+
}
|
|
87
|
+
// integer and float leaves both hold a binary64.
|
|
88
|
+
return scaledOfFloat(v.peg as number)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
function pow10(n: number): bigint {
|
|
93
|
+
return 10n ** BigInt(n)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
// Exact three-way comparison of two scaled decimals.
|
|
98
|
+
function cmpScaled(a: Scaled, b: Scaled): number {
|
|
99
|
+
const ai = a.inf ?? 0
|
|
100
|
+
const bi = b.inf ?? 0
|
|
101
|
+
if (0 !== ai || 0 !== bi) {
|
|
102
|
+
return ai < bi ? -1 : ai > bi ? 1 : 0
|
|
103
|
+
}
|
|
104
|
+
let au = a.unscaled
|
|
105
|
+
let bu = b.unscaled
|
|
106
|
+
if (a.scale < b.scale) {
|
|
107
|
+
au *= pow10(b.scale - a.scale)
|
|
108
|
+
}
|
|
109
|
+
else if (b.scale < a.scale) {
|
|
110
|
+
bu *= pow10(a.scale - b.scale)
|
|
111
|
+
}
|
|
112
|
+
return au < bu ? -1 : au > bu ? 1 : 0
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
// Exact three-way comparison of two numeric leaf Vals, any leaves.
|
|
117
|
+
function cmpNumeric(a: any, b: any): number {
|
|
118
|
+
return cmpScaled(scaledOfNumeric(a), scaledOfNumeric(b))
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
// Lexical comparison by Unicode CODE POINTS — not UTF-16 code units,
|
|
123
|
+
// which order astral-plane text differently. Go compares strings
|
|
124
|
+
// byte-wise in UTF-8, which IS code-point order, so this is the side
|
|
125
|
+
// that must adapt (a Phase 0 decision, docs/reference-language.md).
|
|
126
|
+
function cmpCodePoints(a: string, b: string): number {
|
|
127
|
+
let ai = 0
|
|
128
|
+
let bi = 0
|
|
129
|
+
while (ai < a.length && bi < b.length) {
|
|
130
|
+
const ac = a.codePointAt(ai) as number
|
|
131
|
+
const bc = b.codePointAt(bi) as number
|
|
132
|
+
if (ac !== bc) {
|
|
133
|
+
return ac < bc ? -1 : 1
|
|
134
|
+
}
|
|
135
|
+
ai += ac > 0xffff ? 2 : 1
|
|
136
|
+
bi += bc > 0xffff ? 2 : 1
|
|
137
|
+
}
|
|
138
|
+
const ar = a.length - ai
|
|
139
|
+
const br = b.length - bi
|
|
140
|
+
return ar < br ? -1 : ar > br ? 1 : 0
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
// The tower order integer < float < biginteger < bigdecimal, used when
|
|
145
|
+
// two endpoints at the SAME point meet: the survivor is the
|
|
146
|
+
// tower-lowest spelling (docs/reference-language.md, bounds ruling 2).
|
|
147
|
+
function towerRank(v: any): number {
|
|
148
|
+
return v.isBigDecimal ? 3 : v.isBigInteger ? 2 :
|
|
149
|
+
v.isInteger ? 0 : 1
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
// True when the scaled value is integral (an exact whole number).
|
|
154
|
+
function scaledIsIntegral(s: Scaled): boolean {
|
|
155
|
+
if (s.inf) {
|
|
156
|
+
return false
|
|
157
|
+
}
|
|
158
|
+
if (0 === s.scale) {
|
|
159
|
+
return true
|
|
160
|
+
}
|
|
161
|
+
const p = pow10(s.scale)
|
|
162
|
+
return 0n === s.unscaled % p
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
// The exact floor of a scaled value, as a bigint. Infinite inputs are
|
|
167
|
+
// the caller's job to exclude.
|
|
168
|
+
function scaledFloor(s: Scaled): bigint {
|
|
169
|
+
if (0 === s.scale) {
|
|
170
|
+
return s.unscaled
|
|
171
|
+
}
|
|
172
|
+
const p = pow10(s.scale)
|
|
173
|
+
const q = s.unscaled / p
|
|
174
|
+
// BigInt division truncates toward zero; floor rounds down.
|
|
175
|
+
return (s.unscaled < 0n && 0n !== s.unscaled % p) ? q - 1n : q
|
|
176
|
+
} /* node:coverage ignore next 14 */
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
export {
|
|
180
|
+
Scaled,
|
|
181
|
+
scaledOfFloat,
|
|
182
|
+
scaledOfNumeric,
|
|
183
|
+
cmpScaled,
|
|
184
|
+
cmpNumeric,
|
|
185
|
+
cmpCodePoints,
|
|
186
|
+
towerRank,
|
|
187
|
+
scaledIsIntegral,
|
|
188
|
+
scaledFloor,
|
|
189
|
+
}
|
package/src/val/numkind.ts
CHANGED
|
@@ -241,7 +241,7 @@ function stripSep(s: string): string {
|
|
|
241
241
|
// select on kind, not merely on the peg being a JS number.
|
|
242
242
|
function integerDigits(peg: number): string {
|
|
243
243
|
return BigInt(peg).toString()
|
|
244
|
-
}
|
|
244
|
+
} /* node:coverage ignore next 13 */
|
|
245
245
|
|
|
246
246
|
|
|
247
247
|
// The window bounds stay module-local: they are the rules' working
|