Commit Graph

274 Commits

Author SHA1 Message Date
4a35998469 haskell: Phase 7 string=[Char] — O(1) string-view head/tail + chr/ord/toUpper/toLower/++ (+35 tests, 810/810)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 49s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 19:44:19 +00:00
09d65d2d7b haskell: 13 new program suites + scoreboard 156/156 (775 tests)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 24s
collatz, palindrome, maybe, fizzbuzz, anagram, roman, binary, either,
primes, zipwith, matrix, wordcount, powers — all 18/18 programs green.
conformance.sh PROGRAMS array updated; scoreboard.md regenerated.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 17:02:02 +00:00
6bfb7b19f4 haskell: Phase 6 prelude extras (635/635)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
- hk-list-append: string ++ string via str (fixes unwords/unlines/intercalate)
- --sx-to-hk-- in words/lines builtins: use ":"/"[]" not "Cons"/"Nil"
- lines builtin: empty-string case returns ("[]") not ("Nil")
- New test file prelude-extra.sx: 47 tests covering ord, isAlpha/isDigit/
  isSpace/isUpper/isLower/isAlphaNum, digitToInt, words, lines, unwords,
  unlines, sort, nub, splitAt, span, break, partition, intercalate,
  intersperse, isPrefixOf, isSuffixOf, isInfixOf

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 15:51:12 +00:00
041cb9f3ef haskell: getLine/getContents/readFile/writeFile + 0-arity builtin force (+12 tests, 587/587)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 21s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 13:43:13 +00:00
578e54f06d haskell: real IO monad — putStrLn/print/putStr + hk-run-io (+10 tests, 575/575)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 20s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 13:10:42 +00:00
1c45262577 haskell: deriving (Eq, Show) for ADTs (+11 tests, 565/565)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 34s
Parser parses optional deriving clause; only appended to AST when non-empty.
hk-bind-decls! data arm generates dictShow_Con / dictEq_Con per constructor.
hk-binop == and /= now deep-force both sides (SX dict equality is by
reference — two thunks wrapping the same value compared as not-equal without
this). Three token-type fixes in the deriving parser (lparen/rparen/comma,
not "special").

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 12:25:51 +00:00
d3e71ba356 haskell: standard classes — show, Ord, Num, Functor, Monad prelude (+48 tests, 554/554)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
2026-05-06 10:57:20 +00:00
60a8eb24e0 haskell: dict-passing elaborator — runtime dispatch via hk-mk-lazy-builtin (+3 tests, 506/506)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 35s
2026-05-06 08:56:39 +00:00
41a69ecca7 haskell: class/instance declarations — parse + instance dict eval (+11 tests, 503/503)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 53s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 00:22:44 +00:00
5c00b5c58b haskell: inference unit tests — 55+ expressions, Phase 4 complete (+16 tests, 492/492)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 45s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-05 23:47:57 +00:00
622c0851ce haskell: let-polymorphism tests — id/const/nested/twice at multiple types (+6 tests, 476/476)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 47s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-05 23:26:01 +00:00
d8f3f8c3b2 haskell: type-sig checking — hk-ast-type + hk-check-sig + sig-aware infer-prog (+6 tests, 470/470)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 39s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-05 23:02:34 +00:00
2606b83920 haskell: reject untypeable programs — hk-typecheck + hk-run-typed (+9 tests, 464/464)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 46s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-05 22:32:18 +00:00
68124adc3b haskell: type error reporting — hk-expr->brief + hk-infer-decl/prog (+21 tests, 455/455)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 48s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-05 21:40:16 +00:00
8f3b0d9301 haskell: Algorithm W type inference + 32 tests (434/434)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 43s
Full HM inference in lib/haskell/infer.sx: unification, substitution,
occurs check, instantiation, generalisation, let-polymorphism.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-05 20:26:44 +00:00
9f71706bc8 haskell: conformance.sh runner + scoreboard.json + scoreboard.md (16/16, 5/5)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 19:26:26 +00:00
ba63cdf8c4 haskell: classic program calculator.hs + nested constructor patterns (+5 tests, 402/402)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 18:57:44 +00:00
8a9168c8d5 haskell: n-queens via list comprehension + where (+2 tests, 397/397)
- fix hk-eval-let: multi-clause where/let now uses hk-bind-decls!
  grouping (enables go 0 / go k pattern)
