Project

General

Profile

root / trunk / compiler / ooasCompiler / src / org / momut / ooas / visitors / optimisation / OoaRemoveTrivialSequentialCompositionVisitor.java @ 7

1
/**
2
  *
3
  *                      OOAS Compiler
4
  *
5
  *       Copyright 2015, AIT Austrian Institute of Technology.
6
  * This code is based on the C# Version of the OOAS Compiler, which is
7
  * copyright 2015 by the Institute of Software Technology, Graz University
8
  * of Technology with portions copyright by the AIT Austrian Institute of
9
  * Technology. All rights reserved.
10
  *
11
  * SEE THE "LICENSE" FILE FOR THE TERMS UNDER WHICH THIS FILE IS PROVIDED.
12
  *
13
  * If you modify the file please update the list of contributors below to in-
14
  * clude your name. Please also stick to the coding convention of using TABs
15
  * to do the basic (block-level) indentation and spaces for anything after
16
  * that. (Enable the display of special chars and it should be pretty obvious
17
  * what this means.) Also, remove all trailing whitespace.
18
  *
19
  * Contributors:
20
  *               Willibald Krenn (AIT)
21
  *               Stephan Zimmerer (AIT)
22
  *               Markus Demetz (AIT)
23
  *               Christoph Czurda (AIT)
24
  *
25
  */
26

    
27

    
28
package org.momut.ooas.visitors.optimisation;
29

    
30
import org.momut.ooas.ast.AstNodeTypeEnum;
31
import org.momut.ooas.ast.IAst;
32
import org.momut.ooas.ast.IScope;
33
import org.momut.ooas.ast.identifiers.FunctionIdentifier;
34
import org.momut.ooas.ast.identifiers.Identifier;
35
import org.momut.ooas.ast.identifiers.IdentifierKind;
36
import org.momut.ooas.ast.statements.Block;
37
import org.momut.ooas.ast.statements.GuardedCommand;
38
import org.momut.ooas.ast.statements.SeqBlock;
39
import org.momut.ooas.ast.statements.Statement;
40
import org.momut.ooas.ast.statements.StatementKind;
41
import org.momut.ooas.parser.ParserState;
42
import org.momut.ooas.utils.exceptions.NotImplementedException;
43
import org.momut.ooas.utils.exceptions.InternalCompilerException;
44
import org.momut.ooas.utils.exceptions.OoasCompilerRuntimeException;
45
import org.momut.ooas.visitors.OoaCompleteAstTraversalVisitor;
46

    
47
/**
48
 * Removes Seq blocks that only have one element...
49
 * @author KrennW
50
 */
51
public final class OoaRemoveTrivialSequentialCompositionVisitor extends OoaCompleteAstTraversalVisitor {
52

    
53
        private void setNewParent(Statement s, final IScope oldScope,final IScope newParentScope) {
54
                class ParentScopeVis extends OoaCompleteAstTraversalVisitor {
55
                        @Override
56
                        protected void VisitAstElement(IAst element, IAst parent) {
57
                                if (element instanceof IScope) {
58
                                        final IScope scope = (IScope) element;
59
                                        if (scope.GetParentScope() == oldScope)
60
                                                scope.SetParentScope(newParentScope);
61
                                }
62
                                super.VisitAstElement(element, parent);
63
                        }
64

    
65
                        public ParentScopeVis() {
66
                                super(null);
67
                        }
68

    
69
                }
70
                if (s instanceof IScope)
71
                        ((IScope)s).SetParentScope(newParentScope);
72
                final ParentScopeVis visitor = new ParentScopeVis();
73
                s.Accept(visitor);
74
        }
75

    
76
        /// <summary>
77
        /// replaces the seqBlock by its child
78
        /// </summary>
79
        private IAst ConvertNondetBlock(SeqBlock seqBlock, IAst parent)
80
        {
81
                if (seqBlock.statements().size() <= 1 &&            // max one statement in block
82
                    seqBlock.isSimpleBlock() &&                     // block must not have local vars etc.
83
                    parent.nodeType() !=  AstNodeTypeEnum.type)     // we cannot simplify if block is owned by an OoActionSystem since dood always is a block
84
                {
85
                        final Statement stmt = seqBlock.statements().peekFirst();
86
                        setNewParent(stmt, seqBlock, seqBlock.GetParentScope()); // change AST and correct all parentscope pointers to this seqblock
87

    
88
                        switch (parent.nodeType())
89
                        {
90
                        case statement:
91
                                switch (((Statement)parent).kind())
92
                                {
93
                                case SeqBlock:
94
                                case NondetBlock:
95
                                case PrioBlock:
96
                                        final Block aBlock = (Block)parent;
97
                                        final int idx = aBlock.statements().indexOf(seqBlock);
98
                                        if (idx == -1)
99
                                                throw new OoasCompilerRuntimeException(); // must not happen?!
100
                                        aBlock.statements().set(idx, stmt);
101
                                        break;
102
                                case GuardedCommand:
103
                                        final GuardedCommand gc = (GuardedCommand)parent;
104
                                        if(gc.body() != seqBlock) // ref equ.
105
                                                throw new InternalCompilerException("Internal Error: Cannot replace guarded command body.");
106
                                        gc.SetBody(stmt);
107
                                        break;
108
                                default:
109
                                        throw new NotImplementedException();
110
                                }
111
                                break;
112
                        case identifier:
113
                                switch (((Identifier)parent).kind())
114
                                {
115
                                case NamedActionIdentifier:
116
                                case MethodIdentifier:
117
                                        final FunctionIdentifier method = (FunctionIdentifier)parent;
118
                                        if (method.body() != seqBlock) // ref equ.
119
                                                throw new InternalCompilerException("Internal Error: Cannot replace method body.");
120
                                        method.SetBody(stmt);
121
                                        break;
122
                                default:
123
                                        throw new NotImplementedException();
124
                                }
125
                                break;
126
                        default:
127
                                throw new NotImplementedException();
128
                        }
129
                        m_changes = true;
130
                        return stmt;
131
                }
132
                else
133
                        return seqBlock;
134
        }
135

    
136

    
137
        @Override
138
        protected void VisitAstElement(IAst element, IAst parent)
139
        {
140
                if ( (element.nodeType() == AstNodeTypeEnum.statement) &&
141
                     (((Statement)element).kind() == StatementKind.SeqBlock) &&
142
                      // we're only interested in actionblock and actionbody composition, not in type composition
143
                     !(parent.nodeType() == AstNodeTypeEnum.identifier &&
144
                       ((Identifier)parent).kind() == IdentifierKind.List))
145
                {
146
                        final IAst newchild = ConvertNondetBlock((SeqBlock)element, parent);
147
                        super.VisitAstElement(newchild, parent);
148
                }
149
                else
150
                        super.VisitAstElement(element, parent);
151
        }
152

    
153
        private boolean m_changes = false;
154

    
155
        public OoaRemoveTrivialSequentialCompositionVisitor(ParserState aState)
156
        {
157
                super (aState);
158
        }
159

    
160

    
161
        public boolean changedAst() {
162
                return m_changes;
163
        }
164

    
165
}