Przeglądaj źródła

[cpp] work on switch and try/catch for cppast

Hugh 9 lat temu
rodzic
commit
af8572dd15
1 zmienionych plików z 118 dodań i 48 usunięć
  1. 118 48
      gencpp.ml

+ 118 - 48
gencpp.ml

@@ -1686,6 +1686,7 @@ and tcpp_expr_expr =
    | CppIf of tcppexpr * tcppexpr * tcppexpr option
    | CppWhile of tcppexpr * tcppexpr * Ast.while_flag
    | CppIntSwitch of tcppexpr * (Int32.t list * tcppexpr) list * tcppexpr option
+   | CppSwitch of tcppexpr * (tcppexpr list * tcppexpr) list * tcppexpr option
    | CppTry of tcppexpr * (tvar * tcppexpr) list
    | CppBreak
    | CppContinue
@@ -2302,16 +2303,19 @@ let retype_expression ctx request_type expression_tree =
 
             let condition = retype (cpp_type_of condition.etype) condition in
             let conditionType = condition.cpptype in
-            let def = match def with None -> None | Some e -> Some (retype TCppVoid (mk_block e)) in
+            let cppDef = match def with None -> None | Some e -> Some (retype TCppVoid (mk_block e)) in
             (try 
                (match conditionType with TCppScalar("Int") | TCppScalar("Bool") -> () | _ -> raise Not_found );
+               (match def with None -> () | Some e -> if (contains_break e) then raise Not_found);
                let cases = List.map (fun (el,e2) ->
                   if (contains_break e2) then raise Not_found;
                   (List.map const_int_of el), (retype TCppVoid (mk_block e2)) ) cases in
-               CppIntSwitch(condition, cases, def), cpp_type_of expr.etype
+               CppIntSwitch(condition, cases, cppDef), TCppVoid
             with Not_found ->
-               (* TODO *)
-               condition.cppexpr, conditionType
+               (* do something better maybe ... *)
+               let cases = List.map (fun (el,e2) ->
+                  (List.map (retype conditionType) el), (retype TCppVoid (mk_block e2)) ) cases in
+               CppSwitch(condition, cases, cppDef), TCppVoid
             )
 
          | TTry (try_block,catches) ->
@@ -2347,6 +2351,7 @@ let gen_cpp_ast_expression_tree ctx tree =
    let writer = ctx.ctx_writer in
    let out = ctx.ctx_output in
    let lastLine = ref (-1) in
+   let tempId = ref 0 in
 
    let spacer = if (ctx.ctx_debug_level>0) then "            \t" else "" in
    let output_i value = out spacer; writer#write_i value in
@@ -2595,49 +2600,116 @@ let gen_cpp_ast_expression_tree ctx tree =
          | Some expr -> output_i "default:"; gen expr; | _ -> ()  );
          out spacer;
          writer#end_block;
