在Ocaml中生成C代码

在Ocaml中生成C代码,ocaml,code-generation,dsl,Ocaml,Code Generation,Dsl,我试图在OCaml中创建一个代码生成DSL,但是我找不到很多关于代码生成的示例。我只想看看如何在OCaml中创建代码值 例如,如果我有这样的类型: let equation = Add of int * int | Sub of int * int | Mul of int * int | Div of int * int;; let write_code = function | Add (x, y) -> // INSERT CODE "x +

我试图在OCaml中创建一个代码生成DSL,但是我找不到很多关于代码生成的示例。我只想看看如何在OCaml中创建代码值

例如,如果我有这样的类型:

let equation =
    Add of int * int
    | Sub of int * int
    | Mul of int * int
    | Div of int * int;;
let write_code = function
    | Add (x, y) -> // INSERT CODE "x + y" here
我想要一个这样的函数:

let equation =
    Add of int * int
    | Sub of int * int
    | Mul of int * int
    | Div of int * int;;
let write_code = function
    | Add (x, y) -> // INSERT CODE "x + y" here
等等。。。这看起来怎么样

我已经看了这个例子,但是没有看到角色。<>。在我尝试编译时导致语法错误

生成的代码不需要编译或执行,而是保存到.c文件中供以后使用


我只想看看这个简单示例的基本结构,以便将其应用于更复杂的问题。

您可以这样做:

type equation =
  | Const of int
  | Var of string
  | Add of equation * equation
  | Mul of equation * equation ;;

let rec c_string_of_equation = function
  | Const i -> string_of_int i
  | Var x -> x
  | Add (e1, e2) -> 
    "(" ^ c_string_of_equation e1 ^ ") + (" ^ c_string_of_equation e2 ^ ")"
  | Mul (e1, e2) -> 
    "(" ^ c_string_of_equation e1 ^ ") * (" ^ c_string_of_equation e2 ^ ")"
;;
在这里生成一个字符串,然后可以在需要的地方编写该字符串

我将您的表达式类型更改了一点,使其更为通用

结果字符串将包含太多的括号,但这并不重要,因为生成的代码不是针对人类的,而是针对编译器的。

您可以使用:

正如模块中所述:

此模块实现了根据需要自动扩展的缓冲区。它在准线性时间(而不是成对串联字符串时的二次时间)内提供字符串的累积串联

例如,您可以编写:

let equation =
  | Add of int * int
  | Sub of int * int
  | Mul of int * int
  | Div of int * int;;

let co = open_out filename

let buff = Buffer.create 11235

let write_code = function
  | Add (x, y) -> Buffer.add_string buff (Printf.sprintf "%d + %d" x y)
  | ... -> ...

 let write c =
    write_code c;
    Buffer.output_buffer co buff

#Buffer.create;;
-:int->Buffer.t=
#Buffer.add_string;;
-:Buffer.t->string->unit=
#Buffer.output_Buffer;;
-:输出通道->缓冲区.t->单位=

请注意,
Buffer.add_string
在缓冲区的末尾写入字符串;-)

如果需要生成并保存C代码,只需生成字符串并将其保存到C文件中即可
| Add(x,y)->Printf.sprintf“(%s+%s)”(write_code x)(write_code y)
用于MetaOCaml。你需要用它来代替香草的OCaml。但我想这不是你真正想要的。