/*
* This file is part of the X10 project (http://x10-lang.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* (C) Copyright IBM Corporation 2006-2010.
*/
package x10.util.synthesizer;
import java.util.ArrayList;
import java.util.List;
import polyglot.ast.Case;
import polyglot.ast.Expr;
import polyglot.ast.IntLit;
import polyglot.ast.NodeFactory;
import polyglot.ast.Stmt;
import polyglot.ast.Switch;
import polyglot.ast.SwitchBlock;
import polyglot.ast.SwitchElement;
import polyglot.util.Position;
import polyglot.types.Context;
/**
* The first try a state synthesizer for Switch statements
* Currently, it only supports IntLit as case condition.
* Later version should support all NumLit case condition.
*/
public class SwitchSynth extends AbstractStateSynth implements IStmtSynth{
Expr switchCond;
ArrayList<Integer> switchTable; //store the switch condition
ArrayList<List<Stmt>> switchBlockTable; //store the statements under the switch table
List<Stmt> defaultStmts;
public SwitchSynth(NodeFactory xnf, Context context, Position pos, Expr switchCond){
super(xnf, context, pos);
this.switchCond = switchCond;
switchTable = new ArrayList<Integer>();
switchBlockTable = new ArrayList<List<Stmt>>();
}
public void insertStatementsInCondition(int cond, List<Stmt> stmts){
for(Stmt s : stmts){
insertStatementInCondition(cond, s);
}
}
/**
* Will insert the statement in the condition( case cond:)
* If there is no such a condition, just create it, and insert it according to the order
* All statements will be inserted one by one
* @param cond
* @param stmt
*/
public void insertStatementInCondition(int cond, Stmt stmt){
//first look for the switch block
List<Stmt> stmts = null;
for(int i = 0; i < switchTable.size(); i++){
int c = switchTable.get(i);
if(c == cond){
stmts = switchBlockTable.get(i);
break;
}
// if( c > cond){
// //in order to make it clear, the condition should be inserted here
// stmts = new ArrayList<Stmt>();
// switchTable.add(i, cond);
// switchBlockTable.add(i, stmts);
// break;
// }
}
if(stmts == null){
stmts = new ArrayList<Stmt>();
switchTable.add(cond);
switchBlockTable.add(stmts);
}
stmts.add(stmt);
}
/**
* Insert stmts into the switch's default condition
* @param stmts
*/
public void insertStatementsInDefault(List<Stmt> stmts){
for(Stmt stmt : stmts){
insertStatementInDefault(stmt);
}
}
/**
* Insert one stmt into the switch's default condition
* @param stmt
*/
public void insertStatementInDefault(Stmt stmt){
if(defaultStmts == null){
defaultStmts = new ArrayList<Stmt>();
}
defaultStmts.add(stmt);
}
public ArrayList<Integer> getSwitchTable() {
return switchTable;
}
public List<Stmt> getStmtsInCondtion(int i) {
if(switchBlockTable.size() > i){
return switchBlockTable.get(i);
}
else{
return new ArrayList<Stmt>(); //return null;
}
}
public Switch genStmt(){
ArrayList<SwitchElement> switchElements = new ArrayList<SwitchElement>();
//iterate all switch block and statements table to insert it
for(int i = 0; i < switchTable.size(); i++){
int cond = switchTable.get(i);
List<Stmt> stmts = switchBlockTable.get(i);
Expr caseExpr = xnf.IntLit(pos, IntLit.INT, cond).type(xts.Int());
Case ca = xnf.Case(pos, caseExpr);
SwitchBlock swb =xnf.SwitchBlock(pos, stmts);
switchElements.add(ca);
switchElements.add(swb);
}
if(defaultStmts != null && defaultStmts.size() > 0){
switchElements.add(xnf.Default(pos));
switchElements.add(xnf.SwitchBlock(pos, defaultStmts));
}
Switch sw = xnf.Switch(pos,
switchCond, switchElements);
return sw;
}
}