@@ -105,27 +105,37 @@ type table = {
105105 uuid : Util.UUID .t ;
106106} [@@ deriving show ]
107107
108- type pruned_table = {
109- c2s0 : string D.Constants.Map .t ;
110- c2t0 : D .term D.Constants.Map .t ;
111- } [@@ deriving show ]
108+ type entry =
109+ | GlobalSymbol of D .constant * string
110+ | BoundVariable of D .constant * D .term
111+ [@@ deriving show ]
112+
113+ type pruned_table = entry array [@@ deriving show ]
112114
113115let locked { locked } = locked
114116let lock t = { t with locked = true }
115117let uuid { uuid } = uuid
116118let equal t1 t2 =
117119 locked t1 && locked t2 && uuid t1 = uuid t2
118120
119- let size t = D.Constants.Map. cardinal t.c2t0
121+ let size t = Array. length t
120122
121- let symbols { c2s0 } =
122- List. map (fun (c ,s ) -> s ^ " :" ^ string_of_int c) (D.Constants.Map. bindings c2s0)
123+ let symbols table =
124+ let map = function
125+ | GlobalSymbol (c , s ) -> Some (s ^ " :" ^ string_of_int c)
126+ | BoundVariable _ -> None
127+ in
128+ List. rev @@ List. filter_map map @@ Array. to_list table
123129
124130let prune t ~alive =
125- {
126- c2s0 = D.Constants.Map. filter (fun k _ -> D.Constants.Set. mem k alive) t.c2s;
127- c2t0 = D.Constants.Map. filter (fun k _ -> D.Constants.Set. mem k alive) t.c2t;
128- }
131+ let c2s = t.c2s in
132+ let c2t0 = D.Constants.Map. filter (fun k _ -> D.Constants.Set. mem k alive) t.c2t in
133+ let map k t =
134+ if k < 0 then GlobalSymbol (k, D.Constants.Map. find k c2s)
135+ else BoundVariable (k, t)
136+ in
137+ let c2t0 = D.Constants.Map. mapi map c2t0 in
138+ Array. of_list @@ List. rev_map snd @@ D.Constants.Map. bindings c2t0
129139
130140let table = D.State. declare
131141 ~descriptor: D. elpi_state_descriptor
@@ -247,10 +257,10 @@ let build_shift ?(lock_base=false) ~flags:{ print_units } ~base symbols =
247257 (* We try hard to respect the same order if possible, since some tests
248258 (grundlagen) depend on this order (for performance, the constant-timestamp
249259 heuristic in unfolding) *)
250- List . fold_left (fun (base ,shift as acc ) ( v , t ) ->
251- if v < 0 then
252- let name = Map. find v symbols.c2s0 in
253- try
260+ Array . fold_left (fun (base ,shift as acc ) e ->
261+ match e with
262+ | GlobalSymbol ( v , name ) ->
263+ begin try
254264 let c, _ = F.Map. find (F. from_string name) base.ast2ct in
255265 if c == v then acc
256266 else begin
@@ -262,13 +272,14 @@ let build_shift ?(lock_base=false) ~flags:{ print_units } ~base symbols =
262272 | Not_found ->
263273 let base, (c,_) = allocate_global_symbol_aux (Ast.Func. from_string name) base in
264274 base, Map. add v c shift
265- else
275+ end
276+ | BoundVariable (v , t ) ->
266277 if Map. mem v base.c2t then acc
267278 else
268279 let base = { base with c2t = Map. add v t base.c2t } in
269280 base, shift
270281 )
271- (base,Map. empty) ( List. rev ( Map. bindings symbols.c2t0)) )
282+ (base, Map. empty) symbols)
272283
273284let build_shift ?lock_base ~flags ~base symbols =
274285 try Stdlib.Result. Ok (build_shift ?lock_base ~flags ~base symbols)
@@ -533,9 +544,6 @@ type program = {
533544 clauses : (preterm ,Ast.Structured .attribute ) Ast.Clause .t list ;
534545 chr : (constant list * prechr_rule list ) list ;
535546 local_names : int ;
536- symbols : C.Set .t ;
537-
538- toplevel_macros : macro_declaration ;
539547}
540548[@@ deriving show ]
541549
@@ -579,7 +587,7 @@ type compilation_unit = {
579587
580588type builtins = string * Data.BuiltInPredicate .declaration list
581589
582- type header = State .t * compilation_unit
590+ type header = State .t * compilation_unit * macro_declaration
583591type program = State .t * Assembled .program
584592
585593
@@ -1497,7 +1505,7 @@ module Flatten : sig
14971505
14981506 (* Eliminating the structure (name spaces) *)
14991507
1500- val run : State .t -> Structured .program -> Flat .program
1508+ val run : State .t -> Structured .program -> C.Set .t * macro_declaration * Flat .program
15011509
15021510 val relocate : State .t -> D .constant D.Constants.Map .t -> Flat .program -> Flat .program
15031511 val relocate_term : State .t -> D .constant D.Constants.Map .t -> term -> term
@@ -1696,14 +1704,12 @@ let subst_amap state f { nargs; c2i; i2n; n2t; n2i } =
16961704 let modes = apply_subst_modes ~live_symbols empty_subst modes in
16971705 let types, type_abbrevs, modes, clauses, chr =
16981706 compile_body live_symbols state local_names types type_abbrevs modes [] [] empty_subst body in
1699- { Flat. types;
1707+ ! live_symbols, toplevel_macros, { Flat. types;
17001708 type_abbrevs;
17011709 modes;
17021710 clauses;
17031711 chr = List. rev chr;
17041712 local_names;
1705- toplevel_macros;
1706- symbols = ! live_symbols
17071713 }
17081714 let relocate_term state s t =
17091715 let ksub = apply_subst_constant ([] ,s) in
@@ -1716,8 +1722,6 @@ let subst_amap state f { nargs; c2i; i2n; n2t; n2i } =
17161722 clauses;
17171723 chr;
17181724 local_names;
1719- toplevel_macros;
1720- symbols;
17211725 } =
17221726 let f = [] , f in
17231727 {
@@ -1727,8 +1731,6 @@ let subst_amap state f { nargs; c2i; i2n; n2t; n2i } =
17271731 clauses = apply_subst_clauses state f clauses;
17281732 chr = smart_map (apply_subst_chr state f) chr;
17291733 local_names;
1730- toplevel_macros;
1731- symbols;
17321734 }
17331735
17341736
@@ -2073,7 +2075,7 @@ let assemble flags state code (ul : compilation_unit list) =
20732075
20742076 let state, clauses_rev, types, type_abbrevs, modes, chr_rev =
20752077 List. fold_left (fun (state , cl1 , t1 , ta1 , m1 , c1 ) ({ symbol_table; code } as _u ) ->
2076- let state, { Flat. clauses = cl2; types = t2; type_abbrevs = ta2; modes = m2; chr = c2; toplevel_macros = _ } =
2078+ let state, { Flat. clauses = cl2; types = t2; type_abbrevs = ta2; modes = m2; chr = c2; } =
20772079 let state, shift = Stdlib.Result. get_ok @@ Symbols. build_shift ~flags ~base: state symbol_table in
20782080 let code =
20792081 if C.Map. is_empty shift then code
@@ -2146,7 +2148,7 @@ let unit_or_header_of_ast { print_passes } s ?(toplevel_macros=F.Map.empty) p =
21462148 Format. eprintf " == Structured ================@\n @[<v 0>%a@]@\n "
21472149 (w_symbol_table s Structured. pp_program) p;
21482150
2149- let p = Flatten. run s p in
2151+ let alive, toplevel_macros, p = Flatten. run s p in
21502152
21512153 if print_passes then
21522154 Format. eprintf " == Flat ================@\n @[<v 0>%a@]@\n "
@@ -2155,8 +2157,8 @@ let unit_or_header_of_ast { print_passes } s ?(toplevel_macros=F.Map.empty) p =
21552157 s, {
21562158 version = " %%VERSION_NUM%%" ;
21572159 code = p;
2158- symbol_table = Symbols. prune (State. get Symbols. table s) ~alive: p. Flat. symbols
2159- }
2160+ symbol_table = Symbols. prune (State. get Symbols. table s) ~alive
2161+ }, toplevel_macros
21602162;;
21612163
21622164let print_unit { print_units } x =
@@ -2199,25 +2201,24 @@ let header_of_ast ~flags ~parser:p state_descriptor quotation_descriptor hoas_de
21992201 | Data.BuiltInPredicate. MLDataC _ -> state
22002202 | Data.BuiltInPredicate. LPCode _ -> state
22012203 | Data.BuiltInPredicate. LPDoc _ -> state) state decls) state builtins in
2202- let state, u = unit_or_header_of_ast flags state ast in
2204+ let state, u, toplevel_macros = unit_or_header_of_ast flags state ast in
22032205 print_unit flags u;
2204- state, u
2206+ state, u, toplevel_macros
22052207
2206- let unit_of_ast ~flags ~header :(s , (header : compilation_unit )) p : compilation_unit =
2207- let toplevel_macros = header.code.Flat. toplevel_macros in
2208- let _, u = unit_or_header_of_ast flags s ~toplevel_macros p in
2208+ let unit_of_ast ~flags ~header :(s , (header : compilation_unit ), toplevel_macros ) p : compilation_unit =
2209+ let _, u, _ = unit_or_header_of_ast flags s ~toplevel_macros p in
22092210 print_unit flags u;
22102211 u
22112212
2212- let assemble_units ~flags ~header :(s ,h ) units : program =
2213+ let assemble_units ~flags ~header :(s ,h , toplevel_macros ) units : program =
22132214
22142215 let nunits_with_locals =
22152216 (h :: units) |> List. filter (fun {code = { Flat. local_names = x } } -> x > 0 ) |> List. length in
22162217
22172218 if nunits_with_locals > 0 then
22182219 error " Only 1 compilation unit is supported when local directives are used" ;
22192220
2220- let init = { Assembled. empty with toplevel_macros = h.code.toplevel_macros ; local_names = h.code.local_names } in
2221+ let init = { Assembled. empty with toplevel_macros; local_names = h.code.local_names } in
22212222
22222223 let s, p = Assemble. assemble flags s init (h :: units) in
22232224
0 commit comments