Commit Graph

4 Commits

Author SHA1 Message Date
95fde5b177
fix(xpath): format a large integer-valued number with no decimal point (#268)
XPath 1.0 4.2: an integer-valued number converts to a string with no decimal
point. The formatter only took the integer branch for a magnitude below 1e15,
so a value like 1234567890123456 (exact in a double, which holds integers
exactly to 2^53) printed as 1234567890123456.0. Raise the bound to 2^63, the
range where the Int64 conversion is safe; larger magnitudes still expand
through the exponent path.

Closes Apache Xalan conformance case string132.
2026-06-24 04:31:19 +02:00
9070ccc3f1
fix(xpath): parse a lone / as the root node before a terminator (#267)
The XPath grammar makes the relative part after / optional, but the compiler
only treated / as the root location path when it was at the end of the
expression (isAtEnd). When a / was followed by ), ], |, or an operator (as in
count(/), generate-id(/), or / = .), it fell through and tried to parse a step
from the terminator, yielding an empty node-set. Recognize / as the root
whenever no location step follows.

Closes Apache Xalan conformance cases position106 and mdocs15.
2026-06-24 04:21:46 +02:00
83e6e27d12 style(format): adopt --importgrouping testable-bottom from canonical rules-swift
Group @testable imports at the bottom, per public/rules-swift's swiftformat. A
behavior-preserving import-ordering reformat across 252 files (mostly tests).
--trailingclosures was deliberately not adopted (cosmetic, and swiftformat flags
it as caution-worthy).
2026-06-18 20:33:07 +02:00
d83e5a88ce feat(xpath): expression engine and the four-type model
Compile and evaluate full XPath 1.0 expressions, not just location paths.
Add the four-type Value (node-set, boolean, number, string) with the spec's
coercion rules and canonical number formatting, a recursive-descent parser
for the operator grammar (or/and, equality, relational, additive,
multiplicative, unary minus, union) whose grammatical position disambiguates
* and the operator keywords, function calls, variable references, and filter
expressions. Predicates are now arbitrary expressions (a numeric predicate
is a position test). Comparison follows the node-set quantification rules.
Query gains value/number/string/boolean accessors and a $variable binding
map; the core functions last, position, count, not, true, false, boolean,
number, and string ship with it.

Closes #42
2026-06-08 05:33:13 +02:00