@@ -147,7 +147,7 @@ let rec format_typ
147147
148148let format_ctx
149149 (type_ordering : TypeIdent.t list )
150- ( fmt : Format.formatter )
150+ ~ ppc ~ pph
151151 (ctx : decl_ctx ) : unit =
152152 let format_struct_decl fmt (struct_name , struct_fields ) =
153153 let fields = StructField.Map. bindings struct_fields in
@@ -171,16 +171,15 @@ let format_ctx
171171 if EnumConstructor.Map. is_empty enum_cons then
172172 failwith " no constructors in the enum"
173173 else
174- Format. fprintf fmt " @,@[<v 2>enum %s_code {@,%a@;<0 -2>}@] %s__code ;@,"
174+ Format. fprintf fmt " @,@[<v 2>enum %s__code {@,%a@;<0 -2>}@];@,"
175175 (EnumName. base enum_name)
176176 (Format. pp_print_list
177177 ~pp_sep: (fun fmt () -> Format. fprintf fmt " ,@ " )
178178 (fun fmt (enum_cons , _ ) -> EnumConstructor. format fmt enum_cons))
179- (EnumConstructor.Map. bindings enum_cons)
180- (EnumName. base enum_name);
179+ (EnumConstructor.Map. bindings enum_cons);
181180 Format. fprintf fmt
182181 " @,\
183- @[<v 2>typedef struct %s {@ enum %s_code code;@ @[<v 2>union {@ %a@]@,\
182+ @[<v 2>typedef struct %s {@ enum %s__code code;@ @[<v 2>union {@ %a@]@,\
184183 } payload;@]@,\
185184 } %s;" (EnumName. base enum_name) (EnumName. base enum_name)
186185 (Format. pp_print_list
@@ -194,36 +193,32 @@ let format_ctx
194193 (EnumConstructor.Map. bindings enum_cons)
195194 (EnumName. base enum_name)
196195 in
197-
198- let is_in_type_ordering s =
199- List. exists
200- (fun struct_or_enum ->
201- match struct_or_enum with
202- | TypeIdent. Enum _ -> false
203- | TypeIdent. Struct s' -> s = s')
204- type_ordering
205- in
206196 let scope_structs =
207- List. map
208- ( fun ( s , _ ) -> TypeIdent. Struct s)
209- ( StructName.Map. bindings
210- ( StructName.Map. filter
211- ( fun s _ -> not (is_in_type_ordering s))
212- ctx.ctx_structs) )
197+ List. fold_left ( fun acc -> function
198+ | TypeIdent. Struct s -> StructName.Map. remove s acc
199+ | _ -> acc)
200+ ctx.ctx_structs type_ordering
201+ |> StructName.Map. keys
202+ |> List. map ( fun s -> TypeIdent. Struct s )
213203 in
214- Format. pp_print_list
215- ~pp_sep: (fun _ () -> () )
216- (fun fmt struct_or_enum ->
204+ List. iter
205+ (fun struct_or_enum ->
217206 match struct_or_enum with
218- | TypeIdent. Struct s ->
207+ | TypeIdent. Struct s as tid ->
219208 if StructName. path s = [] then
220- Format. fprintf fmt " @,%a" format_struct_decl
221- (s, StructName.Map. find s ctx.ctx_structs)
222- | TypeIdent. Enum e ->
209+ let def = StructName.Map. find s ctx.ctx_structs in
210+ Format. fprintf ppc " @,%a" format_struct_decl (s, def);
211+ if TypeIdent.Set. mem tid ctx.ctx_public_types
212+ then Format. fprintf pph " @,%a" format_struct_decl (s, def)
213+ else Format. eprintf " NOT PUB: %a (pub: %a)@."
214+ StructName. format s
215+ (Format. pp_print_seq ~pp_sep: Format. pp_print_space TypeIdent. format) (TypeIdent.Set. to_seq ctx.ctx_public_types)
216+ | TypeIdent. Enum e as tid ->
223217 if EnumName. path e = [] then
224- Format. fprintf fmt " @,%a" format_enum_decl
225- (e, EnumName.Map. find e ctx.ctx_enums))
226- fmt
218+ let def = EnumName.Map. find e ctx.ctx_enums in
219+ Format. fprintf ppc " @,%a" format_enum_decl (e, def);
220+ if TypeIdent.Set. mem tid ctx.ctx_public_types
221+ then Format. fprintf pph " @,%a" format_enum_decl (e, def))
227222 (type_ordering @ scope_structs)
228223
229224let format_lit (fmt : Format.formatter ) (l : lit Mark.pos ) : unit =
@@ -714,26 +709,36 @@ let format_main (fmt : Format.formatter) (p : Ast.program) =
714709 Format. fprintf fmt " @,return 0;@;<1 -2>}@]"
715710
716711let format_program
717- (fmt : Format.formatter )
712+ ~ppf_src :ppc
713+ ~ppf_intf :pph
718714 (p : Ast.program )
719715 (type_ordering : TypeIdent.t list ) : unit =
720- Fun. protect ~finally: (Format. pp_print_newline fmt)
716+ let ppboth f = f ppc; f pph in
717+ let ppboth_if condition f = f ppc; if condition then f pph in
718+ Fun. protect ~finally: (fun () -> ppboth (fun ppf -> Format. pp_print_newline ppf () ))
721719 @@ fun () ->
722- Format. pp_open_vbox fmt 0 ;
723- Format. fprintf fmt
724- " /* This file has been generated by the Catala compiler, do not edit! */@,\
725- @,\
726- #include <stdio.h>@,\
720+ ppboth ( fun ppf -> Format. pp_open_vbox ppf 0 ) ;
721+ ppboth ( fun ppf -> Format. fprintf ppf
722+ " /* This file has been generated by the Catala compiler, do not edit! */@,@, " );
723+ Format. fprintf ppc
724+ " #include <stdio.h>@,\
727725 #include <stdlib.h>@,\
728726 #include <catala_runtime.h>@,\
729727 @," ;
728+ let module_id =
729+ match p.module_name with
730+ | None -> " MAIN"
731+ | Some (m , _ ) -> String. uppercase_ascii (String. to_ascii (ModuleName. to_string m))
732+ in
733+ Format. fprintf pph " #ifndef __%s_H__@,#define __%s_H__@," module_id module_id;
730734 List. iter
731735 (fun (m , _intf_id ) ->
732- Format. fprintf fmt " #include \" %s.c \" @, "
733- (String. uncapitalize_ascii (ModuleName. to_string m)))
736+ ppboth @@ fun ppf -> Format. fprintf ppf " @, #include \" %s.h \" "
737+ (String. uncapitalize_ascii (ModuleName. to_string m)))
734738 (Program. modules_to_list p.ctx.decl_ctx.ctx_modules);
735- format_ctx type_ordering fmt p.ctx.decl_ctx;
736- Format. pp_print_cut fmt () ;
739+ (* TODO: check the module hash ? *)
740+ format_ctx type_ordering ~ppc ~pph p.ctx.decl_ctx;
741+ ppboth (fun ppf -> Format. pp_print_cut ppf () );
737742 let ctx = { decl_ctx = p.ctx.decl_ctx } in
738743 let _env =
739744 List. fold_left
@@ -744,21 +749,27 @@ let format_program
744749 parameters that perform lazy evaluation: {[ inline foo_type foo() {
745750 static foo_type foo = NULL; return (foo ? foo : foo = foo_init());
746751 } ]} NOTE: "inline" is not defined in C89 *)
747- Format. fprintf fmt " @[<v 2>@[<hov 4>%a () {@]@,"
748- (format_typ ~const: true p.ctx.decl_ctx (fun fmt ->
749- Format. pp_print_space fmt () ;
750- VarName. format fmt var))
751- typ;
752- Format. fprintf fmt " @[<hov 2>static %a = NULL;@]@,"
752+ let public = (* TODO: Ugh! Pass this info into scalc ! *)
753+ Re. (execp (compile (seq [str " __" ; diff any digit])) (VarName. to_string var))
754+ in
755+ ppboth_if public (fun ppf ->
756+ Format. fprintf ppf " @,@[<v 2>@[<hov 4>%a"
757+ (format_typ ~const: true p.ctx.decl_ctx (fun fmt ->
758+ Format. pp_print_space fmt () ;
759+ VarName. format fmt var))
760+ typ);
761+ if public then Format. fprintf pph " ;@]@]@," ;
762+ Format. fprintf ppc " () {@]@," ;
763+ Format. fprintf ppc " @[<hov 2>static %a = NULL;@]@,"
753764 (format_typ ~const: true p.ctx.decl_ctx (fun fmt ->
754765 Format. pp_print_space fmt () ;
755766 VarName. format fmt var))
756767 typ;
757- Format. fprintf fmt " @[<hov 2>return (%a ? %a : (%a = %a));@]"
768+ Format. fprintf ppc " @[<hov 2>return (%a ? %a : (%a = %a));@]"
758769 VarName. format var VarName. format var VarName. format var
759770 (format_expression ctx env)
760771 expr;
761- Format. fprintf fmt " @;<1 -2>}@]@, @," ;
772+ Format. fprintf ppc " @;<1 -2>}@]@," ;
762773 { env with global_vars = VarName.Set. add var env.global_vars }
763774 | SFunc { var; func }
764775 | SScope { scope_body_var = var ; scope_body_func = func ; _ } ->
@@ -767,29 +778,36 @@ let format_program
767778 VarName.Set. of_list
768779 (List. map (fun (v , _ ) -> Mark. remove v) func_params)
769780 in
770- Format. fprintf fmt
771- " @,@[<v 2>@[<hov 4>%a@ @[<hv 1>(%a)@]@]@;<1 -2>{%a@]@,}@,"
772- (format_typ ~const: true ctx.decl_ctx (fun fmt ->
773- Format. pp_print_space fmt () ;
774- FuncName. format fmt var))
775- func_return_typ
776- (Format. pp_print_list
777- ~pp_sep: (fun fmt () -> Format. fprintf fmt " ,@ " )
778- (fun fmt (var , typ ) ->
779- Format. pp_open_hovbox fmt 2 ;
780- (format_typ ~const: true p.ctx.decl_ctx (fun fmt ->
781- Format. pp_print_space fmt () ;
782- VarName. format fmt (Mark. remove var)))
783- fmt typ;
784- Format. pp_close_box fmt () ))
785- func_params
781+ let public = (* TODO: Ugh! Pass this info into scalc ! *)
782+ Re. (execp (compile (seq [str " __" ; diff any digit])) (FuncName. to_string var))
783+ in
784+ ppboth_if public (fun ppf ->
785+ Format. fprintf ppf
786+ " @,@[<v 2>@[<hov 4>%a@ @[<hv 1>(%a)@]@]"
787+ (format_typ ~const: true ctx.decl_ctx (fun fmt ->
788+ Format. pp_print_space fmt () ;
789+ FuncName. format fmt var))
790+ func_return_typ
791+ (Format. pp_print_list
792+ ~pp_sep: (fun fmt () -> Format. fprintf fmt " ,@ " )
793+ (fun fmt (var , typ ) ->
794+ Format. pp_open_hovbox fmt 2 ;
795+ (format_typ ~const: true p.ctx.decl_ctx (fun fmt ->
796+ Format. pp_print_space fmt () ;
797+ VarName. format fmt (Mark. remove var)))
798+ fmt typ;
799+ Format. pp_close_box fmt () ))
800+ func_params);
801+ if public then Format. fprintf pph " @];@," ;
802+ Format. fprintf ppc " @;<1 -2>{%a@]@,}@,"
786803 (format_block ctx { env with local_vars })
787804 func_body;
788805 env)
789806 { global_vars = VarName.Set. empty; local_vars = VarName.Set. empty }
790807 p.code_items
791808 in
792809 if p.module_name = None then (
793- Format. pp_print_cut fmt () ;
794- format_main fmt p);
795- Format. pp_close_box fmt ()
810+ Format. pp_print_cut ppc () ;
811+ format_main ppc p);
812+ Format. fprintf pph " @,#endif /* __%s_H__ */" module_id;
813+ ppboth (fun ppf -> Format. pp_close_box ppf () )
0 commit comments