package com.hpctoday.fada.c2fada;
import java.util.Collections;
import java.util.List;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import com.hpctoday.fada.Assignment;
import com.hpctoday.fada.Expression;
import com.hpctoday.fada.Statement;
import com.hpctoday.fada.FADA_Index;
/*
* AST node for FADA assignment statement
* Other statements are not considered by FADA AST
* TODO: Make other statements "dummy" ones
* TODO: tag fada statements with ast statments
*/
public class StmtVisitor extends ASTVisitor {
private Statement parent;
private boolean inElse;
StmtVisitor(Statement _parent, IASTStatement stmt, boolean inElse) {
parent = _parent;
this.shouldVisitExpressions=true;
this.inElse = inElse;
}
private boolean isAssign (IASTBinaryExpression expr) {
int op = expr.getOperator();
if (op == IASTBinaryExpression.op_assign ||
op == IASTBinaryExpression.op_plusAssign ||
op == IASTBinaryExpression.op_minusAssign ||
op == IASTBinaryExpression.op_divideAssign ||
op == IASTBinaryExpression.op_multiplyAssign)
return true;
return false;
}
@Override
public int visit(IASTExpression expr) {
if (expr instanceof IASTBinaryExpression) {
IASTBinaryExpression bexpr = (IASTBinaryExpression) expr;
if (isAssign(bexpr)) {
ExprVisitor rhsVisitor = new ExprVisitor();
bexpr.getOperand2().accept(rhsVisitor);
Expression rhs = rhsVisitor.getExpr();
ExprVisitor lhsVisitor = new ExprVisitor();
switch (bexpr.getOperator()) {
case IASTBinaryExpression.op_plusAssign:
bexpr.getOperand1().accept(lhsVisitor);
rhs = lhsVisitor.getExpr().add(rhs);
break;
case IASTBinaryExpression.op_minusAssign:
bexpr.getOperand1().accept(lhsVisitor);
rhs=lhsVisitor.getExpr().sub(rhs);
break;
case IASTBinaryExpression.op_divideAssign:
bexpr.getOperand1().accept(lhsVisitor);
rhs=lhsVisitor.getExpr().div(rhs);
break;
case IASTBinaryExpression.op_multiplyAssign:
bexpr.getOperand1().accept(lhsVisitor);
rhs=lhsVisitor.getExpr().mul(rhs);
break;
case IASTBinaryExpression.op_assign:
break;
default:
System.err.println ("Operator is not handled !");
}
IASTExpression operand1 = bexpr.getOperand1();
while(operand1 instanceof IASTUnaryExpression && ((IASTUnaryExpression)operand1).getOperator() == IASTUnaryExpression.op_bracketedPrimary){
IASTUnaryExpression unOperand1 = (IASTUnaryExpression)operand1;
operand1 = unOperand1.getOperand();
}
if(operand1 instanceof IASTIdExpression){
Statement stmt = new Statement(new Assignment (operand1.getRawSignature(),rhs));
if(inElse) parent.Enclose(stmt, true);
else parent.Enclose(stmt, false);
}
else if (operand1 instanceof IASTArraySubscriptExpression) {
ArrayAccessVisitor aVisitor = new ArrayAccessVisitor();
operand1.accept(aVisitor);
List<Expression> flist = aVisitor.indices;
Collections.reverse(flist);
Statement stmt = new Statement(new Assignment (aVisitor.id, new FADA_Index(flist), rhs));
if(inElse) parent.Enclose(stmt, true);
else parent.Enclose(stmt, false);
} else {
//bexpr.getOperand1().accept(lhsVisitor);
//FadaExpression lhs = lhsVisitor.getExpr();
System.err.println("StmtVisitor.visit: unknown binary operand " + bexpr.getOperand1() + " " + expr.getRawSignature());
}
} else {
System.err.println("StmtVisitor.visit: unknown binary expression " + expr.getRawSignature());
}
} else if(expr instanceof IASTUnaryExpression){
visit((IASTUnaryExpression)expr);
} else if (expr instanceof IASTFunctionCallExpression){
ExprVisitor visitor = new ExprVisitor();
expr.accept(visitor);
Statement stmt = new Statement(new Assignment ("", visitor.getExpr()));
if(inElse) parent.Enclose(stmt, true);
else parent.Enclose(stmt, false);
} else {
System.err.println("StmtVisitor.visit: unknown expression (" + expr.getClass() + ") " + expr.getRawSignature() );
}
return PROCESS_SKIP;
}
private int visit(IASTUnaryExpression expr){
switch (expr.getOperator()){
case IASTUnaryExpression.op_bracketedPrimary:
return visit(expr.getOperand());
case IASTUnaryExpression.op_prefixIncr:
case IASTUnaryExpression.op_postFixIncr:
{
ExprVisitor lhsVisitor = new ExprVisitor();
((IASTUnaryExpression) expr).getOperand().accept(lhsVisitor);
Expression lhsExpr = lhsVisitor.getExpr();
String lhs = lhsExpr.Generate_C_Code();
Expression rhs = lhsExpr.add(1);
Statement stmt = new Statement(new Assignment (lhs, rhs));
if(inElse) parent.Enclose(stmt, true);
else parent.Enclose(stmt, false);
}
break;
case IASTUnaryExpression.op_prefixDecr:
case IASTUnaryExpression.op_postFixDecr:
{
ExprVisitor lhsVisitor = new ExprVisitor();
((IASTUnaryExpression) expr).getOperand().accept(lhsVisitor);
Expression lhsExpr = lhsVisitor.getExpr();
String lhs = lhsExpr.Generate_C_Code();
Expression rhs = lhsExpr.add(1);
Statement stmt = new Statement(new Assignment (lhs, rhs));
if(inElse) parent.Enclose(stmt, true);
else parent.Enclose(stmt, false);
}
break;
default:
System.err.println("StmtVisitor.visit: unknown unary op " + expr.getOperator() + " " + expr.getRawSignature());
}
return PROCESS_SKIP;
}
}