"Eval" a string in OCaml - ocaml

I'm trying to "eval" a string representing an OCaml expression in OCaml. I'm looking to do something equivalent to Python's eval.
So far I've not been able to find much. The Parsing module looks like it could be helpful, but I was not able to find a way to just eval a string.

Here is how to do it, but I didn't tell you. (Also the Parsing module is about Parsing, not executing code)
#require "compiler-libs" (* Assuming you're using utop, if compiling then this is the package you need *)
let eval code =
let as_buf = Lexing.from_string code in
let parsed = !Toploop.parse_toplevel_phrase as_buf in
ignore (Toploop.execute_phrase true Format.std_formatter parsed)
example:
eval "let () = print_endline \"hello\";;"
Notice the trailing ;; in the code sample.
To use ocamlbuild, you will need to use both compiler-libs and compiler-libs.toplevel.

OCaml is a compiled (not interpreted) language. So there's no simple way to do this. Certainly there are no language features that support it (as there are in almost every interpreted language). About the best you could do would be to link your program against the OCaml toplevel (which is an OCaml interpreter).

Related

Ocaml interpreter first approach

I have to create an interpreter in ocaml, I have to implement ths String and some operation on it. Something like strcpy in c . I never use ocaml, I googled a lot but I can't find something that helps me. So I have to write the synthax?
Something like :
type ide = string
type exp = ........ EXPRESSIONS
Then some module, struct in c ? And some SEMANTIC EVALUATION FUNCTIONS ? Sorry is my first time in ocaml, but also my first interpreter, I want to learn it so I need just some input to know where to study it . Please don't rate me wrong I wanna learn!

Primitive but efficient grep clone in haskell?

Whenever I consider learning a new language -- haskell in this case -- I try to hack together a primitive grep clone to see how good the language implementation and/or its libraries are at text processing, because that's a major use case for me.
Inspired by code on the haskell wiki, I came up with the following naive attempt:
{-# LANGUAGE FlexibleContexts, ExistentialQuantification #-}
import Text.Regex.PCRE
import System.Environment
io :: ([String] -> [String]) -> IO ()
io f = interact (unlines . f . lines)
regexBool :: forall r l .
(RegexMaker Regex CompOption ExecOption r,
RegexLike Regex l) =>
r -> l -> Bool
regexBool r l = l =~ r :: Bool
grep :: forall r l .
(RegexMaker Regex CompOption ExecOption r, RegexLike Regex l) =>
r -> [l] -> [l]
grep r = filter (regexBool r)
main :: IO ()
main = do
argv <- getArgs
io $ grep $ argv !! 0
This appears to be doing what I want it to, but unfortunately, it's really slow -- about 10 times slower than a python script doing the same thing. I assume it's not the regex library that's at fault here, because it's calling into PCRE which should be plenty fast (switching to Text.Regex.Posix slows things down quite a bit further). So it must be the String implementation, which is instructive from a theoretical point of view but inefficient according to what I've read.
Is there an alternative to Strings in haskell that's both efficient and convenient (i.e. there's little or no friction when switching to using that instead of Strings) and that fully and correctly handles UTF-8-encoded Unicode, as well as other encodings without too much hassle if possible? Something that everybody uses when doing text processing in haskell but that I just don't know about because I'm a complete beginner?
It's possible that the slow speed is caused by using the standard library's list type. I've often run into performance problems with it in the past.
It would be a good idea to profile your executable, to see where it spends its time: Tools for analyzing performance of a Haskell program. Profiling Haskell programs is really easy (compile with a switch and execute your program with an added argument, and the report is written to a text file in the current working directory).
As a side note, I use exactly the same approach as you when learning a new language: create something that works. My experience doing this with Haskell is that I can easily gain an order of magnitude or two in performance by profiling and making relatively simple changes (usually a couple of lines).

Can OCaml check tail recursion

Is there a way to get ocaml to tell me if a function implements a recursion using tail recursion? I don't mean reading the code. I mean getting ocaml to tell me, say like this:
let x = tail_recursion f;;
You can compile your source code with '-annot'. It will produce an annotation file, that some editors can use.
In caml-mode (emacs) the command ist:
M-x caml-types-show-call

External definitions for ocamllex regular expressions

I have implemented the usual combination of lexer/parser/pretty-printer for reading-in/printing a type in my code. I find there is redundancy among the lexer and the pretty-printer when it comes to plain-string regular expressions, usually employed for symbols, punctuation or separators.
For example I now have
rule token = parse
| "|-" { TURNSTILE }
in my lexer.mll file, and a function like:
let pp fmt (l,r) =
Format.fprintf fmt "#[%a |-# %a#]" Form.pp l Form.pp r
for pretty-printing. If I decide to change the string for TURNSTILE, I have to edit two places in the code, which I find less than ideal.
Apparently, the OCaml lexer supports a certain ability to define regular expressions and then refer to them within the mll file. So lexer.mll could be written as
let symb_turnstile = "|-"
rule token = parse
| symb_turnstile { TURNSTILE }
But this will not let me externally access symb_turnstile, say from my pretty-printing functions. In fact, after running ocamllex, there are no occurences of symb_turnstile in lexer.ml. I cannot even refer to these identifiers in the OCaml epilogue of lexer.mll.
Is there any way of achieving this?
In the end, I went for the following style which I stole from the sources of ocamllex itself (so I am guessing it's standard practice). A map from strings to tokens (here an association list) is defined in the preamble of lexer.mll
let symbols =
[
...
(Symb.turnstile, TURNSTILE);
...
]
where Symb is a module defining turnstile as a string. Then, the lexing part of lexer.mll is purposely overly general:
rule token = parse
...
| punctuation
{
try
List.assoc (Lexing.lexeme lexbuf) symbols
with Not_found -> lex_error lexbuf
}
...
where punctuation is a regular expression matching a sequence of symbols.
The pretty-printer can now be written like this.
let pp fmt (l,r) =
Format.fprintf fmt "#[%a %s# %a#]" Form.pp Symb.turnstile l Form.pp r
Although the two tokens both look like strings notationally, they're really very different. I don't think there's a convenient type under which they could be shared for use by ocamllex and Printf.printf. This is possibly the reason that ocamllex doesn't support such external definitions. You could get probably the effect you want with a macro facility (textual inclusion).

Why does camlp4o fail to parse (or) as a binary function?

In vanilla OCaml, (or) is a binary function just like (+) and all the others, so code like this works fine:
let any (truths:bool list) = List.fold_left (or) false truths
But in any environment where camlp4o is loaded, this fails to parse with:
Error: Parse error: ")" or "module" or [expr] expected after "(" (in [expr])
Meanwhile, (+) and the other integer arithmetic operators continue to work as expected in either environment:
let sum (nums:int list) = List.fold_left (+) 0 nums
Why is this? Is this a limitation with camlp4o, or a bug? This occurs on OCaml 3.12.1 (on OS X 10.7.4, installed freshly via GODI bootstrap).
This is a known bug that has been fixed since. The soon to be released 4.00 version will not have that issue.
PS: when I find something suspicious about OCaml that I strongly suspect is a bug, my technique is to do a google search with the site:caml.inria.fr/mantis modifier to search the OCaml bugtracker for similar content.
In "normal" OCaml you can use (or) interchangeably with (||). If you look at the definition of the revised syntax, the use of (or) is not supported. You always need to use (||). Perhaps this is a side effect of that change?
At any rate, some quick tests indicate that (||) works with camlp4o.