@@ -26,8 +26,6 @@ open Core.Prog
2626
2727let runtime =
2828 {% pla|
29- import java.util.Arrays ;
30- import java.util.Random ;
3129
3230static int clip(int x, int minv, int maxv) {
3331 if (x > maxv)
@@ -286,6 +284,15 @@ let rec print_exp e =
286284 | ECall { path = "not" ; args = [ e1 ] } ->
287285 let e1 = print_exp e1 in
288286 {% pla|! (< #e1 #> )| }
287+ | ECall { path = "real" ; args = [ e1 ] } ->
288+ let e1 = print_exp e1 in
289+ {% pla| (float )(< #e1 #> )| }
290+ | ECall { path = "int" ; args = [ e1 ] } ->
291+ let e1 = print_exp e1 in
292+ {% pla| (int )(< #e1 #> )| }
293+ | ECall { path = "bool" ; args = [ e1 ] } ->
294+ let e1 = print_exp e1 in
295+ {% pla| ((< #e1 #> ) != 0 )| }
289296 | ECall { path; args } ->
290297 let args = Pla. map_sep Pla. commaspace print_exp args in
291298 {% pla|< #path #s> (< #args #> )| }
@@ -427,17 +434,30 @@ let print_arg ({ name; t; _ } : param) =
427434 {% pla|< #t #> < #name #s> | }
428435
429436
430- let print_function_def (def : function_def ) =
437+ let print_function_def ?( force_public = false ) ?( is_performance = false ) (def : function_def ) =
431438 let name = def.name in
432439 let args = Pla. map_sep Pla. commaspace print_arg def.args in
433440 let ret = print_type_ (snd def.t) in
434441 let visibility =
435- if def.info.is_root then
442+ if def.info.is_root || force_public then
436443 " public"
444+ else if is_performance && String. contains name '_' then
445+ (* Make _alloc and _default functions public for performance template *)
446+ let suffix = String. sub name (String. rindex name '_' ) (String. length name - String. rindex name '_' ) in
447+ if suffix = " _alloc" || suffix = " _default" then
448+ " public"
449+ else
450+ " private"
437451 else
438452 " private"
439453 in
440- {% pla|< #visibility #s> static < #ret #> < #name #s> (< #args #> ) {| }
454+ let static_keyword =
455+ if is_performance then
456+ " "
457+ else
458+ " static "
459+ in
460+ {% pla|< #visibility #s> < #static_keyword #s>< #ret #> < #name #s> (< #args #> ) {| }
441461
442462
443463let print_body body =
@@ -485,12 +505,39 @@ let print_struct_def { path; members; _ } =
485505 {% pla| public static class < #path #s> {< #members_decl #+>< #default_constructor #+>< #param_constructor #+> }| }
486506
487507
488- let print_top_stmt (_args : Util.Args.args ) t =
508+ (* Generate type alias as inheritance *)
509+ let print_type_alias alias_name base_name =
510+ {% pla| public static class < #alias_name #s> extends < #base_name #s> {
511+ public < #alias_name #s> () { super() ; }
512+ }| }
513+
514+
515+ let print_top_stmt (args : Util.Args.args ) t =
489516 match t.top with
490- | TopFunction (def , body ) ->
491- let def = print_function_def def in
492- let body = print_body body in
493- {% pla|< #def #>< #body #>< #>< #> | }
517+ | TopFunction (func_def , body ) ->
518+ let is_performance = args.template = Some " performance" in
519+ let force_public = is_performance in
520+ let def = print_function_def ~force_public ~is_performance func_def in
521+ let name = func_def.name in
522+ (* Check if this is a type alias allocation function *)
523+ if String. contains name '_' && CCString. suffix ~suf: " _type_alloc" name && List. length func_def.args > 0 then
524+ let parts = String. split_on_char '_' name in
525+ let len = List. length parts in
526+ if len > = 4 then
527+ (* This is a type alias allocation function - override body to create correct type *)
528+ let name_len = String. length name in
529+ let alias_type = String. sub name 0 (name_len - 6 ) in
530+ (* Remove "_alloc" *)
531+ let body = {% pla|
532+ return new < #alias_type #s> () ;
533+ }| } in
534+ {% pla|< #def #>< #body #>< #>< #> | }
535+ else
536+ let body = print_body body in
537+ {% pla|< #def #>< #body #>< #>< #> | }
538+ else
539+ let body = print_body body in
540+ {% pla|< #def #>< #body #>< #>< #> | }
494541 | TopExternal _ -> Pla. unit
495542 | TopType descr -> print_struct_def descr
496543 | TopAlias _ -> Pla. unit
@@ -500,12 +547,58 @@ let print_top_stmt (_args : Util.Args.args) t =
500547 {% pla| public static final < #t #> < #name #s> = < #rhs #> ;< #> | }
501548
502549
503- let print_prog args t = Pla. map_join (print_top_stmt args) t
550+ (* Collect type aliases needed based on function signatures *)
551+ let collect_type_aliases stmts =
552+ let aliases = ref [] in
553+ let collect_from_stmt stmt =
554+ match stmt.top with
555+ | TopFunction (def , _ ) ->
556+ let name = def.name in
557+ (* Look for pattern: *_function_type_alloc that takes arguments (indicating it's a type alias) *)
558+ if String. contains name '_' && CCString. suffix ~suf: " _type_alloc" name && List. length def.args > 0 then
559+ let parts = String. split_on_char '_' name in
560+ (* Handle patterns like Module_noteOn_type_alloc or Module_submodule_pulse_start_type_alloc *)
561+ let len = List. length parts in
562+ if len > = 4 then
563+ (* Check for various patterns including perf variants *)
564+ if len > = 5 && List. nth parts (len - 4 ) = " perf" then
565+ (* Handle perf patterns like Module_perf_noteOn_type_alloc *)
566+ let module_parts = CCList. take (len - 4 ) parts in
567+ let module_name = String. concat " _" module_parts in
568+ let name_len = String. length name in
569+ let alias_type = String. sub name 0 (name_len - 6 ) in
570+ (* Remove "_alloc" *)
571+ let base_type = module_name ^ " _perf_process_type" in
572+ aliases := (alias_type, base_type) :: ! aliases
573+ else
574+ (* Handle regular patterns like Module_noteOn_type_alloc or Module_pulse_start_type_alloc *)
575+ let module_parts = CCList. take (len - 3 ) parts in
576+ let module_name = String. concat " _" module_parts in
577+ let name_len = String. length name in
578+ let alias_type = String. sub name 0 (name_len - 6 ) in
579+ (* Remove "_alloc" *)
580+ let base_type = module_name ^ " _process_type" in
581+ aliases := (alias_type, base_type) :: ! aliases
582+ | _ -> ()
583+ in
584+ List. iter collect_from_stmt stmts;
585+ ! aliases
586+
587+
588+ let print_prog args t =
589+ let aliases = collect_type_aliases t in
590+ let main_code = Pla. map_join (print_top_stmt args) t in
591+ let alias_code = Pla. map_sep_all Pla. newline (fun (alias , base ) -> print_type_alias alias base) aliases in
592+ if aliases = [] then
593+ main_code
594+ else
595+ {% pla|< #main_code #>< #alias_code #+>| }
596+
504597
505598let getTemplateCode (args : Util.Args.args ) =
506599 match args.template with
507600 | None -> Pla. unit , Pla. unit
508- | Some "performance" -> Pla. unit , Pla. unit (* TODO: implement T_performance.generateJava *)
601+ | Some "performance" -> T_performance. generateJava args
509602 | Some name -> Util.Error. raiseErrorMsg (" Unknown template '" ^ name ^ " '" )
510603
511604
@@ -523,15 +616,42 @@ let generate (args : Util.Args.args) (stmts : top_stmt list) =
523616 in
524617 let code = print_prog args stmts in
525618 let pre, post = getTemplateCode args in
526- let full_code =
527- {% pla|
619+ match args.template with
620+ | Some "performance" ->
621+ (* For performance template, generate two files: main class and performance test *)
622+ let main_code =
623+ {% pla|
528624package < #package_name #s> ;
529625
626+ import java.util.Arrays ;
627+ import java.util.Random ;
628+
629+ public class < #class_name #s> {
530630< #runtime #>
631+ < #code #>
632+ }
633+ | }
634+ in
635+ let perf_file = Common. setExt " Perf.java" args.output in
636+ let perf_code = {% pla|
637+ package < #package_name #s> ;
638+
639+ < #post #>
640+ | } in
641+ [ main_code, file; perf_code, perf_file ]
642+ | _ ->
643+ (* Regular template or no template *)
644+ let full_code =
645+ {% pla|
646+ package < #package_name #s> ;
647+
648+ import java.util.Arrays ;
649+ import java.util.Random ;
531650
532651public class < #class_name #s> {
652+ < #runtime #>
533653< #pre #>< #code #>< #post #>
534654}
535655| }
536- in
537- [ full_code, file ]
656+ in
657+ [ full_code, file ]
0 commit comments