+      | CppSwitch(condition, cases, optional_default) ->
+         let tmp_name = "_hx_switch_" ^ (string_of_int !tempId) in
+         incr tempId;
+         out ( (tcpp_to_string condition.cpptype) ^ " " ^ tmp_name ^ " = " );
+         gen condition;
+         out ";\n";
+         let else_str = ref "" in
+         if (List.length cases > 0) then
+            List.iter (fun (cases,expression) ->
+               output_i ( !else_str ^ "if ( ");
+               else_str := "else ";
+               let or_str = ref "" in
+               List.iter (fun value ->
+                  out (!or_str ^ " (" ^ tmp_name ^ "=="); gen value; out ")";
+                  or_str := " || ";
+                  ) cases;
+               out (" )");
+               gen expression;
+               ) cases;
+         (match optional_default with | None -> ()
+         | Some default ->
+            out spacer;
+            output_i ( !else_str ^ " ");
+            gen default;
+         );
+
+      | CppUnop(unop,value) ->
+           out (match unop with
+           | CppNot -> "!"
+           | CppNeg -> "-"
+           | CppNegBits -> "~"
+           );
+           out "(";  gen value; out ")"
+
+      | CppWhile(condition, block, while_flag) ->
+          (match while_flag with
+          | NormalWhile ->
+              out "while("; gen condition; out (")");
+              gen block;
+          | DoWhile ->
+              out ("do ");
+              gen block;
+              out "while("; gen condition; out ")"
+          );
+
+      | CppIf (condition,block,None) ->
+          out "if ("; gen condition; out (") ");
+          gen block;
+
+      | CppIf (condition,block,Some elze) when expr.cpptype = TCppVoid ->
+          out "if ("; gen condition; out (") ");
+          gen block;
+          output_i ("else ");
+          gen elze;
+
+      | CppIf (condition,block,Some elze) ->
+          gen condition; out " ? "; gen block; out " : "; gen elze;
+
+      | CppFor (tvar, init, loop) ->
+         let varType = cpp_var_type_of tvar in
+         out ("for(::cpp::FastIterator_obj< " ^  varType ^
+               " > *__it = ::cpp::CreateFastIterator< "^ varType ^ " >(");
+         gen init;
+         out (");  __it->hasNext(); )");
+         let prologue = fun () ->
+            output_i ( varType ^ " " ^ (cpp_var_name_of tvar) ^ " = __it->next();\n" );
+         in
+         gen_with_prologue (Some prologue) loop;
+
+
+      | CppTry(block,catches) ->
+          let prologue = function () ->
+             ExtList.List.iteri (fun idx (v,_) ->
+                output_i ("HX_STACK_CATCHABLE(" ^ cpp_var_type_of v  ^ ", " ^ string_of_int idx ^ ");\n")
+             ) catches
+          in
+          out ("try ");
+          gen_with_prologue (Some prologue) block;
+          if (List.length catches > 0 ) then begin
+             output_i "catch(Dynamic _hx_e)";
+             writer#begin_block;
+
+             let seen_dynamic = ref false in
+             let else_str = ref "" in
+             List.iter (fun (v,catch) ->
+                let type_name = cpp_var_type_of v in
+                if (type_name="Dynamic") then begin
+                   seen_dynamic := true;
+                   output_i !else_str;
+                end else
+                   output_i (!else_str ^ "if (_hx_e.IsClass< " ^ type_name ^ " >() )");
+                let prologue = function () ->
+                   output_i "HX_STACK_BEGIN_CATCH\n";
+                   output_i (type_name ^ " " ^ (cpp_var_name_of v) ^ " = _hx_e;\n");
+                in
+                gen_with_prologue (Some prologue) catch;
+                else_str := "else ";
+                ) catches;
+
+             if (not !seen_dynamic) then begin
+                output_i "else {\n";
+                output_i "\tHX_STACK_DO_THROW(_hx_e);\n";
+                output_i "}\n";
+             end;
+             out spacer;
+             writer#end_block;
+          end
 
-   | CppUnop(unop,value) ->
-        out (match unop with
-        | CppNot -> "!"
-        | CppNeg -> "-"
-        | CppNegBits -> "~"
-        );
-        out "(";  gen value; out ")"
-
-   | CppWhile(condition, block, while_flag) ->
-       (match while_flag with
-       | NormalWhile ->
-           out "while("; gen condition; out (")\n");
-           gen block;
-       | DoWhile ->
-           out ("do\n");
-           gen block;
-           out "while("; gen condition; out ")"
-       );
-   | CppIf (condition,block,None) ->
-       out "if ("; gen condition; out (")\n");
-       gen block;
-
-   | CppIf (condition,block,Some elze) when expr.cpptype = TCppVoid ->
-       out "if ("; gen condition; out (") ");
-       gen block;
-       out (" else ");
-       gen elze;
-
-   | CppIf (condition,block,Some elze) ->
-       gen condition; out " ? "; gen block; out " : "; gen elze;
-
-   | CppFor(tvar, init, block) ->
-       out ("for(var " ^ tvar.v_name ^ "-"); gen init; out (") ");
-       gen block;
-
-   | CppTry(block,catches) ->
-       out ("try ");
-       gen block;
-       List.iter (fun (var,block) ->
-         output_i ("catch(var " ^ var.v_name ^ ") " );
-         gen block;
-       ) catches;
+      | CppCode(value, exprs) ->
+         Codegen.interpolate_code ctx.ctx_common (format_code value) exprs out (fun e -> gen e) expr.cpppos
 
    | CppCast(expr,None) ->
        out "cast("; gen expr; out ")";
@@ -2645,8 +2717,6 @@ let gen_cpp_ast_expression_tree ctx tree =
    | CppCast(expr,Some _) ->
        out "castTo("; gen expr; out ")";
 
-   | CppCode(value, exprs) ->
-       Codegen.interpolate_code ctx.ctx_common (format_code value) exprs out (fun e -> gen e) expr.cpppos
 
    and gen expr =
       gen_with_prologue None expr