/** * Pretty-print an ATerm to a Box using the given pretty-print tables. * * @author Merijn de Jonge <mdjonge@cs.uu.nl> * @author Martin Bravenboer <martin.bravenboer@gmail.com> */ module stratego/gpp/AstToBox imports stratego/gpp/PpTableIO stratego/gpp/Instantiate stratego/gpp/Util strategies /** * Pretty-prints an ATerm to a Box using the given pretty-print tables. * * @param List(PpTable) * @type a -> Box */ ast2abox(|pptables) = where(tbl := <pptable-make-hashtable> pptables) ; trm2abox(|tbl) ; if is-list then !HV([], <id>) end strategies trm2abox(|tbl) = trm2abox-string(|tbl) <+ trm2abox-int(|tbl) <+ trm2abox-real(|tbl) <+ trm2abox-list(|tbl) <+ trm2abox-appl(|tbl) <+ log(|Error(),"Cannot rewrite to box: ", <id>) ; fail trm2abox-string(|tbl) = !S(<is-string>) trm2abox-real(|tbl) = !S(<is-real; real-to-string>) trm2abox-int(|tbl) = !S(<is-int; int-to-string>) trm2abox-list(|tbl) = is-list; map(trm2abox(|tbl)) trm2abox-appl(|tbl) = ?f#(args) ; where(<length> args => arity) ; <pptable-get-log(|tbl)> (arity, [f]) => (_, template) ; ![f] => currentpath ; let narg2abox(|n) = arg2abox(|tbl, n, currentpath) in <nmap(narg2abox | 1)> args => aboxes end ; <gpp-instantiate(|aboxes)> template /** * Path is a list. * First element is the constructor name (string) * */ strategies /** * @param n Integer: Argument index * @param path Path of the parent node * @param arg Any term * * @todo Store get-symbol in the table. */ arg2abox(|tbl, n, path) = ?arg ; ![n | path] => new_path ; ( <hashtable-get(|new_path)> tbl => (full_path, template) ; <symbol2abox(|tbl, <pptable-path-get-symbol> full_path, new_path, template)> arg <+ <trm2abox(|tbl)> arg ) strategies symbol2abox(|tbl, symbol, path, template) = ?alt(_, _) ; symbol2abox-alt(|tbl, path, template) <+ (?Some(_) + None()) ; symbol2abox-opt(|tbl, path, template) <+ where(!symbol; (?"iter" + ?"iter-star")) ; symbol2abox-iter(|tbl, path, template) <+ where(!symbol; (?"iter-sep" + ?"iter-star-sep")) ; symbol2abox-iter-sep(|tbl, path, template) <+ where(!symbol => "seq") ; symbol2abox-seq(|tbl, path, template) /** * Rule to format alt(n,[]), with empty list of arguments */ symbol2abox-alt(|tbl, path, template) = ?alt(n, []) ; <gpp-instantiate(|[])> [<index(|n)> template] /** * Rule to format alt(n,[arg]), with non-empty list of arguments */ symbol2abox-alt(|tbl, path, template) = ?alt(n, [arg]) ; <arg2abox(|tbl, n, path)> arg => abox ; <gpp-instantiate(|[abox])> [<index(|n)> template] /** * Rule to format optional: Some(x) */ symbol2abox-opt(|tbl, path, template) = ?Some(<id>) ; arg2abox(|tbl, 1, path) => abox ; <gpp-instantiate(|[abox])> template /** * Rule to format optinal: None */ symbol2abox-opt(|tbl, path, template) = ?None(); ![] /** * Rule to format iter and iter-star list */ symbol2abox-iter(|tbl, path, template) = map(arg2abox(|tbl, 1, path)) => abox ; <gpp-instantiate(| [abox])> template /** * Rule to format iter-sep and iter-star-sep list */ symbol2abox-iter-sep(|tbl, path, template) = map(arg2abox(|tbl, 1, path)) ; if <collect-om(?S(_), conc)> template => [_] then rec x( \ [] -> [] \ <+ \ [e] -> [e] \ <+ \ [e | xs] -> [e, e| <x> xs] \ ) end ; gpp-instantiate-sep-list(|template) /** * Rule ro format sequences */ symbol2abox-seq(|tbl, path, template) = TupleToList ; nzip( \ (n, t) -> <arg2abox(|tbl, n, path)> t \ ) => abox ; <gpp-instantiate(|abox)> template rules /** * Build a sepator list by formatting its elements which are numbered * tuples. Odd entries denote symbols and are formatted using the path * <path>.1; even entries denote separators and are formatted using the path * <path>.2 BuildSepList(|path) : (n, s) -> abox where if <even> n then !1 else !1 end ; <arg2abox> (<id>, path, s) => abox */ /** * The symbol of the SDF production is contained in the path of * pretty-print rules. Get-symbol returns the last symbol of a path. */ pptable-path-get-symbol : Path(cons-name, selectors) -> symbol where <at-last(?[selector(_, symbol)])> selectors