7
7
package net.launchpad.vide.algorithm.impl;
9
import java.util.ArrayList;
9
10
import java.util.Collection;
11
import java.util.HashSet;
12
import java.util.List;
10
15
import net.launchpad.vide.algorithm.Algorithm;
16
import net.launchpad.vide.algorithm.AlgorithmFactory;
11
17
import net.launchpad.vide.algorithm.AlgorithmPackage;
18
import net.launchpad.vide.algorithm.Block;
19
import net.launchpad.vide.algorithm.BlockInfo;
20
import net.launchpad.vide.algorithm.BlockType;
21
import net.launchpad.vide.algorithm.BooleanExpression;
22
import net.launchpad.vide.algorithm.Branch;
23
import net.launchpad.vide.algorithm.If;
12
24
import net.launchpad.vide.algorithm.Instruction;
25
import net.launchpad.vide.algorithm.SingleInstruction;
26
import net.launchpad.vide.algorithm.While;
27
import net.launchpad.vide.algorithm.WhileLanguageAlgorithm;
28
import net.launchpad.vide.algorithm.WhileLanguageBlock;
13
29
import net.launchpad.vide.algorithm.WhileLanguageInstruction;
15
import java.util.ArrayList;
16
import java.util.HashSet;
17
import java.util.List;
20
import net.launchpad.vide.algorithm.*;
22
import net.launchpad.vide.algorithm.WhileLanguageAlgorithm;
24
31
import org.eclipse.core.runtime.Assert;
25
import org.eclipse.core.runtime.IStatus;
26
32
import org.eclipse.emf.common.notify.NotificationChain;
28
33
import org.eclipse.emf.common.util.EList;
30
34
import org.eclipse.emf.ecore.EClass;
31
35
import org.eclipse.emf.ecore.InternalEObject;
33
36
import org.eclipse.emf.ecore.impl.EObjectImpl;
35
37
import org.eclipse.emf.ecore.util.EObjectContainmentEList;
36
38
import org.eclipse.emf.ecore.util.InternalEList;
164
168
boolean blockHasOneInstruction= false;
165
169
Instruction nextInstruction = null;
167
//***********************************************************************
168
// preliminary checks - stop processing if reached processed instructions
169
//***********************************************************************
170
if (processedInstructions.contains(instruction)){
171
// we encountered the curious and ambiguous case of a block pointing to some previous block
172
// this could mean: end of an if-branch, a loop or a constraint-breech (e.g. an endless loop or something worse)
173
if (instruction instanceof Branch){
174
if ((Branch)instruction == currentBlockInfo.getParentBranch() && currentBlockInfo.getType() == BlockType.UNKNOWN_BRANCH){// it's a loop body
175
currentBlockInfo.setType(BlockType.LOOP_BODY);
176
// we've reached it's body's end so the block is finished
177
return currentWhileLanguageBlock;
178
} else if ((currentBlockInfo.getType() == BlockType.IF_BODY_FALSE)) {// it's a false body of the loop
171
// check to see the block is not empty
172
if (instruction!=null)
173
blockHasOneInstruction = true;
174
//******************************************
175
// processing instructions further in depth
176
//******************************************
177
while (instruction!=null){
178
//some special case data...
179
boolean needsTransferFromIfBranch = false;
180
Instruction childrenIntersection = null;
182
// check to see that we haven't found a backward connection
183
if (!processedInstructions.contains(instruction)){
184
// make a note that we're processing this instruction
185
// (for detection of backward pointers)
186
processedInstructions.add(instruction);
188
//---------------------------
189
// process single instruction
190
//---------------------------
191
if (instruction instanceof Block){// it's just a block, nothing too complicated
192
// create equivalent WL instruction
193
equivalentWhileLanguageInstruction = AlgorithmFactory.eINSTANCE.createSingleInstruction();
194
((SingleInstruction)equivalentWhileLanguageInstruction).setCommand(((Block)instruction).getCommands());
195
// see what instruction we'll process next
196
nextInstruction = ((Block) instruction).getNext();
198
} else if (instruction instanceof Branch){
199
Branch branch = (Branch)instruction;
200
BooleanExpression condition = AlgorithmFactory.eINSTANCE.createBooleanExpression();
201
condition.setCommand(branch.getCondtion());
203
//----------------------
204
// process true branch
205
// - we don't know if it's an IF or a WHILE
206
//----------------------
207
//prepare information for the child
208
BlockInfo childBlockInfo = AlgorithmFactory.eINSTANCE.createBlockInfo();
209
childBlockInfo.setParentBranch(branch);
210
childBlockInfo.setDepth(currentBlockInfo.getDepth()+1);
211
childBlockInfo.setType(BlockType.UNKNOWN_BRANCH);
213
WhileLanguageBlock trueBlock = processInstructionBlock(branch.getTrue(), processedInstructions, childBlockInfo);
214
if (childBlockInfo.getType() == BlockType.LOOP_BODY){//further child processing told us it is a WHILE
217
equivalentWhileLanguageInstruction = AlgorithmFactory.eINSTANCE.createWhile();
218
((While)equivalentWhileLanguageInstruction).setCondition(condition);
219
// the true block is the loop's body (the next command after the loop will be set later like for a normal single instruction)
220
((While)equivalentWhileLanguageInstruction).setBody(trueBlock);
221
// we continue the program after the while is not true any more
222
nextInstruction=branch.getFalse();
223
} else if (childBlockInfo.getType() == BlockType.IF_BODY_TRUE){//further child processing told us it is an IF
226
equivalentWhileLanguageInstruction = AlgorithmFactory.eINSTANCE.createIf();
227
If whileLanguageIf = (If)equivalentWhileLanguageInstruction;
228
whileLanguageIf.setCondition(condition);
229
// there has to be a true branch - diagram constraint
230
whileLanguageIf.setTrue(trueBlock);
231
if (branch.getFalse()!=null){
232
//----------------------
233
// process false branch
234
// - we know it's an IF - the false block needs to be processed to find where the IF ends
235
//----------------------
236
childBlockInfo.setType(BlockType.IF_BODY_FALSE);
237
WhileLanguageBlock falseBlock = processInstructionBlock(branch.getFalse(), processedInstructions, childBlockInfo);
238
whileLanguageIf.setFalse(falseBlock);
239
needsTransferFromIfBranch = true;
240
childrenIntersection = childBlockInfo.getEndOfIF();
243
// no else block, which means everything else happens in the (processed) true branch - processing is finished
244
nextInstruction=null;
250
//-------------------------------------------------------
251
// finalizing the instruction transformation & adding it
252
//-------------------------------------------------------
253
// a pointer to know where the new command was created from
254
equivalentWhileLanguageInstruction.setTransformedFrom(instruction);
255
// we add the command's while language equivalent to the current block
256
currentWhileLanguageBlock.getInstructions().add(equivalentWhileLanguageInstruction);
257
if (needsTransferFromIfBranch){
258
transferToDifferentBlockAllAfterIntersection(childrenIntersection, ((If)equivalentWhileLanguageInstruction).getTrue(), currentWhileLanguageBlock);
259
nextInstruction = null; // because the true branch already processed all the following instructions
262
// and we move on to the next instruction
263
instruction = nextInstruction;
266
//************************************************************************************
267
// preliminary checks failed - stop processing, because processed instruction reached
268
//************************************************************************************
269
// we encountered the curious and ambiguous case of a block pointing to some previous block
270
// this could mean: end of an if-branch, a loop or a constraint-breech (e.g. an endless loop or something worse)
272
//let's first check for an if-branch
273
if ((currentBlockInfo.getType() == BlockType.IF_BODY_FALSE)) {// it's a false body of the loop
179
274
// we tell our parent what's the intersection of the true and false branches
180
275
currentBlockInfo.setEndOfIF(instruction);
181
276
//TODO: check whether this intersection was processed on the same depth on both sides
182
277
// and we return the (now processed) false branch
183
278
return currentWhileLanguageBlock;
281
// ok, then it's gotta be a loop
282
if (instruction instanceof Branch){
283
if ((Branch)instruction == currentBlockInfo.getParentBranch() && currentBlockInfo.getType() == BlockType.UNKNOWN_BRANCH){// it's a loop body
284
currentBlockInfo.setType(BlockType.LOOP_BODY);
285
// we've reached it's body's end so the block is finished
286
return currentWhileLanguageBlock;
288
//TODO: constraint breach
289
System.out.println("Loops can only lead to the last branch on this depth!");
185
throw new UnknownError("this should never occur");
188
//TODO: constraint breach
189
System.out.println("Looping back to a processed normal instruction is not allowed!");
194
while (instruction!=null){
195
blockHasOneInstruction = true;
197
//******************************************
198
// processing instructions further in depth
199
//******************************************
200
if (instruction instanceof Block){// it's just a block, nothing too complicated
201
// create equivalent WL instruction
202
equivalentWhileLanguageInstruction = AlgorithmFactory.eINSTANCE.createSingleInstruction();
203
((SingleInstruction)equivalentWhileLanguageInstruction).setCommand(((Block)instruction).getCommands());
204
// see what instruction we'll process next
205
nextInstruction = ((Block) instruction).getNext();
207
} else if (instruction instanceof Branch){
208
Branch branch = (Branch)instruction;
210
//----------------------
211
// process true branch
212
// - we don't know if it's an IF or a WHILE
213
//----------------------
214
//prepare information for the child
215
BlockInfo childBlockInfo = AlgorithmFactory.eINSTANCE.createBlockInfo();
216
childBlockInfo.setParentBranch(branch);
217
childBlockInfo.setDepth(currentBlockInfo.getDepth()+1);
218
childBlockInfo.setType(BlockType.UNKNOWN_BRANCH);
220
WhileLanguageBlock trueBlock = processInstructionBlock(branch.getTrue(), processedInstructions, childBlockInfo);
221
if (childBlockInfo.getType() == BlockType.LOOP_BODY){//further child processing told us it is a WHILE
223
equivalentWhileLanguageInstruction = AlgorithmFactory.eINSTANCE.createWhile();
224
// the true block is the loop's body (the next command after the loop will be set later like for a normal single instruction)
225
((While)equivalentWhileLanguageInstruction).setBody(trueBlock);
226
// we continue the program after the while is not true any more
227
nextInstruction=branch.getFalse();
228
} else if (childBlockInfo.getType() == BlockType.IF_BODY_TRUE){//further child processing told us it is an IF
229
equivalentWhileLanguageInstruction = AlgorithmFactory.eINSTANCE.createIf();
230
If whileLanguageIf = (If)equivalentWhileLanguageInstruction;
231
// there has to be a true branch - diagram constraint
232
whileLanguageIf.setTrue(trueBlock);
233
if (branch.getFalse()!=null){
234
//----------------------
235
// process false branch
236
// - we know it's an IF - the false block needs to be processed to find where the IF ends
237
//----------------------
238
childBlockInfo.setType(BlockType.IF_BODY_FALSE);
239
WhileLanguageBlock falseBlock = processInstructionBlock(branch.getFalse(), processedInstructions, childBlockInfo);
240
whileLanguageIf.setFalse(falseBlock);
241
transferToDifferentBlockAllAfterIntersection(childBlockInfo.getEndOfIF(), trueBlock, currentWhileLanguageBlock);
244
// no else block, which means everything else happens in the (processed) true branch - processing is finished
245
nextInstruction=null;
251
//***********************************************************************
252
// finalizing the instruction transformation, before we go to the next one
253
//***********************************************************************
254
// we finished processing this instruction
255
processedInstructions.add(instruction);
256
// a pointer to know where the new command was created from
257
equivalentWhileLanguageInstruction.setTransformedFrom(instruction);
258
// we add the command's while language equivalent to the current block
259
currentWhileLanguageBlock.getInstructions().add(equivalentWhileLanguageInstruction);
260
// and we move on to the next instruction
261
instruction = nextInstruction;
292
//TODO: constraint breach
293
System.out.println("Looping back to a processed normal instruction is not allowed!");
264
298
//---------------------