Commits

Paweł Wieczorek committed 66184fd

PrettyPrinting routine calls in WHILE

  • Participants
  • Parent commits b9a60d4
  • Branches very_simple_while_compiler

Comments (0)

Files changed (8)

File samples/WHILE/006_call.while

 procedure main()
 {
     read n;
-    fib();
-    write result;
+    try {
+        fib();
+    } catch EXIT {
+        write result;
+    }
     
 }

File source/Command/WHILE_Commands.ml

         Tempfile.with_temp_file None ".s"
         begin fun tmp_filename tmp_channel_out ->
             if configuration.verbose then
-                Printf.printf "- compiling %s to %s\n" tmp_filename output_filename ;
+                Printf.printf "- compiling %s to %s%!\n" tmp_filename output_filename ;
             dump_assembly_to_channel tmp_channel_out assembly;
             Pervasives.close_out tmp_channel_out;
             Lib.Toolchain.Gcc.compile_assembly output_filename tmp_filename;

File source/Compiler/WhileX86Compiler.ml

                 [ collect_all_variables_from_arithmetic_expression expr
                 ]
 
+        | AST.AE_Call (identifier, arguments) ->
+            Util.concat_map
+                collect_all_variables_from_arithmetic_expression arguments 
+
         | AST.AE_BinaryOperator (_, expr1, expr2) ->
             List.concat
                 [ collect_all_variables_from_arithmetic_expression expr1
         | AST.BE_Constant _ ->
             []
 
-        | AST.BE_Variable variable ->
-            [variable]
-
         | AST.BE_UnaryOperator (_, expr) ->
             List.concat
                 [ collect_all_variables_from_boolean_expression expr
 
 module AstCompiler = struct
 
-    (* Call routine with the standard C calling conversion on x86 *)
+    (*----------------------------------------------------------------------------------------------------------------
+     * Helpers for calling runtime symbols with correct calling vonersion
+     *)
+
     let call_routine_lv32_args loc32_routine lv32_args = 
         let passing_arguments_code =
             List.rev_map emit_PUSHL lv32_args
     let call_routine_symbol_lv32_args routine_symbol lv32_args = 
         call_routine_lv32_args (loc32_symbol routine_symbol) lv32_args
 
+    (*----------------------------------------------------------------------------------------------------------------
+     * Arithmetic and boolean operators
+     *)
 
     let compile_arithmetic_binary_operator reg1 reg2 aop =
         let compile emit rreg =
             | AST.AOP_MUL -> compile emit_IMULL reg2
             | _ -> Error.not_yet_implemented "arith bin op"
 
+    let compile_boolean_arithmetic_binary_operator else_branch reg1 reg2 bop =
+        let compile emit_jump =
+            let code = 
+                [ emit_CMP (lv32_reg reg1) (loc32_reg reg2)
+                ; emit_jump (loc32_symbol else_branch)
+                ]
+                in
+            code
+            in
+        match bop with
+            | AST.BOP_LT -> compile emit_JNL
+            | AST.BOP_LEQ -> compile emit_JNLE
+            | AST.BOP_EQ -> compile emit_JNE
+            | AST.BOP_NEQ -> compile emit_JE
+            | AST.BOP_GT -> compile emit_JNG
+            | AST.BOP_GEQ -> compile emit_JNGE
+
+
+    (*----------------------------------------------------------------------------------------------------------------
+     * Calling program routines and translating arithmetic expression.
+     *)
+
     let rec call_routine context loc32_routine arguments =
 
         let pass_argument arithmetic_expression =
                 ] in
             (code, EAX)
 
+        | AST.AE_Call (routine, arguments) ->
+            let routine_symbol = Context.lookup_for_symbol context routine in
+            call_routine_symbol context routine_symbol arguments
+
         | AST.AE_BinaryOperator (op, expr1, expr2) ->
             let (code1, reg1) = compile_arithmetic_expression context expr1 in
             let (code2, reg2) = compile_arithmetic_expression context expr2 in
 
             (code, reg3)
 
-    let compile_boolean_arithmetic_binary_operator else_branch reg1 reg2 bop =
-        let compile emit_jump =
-            let code = 
-                [ emit_CMP (lv32_reg reg1) (loc32_reg reg2)
-                ; emit_jump (loc32_symbol else_branch)
-                ]
-                in
-            code
-            in
-        match bop with
-            | AST.BOP_LT -> compile emit_JNL
-            | AST.BOP_LEQ -> compile emit_JNLE
-            | AST.BOP_EQ -> compile emit_JNE
-            | AST.BOP_NEQ -> compile emit_JE
-            | AST.BOP_GT -> compile emit_JNG
-            | AST.BOP_GEQ -> compile emit_JNGE
-
+    (*----------------------------------------------------------------------------------------------------------------
+     * Translating boolean expression.
+     *)
 
     let rec compile_boolean_expression context else_branch = function
         | AST.BE_Constant c  ->
 
             code
 
+    (*----------------------------------------------------------------------------------------------------------------
+     * Translating command.
+     *)
+
     let rec compile_command context = function
         | AST.CMD_Skip ->
             [
                     call_routine_symbol_lv32_args Runtime.get_exception_handler_symbol
                         [lv32_symboladdr exception_symbol
                         ]
-                        in
+                    in
 
                 List.concat
                     [ calling_code
                     [ lv32_symboladdr exception_symbol
                     ; lv32_symboladdr symbol_catch
                     ]
-                    in
+                in
 
             let try_catch =
                 [ emit_JMP (loc32_symbol symbol_after)
                 ; try_after
                 ]
 
+    (*----------------------------------------------------------------------------------------------------------------
+     * Translating program routine.
+     *)
+
     let compile_procedure_command context symbol command =
         let frame_leave_symbol = Context.new_frame_leave_symbol context in
         let compiled_command   = compile_command context command in
         let compiled_command = compile_procedure_command context symbol command in
         Shrinker.shrink compiled_command
 
+    (*----------------------------------------------------------------------------------------------------------------
+     * Compiling text section.
+     *)
+
     let compile_text_section context declarations =
         let compiled_declarations = List.map (compile_declaration context) declarations in
         let text_section          = Section (".text", compiled_declarations) in
         text_section
 
+    (*----------------------------------------------------------------------------------------------------------------
+     * Compiling data section.
+     *)
+
     let compile_data_section context declarations =
         let reserve_integer_for_symbol symbol = 
             [emit_memory_reservation symbol (Reservation_Int32 0l)]
 
         data_section
 
+    (*----------------------------------------------------------------------------------------------------------------
+     * Compiling assembly.
+     *)
+
     let compile_assembly context sections = 
         let symbols_to_export     = Context.get_all_symbols_from_table context in
         let header = 

File source/Lang/While/AST.ml

 
 type boolean_expression
     = BE_Constant of bool
-    | BE_Variable of variable
     | BE_BinaryOperator of boolean_binary_operator * boolean_expression * boolean_expression
     | BE_UnaryOperator of boolean_unary_operator * boolean_expression
     | BE_ArithmeticBinaryOperator of boolean_arithmetic_binary_operator * arithmetic_expression * arithmetic_expression

File source/Lang/While/Eval.ml

         | BE_Constant constant ->
             constant
 
-        | BE_Variable variable ->
-            store_get_boolean_value store variable 
-
         | BE_BinaryOperator (boolean_op, first_expression, second_expression) ->
             let     first_value = eval_boolean_expression store first_expression
             in let second_value = eval_boolean_expression store second_expression

File source/Lang/While/Parser.mly

     | FALSE
     { BE_Constant false }
 
-    | variable
-    { BE_Variable $1 }
-
     | RPARENT boolean_expression LPARENT
     { $2 }
     ;

File source/Lang/While/PrettyPrinter.ml

     | BE_Constant _ ->
         psp_max_priority
 
-    | BE_Variable _ ->
-        psp_max_priority
-
     | BE_BinaryOperator (operator, _, _) ->
         boolean_binary_operator_priority operator
 
 
 let rec paint_program = function
     | PROGRAM decls ->
-        let paint_declaration decls = function
-            | DECL_Procedure (ident, command) ->
-                [ psp_keyword "procedure"
-                ; psp_identifier ident
-                ; psp_word "()"
-                ; psp_break
-                ; psp_syntax "{"
-                ; psp_break
-                ; psp_indent (paint_command command)
-                ; psp_syntax "}"
-                ; psp_break
-                ]
+        psp_group (List.map paint_declaration decls)
 
-        in psp_group (List.fold_left paint_declaration [] decls)
+and paint_declaration = function
+    | DECL_Procedure (ident, command) -> psp_group
+        [ psp_keyword "procedure"
+        ; psp_identifier ident
+        ; psp_word "()"
+        ; psp_break
+        ; psp_syntax "{"
+        ; psp_break
+        ; psp_indent (paint_command command)
+        ; psp_syntax "}"
+        ; psp_break
+        ]
 
 and paint_command = function
     | CMD_Skip -> psp_group
         ; psp_break
         ]
 
+    | CMD_Return arithmetic_expression -> psp_group
+        [ psp_keyword "return"
+        ; paint_arithmetic_expression arithmetic_expression
+        ; psp_syntax ";"
+        ; psp_break
+        ]
+
+    | CMD_Call (identifier, arguments) -> psp_group
+        [ psp_identifier identifier
+        ; psp_list_map psp_std_bracket (psp_syntax ",") paint_arithmetic_expression arguments
+        ; psp_syntax ";"
+        ; psp_break
+        ]
+
     | CMD_Compose (first_command, second_command) -> psp_group
         [ paint_command first_command
         ; paint_command second_command
         [ psp_value_bool constant
         ]
 
-    | BE_Variable variable ->  psp_group
-        [ psp_variable variable
-        ]
-
     | BE_BinaryOperator (boolean_operator, first_expression, second_expression) -> 
         psp_gen_infix
             boolean_binary_operator_associativity

File source/Machine/X86/GasPrettyPrinter.ml

     | PUSHL  _ -> "pushl"
     | POPL  _ -> "popl"
     | CMP  _ -> "cmp"
-                                        
+
+let paint_jump_location32 = function
+    | LOC32_Register reg -> psp_group
+        [ psp_operator "*"
+        ; paint_register32 reg
+        ]
+
+    | LOC32_Memory (MEM_Symbol symbol) -> psp_group
+        [ paint_symbol symbol
+        ]
+
+    | LOC32_Memory mem -> psp_group
+        [ psp_operator "*"
+        ; paint_memory_location mem
+        ]
+        
+
 let paint_instruction instr =
     let mnemonic = get_instruction_mnemonic instr in
     let psp_mnemonic = psp_operator in
     | JGE (l32)
     | JNLE(l32)
     | JNGE(l32)
+    | CALL (l32) -> psp_group
+        [ psp_mnemonic mnemonic
+        ; paint_jump_location32 l32
+        ]
+
 
     | NOTL (l32)
     | NEGL (l32)
-    | POPL (l32)
-    | CALL (l32) -> psp_group
+    | POPL (l32) -> psp_group
         [ psp_mnemonic mnemonic
         ; paint_location32 l32
         ]