stringify.ml 4.4 KB

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