def testResolveBinaryExpressionTypeMVPromotesRightSide(self): m44 = types.MatrixType(types.Float(), 4, 4) f4 = types.VectorType(types.Integer(), 4) r = types.ResolveBinaryExpressionType(op.Operation.MUL, m44, f4) assert r.GetOperandType(1) == types.VectorType(types.Float(), 4)
def testResolveBinaryExpressionWorksOnCompatibleSizes(self): r = types.ResolveBinaryExpressionType( op.Operation.MUL, types.MatrixType(types.Float(), 4, 2), types.VectorType(types.Float(), 2)) expectedType = types.VectorType(types.Float(), 4) assert r.GetReturnType() == expectedType
def testResolveBinaryExpressionVectorScalarDiv(self): vt = types.VectorType(types.Float(), 4) it = types.Integer() rt = types.ResolveBinaryExpressionType(op.Operation.DIV, vt, it) assert rt.GetReturnType() == vt
def testResolveBinaryExpressionTypeMV(self): m44 = types.MatrixType(types.Float(), 4, 4) f4 = types.VectorType(types.Float(), 4) r = types.ResolveBinaryExpressionType(op.Operation.MUL, m44, f4) assert r.GetReturnType() == f4
def testResolveBinaryExpressionForScalarVectorPromotes(self): left = types.Integer() right = types.VectorType(types.Float(), 4) t = types.ResolveBinaryExpressionType(op.Operation.MUL, left, right) assert t.GetOperandType(0) == types.Float() assert t.GetOperandType(1) == right
def testResolveBinaryExpressionMVFailsForNonMultiply(self): invalidOperations = [ op.Operation.ADD, op.Operation.SUB, op.Operation.DIV ] for operation in invalidOperations: with pytest.raises(Exception): types.ResolveBinaryExpressionType( operation, types.MatrixType(types.Float(), 4, 4), types.VectorType(types.Float(), 2))
def ComputeSwizzleType(inType, mask): '''Compute the resulting type of a swizzle operation. @param inType: Must be a PrimitiveType @param mask: A valid swizzle mask ''' assert isinstance(inType, types.Type) outComponentCount = len(mask) swizzleType = inType.GetComponentType() if outComponentCount == 1: return swizzleType else: result = types.VectorType(swizzleType, outComponentCount) return result
def testResolveBinaryExpressionFailsForVVDiv(self): vt = types.VectorType(types.Float(), 4) with pytest.raises(Exception): types.ResolveBinaryExpressionType(op.Operation.DIV, vt, vt)
def testIsCompatibleFloat2Int2(self): f2 = types.VectorType(types.Float(), 2) i2 = types.VectorType(types.Integer(), 2) assert types.IsCompatible(f2, i2)
def testResolveBinaryExpressionMVFailsOnIncompatibleSizes(self): with pytest.raises(Exception): types.ResolveBinaryExpressionType( op.Operation.MUL, types.MatrixType(types.Float(), 2, 4), types.VectorType(types.Float(), 2))
def testIsCompatibleIntInt1(self): i = types.Integer() i1 = types.VectorType(types.Integer(), 1) assert types.IsCompatible(i, i1)
def testIsCompatibleFloat2Int4(self): f2 = types.VectorType(types.Float(), 2) i4 = types.VectorType(types.Integer(), 4) assert not types.IsCompatible(f2, i4)
def _ProcessExpression(self, expr, scope): assert isinstance( expr, ast.Expression ), 'Expression {1} has type {0} which is not an expression type'.format( type(expr), expr) # We type-cast here so we can process access trees separately if isinstance(expr, ast.VariableAccessExpression): p = expr.GetParent() # Figure out the parent type self._ProcessExpression(p, scope) if isinstance(expr, ast.MemberAccessExpression): parentType = p.GetType() if parentType.IsPrimitive(): if parentType.IsVector() or parentType.IsScalar(): # We allow swizzling of vector and scalar types expr.SetType( ComputeSwizzleType(parentType, expr.GetMember().GetName())) expr.SetSwizzle(True) else: Errors.ERROR_CANNOT_SWIZZLE_PRIMITIVE_TYPE.Raise() elif parentType.IsAggregate(): expr.SetType(parentType.GetMembers().GetFieldType( expr.GetMember().GetName())) else: Errors.ERROR_CANNOT_SWIZZLE_TYPE.Raise(parentType) expr.GetMember().SetType(expr.GetType()) elif isinstance(expr, ast.ArrayExpression): self._ProcessExpression(expr.GetExpression(), scope) if not expr.GetExpression().GetType().IsScalar(): Errors.ERROR_ARRAY_ACCESS_WITH_NONSCALAR.Raise( expr.GetExpression().GetType()) parentType = p.GetType() nestedSize = parentType.GetSize() if isinstance(parentType, types.MatrixType): # Array access on matrix returns a vector arrayType = types.VectorType(parentType.GetComponentType(), parentType.GetColumnCount()) expr.SetType(arrayType) elif len(nestedSize) > 1: # Drop one dimension from the array arrayType = types.ArrayType(parentType.GetComponentType(), nestedSize[1:]) expr.SetType(arrayType) else: # We've reached the last dimension (array is 1D now), so # return the element type expr.SetType(p.GetType().GetComponentType()) elif isinstance(expr, ast.PrimaryExpression): # Simply check the name expr.SetType(scope.GetFieldType(expr.GetName())) else: # Walk through all children for c in expr: self._ProcessExpression(c, scope) # during the walking up, we can compute the expression # type as well if isinstance(expr, ast.CallExpression): # As we know the parameter types now, we can finally resolve # overloaded functions expr.ResolveType(scope) expr.SetType(expr.function.GetReturnType()) elif isinstance(expr, ast.BinaryExpression): expr.ResolveType(expr.GetLeft().GetType(), expr.GetRight().GetType()) expr.SetType(expr.GetOperator().GetReturnType()) elif isinstance(expr, ast.AffixExpression): expr.SetType(expr.children[0].GetType()) return expr.GetType()