stringify.ml 5.5 KB

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