BoolLiteralNode::BoolLiteralNode (int lineNumber, const LContext &lcontext, bool value) : LiteralNode (lineNumber), value (value) { type = lcontext.newBoolType (); }
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() << ")."); }
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() << ")."); }