- add concatMap/concat/abs/negate to Prelude (list comprehension support)
- cache init env in hk-env0 (eval-expr-source 5x faster)
2026-04-25 18:40:27 +00:00
a12dcef327 haskell: naive quicksort classic program (+5 tests, 395/395) 2026-04-25 18:06:41 +00:00
9be65d7d60 haskell: lazy sieve of Eratosthenes (+mod/div/rem/quot, +2 tests, 390/390) 2026-04-25 17:59:39 +00:00
4ed7ffe9dd haskell: classic program fib.hs + source-order top-level binding (+2 tests, 388/388)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
2026-04-25 08:53:47 +00:00
cd489b19be haskell: do-notation desugar + stub IO monad (return/>>=/>>) (+14 tests, 382/382)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
2026-04-25 00:59:42 +00:00
04a25d17d0 haskell: seq + deepseq via lazy-builtin flag (+9 tests, 368/368)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
2026-04-25 00:28:19 +00:00
cc5315a5e6 haskell: lazy : + ranges + Prelude (repeat/iterate/fibs/take, +25 tests, 359/359)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
2026-04-24 23:58:21 +00:00
0e53e88b02 haskell: thunks + force, app args become lazy (+6 tests, 333/333)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
2026-04-24 23:22:21 +00:00
fba92c2b69 haskell: strict evaluator + 38 eval tests, Phase 2 complete (329/329)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
2026-04-24 22:49:12 +00:00
1aa06237f1 haskell: value-level pattern matcher (+31 tests, 281/281)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
2026-04-24 22:15:13 +00:00
e9c8f803b5 haskell: runtime constructor registry (+24 tests, 250/250)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
2026-04-24 21:45:51 +00:00
ef81fffb6f haskell: desugar guards/where/list-comp → core AST (+15 tests, 226/226)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
2026-04-24 21:16:53 +00:00
cab7ca883f haskell: operator sections + list comprehensions, Phase 1 parser complete (+22 tests, 211/211)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
2026-04-24 20:47:51 +00:00
bf0d72fd2f haskell: module header + imports (+16 tests, 189/189)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
2026-04-24 20:08:30 +00:00
defbe0a612 haskell: guards + where clauses (+11 tests, 173/173)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
2026-04-24 19:37:52 +00:00
869b0b552d haskell: top-level decls (fn-clause, type-sig, data, type, newtype, fixity) + type parser (+24 tests, 162/162)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
2026-04-24 19:06:38 +00:00
58dbbc5d8b haskell: full patterns — as/lazy/negative/infix + lambda & let pat LHS (+18 tests, 138/138)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
2026-04-24 18:34:47 +00:00
36234f0132 haskell: case/do + minimal patterns (+19 tests, 119/119)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
2026-04-24 18:00:58 +00:00
6ccef45ce4 haskell: expression parser + precedence climbing (+42 tests, 100/100)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
2026-04-24 17:31:38 +00:00
c07ff90f6b haskell: layout rule per §10.3 (+15 tests, 58/58)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
2026-04-24 17:05:35 +00:00
99753580b4 Recover agent-loop progress: lua/prolog/forth/erlang/haskell phases 1-2
Salvaged from worktree-agent-* branches killed during sx-tree MCP outage:
- lua: tokenizer + parser + phase-2 transpile (~157 tests)
- prolog: tokenizer + parser + unification (72 tests, plan update lost to WIP)
- forth: phase-1 reader/interpreter + phase-2 colon/VARIABLE (134 tests)
- erlang: tokenizer + parser (114 tests)
- haskell: tokenizer + parse tests (43 tests)

Cherry-picked file contents only, not branch history, to avoid pulling in
unrelated ocaml-vm merge commits that were in those branches' bases.
2026-04-24 16:03:00 +00:00
b45a69b7a4 sx: format_number helper — defuse int_of_float overflow on huge floats
Shared formatter in sx_types.ml. Small integer-valued floats still print
as plain ints; floats outside safe-int range (|n| >= 1e16) now print as
%.17g (full precision) instead of silently wrapping to negative or 0.
Non-integer values keep %g 6-digit behavior — no existing SX tests regress.

