/**
* 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