From b798ac29c37299b2f761243ae92ab8f7c4c4d7f1 Mon Sep 17 00:00:00 2001 From: Paweł Dybiec Date: Tue, 30 Oct 2018 15:32:56 +0100 Subject: Initial commit --- source/xi_lib/ast_rawprinter.ml | 313 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 313 insertions(+) create mode 100644 source/xi_lib/ast_rawprinter.ml (limited to 'source/xi_lib/ast_rawprinter.ml') diff --git a/source/xi_lib/ast_rawprinter.ml b/source/xi_lib/ast_rawprinter.ml new file mode 100644 index 0000000..0c6494e --- /dev/null +++ b/source/xi_lib/ast_rawprinter.ml @@ -0,0 +1,313 @@ +open Ast + + +let string_of_binop = function + | BINOP_And -> "BINOP_And" + | BINOP_Or -> "BINOP_Or" + | BINOP_Add -> "BINOP_Add" + | BINOP_Sub -> "BINOP_Sub" + | BINOP_Mult -> "BINOP_Mult" + | BINOP_Div -> "BINOP_Div" + | BINOP_Rem -> "BINOP_Rem" + +let string_of_relop = function + | RELOP_Eq -> "RELOP_Eq" + | RELOP_Ne -> "RELOP_Ne" + | RELOP_Lt -> "RELOP_Lt" + | RELOP_Gt -> "RELOP_Gt" + | RELOP_Le -> "RELOP_Le" + | RELOP_Ge -> "RELOP_Ge" + +let string_of_unop = function + | UNOP_Not -> "UNOP_Not" + | UNOP_Neg -> "UNOP_Neg" + +let indent x = " " ^ x +let indentfmt fmt = + let cont = Format.sprintf " %s" in + Format.ksprintf cont fmt + +let indentxs = List.map indent + +type p = + | P_String of string + | P_Sequence of p list + | P_List of p list + | P_Dict of string * (string * p) list + +type r = + | R_String of string + | R_Indent of r + | R_Break + | R_Tab + | R_Group of r list + +let render_r = function + | R_String s -> s + | R_Tab -> " " + | R_Break -> "\n" + | R_Group _ -> failwith "R_Group should be eliminated" + | R_Indent _ -> failwith "R_Indent should be eliminated" + +let rec insert_tabs tabs = function + | R_Indent r -> + insert_tabs (R_Tab::tabs) r + | R_Break -> + R_Group [R_Break; R_Group tabs] + | R_Group rs -> + R_Group (List.map (insert_tabs tabs) rs) + | r -> + r + +let rec flatten = function + | R_Indent _ -> failwith "R_Indent should be eliminated" + | R_Group xs -> List.concat @@ List.map flatten xs + | r -> [r] + +let render_r r = + String.concat "" @@ List.map render_r @@ flatten @@ insert_tabs [] r + +let rec render_p = function + | P_String s -> + R_String s + | P_List xs -> + let rec f acc = function + | [] -> + R_Group (List.rev acc) + + | x::xs -> + let entry = R_Group [render_p x; R_String ";"; R_Break] in + f (entry::acc) xs + in + R_Group + [ R_String "[" + ; R_Indent (R_Group [R_Break; f [] xs]) + ; R_String "]" + ] + + | P_Dict (kind, items) -> + let rec f acc = function + | [] -> + R_Group (List.rev acc) + | (k,v)::xs -> + let entry = R_Group [R_String k; R_String " = "; R_Indent (render_p v); R_String ";"; R_Break] in + f (entry::acc) xs + in + R_Group + [ R_String kind + ; R_String " " + ; R_String "{" + ; R_Indent (R_Group [R_Break; f [] items]) + ; R_String "}" + ] + + | P_Sequence xs -> + R_Group (List.map render_p xs) + +let p_dict k items = P_Dict (k,items) + +let p_identifier id = P_String (Format.sprintf "\"%s\"" @@ string_of_identifier id) +let p_string id = P_String (Format.sprintf "\"%s\"" id) +let p_location loc = P_String (string_of_location loc) +let p_node_tag tag = P_String (string_of_node_tag tag) +let p_i32 i = P_String (Int32.to_string i) +let p_char c = P_String (Format.sprintf "'%c'" c) +let p_bool b = P_String (string_of_bool b) + +let p_opt f = function + | None -> P_String "None" + | Some x -> P_Sequence [P_String "Some "; f x] + + +let rec p_expression = function + | EXPR_Id {loc; tag; id} -> p_dict "EXPR_Id" + [ "loc", p_location loc + ; "tag", p_node_tag tag + ; "id", p_identifier id + ] + + | EXPR_Int {tag; loc; value} -> p_dict "EXPR_Int" + [ "loc", p_location loc + ; "tag", p_node_tag tag + ; "value", p_i32 value + ] + + | EXPR_Char {tag; loc; value} -> p_dict "EXPR_Char" + [ "loc", p_location loc + ; "tag", p_node_tag tag + ; "value", p_char value + ] + + | EXPR_String {tag; loc; value} -> p_dict "EXPR_String" + [ "loc", p_location loc + ; "tag", p_node_tag tag + ; "value", p_string value + ] + + | EXPR_Bool {tag; loc; value} -> p_dict "EXPR_Bool" + [ "loc", p_location loc + ; "tag", p_node_tag tag + ; "value", p_bool value + ] + + | EXPR_Relation {tag; loc; op; lhs; rhs} -> p_dict "EXPR_Relation" + [ "loc", p_location loc + ; "tag", p_node_tag tag + ; "op", P_String (string_of_relop op) + ; "lhs", p_expression lhs + ; "rhs", p_expression rhs + ] + + | EXPR_Binop {tag; loc; op; lhs; rhs} -> p_dict "EXPR_Binop" + [ "loc", p_location loc + ; "tag", p_node_tag tag + ; "op", P_String (string_of_binop op) + ; "lhs", p_expression lhs + ; "rhs", p_expression rhs + ] + + | EXPR_Unop {tag; loc; op; sub} -> p_dict "EXPR_Unop" + [ "loc", p_location loc + ; "tag", p_node_tag tag + ; "op", P_String (string_of_unop op) + ; "sub", p_expression sub + ] + + | EXPR_Length {tag; loc; arg} -> p_dict "EXPR_Length" + [ "loc", p_location loc + ; "tag", p_node_tag tag + ; "arg", p_expression arg + ] + + | EXPR_Index {tag; loc; expr; index} -> p_dict "EXPR_Length" + [ "loc", p_location loc + ; "tag", p_node_tag tag + ; "expr", p_expression expr + ; "index", p_expression index + ] + + | EXPR_Struct {tag; loc; elements} -> p_dict "EXPR_Struct" + [ "loc", p_location loc + ; "tag", p_node_tag tag + ; "elements", P_List (List.map p_expression elements) + ] + + | EXPR_Call call -> P_Sequence + [ P_String "EXPR_Call " + ; p_call call + ] + +and p_call = function + | Call {tag; loc; callee; arguments} -> p_dict "Call" + [ "loc", p_location loc + ; "tag", p_node_tag tag + ; "callee", p_identifier callee + ; "arguments", P_List (List.map p_expression arguments) + ] + +let rec p_type_expression = function + | TEXPR_Int {loc} -> p_dict "TEXPR_Int" + [ "loc", p_location loc + ] + + | TEXPR_Bool {loc} -> p_dict "TEXPR_Bool" + [ "loc", p_location loc + ] + + | TEXPR_Array {loc;sub;dim} -> p_dict "TPEXPR_Array" + [ "loc", p_location loc + ; "sub", p_type_expression sub + ; "dim", p_opt p_expression dim + ] + +let p_lvalue = function + | LVALUE_Id {loc; id} -> p_dict "LVALUE_Id" + [ "loc", p_location loc + ; "id", p_identifier id + ] + | LVALUE_Index {loc; sub; index} -> p_dict "LVALUE_Index" + [ "loc", p_location loc + ; "sub", p_expression sub + ; "index", p_expression index + ] + +let p_var_declaration = function + | VarDecl {loc;id;tp} -> p_dict "VarDecl" + [ "loc", p_location loc + ; "id", p_identifier id + ; "tp", p_type_expression tp + ] + +let rec p_statement = function + | STMT_Call call -> P_Sequence + [ P_String "STMT_Call " + ; p_call call + ] + + | STMT_Assign {loc; lhs; rhs} -> p_dict "STMT_Assign" + [ "loc", p_location loc + ; "lhs", p_lvalue lhs + ; "rhs", p_expression rhs + ] + + | STMT_VarDecl {var; init} -> p_dict "STMT_VarDecl" + [ "var", p_var_declaration var + ; "init", p_opt p_expression init + ] + + | STMT_If {loc; cond; then_branch; else_branch} -> p_dict "STMT_If" + [ "loc", p_location loc + ; "cond", p_expression cond + ; "then_branch", p_statement then_branch + ; "else_branch", p_opt p_statement else_branch + ] + + | STMT_While {loc; cond; body} -> p_dict "STMT_While" + [ "loc", p_location loc + ; "cond", p_expression cond + ; "body", p_statement body + ] + + | STMT_Block block -> P_Sequence + [ P_String "STMT_Block " + ; p_statement_block block + ] + + | STMT_MultiVarDecl {loc; vars; init} -> p_dict "STMT_MultiVarDecl" + [ "loc", p_location loc + ; "vars", P_List (List.map (p_opt p_var_declaration) vars) + ; "init", p_call init + ] + + | STMT_Return {loc; values} -> p_dict "STMT_Return" + [ "loc", p_location loc + ; "values", P_List (List.map p_expression values) + ] + +and p_statement_block = function + | STMTBlock {loc; body} -> p_dict "STMTBlock" + [ "loc", p_location loc + ; "body", P_List (List.map p_statement body) + ] + + + +let p_global_declaration = function + | GDECL_Function {loc;id;formal_parameters; return_types; body} -> + p_dict "GDECL_Function" + [ "loc", p_location loc + ; "id", p_identifier id + ; "formal_parameters", P_List (List.map p_var_declaration formal_parameters) + ; "return_types", P_List (List.map p_type_expression return_types) + ; "body", p_opt p_statement_block body + ] + +let p_module_definition = function + | ModuleDefinition {global_declarations} -> P_Sequence + [ P_String "ModuleDefinition " + ; P_List (List.map p_global_declaration global_declarations) + ] + +let show_module_definition mdef = + let p = p_module_definition mdef in + render_r @@ render_p p -- cgit 1.4.1