Unblocks Number.MAX_VALUE / Math.pow(2,N) style tests in js-on-sx where
iterative float loops were collapsing to 0 at ~2^63.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 15:09:11 +00:00
8f202e03c2 js-on-sx: .constructor backlink on Number/String/Array/Object protos (+1)
Number.prototype.constructor === Number etc. Four dict-set! lines add
the backlink after each constructor dict is defined.

new String().constructor === String now returns true. Array literals
don't yet link to Array.prototype so [].constructor === Array is still
false — that would need a boxing refactor.

Unit 521/522, slice 148/148 unchanged.
Number 76/100 → 77/100 (+1). String variance-heavy under CPU load.
2026-04-24 14:18:18 +00:00
6c1da9212a HS: ask/answer + prompt/confirm mock (+4 tests)
Wire up the `ask` and `answer` commands end-to-end:

- tokenizer.sx: register `ask` and `answer` as hs-keywords.

- parser.sx: cmd-kw? gains both; parse-cmd dispatches to new
  parse-ask-cmd (emits `(ask MSG)`) and parse-answer-cmd, which
  reads `answer MSG [with YES or NO]`. The with/or pair reads
  yes/no via parse-atom — parse-expr would collapse
  `"Yes" or "No"` into `(or "Yes" "No")` before match-kw "or"
  could fire. The no-`with` form emits `(answer-alert MSG)`.

- compiler.sx: three new cond branches (ask, answer, answer-alert)
  compile to a let that binds __hs-a, sets `the-result` and `it`,
  and returns the value — so `then put it into ...` works.

- runtime.sx: hs-ask / hs-answer / hs-answer-alert call
  window.prompt / confirm / alert via host-call + host-global.

- tests/hs-run-filtered.js: test-name-keyed globalThis.{alert,
  confirm,prompt}; __currentHsTestName is updated before each
  test. Host-set! for innerHTML/textContent now coerces JS
  null → "null" (browser behaviour) so `prompt → null` →
  `put it into #out` renders literal text "null", which the
  fourth test depends on.

Suite hs-upstream-askAnswer: 1/5 -> 5/5.
Smoke 0-195: 166/195 -> 170/195.
2026-04-24 14:08:25 +00:00
d7a88d85ae HS: parenthesized commands and features (+1 test)
Three parser additions so scripts like `(on click (log me) (trigger foo))`
parse into a single feature with both commands in its body:

1. parse-feat: new cond branch for `paren-open` — advance, recurse
   parse-feat, consume `paren-close`. Allows a feature like `(on click
   ...)` to be grouped in parens.

2. parse-cmd: two new cond branches — on `paren-close` return nil (so
   cl-collect terminates at an outer group close), and on `paren-open`
   advance / recurse / close. Allows single parenthesized commands like
   `(log me)`.

3. cl-collect: previously only recursed when the next token was a
   recognised command keyword (`cmd-kw?`), so after `(log me)` the
   sibling `(trigger foo)` would end the feature body and re-surface as
   a top-level feature. Extended the recursion predicate to also fire
   when the next token is `paren-open`.

Suite hs-upstream-core/parser: 9/14 -> 10/14.
Smoke 0-195: 165/195 -> 166/195.
2026-04-24 13:53:36 +00:00
9db703324d scoreboard: 162/300 (54.0%) wide, +48 over session baseline 2026-04-24 13:27:55 +00:00
b2810db1a0 js-on-sx: strip leading zeros from exponent in num→string (+3)
SX's (str 1e-7) gives "1e-07" but JS spec is "1e-7" — no padding, no
leading zeros in the exponent (sign stays). We stepped through:
  mant "e" expraw  →  mant "e" (sign (strip-zeros body))

Added four small helpers: js-normalize-num-str, js-split-sign,
js-strip-leading-zeros, js-strip-zeros-loop. All pure string walkers.

Unit 521/522, slice 148/148 unchanged.
String 40 → 42, Number 75 → 76 (+3 total).
Fixes S9.8.1_A9_T1, fromCharCode/S9.7_A3.1_T1..T2 family.
2026-04-24 13:23:08 +00:00
2af31248f2 js-on-sx: js-num-to-int guards NaN/Infinity → 0 (+2 String)
Spec ToUint16 (String.fromCharCode argument coercion) maps non-finite
values to 0. We had bare (floor v) which left inf/-inf/nan through,
breaking:
  String.fromCharCode(Infinity).charCodeAt(0) === 0      // was "" → err
  String.fromCharCode(NaN).charCodeAt(0) === 0           // was "" → err

