|
@@ -2,10 +2,8 @@ open Ast
|
|
|
|
|
|
|
|
let tab = " "
|
|
let tab = " "
|
|
|
|
|
|
|
|
-(* int -> string list -> string list *)
|
|
|
|
|
-let indent (lines : string list) =
|
|
|
|
|
- let prepend_tab line = tab ^ line in
|
|
|
|
|
- List.map prepend_tab lines
|
|
|
|
|
|
|
+(* string -> string *)
|
|
|
|
|
+let indent = Str.global_replace (Str.regexp "^\\(.\\)") (tab ^ "\\1")
|
|
|
|
|
|
|
|
(* monop -> string *)
|
|
(* monop -> string *)
|
|
|
let monop2str = function
|
|
let monop2str = function
|
|
@@ -37,111 +35,80 @@ let rec type2str = function
|
|
|
| ArrayDec (t, dims) -> (type2str t) ^ "[" ^ (String.concat ", " dims) ^ "]"
|
|
| ArrayDec (t, dims) -> (type2str t) ^ "[" ^ (String.concat ", " dims) ^ "]"
|
|
|
| ArrayDef (t, dims) -> (type2str t) ^ "[" ^ (String.concat ", " (List.map node2str dims)) ^ "]"
|
|
| ArrayDef (t, dims) -> (type2str t) ^ "[" ^ (String.concat ", " (List.map node2str dims)) ^ "]"
|
|
|
|
|
|
|
|
-(* decl -> string list *)
|
|
|
|
|
-and node2lines node =
|
|
|
|
|
- let all_str = List.map node2str in
|
|
|
|
|
- let all_lines = List.map node2lines in
|
|
|
|
|
|
|
+(* node -> string *)
|
|
|
|
|
+and node2str node =
|
|
|
|
|
+ let str = node2str in
|
|
|
|
|
+ let all_str = List.map str in
|
|
|
|
|
+ let concat sep nodes = String.concat sep (all_str nodes) in
|
|
|
match node with
|
|
match node with
|
|
|
- (* Decls *)
|
|
|
|
|
|
|
+
|
|
|
|
|
+ (* Global *)
|
|
|
|
|
+ | Program (decls, _) ->
|
|
|
|
|
+ concat "\n\n" decls
|
|
|
|
|
+ | Param (param_type, name, _) ->
|
|
|
|
|
+ (type2str param_type) ^ " " ^ name
|
|
|
| FunDec (ret_type, name, params, _) ->
|
|
| FunDec (ret_type, name, params, _) ->
|
|
|
- let params = String.concat ", " (all_str params) in
|
|
|
|
|
- ["extern " ^ type2str ret_type ^ " " ^ name ^ "(" ^ params ^ ");"]
|
|
|
|
|
|
|
+ let params = concat ", " params in
|
|
|
|
|
+ "extern " ^ type2str ret_type ^ " " ^ name ^ "(" ^ params ^ ");"
|
|
|
| FunDef (export, ret_type, name, params, body, _) ->
|
|
| FunDef (export, ret_type, name, params, body, _) ->
|
|
|
let export = if export then "export " else "" in
|
|
let export = if export then "export " else "" in
|
|
|
- let params = String.concat ", " (all_str params) in
|
|
|
|
|
- let header = type2str ret_type ^ " " ^ name ^ "(" ^ params ^ ")" in
|
|
|
|
|
- let body = indent (List.concat (all_lines body)) in
|
|
|
|
|
- [export ^ header ^ " {"] @
|
|
|
|
|
- body @
|
|
|
|
|
- ["}"]
|
|
|
|
|
|
|
+ let params = "(" ^ (concat "," params) ^ ")" in
|
|
|
|
|
+ export ^ type2str ret_type ^ " " ^ name ^ params ^ " " ^ str body
|
|
|
| GlobalDec (var_type, name, _) ->
|
|
| GlobalDec (var_type, name, _) ->
|
|
|
- ["extern " ^ type2str var_type ^ " " ^ name ^ ";"]
|
|
|
|
|
|
|
+ "extern " ^ type2str var_type ^ " " ^ name ^ ";"
|
|
|
| GlobalDef (export, ret_type, name, init, _) ->
|
|
| GlobalDef (export, ret_type, name, init, _) ->
|
|
|
let export = if export then "export " else "" in
|
|
let export = if export then "export " else "" in
|
|
|
let init = match init with
|
|
let init = match init with
|
|
|
- | Some value -> " = " ^ node2str value
|
|
|
|
|
|
|
+ | Some value -> " = " ^ str value
|
|
|
| None -> ""
|
|
| None -> ""
|
|
|
in
|
|
in
|
|
|
- [export ^ (type2str ret_type) ^ " " ^ name ^ init ^ ";"]
|
|
|
|
|
|
|
+ export ^ (type2str ret_type) ^ " " ^ name ^ init ^ ";"
|
|
|
|
|
|
|
|
(* Statements *)
|
|
(* Statements *)
|
|
|
| VarDec (var_type, name, None, _) ->
|
|
| VarDec (var_type, name, None, _) ->
|
|
|
- [(type2str var_type) ^ " " ^ name ^ ";"]
|
|
|
|
|
|
|
+ (type2str var_type) ^ " " ^ name ^ ";"
|
|
|
| VarDec (var_type, name, Some init, _) ->
|
|
| VarDec (var_type, name, Some init, _) ->
|
|
|
- [(type2str var_type) ^ " " ^ name ^ " = " ^ (node2str init) ^ ";"]
|
|
|
|
|
|
|
+ (type2str var_type) ^ " " ^ name ^ " = " ^ (str init) ^ ";"
|
|
|
| Assign (name, value, _) ->
|
|
| Assign (name, value, _) ->
|
|
|
- [name ^ " = " ^ (node2str value) ^ ";"]
|
|
|
|
|
|
|
+ name ^ " = " ^ (str value) ^ ";"
|
|
|
| Expr expr ->
|
|
| Expr expr ->
|
|
|
- [node2str expr ^ ";"]
|
|
|
|
|
|
|
+ str expr ^ ";"
|
|
|
| Return (value, _) ->
|
|
| Return (value, _) ->
|
|
|
- ["return " ^ (node2str value) ^ ";"]
|
|
|
|
|
|
|
+ "return " ^ (str value) ^ ";"
|
|
|
| If (cond, body, _) ->
|
|
| If (cond, body, _) ->
|
|
|
- let body = indent (List.concat (all_lines body)) in
|
|
|
|
|
- ["if (" ^ node2str cond ^ ") {"] @
|
|
|
|
|
- body @
|
|
|
|
|
- ["}"]
|
|
|
|
|
|
|
+ "if (" ^ str cond ^ ") " ^ str body
|
|
|
| IfElse (cond, true_body, false_body, _) ->
|
|
| IfElse (cond, true_body, false_body, _) ->
|
|
|
- let true_body = indent (List.concat (all_lines true_body)) in
|
|
|
|
|
- let false_body = indent (List.concat (all_lines false_body)) in
|
|
|
|
|
- ["if (" ^ node2str cond ^ ") {"] @
|
|
|
|
|
- true_body @
|
|
|
|
|
- ["} else {"] @
|
|
|
|
|
- false_body @
|
|
|
|
|
- ["}"]
|
|
|
|
|
|
|
+ "if (" ^ str cond ^ ") " ^ str true_body ^ " else " ^ str false_body
|
|
|
| While (cond, body, _) ->
|
|
| While (cond, body, _) ->
|
|
|
- let body = indent (List.concat (all_lines body)) in
|
|
|
|
|
- ["while (" ^ node2str cond ^ ") {"] @
|
|
|
|
|
- body @
|
|
|
|
|
- ["}"]
|
|
|
|
|
|
|
+ "while (" ^ str cond ^ ") " ^ str body
|
|
|
| DoWhile (cond, body, _) ->
|
|
| DoWhile (cond, body, _) ->
|
|
|
- let body = indent (List.concat (all_lines body)) in
|
|
|
|
|
- ["do {"] @
|
|
|
|
|
- body @
|
|
|
|
|
- ["} while (" ^ node2str cond ^ ");"]
|
|
|
|
|
|
|
+ "do " ^ str body ^ " while (" ^ str cond ^ ");"
|
|
|
| For (counter, start, stop, step, body, _) ->
|
|
| For (counter, start, stop, step, body, _) ->
|
|
|
let step = match step with
|
|
let step = match step with
|
|
|
| IntConst (1, _) -> ""
|
|
| IntConst (1, _) -> ""
|
|
|
- | value -> ", " ^ node2str value
|
|
|
|
|
|
|
+ | value -> ", " ^ str value
|
|
|
in
|
|
in
|
|
|
- let range = node2str start ^ ", " ^ node2str stop ^ step in
|
|
|
|
|
- let body = indent (List.concat (all_lines body)) in
|
|
|
|
|
- ["for (int " ^ counter ^ " = " ^ range ^ ") {"] @
|
|
|
|
|
- body @
|
|
|
|
|
- ["}"]
|
|
|
|
|
|
|
+ let range = str start ^ ", " ^ str stop ^ step in
|
|
|
|
|
+ "for (int " ^ counter ^ " = " ^ range ^ ") " ^ str body
|
|
|
| Allocate (name, dims, _) ->
|
|
| Allocate (name, dims, _) ->
|
|
|
- [name ^ " = __allocate(" ^ String.concat ", " (List.map node2str dims) ^ ");"]
|
|
|
|
|
-
|
|
|
|
|
- | Statements (stats, _) -> List.concat (List.map node2lines stats)
|
|
|
|
|
-
|
|
|
|
|
- (* Catch-all, whould never happen *)
|
|
|
|
|
- | _ -> failwith "invalid node"
|
|
|
|
|
-
|
|
|
|
|
-(* node -> string *)
|
|
|
|
|
-and node2str node =
|
|
|
|
|
- let concat sep nodes = String.concat sep (List.map node2str nodes) in
|
|
|
|
|
- match node with
|
|
|
|
|
- (* Global *)
|
|
|
|
|
- | Program (decls, _) ->
|
|
|
|
|
- let decl2str decl = String.concat "\n" (node2lines decl) in
|
|
|
|
|
- String.concat "\n\n" (List.map decl2str decls)
|
|
|
|
|
- | Param (param_type, name, _) -> (type2str param_type) ^ " " ^ name
|
|
|
|
|
|
|
+ name ^ " = __allocate(" ^ concat ", " dims ^ ");"
|
|
|
|
|
+ | Block body -> "{\n" ^ indent (concat "\n" body) ^ "\n}"
|
|
|
|
|
|
|
|
(* Expressions *)
|
|
(* Expressions *)
|
|
|
| BoolConst (b, _) -> string_of_bool b
|
|
| BoolConst (b, _) -> string_of_bool b
|
|
|
| IntConst (i, _) -> string_of_int i
|
|
| IntConst (i, _) -> string_of_int i
|
|
|
| FloatConst (f, _) -> string_of_float f
|
|
| FloatConst (f, _) -> string_of_float f
|
|
|
| ArrayConst (dims, _) -> "[" ^ concat ", " dims ^ "]"
|
|
| ArrayConst (dims, _) -> "[" ^ concat ", " dims ^ "]"
|
|
|
- | ArrayScalar (value, _) -> node2str value
|
|
|
|
|
|
|
+ | ArrayScalar (value, _) -> str value
|
|
|
| Var (v, _) -> v
|
|
| Var (v, _) -> v
|
|
|
- | Deref (name, dims, _) -> name ^ (node2str (ArrayConst (dims, noloc)))
|
|
|
|
|
- | Monop (op, opnd, _) -> monop2str op ^ node2str opnd
|
|
|
|
|
|
|
+ | VarUse (var, _, _) -> str var
|
|
|
|
|
+ | Deref (name, dims, _) -> name ^ (str (ArrayConst (dims, noloc)))
|
|
|
|
|
+ | Monop (op, opnd, _) -> monop2str op ^ str opnd
|
|
|
| Binop (op, left, right, _) ->
|
|
| Binop (op, left, right, _) ->
|
|
|
- "(" ^ node2str left ^ binop2str op ^ node2str right ^ ")"
|
|
|
|
|
|
|
+ "(" ^ str left ^ binop2str op ^ str right ^ ")"
|
|
|
| Cond (cond, t, f, _) ->
|
|
| Cond (cond, t, f, _) ->
|
|
|
- (node2str cond) ^ " ? " ^ node2str t ^ " : " ^ node2str f
|
|
|
|
|
|
|
+ (str cond) ^ " ? " ^ str t ^ " : " ^ str f
|
|
|
| TypeCast (ctype, value, _) ->
|
|
| TypeCast (ctype, value, _) ->
|
|
|
- "(" ^ type2str ctype ^ ")" ^ node2str value
|
|
|
|
|
|
|
+ "(" ^ type2str ctype ^ ")" ^ str value
|
|
|
| FunCall (name, args, _) ->
|
|
| FunCall (name, args, _) ->
|
|
|
name ^ "(" ^ (concat ", " args) ^ ")"
|
|
name ^ "(" ^ (concat ", " args) ^ ")"
|
|
|
-
|
|
|
|
|
- | node -> String.concat "\n" (node2lines node)
|
|
|