I've taken the following code from http://www.ocaml-tutorial.org/data_types_and_matching
I've been trying to write a C stub for following, to invoke from our PHP codebase. I can't quite understand how (and if) I'm supposed to create a typedef for the following Ocaml type expr, and how I can access the function multiply_out from the C stub?
I'm a newbie to Ocaml and we're evaluating it to see if it'll be useful to us in creating a small grammar for our math web app.
type expr = Plus of expr * expr (* means a + b *)
| Minus of expr * expr (* means a - b *)
| Times of expr * expr (* means a * b *)
| Divide of expr * expr (* means a / b *)
| Value of string (* "x", "y", "n", etc. *)
;;
let rec multiply_out e =
match e with
Times (e1, Plus (e2, e3)) ->
Plus (Times (multiply_out e1, multiply_out e2),
Times (multiply_out e1, multiply_out开发者_运维技巧 e3))
| Times (Plus (e1, e2), e3) ->
Plus (Times (multiply_out e1, multiply_out e3),
Times (multiply_out e2, multiply_out e3))
| Plus (left, right) -> Plus (multiply_out left, multiply_out right)
| Minus (left, right) -> Minus (multiply_out left, multiply_out right)
| Times (left, right) -> Times (multiply_out left, multiply_out right)
| Divide (left, right) -> Divide (multiply_out left, multiply_out right)
| Value v -> Value v
;;
Any suggestions will be a big help! Thanks!
The manual is a bit terse but this is covered in the manual. The O'Reilly book is a little better: Representation of structured values. Here is a stub for your type:
int tag = Tag_val(v);
const char *lookup[4] = {"plus", "minus", "times", "divide"};
if(tag == 5) // Value
{
char *val = String_val(Field(v, 0));
}
else
{
value expr1 = Field(v, 0);
value expr2 = Field(v, 1);
const char *operation = lookup[tag-1];
}
To build an OCaml value in C check out Creating and Modifying OCaml values. Here's an example:
#define MINUS 2
#define VALUE 5
value two, five, minus;
CAMLlocal3(two, five, minus);
five = alloc(1, VALUE);
two = alloc(1, VALUE);
Store_field(copy_string("5"), 0, five);
Store_field(copy_string("2"), 0, two);
minus = alloc(2, MINUS); // allocate a block that contains two "words", tagged 2 (MINUX)
Store_field(minus, 0, five); // store five in the zeroith field of minus
Store_field(minus, 1, two); // store two in the first field of minus
CAMLreturn(minus);
A list of links:
Interfacing C with OCaml
Stub code generator.
SWIG can connect almost anything to anything.
Modules and the C interface.
Can't get documentation for a type like "expr".
Manual states this clearly and provides an example :
Non-constant constructors declared with a n-tuple as argument are represented by a block of size n, tagged with the constructor number; the n fields contain the components of its tuple argument.
E.g. Minus (e1,e2)
will be represented as block of size 2 with tag 1.
精彩评论