I'm trying to create a code generating DSL in OCaml, however I can't find many examples on what the code generation looks like. I would just like to see how to create code values in OCaml.
For example if I had a type like this:
let equation =
Add of int * int
| Sub of int * int
| Mul of int * int
| Div of int * int;;
and I want a function like this:
let write_code = function
| Add (x, y) -> // INSERT CODE "x + y" here
etc... how would this look?
I have looked at this example http://okmij.org/ftp/meta-programming/tutorial/power.ml but the characters .< >. are causing syntax errors when I try to compile.
The code generated will not need to be compiled or executed, but saved to a .c file for later use.
I would just like to see the basic structure for this simple example so I can apply it to a more complicated problem.
You can do like that :
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 ^ ")"
;;
Here you produce a string and after that you can write that string where you want.
I changed your expression type a bit to be more general.
The result string will contain too much parentheses, but it does not matter because the generated code is not targeted to humans but to a compiler.
You could use a buffer :
As it's written in the module :
This module implements buffers that automatically expand as necessary. It provides accumulative concatenation of strings in quasi-linear time ( instead of quadratic time when strings are concatenated pairwise ).
For example, you can write :
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
With
# Buffer.create;;
- : int -> Buffer.t = <fun>
# Buffer.add_string;;
- : Buffer.t -> string -> unit = <fun>
# Buffer.output_buffer;;
- : out_channel -> Buffer.t -> unit = <fun>
Notice that Buffer.add_string
write the string at the end of the buffer ;-)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.