What's the easiest way to convert an Int32.t to binary? For example:
-1 -> "\255\255\255\255" ?
Edit:
To use extlib, install it with yum and in the toplevel:
#use "topfind";;
#require "extlib";;
I would suggest using Bitstring for this kind of thing. You can find it here.
For example, in the toplevel:
# #use "topfind";;
# #camlp4o;;
# #require "unix";;
# #require "bitstring.syntax" ;;
# let data = Int32.of_int (-1);;
# let bits = BITSTRING { data: 32 } ;;
then you can perform various conversions on the bitstring including writing it to a binary file or to stdout or to a string:
# Bitstring.string_of_bitstring bits ;;
- : string = "\255\255\255\255"
Use extlib:
# let io = IO.output_string ();;
val io : string IO.output = <abstr>
# IO.write_i32 io (-1);;
- : unit = ()
# IO.close_out io;;
- : string = "\255\255\255\255"
Related
I have searched in modules Sys, Gc, and Unix, but did not find a means to get the system page size in OCaml. How can we get the system page size?
I have OCaml 4.06 and macOS 10.12.6 (Sierra)
If you just want the answer for MacOS, there is a pagesize command that you can run with Unix.open_process_in:
$ rlwrap ocaml
OCaml version 4.06.0
# #load "unix.cma";;
# Unix.open_process_in "pagesize" |> input_line |> int_of_string;;
- : int = 4096
Update
There is a POSIX command line program getconf that is quite portable, I believe. It works on macOS and all the versions of Linux I tried. You can use that instead:
$ rlwrap ocaml
OCaml version 4.06.0
# #load "unix.cma";;
# Unix.open_process_in "getconf PAGE_SIZE" |> input_line |> int_of_string;;
- : int = 4096
You can call sysconf(SC_PAGESIZE) from ocaml to get that information. You can either do that using a .c file, or using ctypes (although you'll need the value of the SC_PAGESIZE, so it might not be the best solution):
% utop -require ctypes.foreign
# open Foreign;;
# open Ctypes;;
# let sysconf = foreign "sysconf" (int #-> returning long);;
val sysconf : int -> Signed.long = <fun>
# sysconf 30;;
- : Signed.long = <long 4096>
This is my ocamlinit:
(* Added by OPAM. *)
let () =
try Topdirs.dir_directory (Sys.getenv "OCAML_TOPLEVEL_PATH")
with Not_found -> ()
;;
(* ## added by OPAM user-setup for ocamltop / base ## 3ec62baf6f9c219ae06d9814069da862 ## you can edit, but keep this line *)
#use "topfind";;
(* ## end of OPAM user-setup addition for ocamltop / base ## keep this line *)
#thread;;
(* #ppx "ppx-jane -as-ppx";; *)
#require "ppx_jane";;
#require "core.top";;
#require "async";;
#require "core_extended";;
open Core.Std;;
With this exactly, I get this in utop
utop # type test = char list [##deriving show];;
Error: Cannot locate deriver show
If I use the line beginning with #ppx instead of #require "ppx_jane", I get this error
utop # type test = char list [##deriving show];;
Error: ppx_type_conv: 'show' is not a supported type type-conv generator
How should I set up ocamlinit to use [##deriving show]?
I managed to have it working using #require "ppx_deriving.show";; (with or without #require "ppx_jane";;).
In addition to Pierre's suggestion, I found that I needed the line with ppx_jane.
Also, I used #require "ppx_deriving.std" instead of just ppx_deriving.show to get ord and the rest of the stuff too.
Here's my full ocamlinit
(* Added by OPAM. *)
let () =
try Topdirs.dir_directory (Sys.getenv "OCAML_TOPLEVEL_PATH")
with Not_found -> ()
;;
(* ## added by OPAM user-setup for ocamltop / base ## 3ec62baf6f9c219ae06d9814069da862 ## you can edit, but keep this line *)
#use "topfind";;
(* ## end of OPAM user-setup addition for ocamltop / base ## keep this line *)
#thread;;
#require "ppx_jane";;
#require "core.top";;
#require "async";;
#require "core_extended";;
#require "ppx_deriving.std";;
open Core.Std;;
When I'm using OCaml utop every line of the input and output is printed into the console:
───┬──────────────────────────────────────────────────────────────┬───
│ Welcome to utop version 2.10.0 (using OCaml version 4.14.0)! │
└──────────────────────────────────────────────────────────────┘
Type #utop_help for help about using utop.
─( 22:17:51 )─< command 0 >─────────────────────────────{ counter: 0}─
utop # let x = 50;;
val x : int = 50
Is it possible to export each of user inputs and outputs from utop session into specific file?
Your input is saved by default at ~/.utop-history .
Isn't that enough for your purpose?
You can also change location and file size by manipulating UTop.history_file_name and other variables.
In ocaml toplevel, I can use "bitstring" package by typing the following commands:
#use "topfind";;
#camlp4o;;
#require "bitstring.syntax";;
let data = 0l;;
let bits = BITSTRING { data : 32 };;
However, if I create an OCaml script, e.g., foo.ml :
#!/usr/bin/env ocaml
#use "topfind";;
#camlp4o;;
#require "bitstring.syntax";;
let data = 0l;;
let bits = BITSTRING { data : 32 };;
And, if I run the OCaml script, I got a syntax error:
$ ./foo.ml
File "./foo.ml", line 8, characters 28-29: Error: Syntax error
What am I missing here? Why does the same code work with an interactive shell, but not with a script file?
I believe that's because script file is first parsed, and then the directives are executed, hence it cannot handle unknown (yet) syntax.
The easiest solution is to use ocamlscript :
#! /usr/bin/env ocamlscript
Ocaml.packs := [ "bitstring"; "bitstring.syntax" ]
--
let data = 0l;;
let bits = BITSTRING { data : 32 };;
How can I emulate this Python idiom in OCaml?
if __name__=="__main__":
main()
See RosettaCode for examples in other programming languages.
There is no notion of main module in Ocaml. All the modules in a program are equal. So you can't directly translate this Python idiom.
The usual way in Ocaml is to have a separate file containing the call to main, as well as other stuff like command line parsing that only make sense in a standalone executable. Don't include that source file when linking your code as a library.
There is a way to get at the name of the module, but it's rather hackish, as it is intended for debugging only. It violates the usual assumption that you can rename a module without changing its behavior. If you rely on it, other programmers reading your code will curse you. This method is provided for entertainment purposes only and should not be used in real life.
let name_of_this_compilation_unit =
try assert false with Assert_failure (filename, _, _) -> filename
You can compare the name of the compilation unit with Sys.executable_name or Sys.argv.(0). Note that this is not really the same thing as the Python idiom, which does not rely on the toplevel script having a particular name.
$ ocamlc -o scriptedmain -linkall str.cma scriptedmain.ml
$ ./scriptedmain
Main: The meaning of life is 42
$ ocamlc -o test -linkall str.cma scriptedmain.ml test.ml
$ ./test
Test: The meaning of life is 42
scriptedmain.ml:
let meaning_of_life : int = 42
let main () = print_endline ("Main: The meaning of life is " ^ string_of_int meaning_of_life)
let _ =
let program = Sys.argv.(0)
and re = Str.regexp "scriptedmain" in
try let _ = Str.search_forward re program 0 in
main ()
with Not_found -> ()
test.ml:
let main () = print_endline ("Test: The meaning of life is " ^ string_of_int Scriptedmain.meaning_of_life)
let _ =
let program = Sys.argv.(0)
and re = Str.regexp "test" in
try let _ = Str.search_forward re program 0 in
main ()
with Not_found -> ()
Posted on RosettaCode.