ocaml: string ports (Eof + Port variants, 15 primitives)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled

Eof sentinel and Port{PortInput/PortOutput} in sx_types.ml. All 15 port
primitives in sx_primitives.ml. type_of/inspect updated. 39/39 port tests
pass (4532 total, +39, zero regressions).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-01 12:50:20 +00:00
parent e9abc2cf61
commit 8ba0a33f6e
3 changed files with 128 additions and 1 deletions

View File

@@ -2301,4 +2301,109 @@ let () =
| v -> raise (Eval_error ("list->string: expected char, got " ^ type_of v))
) chars;
String (Buffer.contents buf)
| _ -> raise (Eval_error "list->string: expected list of chars"))
| _ -> raise (Eval_error "list->string: expected list of chars"));
(* Phase 14 — EOF object + string ports *)
register "eof-object" (fun _args -> Eof);
register "eof-object?" (fun args ->
match args with
| [Eof] -> Bool true
| [_] -> Bool false
| _ -> raise (Eval_error "eof-object?: expected 1 argument"));
register "open-input-string" (fun args ->
match args with
| [String s] ->
Port { sp_closed = false; sp_kind = PortInput (s, ref 0) }
| _ -> raise (Eval_error "open-input-string: expected string"));
register "open-output-string" (fun args ->
match args with
| [] -> Port { sp_closed = false; sp_kind = PortOutput (Buffer.create 64) }
| _ -> raise (Eval_error "open-output-string: expected no arguments"));
register "get-output-string" (fun args ->
match args with
| [Port { sp_kind = PortOutput buf; _ }] -> String (Buffer.contents buf)
| _ -> raise (Eval_error "get-output-string: expected output port"));
register "port?" (fun args ->
match args with
| [Port _] -> Bool true
| [_] -> Bool false
| _ -> raise (Eval_error "port?: expected 1 argument"));
register "input-port?" (fun args ->
match args with
| [Port { sp_kind = PortInput _; _ }] -> Bool true
| [_] -> Bool false
| _ -> raise (Eval_error "input-port?: expected 1 argument"));
register "output-port?" (fun args ->
match args with
| [Port { sp_kind = PortOutput _; _ }] -> Bool true
| [_] -> Bool false
| _ -> raise (Eval_error "output-port?: expected 1 argument"));
register "close-port" (fun args ->
match args with
| [Port p] -> p.sp_closed <- true; Nil
| _ -> raise (Eval_error "close-port: expected port"));
register "read-char" (fun args ->
match args with
| [] -> raise (Eval_error "read-char: no default port in this host")
| [Port p] ->
(match p.sp_kind with
| PortOutput _ -> raise (Eval_error "read-char: expected input port")
| PortInput (src, pos) ->
if p.sp_closed || !pos >= String.length src then Eof
else begin
let cp = Char.code src.[!pos] in
incr pos;
Char cp
end)
| _ -> raise (Eval_error "read-char: expected input port"));
register "peek-char" (fun args ->
match args with
| [] -> raise (Eval_error "peek-char: no default port in this host")
| [Port p] ->
(match p.sp_kind with
| PortOutput _ -> raise (Eval_error "peek-char: expected input port")
| PortInput (src, pos) ->
if p.sp_closed || !pos >= String.length src then Eof
else Char (Char.code src.[!pos]))
| _ -> raise (Eval_error "peek-char: expected input port"));
register "read-line" (fun args ->
match args with
| [] -> raise (Eval_error "read-line: no default port in this host")
| [Port p] ->
(match p.sp_kind with
| PortOutput _ -> raise (Eval_error "read-line: expected input port")
| PortInput (src, pos) ->
if p.sp_closed || !pos >= String.length src then Eof
else begin
let start = !pos in
let len = String.length src in
while !pos < len && src.[!pos] <> '\n' do incr pos done;
let line = String.sub src start (!pos - start) in
if !pos < len then incr pos;
String line
end)
| _ -> raise (Eval_error "read-line: expected input port"));
register "write-char" (fun args ->
match args with
| [Char n; Port p] ->
(match p.sp_kind with
| PortInput _ -> raise (Eval_error "write-char: expected output port")
| PortOutput buf ->
if not p.sp_closed then
Buffer.add_char buf (Char.chr (n land 0xFF));
Nil)
| _ -> raise (Eval_error "write-char: expected char and output port"));
register "write-string" (fun args ->
match args with
| [String s; Port p] ->
(match p.sp_kind with
| PortInput _ -> raise (Eval_error "write-string: expected output port")
| PortOutput buf ->
if not p.sp_closed then Buffer.add_string buf s;
Nil)
| _ -> raise (Eval_error "write-string: expected string and output port"));
register "char-ready?" (fun args ->
match args with
| [Port { sp_closed = false; sp_kind = PortInput (src, pos); _ }] ->
Bool (!pos < String.length src)
| [Port _] -> Bool false
| _ -> raise (Eval_error "char-ready?: expected input port"))