boolop.ml 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. open Types
  2. open Util
  3. let cast ctype node = TypeCast (ctype, node, [Type ctype])
  4. let boolconst value = Const (BoolVal value, [Type Bool])
  5. let intconst value = Const (IntVal value, [Type Int])
  6. let floatconst value = Const (FloatVal value, [Type Float])
  7. let rec trav_binop = function
  8. (* b1 == b2 ==> (int)b1 == (int)b2
  9. * b1 != b2 ==> (int)b1 != (int)b2 *)
  10. | ((Eq | Ne) as op, left, right, ann) ->
  11. bool_op (Binop (op, cast Int left, cast Int right, ann))
  12. (* b1 && b2 ==> b1 ? b2 : false *)
  13. | (And, left, right, ann) ->
  14. bool_op (Cond (left, right, boolconst false, ann))
  15. (* b1 || b2 ==> b1 ? true : b2 *)
  16. | (Or, left, right, ann) ->
  17. bool_op (Cond (left, boolconst true, right, ann))
  18. | (op, left, right, ann) ->
  19. Binop (op, left, right, ann)
  20. and bool_op = function
  21. | Binop (op, left, right, ann) when typeof left = Bool && typeof right = Bool ->
  22. trav_binop (op, bool_op left, bool_op right, ann)
  23. (* (bool)i ==> i != 0 *)
  24. | TypeCast (Bool, value, ann) when typeof value = Int ->
  25. Binop (Ne, bool_op value, intconst 0l, ann)
  26. (* (bool)f ==> f != 0.0 *)
  27. | TypeCast (Bool, value, ann) when typeof value = Float ->
  28. Binop (Ne, bool_op value, floatconst 0.0, ann)
  29. (* (int)b1 ==> b1 ? 1 : 0 *)
  30. | TypeCast (Int, value, ann) when typeof value = Bool ->
  31. Cond (bool_op value, intconst 1l, intconst 0l, ann)
  32. (* (float)b1 ==> b1 ? 1.0 : 0.0 *)
  33. | TypeCast (Float, value, ann) when typeof value = Bool ->
  34. Cond (bool_op value, floatconst 1.0, floatconst 0.0, ann)
  35. | TypeCast (ctype, value, ann) when typeof value = ctype ->
  36. bool_op value
  37. | node -> traverse_unit bool_op node
  38. let phase = function
  39. | Ast node -> Ast (bool_op node)
  40. | _ -> raise InvalidInput