示例#1
0
AstNodePtr SymbolicMultiply::
CodeGenOP( AstInterface &fa, const AstNodePtr& a1, const AstNodePtr& a2) const
  { 
    int val = 0;
    if (fa.IsConstInt(a1, &val) && val == -1)
        return fa.CreateUnaryOP(AstInterface::UOP_MINUS, a2);
    else if (fa.IsConstInt(a2, &val) && val == -1)
        return fa.CreateUnaryOP(AstInterface::UOP_MINUS, a1);
    return fa.CreateBinaryOP(AstInterface::BOP_TIMES, a1, a2); 
  }
示例#2
0
SymbolicVal SymbolicValGenerator ::
GetSymbolicVal( AstInterface &fa, const AstNodePtr& exp)
{
  std::string name;
  AstNodePtr scope;
  int val = 0;
  AstNodePtr s1, s2;
  AstInterface::AstNodeList l;
  AstInterface::OperatorEnum opr = (AstInterface::OperatorEnum)0;
  if (fa.IsVarRef(exp, 0, &name, &scope)) {
     return new SymbolicVar( name, scope );
  }
  else if (fa.IsConstInt(exp, &val)) {
     return new SymbolicConst( val );
  }
  else if (fa.IsBinaryOp(exp, &opr, &s1, &s2)) {
     SymbolicVal v1 = GetSymbolicVal( fa, s1 ), v2 = GetSymbolicVal(fa, s2);
     switch (opr) {
     case AstInterface::BOP_TIMES: return v1 * v2;
     case AstInterface::BOP_PLUS: return v1 + v2;
     case AstInterface::BOP_MINUS: return v1 - v2;
     case AstInterface::BOP_DOT_ACCESS:
     case AstInterface::BOP_ARROW_ACCESS: 
     case AstInterface::BOP_DIVIDE:
        return new SymbolicFunction( opr, "/", v1,v2);
     case AstInterface::BOP_EQ: 
        return new SymbolicFunction( opr, "==", v1,v2);
     case AstInterface::BOP_LE: 
        return new SymbolicFunction( opr, "<=", v1,v2);
     case AstInterface::BOP_LT: 
        return new SymbolicFunction( opr, "<", v1,v2);
     case AstInterface::BOP_NE: 
        return new SymbolicFunction( opr, "!=", v1,v2);
     case AstInterface::BOP_GT: 
        return new SymbolicFunction( opr, ">", v1,v2);
     case AstInterface::BOP_GE: 
        return new SymbolicFunction( opr, ">=", v1,v2);
     case AstInterface::BOP_AND: 
        return new SymbolicFunction( opr, "&&", v1,v2);
     case AstInterface::BOP_OR:
        return new SymbolicFunction( opr, "||", v1,v2);
     default:
        assert(false);
     }
  }
  else if (fa.IsUnaryOp(exp, &opr, &s1)) {
    SymbolicVal v = GetSymbolicVal( fa, s1);
    switch (opr) {
    case AstInterface::UOP_MINUS: 
        return (-1) * v; 
    case AstInterface::UOP_ADDR:
        return new SymbolicFunction( opr, "&", v);
    case AstInterface::UOP_DEREF: 
        return new SymbolicFunction( opr, "*", v);
    case AstInterface::UOP_ALLOCATE:
        return new SymbolicFunction( opr, "new", v);
    case AstInterface::UOP_NOT:
        return new SymbolicFunction( opr, "!", v);
    case AstInterface::UOP_CAST:
        return new SymbolicFunction( opr, "cast", v);
    case AstInterface::UOP_DECR1:
        return new SymbolicFunction( opr, "--", v);
    case AstInterface::UOP_INCR1:
        return new SymbolicFunction( opr, "++", v);
    default:
       std::cerr << "Cannot handle " << AstToString(exp) << ":" << opr << "\n";
       assert(false);
     }
  }
  else if (fa.IsFunctionCall(exp, &s1, &l)) { 
     bool ismin = fa.IsMin(s1), ismax = fa.IsMax(s1);
     AstInterface::AstNodeList::const_iterator p = l.begin();
     if (ismin || ismax) {
       AstNodePtr s = *p;
       SymbolicVal v = GetSymbolicVal( fa, s );  
       for ( ++p; p != l.end(); ++p ) {
           s = *p;
           v = (ismin)? Min(v, GetSymbolicVal(fa, s)) 
                        : Max(v, GetSymbolicVal(fa, s));
       }
       return v;
     }
     if (fa.IsVarRef(exp, 0, &name)) {    
        SymbolicFunction::Arguments args;
        for ( ; p != l.end(); ++p) { 
           SymbolicVal cur = GetSymbolicVal(fa, *p);
           args.push_back( cur );
        }
        return new SymbolicFunction( AstInterface::OP_NONE, name, args);
     }
  } 
  return new SymbolicAstWrap(exp);
}