ocaml: phase 5 parse ctor arg types in user type-defs (+3 tests, 409 total)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 36s

ocaml-hm-parse-type-src recognises primitive type names (int/bool/
string/float/unit), tyvars 'a, and simple parametric T list / T option.
Replaces the previous int-by-default placeholder in
ocaml-hm-register-type-def!.

So 'type tag = TStr of string | TInt of int' correctly registers
TStr : string -> tag and TInt : int -> tag. Pattern-match on tag
gives proper field types in the body. Multi-arg / function types
still fall back to a fresh tv.
This commit is contained in:
2026-05-08 15:43:16 +00:00
parent d61ee088c5
commit 4bca2cacff
3 changed files with 58 additions and 12 deletions

View File

@@ -412,11 +412,35 @@
(set-nth! ocaml-hm-ctors 0
(merge (nth ocaml-hm-ctors 0) (dict name scheme)))))
;; Process a :type-def AST. For each ctor, build its scheme:
;; nullary `A` → scheme [] (con NAME [param-tvs...])
;; ctor `B of int` → scheme [] (int -> (con NAME [...]))
;; Argument types are ignored for now (they're raw source strings) — we
;; assume `int`. A future iteration parses arg types properly.
;; Parse a simple type source into an HM type. Handles primitive type
;; names, type variables `'a`, parametric `'a list`, `T1 * T2`, and
;; function `T1 -> T2`. Unknown tokens default to a fresh tv so the
;; result is at worst polymorphic, never wrong.
(define ocaml-hm-parse-type-src
(fn (src)
(let ((s (trim src)))
(cond
((= s "int") (hm-int))
((= s "bool") (hm-bool))
((= s "string") (hm-string))
((= s "float") (ocaml-hm-float))
((= s "unit") (hm-con "Unit" (list)))
((and (> (len s) 1) (= (nth s 0) "'"))
(hm-tv (slice s 1 (len s))))
;; "T list" / "T option" — split on space, treat last as ctor.
(else
(let ((parts (filter (fn (p) (not (= p ""))) (split s " "))))
(cond
((= (len parts) 2)
(let ((arg (ocaml-hm-parse-type-src (first parts)))
(head (nth parts 1)))
(hm-con head (list arg))))
(else
;; Unknown: emit a fresh tv so unification stays sound.
(hm-tv (str "_unknown"))))))))))
;; Process a :type-def AST. For each ctor, build its scheme. Multi-arg
;; ctors are a list of types — we model that as a tuple arg.
(define ocaml-hm-register-type-def!
(fn (type-def)
(let ((name (nth type-def 1))
@@ -434,11 +458,12 @@
(ocaml-hm-ctor-register! cname
(hm-scheme params self-type)))
(else
;; Single-arg ctor with arg type `int` (placeholder).
;; Multi-arg or other-typed ctors fall back to int.
(ocaml-hm-ctor-register! cname
(hm-scheme params
(hm-arrow (hm-int) self-type))))))))
;; ARG-SRCS is a list of source strings, often a
;; single combined string `T1 * T2 * ...`. Parse.
(let ((arg-type (ocaml-hm-parse-type-src (first arg-srcs))))
(ocaml-hm-ctor-register! cname
(hm-scheme params
(hm-arrow arg-type self-type)))))))))
(for-each register-ctor ctors)))))))
(set! ocaml-infer