11open Core__.Common
2+ open Stage__
23
34(* reify macro for java_v2 backend - creates anonymous class implementing interface *)
45
56(* Parse a method definition: (methodName [this arg1 ...] body...) *)
67(* Metadata like ^void on method name specifies return type *)
8+ (* Returns: (return_type, method_name, args_with_types, original_arg_names, body) *)
79let parse_method = function
810 | SList (_ , SAtom (m , name ) :: SList (_ , _ :: _ :: args ) :: body ) ->
911 (* Skip first element (vector) and second element (this) *)
1012 (* m.symbol contains metadata like "void" from ^void *)
11- (m.symbol, name, args, body)
13+ let arg_names =
14+ List. map
15+ (function SAtom (_ , n ) -> n | x -> failsexp __LOC__ [ x ])
16+ args
17+ in
18+ (m.symbol, name, args, arg_names, body)
1219 | SList (_ , SAtom (m , name ) :: SList (_ , _ :: [] ) :: body ) ->
1320 (* Only [this] - no additional args *)
14- (m.symbol, name, [] , body)
21+ (m.symbol, name, [] , [] , body)
1522 | x -> failsexp __LOC__ [ x ]
1623
1724(* Generate method argument declarations *)
@@ -25,12 +32,34 @@ let generate_method_args args =
2532 | x -> failsexp __LOC__ [ x ])
2633 |> String. concat " , "
2734
35+ (* Generate let bindings to map original arg names to p0, p1, etc *)
36+ let generate_arg_bindings args arg_names body =
37+ if List. length arg_names = 0 then body
38+ else
39+ let bindings =
40+ List. concat_map
41+ (fun (i , (arg , name )) ->
42+ let typ = match arg with SAtom (m , _ ) -> m.symbol | _ -> " " in
43+ let meta = { meta_empty with symbol = typ } in
44+ (* Create binding pair: name p0 *)
45+ [ SAtom (meta, name); SAtom (meta_empty, Printf. sprintf " p%i" i) ])
46+ (List. mapi (fun i x -> (i, x)) (List. combine args arg_names))
47+ in
48+ (* Wrap body with let expression: (let [name1 p0 name2 p1 ...] body) *)
49+ SList
50+ ( meta_empty,
51+ [
52+ SAtom (meta_empty, " let" );
53+ SList (meta_empty, SAtom (meta_empty, " vector" ) :: bindings);
54+ body;
55+ ] )
56+
2857let invoke simplify = function
2958 | SList (_ , SAtom (_ , "reify" ) :: SAtom (_ , interface ) :: methods ) ->
3059 let parsed = List. map parse_method methods in
3160 let method_codes =
3261 parsed
33- |> List. map (fun (annot , name , args , body ) ->
62+ |> List. map (fun (annot , name , args , arg_names , body ) ->
3463 let ret_type = if annot = " " then " Object" else annot in
3564 let args_decl = generate_method_args args in
3665 (* For simplest version, just use the body directly *)
@@ -39,7 +68,13 @@ let invoke simplify = function
3968 | [ single ] -> single
4069 | _ -> SList (meta_empty, SAtom (meta_empty, " do" ) :: body)
4170 in
42- let simplified_body = simplify body_expr in
71+ (* Wrap body with let bindings for parameter name mapping *)
72+ let body_with_bindings =
73+ generate_arg_bindings args arg_names body_expr
74+ in
75+ let simplified_body = simplify body_with_bindings in
76+ (* Flatten nested do* blocks so butlast/last work correctly *)
77+ let flat_body = Stage_flat_do. invoke simplified_body in
4378 (* Build method code using __compiler_emit *)
4479 (* Handle void vs non-void return types *)
4580 (* Use try-catch to handle exceptions without requiring throws clause *)
@@ -52,7 +87,7 @@ let invoke simplify = function
5287 (Printf. sprintf
5388 " \n @Override public void %s(%s) {\n try {\n "
5489 name args_decl);
55- simplified_body ;
90+ flat_body ;
5691 pack_string
5792 " ;\n \
5893 \ } catch (Exception e) {\n \
@@ -61,25 +96,54 @@ let invoke simplify = function
6196 \ }" ;
6297 ] )
6398 else
64- SList
65- ( meta_empty,
66- [
67- SAtom (meta_empty, " __compiler_emit" );
68- pack_string
69- (Printf. sprintf
70- " \n \
71- \ @Override public %s %s(%s) {\n \
72- \ try {\n \
73- \ return ("
74- ret_type name args_decl);
75- simplified_body;
76- pack_string
77- " );\n \
78- \ } catch (Exception e) {\n \
79- \ throw new RuntimeException(e);\n \
80- \ }\n \
81- \ }" ;
82- ] ))
99+ (* For non-void return: emit statements first, then return last expression *)
100+ let butlast = SexpUtil. butlast flat_body in
101+ let last_expr = SexpUtil. last flat_body in
102+ if List. length butlast = 0 then
103+ (* Simple case: just one expression *)
104+ SList
105+ ( meta_empty,
106+ [
107+ SAtom (meta_empty, " __compiler_emit" );
108+ pack_string
109+ (Printf. sprintf
110+ " \n \
111+ \ @Override public %s %s(%s) {\n \
112+ \ try {\n \
113+ \ return (%s)("
114+ ret_type name args_decl ret_type);
115+ flat_body;
116+ pack_string
117+ " );\n \
118+ \ } catch (Exception e) {\n \
119+ \ throw new RuntimeException(e);\n \
120+ \ }\n \
121+ \ }" ;
122+ ] )
123+ else
124+ (* Multiple statements: emit all but last, then return last *)
125+ let statements =
126+ SList (meta_empty, SAtom (meta_empty, " do*" ) :: butlast)
127+ in
128+ SList
129+ ( meta_empty,
130+ [
131+ SAtom (meta_empty, " __compiler_emit" );
132+ pack_string
133+ (Printf. sprintf
134+ " \n @Override public %s %s(%s) {\n try {\n "
135+ ret_type name args_decl);
136+ statements;
137+ pack_string " ;\n return (" ;
138+ pack_string (ret_type ^ " )(" );
139+ last_expr;
140+ pack_string
141+ " );\n \
142+ \ } catch (Exception e) {\n \
143+ \ throw new RuntimeException(e);\n \
144+ \ }\n \
145+ \ }" ;
146+ ] ))
83147 in
84148 (* Build the anonymous class *)
85149 (* Convert $ to . for inner classes (e.g., Thread$UncaughtExceptionHandler -> Thread.UncaughtExceptionHandler) *)
0 commit comments