예제 #1
0
void TypeDeduction::Visit(ConditionalExpression* node)
{
    std::map<Expression *, Expression *> *condBranches = node->GetConditionalBranches();
    for (std::map<Expression *, Expression *>::iterator it = condBranches->begin(); it != condBranches->end(); ++it)
    {
        Expression *condition = it->first;
        Expression *condExpr = it->second;
        condition->Accept(this);
        condExpr->Accept(this);
        Type *conditionType = condition->GetTag<Type>("Type");
        if (!conditionType->CanImplicitlyConvertTo(new BooleanType()))
        {
            CompilationContext::GetInstance()->ReportError(node->SourceLocation, false, "Boolean expression expected.");
        }
    }
    node->GetDefaultBranch()->Accept(this);

    Type *defType = node->GetDefaultBranch()->GetTag<Type>("Type");
    for (std::map<Expression *, Expression *>::iterator it = condBranches->begin(); it != condBranches->end(); ++it)
    {
        Expression *condition = it->first;
        Expression *condExpr = it->second;
        Type *exprType = condExpr->GetTag<Type>("Type");
        if (!defType->Equals(exprType))
        {
            node->SetTag<Type>("Type", new VoidType());
            return;
        }
    }
    node->SetTag<Type>("Type", defType);
}
예제 #2
0
void TypeDeduction::Visit(IndexExpression* node)
{
    node->GetContainer()->Accept(this);
    node->GetIndex()->Accept(this);

    Type *containerType = node->GetContainer()->GetTag<Type>("Type");
    Type *indexType = node->GetIndex()->GetTag<Type>("Type");

    if (!indexType->CanImplicitlyConvertTo(new IntegerType(8,true)))
    {
        CompilationContext::GetInstance()->ReportError(node->SourceLocation, false, "Index must be an integer, but %s is provided.", containerType->ToString().c_str());
    }
    
    if (typeid(*containerType) == typeid(ArrayType))
    {
        ArrayType *t= dynamic_cast<ArrayType *>(containerType);
        node->SetTag<Type>("Type", t->GetElementType());
    }
    else if (typeid(*containerType) == typeid(PointerType))
    {
        PointerType *t= dynamic_cast<PointerType *>(containerType);
        node->SetTag<Type>("Type", t->GetUnderlyingType());
    }
    else
    {
        CompilationContext::GetInstance()->ReportError(node->SourceLocation, false, "Index expression requires an array or pointer type, but %s is provided.", containerType->ToString().c_str());
    }
}
예제 #3
0
void TypeDeduction::Visit(AssignExpression* node)
{
    Expression *source = node->GetSource();
    Expression *target = node->GetTarget();

    source->Accept(this);
    target->Accept(this);

    Expression *lvalue = target->GetLValue();
    if (lvalue == NULL)
    {
        
        CompilationContext::GetInstance()->ReportError(node->SourceLocation, false, "Assignment target is not an l-value.");
    }

    if (lvalue->GetTag<Type>("Type") == NULL)
    {
        lvalue->Accept(this);
    }


    Type *sourceType = source->GetTag<Type>("Type");
    Type *targetType = lvalue->GetTag<Type>("Type");

    if (!sourceType->CanImplicitlyConvertTo(targetType))
    {
        
        if (sourceType->CanExplicitlyConvertTo(targetType))
        {
            CompilationContext::GetInstance()->ReportError(node->SourceLocation, false, "Cannot assign %s to %s, an explicit conversion is required.", sourceType->ToString().c_str(), targetType->ToString().c_str());
        }
        else
        {
            CompilationContext::GetInstance()->ReportError(node->SourceLocation, false, "Cannot assign %s to %s.", sourceType->ToString().c_str(), targetType->ToString().c_str());
        }
    }
    else
    {
        if (!sourceType->Equals(targetType))
        {
            ConvertExpression *castExpr = new ConvertExpression(targetType, source);
            node->SetSource(castExpr);
            castExpr->SetTag<Type>("Type", targetType);
        }

        node->SetTag<Type>("Type", targetType);
    }
}