diff options
Diffstat (limited to 'source/xi_lib/ast_printer.ml')
-rw-r--r-- | source/xi_lib/ast_printer.ml | 271 |
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 |