ocaml to python

J

Jon Harrop

Gigs_ said:
Is there any way to convert ocaml code to python? but not manually

Translating between dissimilar high-level languages is very difficult, so
difficult that it is hard to do such a task justice by hand, let alone
automating the procedure.

If you must do it then write a compiler that converts OCaml's intermediate
representation into Python (after pattern match compilation), or write an
OCaml bytecode interpreter in Python.

For example, the following simple OCaml code is difficult to write in
Python:

let rec ( +: ) f g = match f, g with
| `Q n, `Q m -> `Q (n +/ m)
| `Q (Int 0), e | e, `Q (Int 0) -> e
| f, `Add(g, h) -> f +: g +: h
| f, g -> `Add(f, g)

let rec ( *: ) f g = match f, g with
| `Q n, `Q m -> `Q (n */ m)
| `Q (Int 0), e | e, `Q (Int 0) -> `Q (Int 0)
| `Q (Int 1), e | e, `Q (Int 1) -> e
| f, `Mul(g, h) -> f *: g *: h
| f, g -> `Mul(f, g)

let rec simplify = function
| `Q _ | `Var _ as e -> e
| `Add(f, g) -> simplify f +: simplify g
| `Mul(f, g) -> simplify f *: simplify g;;

OCaml compiles the pattern matches first, which gives an intermediate
representation much closer to something Python/Lisp can handle:

(seq
(letrec
(+:/71
(function f/72 g/73
(catch
(catch
(if (isint f/72) (exit 3)
(if (!= (field 0 f/72) 81) (exit 3)
(let (n/74 (field 1 f/72))
(catch
(if (isint g/73) (exit 4)
(if (!= (field 0 g/73) 81) (exit 4)
(makeblock 0 81
(apply (field 0 (global Num!)) n/74
(field 1 g/73)))))
with (4)
(switch n/74
case tag 0: (if (!= (field 0 n/74) 0) (exit 3) g/73)
default: (exit 3))))))
with (3)
(if (isint g/73) (exit 2)
(let (variant/113 (field 0 g/73))
(if (!= variant/113 81)
(if (!= variant/113 3254785) (exit 2)
(let (match/112 (field 1 g/73))
(apply +:/71 (apply +:/71 f/72 (field 0 match/112))
(field 1 match/112))))
(let (match/110 (field 1 g/73))
(switch match/110
case tag 0:
(if (!= (field 0 match/110) 0) (exit 2) f/72)
default: (exit 2)))))))
with (2) (makeblock 0 3254785 (makeblock 0 f/72 g/73)))))
(apply (field 1 (global Toploop!)) "+:" +:/71))
(letrec
(*:/83
(function f/84 g/85
(catch
(catch
(catch
(catch
(catch
(if (isint f/84) (exit 10)
(if (!= (field 0 f/84) 81) (exit 10)
(let (n/86 (field 1 f/84))
(catch
(if (isint g/85) (exit 11)
(if (!= (field 0 g/85) 81) (exit 11)
(makeblock 0 81
(apply (field 5 (global Num!)) n/86
(field 1 g/85)))))
with (11)
(switch n/86
case tag 0:
(if (!= (field 0 n/86) 0) (exit 10) (exit 5))
default: (exit 10))))))
with (10)
(if (isint g/85) (exit 9)
(if (!= (field 0 g/85) 81) (exit 9)
(let (match/121 (field 1 g/85))
(switch match/121
case tag 0:
(if (!= (field 0 match/121) 0) (exit 9) (exit 5))
default: (exit 9))))))
with (9)
(if (isint f/84) (exit 8)
(if (!= (field 0 f/84) 81) (exit 8)
(let (match/124 (field 1 f/84))
(switch match/124
case tag 0:
(if (!= (field 0 match/124) 1) (exit 8) g/85)
default: (exit 8))))))
with (8)
(if (isint g/85) (exit 7)
(let (variant/130 (field 0 g/85))
(if (!= variant/130 81)
(if (!= variant/130 3855332) (exit 7)
(let (match/129 (field 1 g/85))
(apply *:/83 (apply *:/83 f/84 (field 0 match/129))
(field 1 match/129))))
(let (match/127 (field 1 g/85))
(switch match/127
case tag 0:
(if (!= (field 0 match/127) 1) (exit 7) f/84)
default: (exit 7)))))))
with (7) (makeblock 0 3855332 (makeblock 0 f/84 g/85)))
with (5) [0: 81 [0: 0]])))
(apply (field 1 (global Toploop!)) "*:" *:/83))
(let
(*:/83 (apply (field 0 (global Toploop!)) "*:")
+:/71 (apply (field 0 (global Toploop!)) "+:"))
(letrec
(simplify/97
(function e/98
(let (variant/135 (field 0 e/98))
(if (!= variant/135 3254785)
(if (!= variant/135 3855332) e/98
(let (match/132 (field 1 e/98))
(apply *:/83 (apply simplify/97 (field 0 match/132))
(apply simplify/97 (field 1 match/132)))))
(let (match/131 (field 1 e/98))
(apply +:/71 (apply simplify/97 (field 0 match/131))
(apply simplify/97 (field 1 match/131))))))))
(apply (field 1 (global Toploop!)) "simplify" simplify/97))))

I suspect your best bet is to write an interface between the two (e.g.
XMLRPC) and keep the OCaml as OCaml.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top