Example #1
0
void
ArrayIndexNode::computeType (LContext &lcontext, const SymbolInfoPtr &initInfo)
{
    if (!array || !index)
	return;

    array->computeType (lcontext, initInfo);
    index->computeType (lcontext, initInfo);

    if (!array->type || !index->type)
	return;

    ArrayTypePtr arrayType = array->type.cast<ArrayType>();

    if (!arrayType)
    {
	string name = "";
	if( NameNodePtr arrayName =  array.cast<NameNode>() )
	{
	    name = arrayName->name;
	    MESSAGE_LE (lcontext, ERR_NON_ARR_IND, array->lineNumber,
			"Applied [] operator to non-array (" << name << " "
			"is of type " << array->type->asString() << ").");
	}
	else
	{
	    MESSAGE_LE (lcontext, ERR_NON_ARR_IND, array->lineNumber,
			"Applied [] operator to non-array of type " 
			<< array->type->asString() << ".");
	}
	type = lcontext.newIntType();
	return;
    }

    IntTypePtr intType = lcontext.newIntType ();

    if (!intType->canPromoteFrom (index->type))
    {
	string name = "";
	if( NameNodePtr arrayName =  array.cast<NameNode>() )
	    name = arrayName->name;

	MESSAGE_LE (lcontext, ERR_ARR_IND_TYPE, array->lineNumber,
	    "Index into array " << name << " is not an iteger "
	    "(index is of type " << index->type->asString() << ").");

	type = lcontext.newIntType();
	return;
    }

    type = arrayType->elementType();
}
Example #2
0
void
MemberNode::computeType (LContext &lcontext, const SymbolInfoPtr &initInfo)
{
    obj->computeType (lcontext, initInfo);

    if (!obj->type)
    {
	type = lcontext.newIntType();
	return;
    }

    StructTypePtr structType = obj->type.cast<StructType>();

    if (!structType)
    {
	MESSAGE_LE (lcontext, ERR_NON_STRUCT, lineNumber,
		    "Applied member access operator to non-struct "
		    "of type " << obj->type->asString() << ".");

	type = lcontext.newIntType();
	return;
    }

    //
    // check that the member exists and gets its type
    //

    for (MemberVectorConstIterator it = structType->members().begin(); 
 	 it != structType->members().end(); 
	 it++)
    {
	if (it->name == member)
	{
	    type = it->type;
	    offset = it->offset;
	    return;
	}
    }

    if (!type)
    {
	MESSAGE_LE (lcontext, ERR_MEMBER_ACCESS, lineNumber,
		    "Unable to find member \"" << member << "\".");

	type = lcontext.newIntType();
    }
}
Example #3
0
IntLiteralNode::IntLiteralNode
    (int lineNumber,
     const LContext &lcontext,
     int value)
:
    LiteralNode (lineNumber),
    value (value)
{
    type = lcontext.newIntType ();
}
Example #4
0
ExprNodePtr
ArrayIndexNode::evaluate (LContext &lcontext)
{
    IntTypePtr intType = lcontext.newIntType ();

    array = array->evaluate (lcontext);
    index = index->evaluate (lcontext);


    if( IntLiteralNodePtr literal = index.cast<IntLiteralNode>())
    {
	if(literal->value < 0)
	{
	    string name = "";
	    if( NameNodePtr arrayName =  array.cast<NameNode>() )
		name = arrayName->name;
	    
	    MESSAGE_LE (lcontext, ERR_ARR_IND_TYPE, array->lineNumber,
			"Index into array " << name << " is negative "
			"(" << literal->value << ").");
	}

	ArrayTypePtr arrayType = array->type.cast<ArrayType>();
	if(!arrayType)
	    return this;
	if( literal->value >= arrayType->size() && arrayType->size() != 0)
	{
	    string name = "";
	    if( NameNodePtr arrayName =  array.cast<NameNode>() )
		name = arrayName->name;
	    
	    MESSAGE_LE (lcontext, ERR_ARR_IND_TYPE, array->lineNumber,
			"Index into array " << name << " is out of range "
			"(index = " << literal->value << ", "
			"array size = " << arrayType->size() << ").");
	}


    }

    if (index->type && !intType->isSameTypeAs (index->type))
	index = intType->castValue (lcontext, index);

    return this;
}
Example #5
0
void
SizeNode::computeType (LContext &lcontext, const SymbolInfoPtr &initInfo)
{
    obj->computeType (lcontext, initInfo);

    ArrayTypePtr arrayType = obj->type.cast<ArrayType>();

    if( !arrayType)
    {
	string type = "unknown";
	if( obj && obj->type)
	    type = obj->type->asString();
	MESSAGE_LE (lcontext, ERR_NON_ARRAY, lineNumber,
		    "Applied size operator to non-array "
		    " of type " << type << ".");
    }
    type = lcontext.newIntType ();
}
Example #6
0
void
UnaryOpNode::computeType (LContext &lcontext, const SymbolInfoPtr &initInfo)
{
    if (!operand)
	return;

    operand->computeType (lcontext, initInfo);

    if (!operand->type)
	return;

    if (op == TK_BITNOT)
    {
	//
	// Operator ~ can only be applied to operands of type bool int, or
	// unsigned int.  The operator produces a result of the same type as
	// the operand.
	//

	BoolTypePtr boolType = lcontext.newBoolType ();

	if (boolType->isSameTypeAs (operand->type))
	{
	    type = boolType;
	    return;
	}

	IntTypePtr intType = lcontext.newIntType ();

	if (intType->isSameTypeAs (operand->type))
	{
	    type = intType;
	    return;
	}

	UIntTypePtr uIntType = lcontext.newUIntType ();

	if (uIntType->isSameTypeAs (operand->type))
	{
	    type = uIntType;
	    return;
	}
    }
    else if (op == TK_MINUS)
    {
	//
	// Operator - can only be applied to operands of type int, unsigned
	// int, half or float.  The operator produces a result of the same
	// type as the operand, except for unsigned int where it produces a
	// result of type int.
	//

	IntTypePtr intType = lcontext.newIntType ();

	if (intType->isSameTypeAs (operand->type))
	{
	    type = intType;
	    return;
	}

	UIntTypePtr uIntType = lcontext.newUIntType ();

	if (uIntType->isSameTypeAs (operand->type))
	{
	    type = intType;  // not uIntType!
	    return;
	}

	HalfTypePtr halfType = lcontext.newHalfType ();

	if (halfType->isSameTypeAs (operand->type))
	{
	    type = halfType;
	    return;
	}

	FloatTypePtr floatType = lcontext.newFloatType ();

	if (floatType->isSameTypeAs (operand->type))
	{
	    type = floatType;
	    return;
	}
    }
    else if (op == TK_NOT)
    {
	//
	// Operator ! can be applied to operands that can be converted
	// to type bool.  The operator produces a result of type bool.
	//

	BoolTypePtr boolType = lcontext.newBoolType ();

	if (boolType->canCastFrom (operand->type))
	{
	    type = boolType;
	    return;
	}
    }

    MESSAGE_LE (lcontext, ERR_OP_TYPE, lineNumber,
	"Invalid operand type for " << tokenAsString (op) << " operator "
	"(" << tokenAsString (op) << operand->type->asString() << ").");
}