Source

Opifex / src / Language / While / While_PrettyPrinter.ml

(*
 * Opifex
 *
 * Copyrights(C) 2012 by Pawel Wieczorek <wieczyk at gmail>
 *)

open While_AST
open Formatter
open Batteries
open Formatter

let rec show_program = function
    | PROGRAM decls ->
        let show_declaration decls = function
            | DECL_Procedure (ident, command) ->
                [ psp_keyword "procedure"
                ; psp_identifier ident
                ; psp_word "()"
                ; psp_break
                ; psp_syntax "{"
                ; psp_break
                ; psp_indent 0 (show_command command)
                ; psp_syntax "}"
                ; psp_break
                ]

        in List.fold_left show_declaration [] decls

and show_command = function
    | CMD_Skip ->
        [ psp_keyword "skip"
        ; psp_syntax ";"
        ]

    | CMD_Assign (variable, arithmetic_expression) ->
        [ psp_variable variable
        ; psp_operator ":="
        ; psp_nested 0 (show_arithmetic_expression arithmetic_expression)
        ; psp_syntax ";"
        ; psp_break
        ]

    | CMD_Compose (first_command, second_command) ->
        [ psp_nested 0 (show_command first_command)
        ; psp_nested 0 (show_command second_command)
        ]

    | CMD_If (condition_expression, then_command, CMD_Skip ) ->
        [ psp_keyword "if"
        ; psp_syntax "("
        ; psp_nested 0 (show_boolean_expression condition_expression)
        ; psp_syntax ")"
        ; psp_syntax "{"
        ; psp_indent 0 (show_command then_command)
        ; psp_syntax "}"
        ; psp_break
        ]

    | CMD_If (condition_expression, then_command, else_command) ->
        [ psp_keyword "if"
        ; psp_syntax "("
        ; psp_nested 0 (show_boolean_expression condition_expression)
        ; psp_syntax ")"
        ; psp_syntax "{"
        ; psp_indent 0 (show_command then_command)
        ; psp_syntax "}"
        ; psp_keyword "else"
        ; psp_syntax "{"
        ; psp_indent 0 (show_command else_command)
        ; psp_syntax "}"
        ; psp_break
        ]

    | CMD_While (condition_expression, body_command) ->
        [ psp_keyword "while"
        ; psp_syntax "("
        ; psp_nested 0 (show_boolean_expression condition_expression)
        ; psp_syntax ")"
        ; psp_syntax "{"
        ; psp_indent 0 (show_command body_command)
        ; psp_syntax "}"
        ; psp_break
        ]

    | CMD_Read variable ->
        [ psp_keyword "read"
        ; psp_variable variable
        ; psp_syntax ";"
        ; psp_break
        ]

    | CMD_Write variable ->
        [ psp_keyword "write"
        ; psp_variable variable
        ; psp_syntax ";"
        ; psp_break
        ]

    | CMD_Abort ->
        [ psp_keyword "abort"
        ; psp_syntax ";"
        ; psp_break
        ]

    | CMD_Throw exception_identifier ->
        [ psp_keyword "throw"
        ; psp_label (string_of_identifier exception_identifier)
        ; psp_syntax ";"
        ]

    | CMD_Try (try_command, catched_exception, catch_command) ->
        [ psp_keyword "try"
        ; psp_syntax "{"
        ; psp_indent 0 (show_command try_command)
        ; psp_syntax "}"
        ; psp_keyword "catch"
        ; psp_label (string_of_identifier catched_exception)
        ; psp_syntax "{"
        ; psp_indent 0 (show_command catch_command)
        ; psp_syntax "}"
        ; psp_break;
        ]

and show_arithmetic_expression = function
    | AE_Constant constant ->
        [ psp_value_int constant
        ]

    | AE_Variable variable ->
        [ psp_variable variable
        ]

    | AE_BinaryOperator (arithmetic_operator, first_expression, second_expression) ->
        [ psp_nested 0 (show_arithmetic_expression first_expression)
        ; psp_arithmetic_binary_operator arithmetic_operator
        ; psp_nested 0 (show_arithmetic_expression second_expression)
        ]

    | AE_UnaryOperator (arithmetic_operator, expression) ->
        [ psp_arithmetic_unary_operator arithmetic_operator
        ; psp_nested 0 (show_arithmetic_expression expression)
        ]

and show_boolean_expression = function
    | BE_Constant constant ->
        [ psp_value_bool constant
        ]

    | BE_Variable variable ->
        [ psp_variable variable
        ]

    | BE_BinaryOperator (boolean_operator, first_expression, second_expression) ->
        [ psp_nested 0 (show_boolean_expression first_expression)
        ; psp_boolean_binary_operator boolean_operator
        ; psp_nested 0 (show_boolean_expression second_expression)
        ]

    | BE_UnaryOperator (boolean_operator, expression) ->
        [ psp_boolean_unary_operator boolean_operator
        ; psp_nested 0 (show_boolean_expression expression)
        ]

    | BE_ArithmeticBinaryOperator (boolean_operator, first_expression, second_expression) ->
        [ psp_nested 0 (show_arithmetic_expression first_expression)
        ; psp_boolean_arithmetic_binary_operator boolean_operator
        ; psp_nested 0 (show_arithmetic_expression second_expression)
        ]


let print_program = 
    Formatter.render_painter -| psp_nested 0 -| show_program