/**
* Simplify insane features of Java.
*
* @author Martin Bravenboer <martin@cs.uu.nl>
*/
module dryad/simplify/Sanity
imports
dryad/lib-ext/list
/**
* @todo Desugar multiple variable declarations
*/
strategies
dryad-simplify-sanity =
topdown-consnil(try(dryad-simplify-sanity-rules))
dryad-simplify-sanity-rules =
DryadSimplify-BracketsInDeclarator
<+ DryadSimplify-MultipleFieldDeclarator
<+ DryadSimplify-MultipleConstantDeclarator
/**
* Rewrites multiple field declarators in a single declaration to multiple declarations
* with a single declarator.
*
* For example, "private int x, y;" is rewritten to "private int x; private int y;"
*/
rules
DryadSimplify-MultipleFieldDeclarator :
[FieldDec(mods, type, [fdec1, fdec2 | fdecs]) | decs]
->
[FieldDec(mods, type, [fdec1]), FieldDec(mods, type, [fdec2 | fdecs]) | decs]
DryadSimplify-MultipleConstantDeclarator :
[ConstantDec(mods, type, [fdec1, fdec2 | fdecs]) | decs]
->
[ConstantDec(mods, type, [fdec1]), ConstantDec(mods, type, [fdec2 | fdecs]) | decs]
/**
* Moves all array dimensions to the type of a variable declaration.
*
* For example, int x[]; will be rewritten to int[] x;
* @todo This doesn't fix 'for (int a, b[];;);'
*/
rules
DryadSimplify-BracketsInDeclarator :
LocalVarDec(mods, component-type, [array-vardec])
->
LocalVarDec(mods, array-type, [vardec])
where
<strip-dimensions-from-vardec> array-vardec => (vardec, dims)
; <component-type-to-array-type(|dims)> component-type => array-type
DryadSimplify-BracketsInDeclarator :
Param(mods, component-type, ArrayVarDecId(name, dims))
->
Param(mods, array-type, name)
where
<component-type-to-array-type(|dims)> component-type => array-type
/**
* @type VarDec -> (VarDec, List(Dim))
*/
rules
strip-dimensions-from-vardec :
VarDec(ArrayVarDecId(Id(x), dims), init) -> (VarDec(Id(x), init), dims)
strip-dimensions-from-vardec :
VarDec(ArrayVarDecId(Id(x), dims)) -> (VarDec(Id(x)), dims)
strategies
/**
* Given dimensions, constructs an array type from a component type.
*
* @param List(Dim)
* @type Type -> Type
*/
component-type-to-array-type(|dims) =
let next(|dim) = !ArrayType(<id>)
in foldl(next | dims)
end