Examples
This page contains short examples illustrating how the RichReports libraries can be used within each of the languages and platforms.
Contents
Haskell
Assume that we are defining a Haskell module that imports the Haskell RichReports module.
import qualified Text.RichReports as R
Suppose we have the following abstract syntax data structure for a small example of a programming language.
data Program = Program [Stmt] data Stmt = Repeat [Stmt] | Prints Exp | Errors | Pass data Exp = OpPlus Exp Exp | OpMax Exp Exp | OpAbs Exp | Num Integer
It is possible to define a function that converts any abstract syntax tree into a report.
instance R.ToReport Program where report (Program ss) = R.Page $ R.Block [] [] [R.report s | s <- ss] instance R.ToReport Stmt where report s = case s of Repeat ss -> R.Concat [R.Line [R.Keyword "repeat", R.Block [] [] [R.report s | s <- ss]]] Prints e -> R.Line [R.Keyword "print", R.Entity R.Space, R.report e] Errors -> R.Line [ R.Span [R.HighlightError] [R.Text "This is a message that applies to the whole highlighted span"] [R.Keyword "error"], R.Entity R.Space, R.Text "outside", R.Entity R.Space, R.Text "span" ] Pass -> R.Line [R.Keyword "pass"] instance R.ToReport Exp where report e = case e of OpPlus e1 e2 -> R.Concat [R.report e1, R.Keyword "+", R.report e2] OpMax e1 e2 -> R.Concat [ R.Builtin "max", R.Punctuation "(", R.report e1, R.Punctuation ",", R.report e2, R.Punctuation ")" ] OpAbs e -> R.Concat [R.Builtin "abs", R.Punctuation "(", R.report e, R.Punctuation ")"] Num i -> R.Atom [] [R.Text "int"] [R.Konstant (show i)]
JavaScript
Assume that we are defining a JavaScript module that imports the JavaScript RichReports module.
var uxadt = require('uxadt'); var _ = null; var R = require('richreports');
Suppose we have the following abstract syntax data structure for a small example of a programming language (defined using the JavaScript UxADT library).
uxadt._('Program', { Program: [['Stmt']] }); uxadt._('Stmt', { Repeat: [['Stmt']], Prints: ['Exp'], Errors: [], Pass: [] }); uxadt._('Exp', { OpPlus: ['Exp', 'Exp'], OpMax: ['Exp', 'Exp'], OpAbs: ['Exp'], Num: ['#'] });
It is possible to define a function that converts any abstract syntax tree into a report (again, we use the JavaScript UxADT library to define an implementation that uses pattern matching).
function report(a) { return a ._(Program(_), function(ss) { var rs = []; for (var i = 0; i < ss.length; i++) rs.push(report(ss[i])); return R.Page(R.Block([], [], rs)); }) ._(Repeat(_), function(ss) { var rs = []; for (var i = 0; i < ss.length; i++) rs.push(report(ss[i])); return ( R.Concat([ R.Line([R.Keyword('repeat')]), R.Block([], [], rs) ]) ); }) ._(Prints(_), function(e) { return R.Line([R.Keyword('print'), R.Entity(R.Space()), report(e)]); }) ._(Errors(), function() { return ( R.Line([ R.Span( [R.HighlightError()], [R.Text('This is a message that applies to the whole highlighted span.')], [R.Keyword('error')] ), R.Entity(R.Space()), R.Text('outside'), R.Entity(R.Space()), R.Text('span') ]) ); }) ._(Pass(), function() { return R.Line([R.Keyword('pass')]); }) ._(OpPlus(_, _), function(e1, e2) { return R.Concat([report(e1), R.Keyword('+'), report(e2)]); }) ._(OpMax(_, _), function(e1, e2) { return R.Concat([ R.Builtin('max'), R.Punctuation('('), report(e1), R.Punctuation(','), report(e2), R.Punctuation(')') ]); }) ._(OpAbs(_), function(e) { return R.Concat([ R.Builtin('abs'), R.Punctuation('('), report(e), R.Punctuation(')') ]); }) ._(Num(_), function(n) { return R.Atom([], [R.Text('int')], [R.Konstant(''+n+'')]); }) .end; }
PHP
Assume that we are defining a Haskell module that imports the PHP RichReports library.
include_once("uxadt.php"); if (!defined('_')) define('_', null); include_once("richreports.php");
Suppose we have the following abstract syntax data structure for a small example of a programming language (defined using the PHP UxADT library).
\uxadt\_('Program', array( 'Program' => array(array('Stmt')) )); \uxadt\_('Stmt', array( 'Repeat' => array(array('Stmt')), 'Prints' => array('Exp'), 'Errors' => array(), 'Pass' => array() )); \uxadt\_('Exp', array( 'OpPlus' => array('Exp', 'Exp'), 'OpMax' => array('Exp', 'Exp'), 'OpAbs' => array('Exp'), 'Num' => array('#') ));
It is possible to define a function that converts any abstract syntax tree into a report (again, we use the PHP UxADT library to define an implementation that uses pattern matching).
function report($a) { if ($a->_(Program(_))) { list($ss) = $a(); $rs = array(); foreach ($ss as $s) array_push($rs, report($s)); return Page(Block(array(), array(), $rs)); } else if ($a->_(Repeat(_))) { list($ss) = $a(); $rs = array(); foreach ($ss as $s) array_push($rs, report($s)); return Concat(array( Line(array(Keyword('repeat'))), Block(array(), array(), $rs) )); } else if ($a->_(Prints(_))) { list($e) = $a(); return Line(array(Keyword('print'), Entity(Space()), report($e))); } else if ($a->_(Errors())) { return Line(array( Span( array(HighlightError()), array(Text('This is a message that applies to the whole highlighted span.')), array(Keyword('error')) ), Entity(Space()), Text('outside'), Entity(Space()), Text('span') )); } else if ($a->_(Pass())) { return Line(array(Keyword('pass'))); } else if ($a->_(OpPlus(_,_))) { list($e1,$e2) = $a(); return Concat(array(report($e1), Keyword('+'), report($e2))); } else if ($a->_(OpMax(_,_))) { list($e1,$e2) = $a(); return Concat(array( Builtin('max'), Punctuation('('), report($e1), Punctuation(','), report($e2), Punctuation(')') )); } else if ($a->_(OpAbs(_))) { list($e) = $a(); return Concat(array(Builtin('abs'), Punctuation('('), report($e), Punctuation(')'))); } else if ($a->_(Num(_))) { list($n) = $a(); return Atom(array(), array(Text('int')), array(Konstant(''.$n.''))); } }
Python
Assume that we are defining a Haskell module that imports the Python RichReports module.
import uxadt import richreports as R
Suppose we have the following abstract syntax data structure for a small example of a programming language (defined using the Python UxADT library).
uxadt._('Program', {\ 'Program': [['Stmt']] }) uxadt._('Stmt', {\ 'Repeat': [['Stmt']],\ 'Prints': ['Exp'],\ 'Errors': [],\ 'Pass': []\ }) uxadt._('Exp', {\ 'OpPlus': ['Exp', 'Exp'],\ 'OpMax': ['Exp', 'Exp'],\ 'OpAbs': ['Exp'],\ 'Num': ['#'] })
It is possible to define a function that converts any abstract syntax tree into a report (again, we use the Python UxADT library to define an implementation that uses pattern matching).
def report(a): if a < Program(_): (ss,) = a return R.Page(R.Block([], [], [report(s) for s in ss])) if a < Repeat(_): (ss,) = a return\ R.Concat([\ R.Line([R.Keyword('repeat')]),\ R.Block([], [], [report(s) for s in ss])\ ]) if a < Prints(_): (e,) = a return R.Line([R.Keyword('print'), R.Entity(R.Space()), report(e)]) if a < Errors(): return\ R.Line([\ R.Span(\ [R.HighlightError()],\ [R.Text('This is a message that applies to the whole highlighted span.')],\ [R.Keyword('error')]\ ),\ R.Entity(R.Space()),\ R.Text('outside'),\ R.Entity(R.Space()),\ R.Text('span')\ ]) if a < Pass(): return R.Line([R.Keyword('pass')]) if a < OpPlus(_,_): (e1,e2) = a return R.Concat([report(e1), R.Keyword('+'), report(e2)]) if a < OpMax(_,_): (e1,e2) = a return R.Concat([\ R.Builtin('max'),\ R.Punctuation('('),\ report(e1),\ R.Punctuation(','),\ report(e2),\ R.Punctuation(')')\ ]) if a < OpAbs(_): (e,) = a return R.Concat([R.Builtin('abs'), R.Punctuation('('), report(e), R.Punctuation(')')]) if a < Num(_): (n,) = a return R.Atom([], [R.Text('int')], [R.Konstant(str(n))])