ocaml: phase 1/5/6 float arithmetic +./-./*./. (+5 tests, 372 total)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 27s

Tokenizer: +. -. *. /. (with -. avoiding clash with negative float
literals). Parser table places dotted ops at int-precedence levels.
Eval routes to host SX +/-/*//. HM types them Float->Float->Float;
literal floats now infer as Float (was Int).

OCaml-style 1.5 +. 2.5 : Float works end-to-end through tokenize +
parse + eval + infer.
This commit is contained in:
2026-05-08 13:55:04 +00:00
parent 16df48ff74
commit ee002f2e02
6 changed files with 53 additions and 1 deletions

View File

@@ -328,6 +328,10 @@
((= op "-") (- lhs rhs))
((= op "*") (* lhs rhs))
((= op "/") (/ lhs rhs))
((= op "+.") (+ lhs rhs))
((= op "-.") (- lhs rhs))
((= op "*.") (* lhs rhs))
((= op "/.") (/ lhs rhs))
((= op "mod") (mod lhs rhs))
((= op "%") (mod lhs rhs))
((= op "**") (pow lhs rhs))

View File

@@ -37,9 +37,15 @@
"true" (hm-monotype (hm-bool))
"false" (hm-monotype (hm-bool))}))))
;; Float type isn't in the kit; use a named ctor.
(define ocaml-hm-float (fn () (hm-con "Float" (list))))
(define ocaml-hm-builtin-env
(fn ()
(let ((int-int-int (hm-arrow (hm-int) (hm-arrow (hm-int) (hm-int))))
(float-float-float
(hm-arrow (ocaml-hm-float)
(hm-arrow (ocaml-hm-float) (ocaml-hm-float))))
(int-int-bool (hm-arrow (hm-int) (hm-arrow (hm-int) (hm-bool))))
(bool-bool-bool (hm-arrow (hm-bool) (hm-arrow (hm-bool) (hm-bool))))
(str-str-str (hm-arrow (hm-string) (hm-arrow (hm-string) (hm-string))))
@@ -66,6 +72,10 @@
"-" (hm-monotype int-int-int)
"*" (hm-monotype int-int-int)
"/" (hm-monotype int-int-int)
"+." (hm-monotype float-float-float)
"-." (hm-monotype float-float-float)
"*." (hm-monotype float-float-float)
"/." (hm-monotype float-float-float)
"mod" (hm-monotype int-int-int)
"%" (hm-monotype int-int-int)
"**" (hm-monotype int-int-int)
@@ -444,7 +454,7 @@
(else
{:subst {} :type (hm-fresh-tv counter)}))))
((= tag "int") {:subst {} :type (hm-int)})
((= tag "float") {:subst {} :type (hm-int)}) ;; treat float as int for now
((= tag "float") {:subst {} :type (ocaml-hm-float)})
((= tag "string") {:subst {} :type (hm-string)})
((= tag "char") {:subst {} :type (hm-string)})
((= tag "bool") {:subst {} :type (hm-bool)})
@@ -572,5 +582,6 @@
(let ((a (ocaml-hm-format-type (nth args 0)))
(b (ocaml-hm-format-type (nth args 1))))
(str "(" a ", " b ") result")))
((= head "Float") "Float")
(else head))))
(else (str t)))))

View File

@@ -67,8 +67,12 @@
(list "::" 6 :right)
(list "+" 7 :left)
(list "-" 7 :left)
(list "+." 7 :left)
(list "-." 7 :left)
(list "*" 8 :left)
(list "/" 8 :left)
(list "*." 8 :left)
(list "/." 8 :left)
(list "%" 8 :left)
(list "mod" 8 :left)
(list "land" 8 :left)

View File

@@ -910,6 +910,18 @@ cat > "$TMPFILE" << 'EPOCHS'
(epoch 2203)
(eval "(ocaml-run \"List.map2 (fun a b -> a + b) [1;2;3] [10;20;30]\")")
;; ── Float arithmetic ───────────────────────────────────────────
(epoch 2300)
(eval "(ocaml-run \"1.5 +. 2.5\")")
(epoch 2301)
(eval "(ocaml-run \"3.0 *. 2.0\")")
(epoch 2302)
(eval "(ocaml-run \"10.0 /. 4.0\")")
(epoch 2303)
(eval "(ocaml-type-of \"1.5 +. 2.5\")")
(epoch 2304)
(eval "(ocaml-type-of \"fun x y -> x +. y\")")
EPOCHS
OUTPUT=$(timeout 180 "$SX_SERVER" < "$TMPFILE" 2>/dev/null)
@@ -1439,6 +1451,13 @@ check 2201 "List.split" '("tuple" (1 2) ("a" "b"))'
check 2202 "List.fold_left2" '66'
check 2203 "List.map2" '(11 22 33)'
# ── Float arithmetic ────────────────────────────────────────────
check 2300 "1.5 +. 2.5" '4'
check 2301 "3.0 *. 2.0" '6'
check 2302 "10.0 /. 4.0" '2.5'
check 2303 "type 1.5 +. 2.5" '"Float"'
check 2304 "type fun x y -> x +. y" '"Float -> Float -> Float"'
TOTAL=$((PASS + FAIL))
if [ $FAIL -eq 0 ]; then
echo "ok $PASS/$TOTAL OCaml-on-SX tests passed"

View File

@@ -294,6 +294,14 @@
(cond
((and (= c ";") (= c1 ";"))
(begin (advance! 2) (push! "op" ";;" start) true))
((and (= c "+") (= c1 "."))
(begin (advance! 2) (push! "op" "+." start) true))
((and (= c "-") (= c1 ".") (not (and (not (= c2 nil)) (ocaml-digit? c2))))
(begin (advance! 2) (push! "op" "-." start) true))
((and (= c "*") (= c1 "."))
(begin (advance! 2) (push! "op" "*." start) true))
((and (= c "/") (= c1 "."))
(begin (advance! 2) (push! "op" "/." start) true))
((and (= c "-") (= c1 ">"))
(begin (advance! 2) (push! "op" "->" start) true))
((and (= c "<") (= c1 "-"))