stringify.ml 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. open Ast
  2. let tab = " "
  3. (* string -> string *)
  4. let indent = Str.global_replace (Str.regexp "^\\(.\\)") (tab ^ "\\1")
  5. (* monop -> string *)
  6. let monop2str = function
  7. | Neg -> "-"
  8. | Not -> "!"
  9. (* binop -> string *)
  10. let binop2str = function
  11. | Add -> " + "
  12. | Sub -> " - "
  13. | Mul -> " * "
  14. | Div -> " / "
  15. | Mod -> " % "
  16. | Eq -> " == "
  17. | Ne -> " != "
  18. | Lt -> " < "
  19. | Le -> " <= "
  20. | Gt -> " > "
  21. | Ge -> " >= "
  22. | And -> " && "
  23. | Or -> " || "
  24. (* ctype -> string *)
  25. let rec type2str = function
  26. | Void -> "void"
  27. | Bool -> "bool"
  28. | Int -> "int"
  29. | Float -> "float"
  30. | ArrayDec (t, dims) -> (type2str t) ^ "[" ^ (String.concat ", " dims) ^ "]"
  31. | ArrayDef (t, dims) -> (type2str t) ^ "[" ^ (String.concat ", " (List.map node2str dims)) ^ "]"
  32. (* node -> string *)
  33. and node2str node =
  34. let str = node2str in
  35. let all_str = List.map str in
  36. let concat sep nodes = String.concat sep (all_str nodes) in
  37. match node with
  38. (* Global *)
  39. | Program (decls, _) ->
  40. concat "\n\n" decls
  41. | Param (param_type, name, _) ->
  42. (type2str param_type) ^ " " ^ name
  43. | FunDec (ret_type, name, params, _) ->
  44. let params = concat ", " params in
  45. "extern " ^ type2str ret_type ^ " " ^ name ^ "(" ^ params ^ ");"
  46. | FunDef (export, ret_type, name, params, body, _) ->
  47. let export = if export then "export " else "" in
  48. let params = "(" ^ (concat "," params) ^ ")" in
  49. export ^ type2str ret_type ^ " " ^ name ^ params ^ " " ^ str body
  50. | GlobalDec (var_type, name, _) ->
  51. "extern " ^ type2str var_type ^ " " ^ name ^ ";"
  52. | GlobalDef (export, ret_type, name, init, _) ->
  53. let export = if export then "export " else "" in
  54. let init = match init with
  55. | Some value -> " = " ^ str value
  56. | None -> ""
  57. in
  58. export ^ (type2str ret_type) ^ " " ^ name ^ init ^ ";"
  59. (* Statements *)
  60. | VarDec (var_type, name, None, _) ->
  61. (type2str var_type) ^ " " ^ name ^ ";"
  62. | VarDec (var_type, name, Some init, _) ->
  63. (type2str var_type) ^ " " ^ name ^ " = " ^ (str init) ^ ";"
  64. | Assign (name, value, _) ->
  65. name ^ " = " ^ (str value) ^ ";"
  66. | Expr expr ->
  67. str expr ^ ";"
  68. | Return (value, _) ->
  69. "return " ^ (str value) ^ ";"
  70. | If (cond, body, _) ->
  71. "if (" ^ str cond ^ ") " ^ str body
  72. | IfElse (cond, true_body, false_body, _) ->
  73. "if (" ^ str cond ^ ") " ^ str true_body ^ " else " ^ str false_body
  74. | While (cond, body, _) ->
  75. "while (" ^ str cond ^ ") " ^ str body
  76. | DoWhile (cond, body, _) ->
  77. "do " ^ str body ^ " while (" ^ str cond ^ ");"
  78. | For (counter, start, stop, step, body, _) ->
  79. let step = match step with
  80. | IntConst (1, _) -> ""
  81. | value -> ", " ^ str value
  82. in
  83. let range = str start ^ ", " ^ str stop ^ step in
  84. "for (int " ^ counter ^ " = " ^ range ^ ") " ^ str body
  85. | Allocate (name, dims, _) ->
  86. name ^ " = __allocate(" ^ concat ", " dims ^ ");"
  87. | Block body -> "{\n" ^ indent (concat "\n" body) ^ "\n}"
  88. (* Expressions *)
  89. | BoolConst (b, _) -> string_of_bool b
  90. | IntConst (i, _) -> string_of_int i
  91. | FloatConst (f, _) -> string_of_float f
  92. | ArrayConst (dims, _) -> "[" ^ concat ", " dims ^ "]"
  93. | ArrayScalar (value, _) -> str value
  94. | Var (v, _) -> v
  95. | VarUse (var, _, _) -> str var
  96. | Deref (name, dims, _) -> name ^ (str (ArrayConst (dims, noloc)))
  97. | Monop (op, opnd, _) -> monop2str op ^ str opnd
  98. | Binop (op, left, right, _) ->
  99. "(" ^ str left ^ binop2str op ^ str right ^ ")"
  100. | Cond (cond, t, f, _) ->
  101. (str cond) ^ " ? " ^ str t ^ " : " ^ str f
  102. | TypeCast (ctype, value, _) ->
  103. "(" ^ type2str ctype ^ ")" ^ str value
  104. | FunCall (name, args, _) ->
  105. name ^ "(" ^ (concat ", " args) ^ ")"