You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
## Summary
String `<` / `<=` / `>` / `>=` typecheck (the `comparison` branch
returns `Bool`, #458) but the wasm backend lowered them to a
**signed-integer compare of the two `[len][utf8]` pointers** — a
meaningless ordering. This **completes the string wall**: slice 8b fixed
`++`, slice 9 fixed `==`/`!=`, and this slice fixes the four relational
operators.
## Approach (mirrors slice 9 exactly)
- **typecheck** records String-typed relational nodes by physical
identity in `synth`'s `comparison` branch (`string_rel_sites`) — that
branch only fires for `OpLt`/`OpLe`/`OpGt`/`OpGe`, so every recorded
node is relational
- `elaborate_string_concat` rewrites them to a new **`ExprStringRel`**
AST node (one walk now drives concat + eq + rel)
- **codegen** lowers `ExprStringRel` to a byte-wise **lexicographic**
comparison: compare the common prefix unsigned (`I32LtU`/`I32GtU`), and
on a tie the shorter string is the smaller; the result `cmp ∈ {−1,0,1}`
maps onto `cmp <signed-op> 0`. The loop is bounded at `min(la,lb)` (via
`Select`), so it never reads past either string
- type-blind passes get matching arms (`interp`/`opt`/`effect_sites`)
`Int`/`Float` relational is untouched — only String operands are
recorded.
## Verification
- lexicographic ordering correct across decisive-byte, **prefix
ordering** (`"ab" < "abc"`), equality (`<=`/`>=`), empty strings (both
directions), and built-vs-literal operands — a 10-case discriminating
program returns the exact expected encoding
- **no regression** across 41,215 int parity cases (Maths 1982, VmState
38577, DifficultyScale 252, PlayerHp 295, SecurityRank 45, NetworkZones
64) and the slice-9 `==` edge-case suite
- new e2e fixture (`test/e2e/fixtures/string_rel.affine`) + test
(`test_e2e.ml`, slice-10)
## Effect on the migration
With `++`, `==`/`!=`, and now `<`/`<=`/`>`/`>=` all lowering correctly,
**String operations work end-to-end on the wasm target**. Future `.res →
.affine` migrations no longer need to integer-gate string
comparison/ordering — the core driver of the "extract an integer brain,
keep strings host-side" pattern is removed.
https://claude.ai/code/session_01WoKhFQePiRsAj7aqnxbG8s
---
_Generated by [Claude
Code](https://claude.ai/code/session_01WoKhFQePiRsAj7aqnxbG8s)_
Co-authored-by: Claude <noreply@anthropic.com>
0 commit comments