summary refs log tree commit diff
path: root/source/xi_lib/ast_printer.ml
diff options
context:
space:
mode:
Diffstat (limited to 'source/xi_lib/ast_printer.ml')
-rw-r--r--source/xi_lib/ast_printer.ml271
1 files changed, 271 insertions, 0 deletions
diff --git a/source/xi_lib/ast_printer.ml b/source/xi_lib/ast_printer.ml
new file mode 100644
index 0000000..67b4dd5
--- /dev/null
+++ b/source/xi_lib/ast_printer.ml
@@ -0,0 +1,271 @@
+open Ast
+
+
+let string_of_binop = function
+  | BINOP_And -> "&"
+  | BINOP_Or -> "|"
+  | BINOP_Add -> "+"
+  | BINOP_Sub -> "-"
+  | BINOP_Mult -> "*"
+  | BINOP_Div -> "/"
+  | BINOP_Rem -> "%"
+
+let string_of_relop = function
+  | RELOP_Eq -> "=="
+  | RELOP_Ne -> "!="
+  | RELOP_Lt -> "<"
+  | RELOP_Gt -> ">"
+  | RELOP_Le -> "<="
+  | RELOP_Ge -> ">="
+
+let string_of_unop = function
+  | UNOP_Not -> "!"
+  | UNOP_Neg -> "-"
+
+let indent x = "  " ^ x
+
+let indentxs = List.map indent 
+
+let rec show_expression = function
+  | EXPR_Id {id; _} ->
+    string_of_identifier id
+
+
+  | EXPR_Int {value; _} ->
+    Int32.to_string value
+
+  | EXPR_Char {value; _} ->
+    Format.sprintf "%c" value
+ 
+  | EXPR_String {value; _} ->
+    value
+  
+  | EXPR_Bool {value; _} ->
+    string_of_bool value
+
+  | EXPR_Binop {op; lhs; rhs; _} ->
+    String.concat ""
+      [ "("
+      ; show_expression lhs
+      ; " "
+      ; string_of_binop op
+      ; " "
+      ; show_expression rhs
+      ; ")"
+      ]
+
+  | EXPR_Relation {op; lhs; rhs; _} ->
+    String.concat ""
+      [ "("
+      ; show_expression lhs
+      ; " "
+      ; string_of_relop op
+      ; " "
+      ; show_expression rhs
+      ; ")"
+      ]
+  
+  | EXPR_Length {arg; _} ->
+    String.concat ""
+      [ "length("
+      ; show_expression arg
+      ; ")"
+      ]
+
+  | EXPR_Unop {op; sub; _} ->
+    String.concat ""
+      [ string_of_unop op
+      ; show_expression sub
+      ]
+
+  | EXPR_Call call ->
+    show_call call
+
+  | EXPR_Index {expr; index; _} ->
+    String.concat ""
+      [ show_expression expr
+      ; "["
+      ; show_expression index
+      ; "]"
+      ]
+
+  | EXPR_Struct {elements; _} ->
+    String.concat ""
+      [ "{"
+      ; String.concat ", " (List.map show_expression elements)
+      ; "}"
+      ]
+
+and show_call (Call {callee; arguments; _}) =
+  String.concat ""
+    [ string_of_identifier callee
+    ; "("
+    ; String.concat ", " (List.map show_expression arguments)
+    ; ")"
+    ]
+
+let rec show_type_expression = function
+  | TEXPR_Int _ ->
+    "int"
+
+  | TEXPR_Bool _ ->
+    "bool"
+
+  | TEXPR_Array {sub;dim;_} ->
+    String.concat ""
+       [ show_type_expression sub
+       ; "["
+       ; (match dim with | None -> "" | Some e -> show_expression e)
+       ; "]"
+       ]
+
+let show_var_declaration (VarDecl {id; tp; _}) =
+  String.concat ""
+    [ string_of_identifier id
+    ; ":"
+    ; show_type_expression tp
+    ]
+
+let show_var_declaration_opt = function
+  | Some v -> show_var_declaration v
+  | None -> "_"
+
+let show_lvalue = function
+  | LVALUE_Id {id; _} ->
+    string_of_identifier id
+  | LVALUE_Index {sub; index; _} ->
+    String.concat ""
+      [ show_expression sub
+      ; "["
+      ; show_expression index
+      ; "]"
+      ]
+
+
+let rec showxs_statement = function
+  | STMT_Call call ->
+    [ show_call call
+    ]
+  
+  | STMT_VarDecl {var; init=None} ->
+    [ show_var_declaration var
+    ]
+
+  | STMT_VarDecl {var; init=Some v} ->
+    [ String.concat " " 
+      [ show_var_declaration var
+      ; "="
+      ; show_expression v
+      ]
+    ]
+
+  | STMT_Return {values; _} ->
+    [ String.concat " " 
+      [ "return"
+      ; String.concat ", " (List.map show_expression values)
+      ]
+    ]
+  
+  | STMT_Block blok ->
+    showxs_block blok
+
+  | STMT_While {cond; body; _} ->
+    List.concat
+      [ [ String.concat " "
+        [ "while"
+        ; "("
+        ; show_expression cond
+        ; ")"
+        ] ]
+      ; showxs_statement_as_block body
+      ]
+
+  | STMT_If {cond; then_branch; else_branch=None; _} ->
+    List.concat
+      [ [ String.concat " "
+        [ "if"
+        ; "("
+        ; show_expression cond
+        ; ")"
+        ] ]
+      ; showxs_statement_as_block then_branch
+      ]
+
+  | STMT_If {cond; then_branch; else_branch=Some else_branch; _} ->
+    List.concat
+      [ [ String.concat " "
+        [ "if"
+        ; "("
+        ; show_expression cond
+        ; ")"
+        ] ]
+      ; showxs_statement_as_block then_branch
+      ; [ "else" ]
+      ; showxs_statement_as_block else_branch
+      ]
+    | STMT_Assign {lhs; rhs; _} ->
+      [ String.concat " "
+        [ show_lvalue lhs
+        ; "="
+        ; show_expression rhs
+        ]
+      ]
+    | STMT_MultiVarDecl {vars; init; _} ->
+      [ String.concat " "
+        [ String.concat ", " (List.map show_var_declaration_opt vars)
+        ; "="
+        ; show_call init
+        ]
+      ]
+
+and showxs_block = function
+  | STMTBlock {body; _} ->
+    List.concat
+    [ ["{"]
+    ; indentxs @@ List.concat @@ List.map showxs_statement body
+    ; ["}"]
+    ]
+
+and showxs_statement_as_block = function
+  | STMT_Block blok ->
+    showxs_block blok
+  |  s ->
+    List.concat
+    [ ["{"]
+    ; indentxs @@ showxs_statement s
+    ; ["}"]
+    ]
+
+let show_formal_parameters params =
+  String.concat ", " @@ List.map show_var_declaration params
+
+
+let show_return_types = function
+  | [] ->
+    ""
+  | return_types ->
+    ": " ^ String.concat ", " (List.map show_type_expression return_types)
+
+let showxs_global_declaration = function
+  | GDECL_Function {id; body; formal_parameters; return_types; _} ->
+    List.concat
+      [ [ String.concat ""
+        [ string_of_identifier id
+        ; "("
+        ; show_formal_parameters formal_parameters
+        ; ")"
+        ; show_return_types return_types
+        ] ]
+      ; match body with
+        | Some body -> showxs_block body
+        | None -> []
+      ]
+
+let showxs_module_definition (ModuleDefinition {global_declarations; _}) = 
+  let f x =
+    showxs_global_declaration x @ [""]
+  in
+  List.flatten (List.map f global_declarations)
+
+let show_module_definition m =
+  String.concat "\n" @@ showxs_module_definition m
\ No newline at end of file