开发者

How will this Ocaml type definition look in its C stub?

开发者 https://www.devze.com 2023-01-21 11:23 出处:网络
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

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号