/*
    analyzing assignment statement,
    if any variable is not declared report an error
    check the type of left and right
*/
void analyze_assign(Assign assign, char* procName)
{
    analyze_expr(assign.expr, procName);
    getExprType(assign.expr, procName);
    int r = checkType(procName, assign.id, 
        getExprType(assign.expr, procName));

    int j = getArrayType(getType(procName,assign.id)) == 
        getExprType(assign.expr, procName) ? 1:0;

    if(getType(procName,assign.id)==FLOAT_TYPE && 
        getExprType(assign.expr, procName)==INT_TYPE ||
         getType(procName,assign.id)==FLOAT_TYPE && 
          getExprType(assign.expr, procName)==INT_ARRAY_TYPE)
        r = 1;
    if(r == 0 && j == 0)
    {
        printf("wrong assign type of %s.\n", assign.id);
        errorNum++;
    }
    if(r == -1)
    {
        printf("no declaration of %s.\n", assign.id);
        errorNum++;
    }
}
Ejemplo n.º 2
0
const RsArrayType* TypeSystem::getArrayType(const std::string& name, size_t size)
{
    const RsType* bt = getTypeInfo(name);

    assert( bt );
    return getArrayType(bt, size);
}
/*
    analyzing each argument of the function call
    check the arguments number and type with the
    defination of the callee
*/
void analyze_arg(Expr arg, char* callee, int paramNum, char* procName)
{
    if(isParamRef(callee, paramNum)==1)
    {
        // ref parameters
        if (arg->kind != EXPR_ID&& arg->kind!=EXPR_ARRAY)
        {
            printf("ref parameter is not a scaler.\n");
            errorNum++;
        }
        if((getParamType(callee, paramNum) != getExprType(arg, procName)) &&
            (getArrayType(getParamType(callee, paramNum)) != 
                              getExprType(arg, procName)))
        {
            printf("No.%d parameter of function call %s has wrong type.\n",
                paramNum+1, callee);
            errorNum++;
        }
    }
    else if(isParamRef(callee, paramNum)==0)
    {
        // val parameters
        if((getParamType(callee, paramNum) != getExprType(arg, procName)) &&
            (getArrayType(getParamType(callee, paramNum)) != 
                              getExprType(arg, procName)))
        {
            if(getParamType(callee, paramNum) == FLOAT_TYPE && 
                (getExprType(arg, procName) == INT_TYPE ||
                  getExprType(arg, procName) == INT_ARRAY_TYPE))
            {}
            else
            {
                printf("No.%d parameter of function call %s has wrong type.\n",
                    paramNum+1, callee);
                errorNum++;
            }
        }
    }
}
Ejemplo n.º 4
0
bool Type::subtypeOf(Type t2) const {
  // First, check for any members in m_bits that aren't in t2.m_bits.
  if ((m_bits & t2.m_bits) != m_bits) return false;

  // If t2 is a constant, we must be the same constant or Bottom.
  if (t2.m_hasConstVal) {
    assert(!t2.isUnion());
    return m_bits == kBottom || (m_hasConstVal && m_extra == t2.m_extra);
  }

  // If t2 is specialized, we must either not be eligible for the same kind of
  // specialization (Int <= {Int|Arr<Packed>}) or have a specialization that is
  // a subtype of t2's specialization.
  if (t2.isSpecialized()) {
    if (t2.canSpecializeClass()) {
      if (!isSpecialized()) return false;

      //  Obj=A <:  Obj=A
      // Obj<=A <: Obj<=A
      if (m_class.isExact() == t2.m_class.isExact() &&
          getClass() == t2.getClass()) {
        return true;
      }

      //      A <: B
      // ----------------
      //  Obj=A <: Obj<=B
      // Obj<=A <: Obj<=B
      if (!t2.m_class.isExact()) return getClass()->classof(t2.getClass());
      return false;
    }

    assert(t2.canSpecializeArray());
    if (!canSpecializeArray()) return true;
    if (!isSpecialized()) return false;

    // Both types are specialized Arr types. "Specialized" in this context
    // means it has at least one of a RepoAuthType::Array* or (const ArrayData*
    // or ArrayData::ArrayKind). We may return false erroneously in cases where
    // a 100% accurate comparison of the specializations would be prohibitively
    // expensive.
    if (m_arrayInfo == t2.m_arrayInfo) return true;
    auto rat1 = getArrayType();
    auto rat2 = t2.getArrayType();

    if (rat1 != rat2 && !(rat1 && !rat2)) {
      // Different rats are only ok if rat1 is present and rat2 isn't. It's
      // possible for one rat to be a subtype of another rat or array kind, but
      // checking that can be very expensive.
      return false;
    }

    auto kind1 = getOptArrayKind();
    auto kind2 = t2.getOptArrayKind();
    assert(kind1 || kind2);
    if (kind1 && !kind2) return true;
    if (kind2 && !kind1) return false;
    if (*kind1 != *kind2) return false;

    // Same kinds but we still have to check for const arrays. a <= b iff they
    // have the same const array or a has a const array and b doesn't. If they
    // have the same non-nullptr const array the m_arrayInfo check up above
    // should've triggered.
    auto const1 = isConst() ? arrVal() : nullptr;
    auto const2 = t2.isConst() ? t2.arrVal() : nullptr;
    assert((!const1 && !const2) || const1 != const2);
    return const1 == const2 || (const1 && !const2);
  }

  return true;
}
inline char getArrayType(PyArrayObject *args)
{ return getArrayType((PyObject *)(args)); }
/*
    analyzing the type of an expression
    return the type of the expression,
    if there is an type error return ERROR_TYPE
    and report the error
*/
Type getExprType(Expr expr, char* procName)
{
    Type exprType;
    switch (expr->kind)
    {
        case EXPR_ID:
            exprType = getType(procName,expr->id);
            break;
        case EXPR_CONST:
            if(expr->constant.type == BOOL_CONSTANT)
                exprType =  BOOL_TYPE;
            else if(expr->constant.type == INT_CONSTANT)
                exprType =  INT_TYPE;
            else if(expr->constant.type == FLOAT_CONSTANT)
                exprType =  FLOAT_TYPE;
            break;
        case EXPR_BINOP:
            if((expr->binop == BINOP_AND) || (expr->binop ==BINOP_OR))
            {
                // 'and' and 'or' must have bool type operands
                if((getExprType(expr->e1, procName)==BOOL_TYPE||
                     getExprType(expr->e1, procName)==BOOL_ARRAY_TYPE) && 
                      (getExprType(expr->e2, procName)==BOOL_TYPE||
                        getExprType(expr->e2, procName)==BOOL_ARRAY_TYPE))
                    exprType = BOOL_TYPE;
                else
                    exprType = ERROR_TYPE;
            }
            else if(getExprType(expr->e1, procName)==ERROR_TYPE || 
                     getExprType(expr->e2, procName)==ERROR_TYPE)
            {
                exprType =  ERROR_TYPE;
            }
            else if((getExprType(expr->e1, procName)==BOOL_TYPE||
                     getExprType(expr->e1, procName)==BOOL_ARRAY_TYPE) ||
                      (getExprType(expr->e2, procName)==BOOL_TYPE||
                        getExprType(expr->e2, procName)==BOOL_ARRAY_TYPE))
            {
                // other binary operators must not have bool type operands
                printf("wrong binop_expression operand ");
                printf("type of bool in line %d.\n", expr->lineno);
                errorNum++;
                exprType =  ERROR_TYPE;
            }
            else if((getExprType(expr->e1, procName)==INT_TYPE||
                      getExprType(expr->e1, procName)==INT_ARRAY_TYPE) && 
                       (getExprType(expr->e2, procName)==INT_TYPE||
                         getExprType(expr->e2, procName)==INT_ARRAY_TYPE))
            {
                // if both operands are 'int' type, 
                // the expression is 'int' type
                exprType =  INT_TYPE;
            }
            else
                // if one of the operands is 'float' type,
                // the expression is 'float' type
                exprType =  FLOAT_TYPE;
            break;
        case EXPR_UNOP:
            if(expr->unop == UNOP_NOT)
            {
                // 'not' operator must have bool type operand
                if(getExprType(expr->e1, procName)==BOOL_TYPE||
                    getExprType(expr->e1, procName)==BOOL_ARRAY_TYPE)
                    exprType = BOOL_TYPE;
                else
                    exprType = ERROR_TYPE;
            }
            else if(getExprType(expr->e1, procName)==BOOL_TYPE||
                     getExprType(expr->e1, procName)==BOOL_ARRAY_TYPE)
            {
                //'-' operator must not have bool type operand
                printf("wrong Unop_expression type of bool in line %d.\n"
                    , expr->lineno);
                errorNum++;
                exprType =  ERROR_TYPE;
            }
            else
                exprType =  getExprType(expr->e1, procName);
            break;
        case EXPR_RELOP:
            
            if(getExprType(expr->e1, procName)==ERROR_TYPE || 
                getExprType(expr->e2, procName)==ERROR_TYPE)
            {
                exprType =  ERROR_TYPE;
            }
            else if (expr->relop == RELOP_EQ || expr->relop == RELOP_NE)
            {
                if(getExprType(expr->e1, procName) != 
                    getExprType(expr->e2, procName) &&
                     getExprType(expr->e1, procName) != 
                      getArrayType(getExprType(expr->e2, procName))&&
                       getArrayType(getExprType(expr->e1, procName))!=
                        getExprType(expr->e2, procName))
                {
                    printf("relation expression have different operands type.\n");
                    errorNum++;
                    exprType =  ERROR_TYPE;
                }
                else
                    exprType = BOOL_TYPE;
            }
            else if((getExprType(expr->e1, procName)==BOOL_TYPE||
                     getExprType(expr->e1, procName)==BOOL_ARRAY_TYPE)||
                      (getExprType(expr->e2, procName)==BOOL_TYPE||
                        getExprType(expr->e2, procName)==BOOL_ARRAY_TYPE))
            {
                // relation operator must not have bool type operand
                printf("wrong relation expression operand type of bool.\n");
                errorNum++;
                exprType =  ERROR_TYPE;
            }
            else
                // relation expression is bool type
                exprType =  BOOL_TYPE;
            break;
        case EXPR_ARRAY:
                exprType = getType(procName, expr->id);
            break;
        }
        if (exprType == ERROR_TYPE)
        {
            // report an error
            printf("Error type of expression!\n");
            errorNum++;
        }
        return exprType;
}