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); }
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); }