/- Copyright (c) 2016 Jared Roesch. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Jared Roesch -/ prelude import init.meta.expr import init.meta.format import init.native.internal import init.native.procedure import init.native.config namespace native meta structure pass := (name : string) (transform : config → procedure → procedure) meta def file_name_for_dump (p : pass) := (pass.name p) -- Unit functions get optimized away, need to talk to Leo about this one. meta def run_pass (conf : config) (p : pass) (proc : procedure) : (format × procedure × format) := let result := pass.transform p conf proc in (to_string proc, result, to_string result) meta def collect_dumps {A : Type} : list (format × A × format) → format × list A × format | [] := (format.nil, [], format.nil) | ((pre, body, post) :: fs) := let (pre', bodies, post') := collect_dumps fs in (pre ++ format.line ++ format.line ++ pre', body :: bodies, post ++ format.line ++ format.line ++ post') meta def inner_loop_debug (conf : config) (p : pass) (es : list procedure) : list procedure := let (pre, bodies, post) := collect_dumps (list.map (fun e, run_pass conf p e) es) in match native.dump_format (file_name_for_dump p ++ ".pre") pre with | n := match native.dump_format (file_name_for_dump p ++ ".post") post with | m := if n = m then bodies else bodies end end meta def inner_loop (conf : config) (p : pass) (es : list procedure) : list procedure := if config.debug conf then inner_loop_debug conf p es else list.map (fun proc, pass.transform p conf proc) es meta def run_passes (conf : config) (passes : list pass) (procs : list procedure) : list procedure := list.foldl (fun pass procs, inner_loop conf procs pass) procs passes end native