stringify.ml 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. open Types
  2. let tab = " "
  3. (* string -> string *)
  4. let indent = Str.global_replace (Str.regexp "^\\(.\\)") (tab ^ "\\1")
  5. (* const -> string *)
  6. let const2str = function
  7. | BoolVal b -> string_of_bool b
  8. | IntVal i -> string_of_int i
  9. | FloatVal f ->
  10. (* Add a trailing zero to a float stringification *)
  11. (match string_of_float f with
  12. | s when s.[String.length s - 1] = '.' -> s ^ "0"
  13. | s -> s
  14. )
  15. (* Copied from util.ml to avoid circular dependency *)
  16. let nameof = function
  17. | GlobalDec (_, name, _)
  18. | GlobalDef (_, _, name, _, _)
  19. | FunDec (_, name, _, _)
  20. | FunDef (_, _, name, _, _, _)
  21. | VarDec (_, name, _, _)
  22. | Param (_, name, _)
  23. | Dim (name, _) -> name
  24. | _ -> raise InvalidNode
  25. (* operator -> string *)
  26. let op2str = function
  27. | Neg -> "-"
  28. | Not -> "!"
  29. | Add -> "+"
  30. | Sub -> "-"
  31. | Mul -> "*"
  32. | Div -> "/"
  33. | Mod -> "%"
  34. | Eq -> "=="
  35. | Ne -> "!="
  36. | Lt -> "<"
  37. | Le -> "<="
  38. | Gt -> ">"
  39. | Ge -> ">="
  40. | And -> "&&"
  41. | Or -> "||"
  42. (* ctype -> string *)
  43. let rec type2str = function
  44. | Void -> "void"
  45. | Bool -> "bool"
  46. | Int -> "int"
  47. | Float -> "float"
  48. | Array (t, dims) -> (type2str t) ^ "[" ^ (concat ", " dims) ^ "]"
  49. | ArrayDepth (t, ndims) -> (type2str t) ^ "[" ^ string_of_int ndims ^ "]"
  50. | FlatArray t -> (type2str t) ^ "[]"
  51. and concat sep nodes = String.concat sep (List.map node2str nodes)
  52. (* node -> string *)
  53. and node2str node =
  54. let str = node2str in
  55. match node with
  56. (* Global *)
  57. | Program (decls, _) ->
  58. concat "\n\n" decls
  59. | Param (param_type, name, _) ->
  60. (type2str param_type) ^ " " ^ name
  61. | FunDec (ret_type, name, params, _) ->
  62. let params = concat ", " params in
  63. "extern " ^ type2str ret_type ^ " " ^ name ^ "(" ^ params ^ ");"
  64. | FunDef (export, ret_type, name, params, body, _) ->
  65. let export = if export then "export " else "" in
  66. let params = "(" ^ (concat ", " params) ^ ")" in
  67. export ^ type2str ret_type ^ " " ^ name ^ params ^ " " ^ str body
  68. | GlobalDec (var_type, name, _) ->
  69. "extern " ^ type2str var_type ^ " " ^ name ^ ";"
  70. | GlobalDef (export, ret_type, name, init, _) ->
  71. let export = if export then "export " else "" in
  72. let init = match init with
  73. | Some value -> " = " ^ str value
  74. | None -> ""
  75. in
  76. export ^ (type2str ret_type) ^ " " ^ name ^ init ^ ";"
  77. (* Statements *)
  78. | VarDec (var_type, name, None, _) ->
  79. (type2str var_type) ^ " " ^ name ^ ";"
  80. | VarDec (var_type, name, Some init, _) ->
  81. (type2str var_type) ^ " " ^ name ^ " = " ^ (str init) ^ ";"
  82. | Assign (name, None, value, _) ->
  83. name ^ " = " ^ (str value) ^ ";"
  84. | Assign (name, Some dims, value, _) ->
  85. name ^ "[" ^ (concat ", " dims) ^ "] = " ^ (str value) ^ ";"
  86. | Expr expr ->
  87. str expr ^ ";"
  88. | Return (value, _) ->
  89. "return " ^ (str value) ^ ";"
  90. | If (cond, body, _) ->
  91. "if (" ^ str cond ^ ") " ^ str body
  92. | IfElse (cond, true_body, false_body, _) ->
  93. "if (" ^ str cond ^ ") " ^ str true_body ^ " else " ^ str false_body
  94. | While (cond, body, _) ->
  95. "while (" ^ str cond ^ ") " ^ str body
  96. | DoWhile (cond, body, _) ->
  97. "do " ^ str body ^ " while (" ^ str cond ^ ");"
  98. | For (counter, start, stop, step, body, _) ->
  99. let step = match step with
  100. | Const (IntVal 1, _) -> ""
  101. | value -> ", " ^ str value
  102. in
  103. let range = str start ^ ", " ^ str stop ^ step in
  104. "for (int " ^ counter ^ " = " ^ range ^ ") " ^ str body
  105. | Allocate (dec, dims, _) ->
  106. nameof dec ^ " := <allocate>(" ^ concat ", " dims ^ ");"
  107. | Block body ->
  108. let rec append = function
  109. | [] -> ""
  110. | [last] -> last
  111. | "" :: tl -> append tl
  112. | hd :: tl -> hd ^ "\n" ^ append tl
  113. in
  114. "{\n" ^ indent (append (List.map str body)) ^ "\n}"
  115. (* Expressions *)
  116. | Const (c, _) -> const2str c
  117. | ArrayConst (dims, _) -> "[" ^ concat ", " dims ^ "]"
  118. | Var (v, None, _) -> v
  119. | Var (name, Some dims, _) -> name ^ (str (ArrayConst (dims, [])))
  120. | Monop (op, opnd, _) -> op2str op ^ str opnd
  121. | Binop (op, left, right, _) ->
  122. "(" ^ str left ^ " " ^ op2str op ^ " " ^ str right ^ ")"
  123. | TypeCast (ctype, value, _) -> "(" ^ type2str ctype ^ ")" ^ str value
  124. | FunCall (name, args, _) -> name ^ "(" ^ (concat ", " args) ^ ")"
  125. | Cond (cond, t, f, _) -> "(" ^ (str cond) ^ " ? " ^ str t ^ " : " ^ str f ^ ")"
  126. (* Annotation nodes print more information at higher verbosity, for
  127. * debugging purposes *)
  128. | VarLet (dec, dims, value, _) when args.verbose >= verbosity_debug ->
  129. "<let:" ^ node2str (Assign (nameof dec, dims, value, [])) ^ ">"
  130. | VarUse (dec, dims, _) when args.verbose >= verbosity_debug ->
  131. "<use:" ^ node2str (Var (nameof dec, dims, [])) ^ ">"
  132. | FunUse (dec, params, _) when args.verbose >= verbosity_debug ->
  133. "<use:" ^ node2str (FunCall (nameof dec, params, [])) ^ ">"
  134. | Dim (name, _) when args.verbose >= verbosity_debug ->
  135. "<dim:" ^ name ^ ">"
  136. | ArrayScalar value when args.verbose >= verbosity_debug ->
  137. "<scalar:" ^ str value ^ ">"
  138. | Arg node when args.verbose >= verbosity_debug ->
  139. "<arg:" ^ str node ^ ">"
  140. | VarLet (dec, dims, value, _) ->
  141. node2str (Assign (nameof dec, dims, value, []))
  142. | VarUse (dec, dims, _) ->
  143. node2str (Var (nameof dec, dims, []))
  144. | FunUse (dec, args, _) ->
  145. node2str (FunCall (nameof dec, args, []))
  146. | Dim (name, _) -> name
  147. | ArrayScalar node
  148. | ArrayInit (node, _)
  149. | Arg node -> str node
  150. | VarDecs nodes
  151. | LocalFuns nodes -> concat "\n" nodes
  152. | DummyNode -> "<dummy>"
  153. (* ctype list -> string *)
  154. let rec types2str = function
  155. | [] -> ""
  156. | [ctype] -> type2str ctype
  157. | ctype :: tail -> type2str ctype ^ " or " ^ (types2str tail)