public class ExpressionFlattener extends NodeVisitor
Modifier and Type | Field and Description |
---|---|
protected java.util.Stack<java.util.List<Stmt>> |
blockStack
Stack of nested blocks we are currently in.
|
protected DeepCopy |
deepCopier
Used to copy a whole AST subtree.
|
protected java.util.Set<Expr> |
dontFlatten
Set of expressions not to flatten.
|
protected boolean |
flatten_all_decls
Whether to move initializers of created localDecls to assignments
|
protected Job |
job |
protected NodeFactory |
nf |
protected TypeSystem |
ts |
Constructor and Description |
---|
ExpressionFlattener(Job job,
TypeSystem ts,
NodeFactory nf) |
ExpressionFlattener(Job job,
TypeSystem ts,
NodeFactory nf,
boolean flatten_all_decls) |
Modifier and Type | Method and Description |
---|---|
protected void |
addDontFlatten(Expr e)
Add e to the list of expressions not to flatten.
|
protected void |
addStmt(Stmt s)
Adds a statement to the current block.
|
protected If |
createAndIf(Expr cond,
Local l,
Expr e,
Binary original)
Create an if statement that assigns to l the value
of "cond && e", evaluating e only if "cond" is true.
|
protected Eval |
createAssign(Expr l,
Expr r)
Create an assignment from r to l, i.e., "l = r;"
|
protected Block |
createBlock(Stmt s) |
protected BooleanLit |
createBool(boolean val)
Create a boolean literal
|
protected If |
createCondIf(Expr cond,
Local l,
Expr e1,
Expr e2,
Conditional original)
Create an if statement that assigns to l the value
of "cond ? e1 : e2"
i.e., "if (cond) l = e1; else l = e2"
|
protected LocalDecl |
createDecl(Type t,
Position pos,
Expr init)
Create a declaration for a local variable with the type t at
position pos, with initializing expression init.
|
protected Local |
createDeclWithInit(Type t,
Position pos,
Expr val)
Create a local declaration that can take a value of the
type t, and initialize it to the expression val.
|
protected Empty |
createEmpty() |
protected Eval |
createEval(Expr e) |
protected Eval |
createIncDec(Unary u)
Convert an increment or decrement to an assignment,
e.g.
|
protected IntLit |
createInt(int val)
Create an int literal
|
protected Local |
createLocal(LocalDecl d)
Create a use of the Local that is declared in the LocalDecl d
|
protected If |
createOrIf(Expr cond,
Local l,
Expr e,
Binary original)
Create an if statement that assigns to l the value
of "cond || e", evaluating e only if "cond" is false.
|
protected Assign |
createSimpleAssign(Assign a)
Convert an assignment "l op= r" to "l = (L)(l op r)" where L is the type of l
|
protected Type |
declType(Type t) |
protected Node |
deepCopy(Node n) |
protected boolean |
dontFlatten(Expr e)
Returns true if e should never be flattened or if e has been added to
the don't flatten list.
|
NodeVisitor |
enter(Node n)
Begin normal traversal of a subtree rooted at
n . |
Expr |
flattenExpr(Expr n,
Expr old) |
protected boolean |
inBlock()
Checks to see if we are in a block.
|
protected boolean |
isAssign(Expr e)
Returns true for assignments, and pre and post increments
and decrements.
|
protected boolean |
isSimpleAssign(Expr e) |
Node |
leave(Node parent,
Node old,
Node n,
NodeVisitor v)
This method is called after all of the children of
n
have been visited. |
protected boolean |
neverFlatten(Expr e)
Returns true if the expression e is of a type that should never be
flattened.
|
protected java.lang.String |
newId() |
Node |
override(Node parent,
Node n)
Given a tree rooted at
n , the visitor has the option of
overriding all traversal of the children of n . |
protected java.util.List<Stmt> |
popBlock()
Pops a block off the stack.
|
protected <N extends Node> |
postCreate(N n)
Whenever a new node is created, this method is called and should do
additional processing of the node as needed.
|
protected void |
pushBlock()
Pushes a new (nested) block onto the stack.
|
protected Expr |
translateBinary(Binary b) |
protected Stmt |
translateLocalDecl(LocalDecl d) |
protected Expr |
translateShortCircuitBinary(Binary b) |
protected Type |
typeOf(Expr e) |
protected Type |
typeOf(LocalInstance li) |
protected final Job job
protected final TypeSystem ts
protected final NodeFactory nf
protected final java.util.Stack<java.util.List<Stmt>> blockStack
protected final java.util.Set<Expr> dontFlatten
protected final DeepCopy deepCopier
protected boolean flatten_all_decls
public ExpressionFlattener(Job job, TypeSystem ts, NodeFactory nf)
public ExpressionFlattener(Job job, TypeSystem ts, NodeFactory nf, boolean flatten_all_decls)
public Node override(Node parent, Node n)
NodeVisitor
n
, the visitor has the option of
overriding all traversal of the children of n
. If no
changes were made to n
and the visitor wishes to prevent
further traversal of the tree, then it should return n
. If
changes were made to the subtree, then the visitor should return a
copy of n
with appropriate changes. Finally, if the
visitor does not wish to override traversal of the subtree rooted at
n
, then it should return null
.
The default implementation of this method is to call
override(n)
, as most subclasses do not need to know
the parent of the node n
.
override
in class NodeVisitor
parent
- The parent of n
,
null
if n
has no parent.n
- The root of the subtree to be traversed.null
if it
is to continue.public NodeVisitor enter(Node n)
NodeVisitor
n
. This gives
the visitor the option of changing internal state or returning a new
visitor which will be used to visit the children of n
.
This method is typically called by the method
enter(parent, n)
. If a subclass overrides the
method enter(parent, n)
then this method
may not be called.
enter
in class NodeVisitor
n
- The root of the subtree to be traversed.NodeVisitor
which should be used to visit the
children of n
.public Node leave(Node parent, Node old, Node n, NodeVisitor v)
NodeVisitor
n
have been visited. In this case, these children were visited by the
visitor v
. This is the last chance for the visitor to
modify the tree rooted at n
. This method will be called
exactly the same number of times as entry
is called.
That is, for each node that is not overridden, enter
and
leave
are each called exactly once.
Note that if old == n
then the visitor should make a copy
of n
before modifying it. It should then return the
modified copy.
The default implementation of this method is to call
leave(old, n, v)
,
as most subclasses do not need to know the parent of the
node n
.
leave
in class NodeVisitor
parent
- The parent of old
,
null
if old
has no parent.old
- The original state of root of the current subtree.n
- The current state of the root of the current subtree.v
- The NodeVisitor
object used to visit the children.n
.protected Local createDeclWithInit(Type t, Position pos, Expr val)
SemanticException
protected boolean dontFlatten(Expr e)
protected void addDontFlatten(Expr e)
protected boolean neverFlatten(Expr e)
protected void pushBlock()
protected java.util.List<Stmt> popBlock()
protected boolean inBlock()
protected void addStmt(Stmt s)
protected <N extends Node> N postCreate(N n)
protected java.lang.String newId()
protected boolean isAssign(Expr e)
protected boolean isSimpleAssign(Expr e)
protected Empty createEmpty()
protected LocalDecl createDecl(Type t, Position pos, Expr init)
protected Local createLocal(LocalDecl d)
protected Eval createAssign(Expr l, Expr r)
l
- r
- protected Assign createSimpleAssign(Assign a)
protected Eval createIncDec(Unary u)
SemanticException
protected If createAndIf(Expr cond, Local l, Expr e, Binary original)
protected If createOrIf(Expr cond, Local l, Expr e, Binary original)
protected If createCondIf(Expr cond, Local l, Expr e1, Expr e2, Conditional original)
protected BooleanLit createBool(boolean val)
protected IntLit createInt(int val)
protected Type typeOf(LocalInstance li)