Example #1
0
BoolLiteralNode::BoolLiteralNode
    (int lineNumber,
     const LContext &lcontext,
     bool value)
:
    LiteralNode (lineNumber),
    value (value)
{
    type = lcontext.newBoolType ();
}
Example #2
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() << ").");
}
Example #3
0
void
BinaryOpNode::computeType (LContext &lcontext, const SymbolInfoPtr &initInfo)
{
    if (!leftOperand || !rightOperand)
	return;

    leftOperand->computeType (lcontext, initInfo);
    rightOperand->computeType (lcontext, initInfo);

    if (!leftOperand->type || !rightOperand->type)
	return;

    ArrayTypePtr arrayType = leftOperand->type.cast<ArrayType>();
    StructTypePtr structType = leftOperand->type.cast<StructType>();

    if( arrayType || structType )
    {
	MESSAGE_LE (lcontext, ERR_OP_TYPE, lineNumber,
	    "Invalid operand types for " << tokenAsString (op) << " "
	    "operator (" << leftOperand->type->asString() << " " <<
	    tokenAsString (op) << " " <<
	    rightOperand->type->asString() << ").");
    }

    if (op == TK_AND || op == TK_OR)
    {
	//
	// It must be possible to cast the operands to type bool,
	// and the operator produces a result of type bool.
	//

	BoolTypePtr boolType = lcontext.newBoolType ();

	if (boolType->canCastFrom (leftOperand->type) &&
	    boolType->canCastFrom (rightOperand->type))
	{
	    operandType = boolType;
	    type = boolType;
	    return;
	}
    }
    else if (op == TK_EQUAL || op == TK_GREATER || op == TK_GREATEREQUAL ||
	     op == TK_LESS || op == TK_LESSEQUAL || op == TK_NOTEQUAL)
    {
	//
	// It must be possible to promote the operands to a common type.
	// The operator produces a result of type bool.
	//

	BoolTypePtr boolType = lcontext.newBoolType ();

	if (leftOperand->type->isSameTypeAs (rightOperand->type))
	{
	    operandType = leftOperand->type;
	    type = boolType;
	    return;
	}
	else if (leftOperand->type->canPromoteFrom (rightOperand->type))
	{
	    operandType = leftOperand->type;
	    type = boolType;
	    return;
	}
	else if (rightOperand->type->canPromoteFrom (leftOperand->type))
	{
	    operandType = rightOperand->type;
	    type = boolType;
	    return;
	}
    }
    else
    {
	//
	// It must be possible to promote the operands to a common type.
	// The operator produces a result of this common type.
	//

	if (leftOperand->type->isSameTypeAs (rightOperand->type))
	{
	    operandType = leftOperand->type;
	    type = operandType;
	    return;
	}
	else if (leftOperand->type->canPromoteFrom (rightOperand->type))
	{
	    operandType = leftOperand->type;
	    type = operandType;
	    return;
	}
	else if (rightOperand->type->canPromoteFrom (leftOperand->type))
	{
	    operandType = rightOperand->type;
	    type = operandType;
	    return;
	}
    }

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