Add NaN/inf/-inf guards returning 0 before the floor+signed-flip path.

Unit 521/522, slice 148/148 unchanged.
String 38/100 → 40/100 (+2: fromCharCode/S9.7_A1, S9.7_A2.1).
2026-04-24 13:14:23 +00:00
81059861fd js-on-sx: Function.prototype.isPrototypeOf recognises callable recvs (+3)
Tests expected Function.prototype.isPrototypeOf(Number/String/…) ===
true because every built-in ctor inherits from Function.prototype.
Our model doesn't link Number.__proto__ anywhere, so the default
Object.isPrototypeOf walked an empty chain and returned false.

Fix: post-definition dict-set! adds an explicit isPrototypeOf override
on js-function-global.prototype that returns (js-function? x) — which
accepts lambdas, functions, components, and __callable__ dicts. Good
enough to satisfy the spec for every case that isn't a bespoke proto
chain.

Unit 521/522, slice 148/148 unchanged.
Wide scoreboard: 156/300 → 159/300 (+3, Number/S15.7.3_A7 and the
three S15.5.3_A2 / S15.6.3_A2 / S15.9.3_A2 twins).
2026-04-24 13:07:33 +00:00
52fc87f222 scoreboard: 156/300 (52%) wide, +42 from session-start 114/300 2026-04-24 12:54:44 +00:00
2caf356fc4 js-on-sx: Math.X.name / Number.X.name via SX→JS name unmap (+4)
Every built-in JS function on Math/Number/Array/Object had .name === ""
because js-invoke-function-method/js-get-prop returned bare "" for the
"name" slot. That breaks tests like Math.abs.name === "abs" and
Array.isArray.name === "isArray".

Fix: extract the SX symbol name from (inspect fn) which prints
<js-math-abs(x)>, then unmap through a small string table that maps
js-math-abs → "abs", js-array-is-array → "isArray" etc. Also strips
the angle-bracket marker and stops at ( or space.

Non-mapped lambdas (user fns) fall through to the raw "js-foo" form
rather than "", which is slightly worse but only hit in debug prints.

Unit 521/522, slice 148/148 unchanged.
Scoreboard: Math 40/100 → 43/100 (+3); Number 74 → 75 (+1).

Sample: Math/abs/name.js, Math/floor/name.js, Math/max/name.js,
Number/isNaN/name.js — all flipped. length.js tests still fail for
trig because the underlying fn isn't implemented.
2026-04-24 12:49:56 +00:00
67df95508d js-on-sx: format Infinity/-Infinity/NaN per JS spec (+4 String)
js-number-to-string did (str n), which gives OCaml-native "inf"/"-inf"/
"nan"/"-nan" strings. JS spec requires "Infinity"/"-Infinity"/"NaN".

Fix: cond-check js-number-is-nan, and =infinity-value first, fall
through to (str n) for finite.

Unit 521/522, slice 148/148 unchanged.
String scoreboard: 34/100 → 38/100 (+4, S15.5.1.1_A1_T11/T12 family —
String(1/0)/String(-1/0)/String(0/0)).
2026-04-24 12:39:06 +00:00
679d6bd590 js-on-sx: fall-off-end functions return undefined, not null (+2)
Previously a JS function body with no return fell through the call/cc
begin as nil, making `(function(){}())` return null and typeof → object.
Spec: falls-off-end gives undefined.

Wrap the call/cc in (let ((__r__ ...)) (if (= __r__ nil) :js-undefined __r__)).
Downside: explicit `return null` also returns nil, but so does (pick
your last expression evaluating to null). For 99% of cases it's
fall-off-end and the fix is correct. Code that genuinely needs
distinguishable null would need separate nil/undef handling in the
evaluator.

Unit 521/522, slice 148/148 unchanged.
Number 73/100 → 74/100 (+1), String 33/100 → 34/100 (+1).
Fixes S15.5.1.1_A1_T1 family (String(function(){}()) should be "undefined").
2026-04-24 12:31:32 +00:00