| 2889 | } |
| 2890 | |
| 2891 | bool HLSLParser::ParseTerminalExpression(HLSLExpression*& expression, bool& needsEndParen) |
| 2892 | { |
| 2893 | const char* fileName = GetFileName(); |
| 2894 | int line = GetLineNumber(); |
| 2895 | |
| 2896 | needsEndParen = false; |
| 2897 | |
| 2898 | HLSLUnaryOp unaryOp; |
| 2899 | if (AcceptUnaryOperator(true, unaryOp)) { |
| 2900 | HLSLUnaryExpression* unaryExpression = m_tree->AddNode<HLSLUnaryExpression>(fileName, line); |
| 2901 | unaryExpression->unaryOp = unaryOp; |
| 2902 | if (!ParseTerminalExpression(unaryExpression->expression, needsEndParen)) { |
| 2903 | return false; |
| 2904 | } |
| 2905 | if (unaryOp == HLSLUnaryOp_BitNot) { |
| 2906 | if (!IsIntegerType(unaryExpression->expression->expressionType.baseType)) { |
| 2907 | const char* typeName = GetTypeNameHLSL(unaryExpression->expression->expressionType); |
| 2908 | m_tokenizer.Error("unary '~' : no global operator found which takes type '%s' (or there is no acceptable conversion)", typeName); |
| 2909 | return false; |
| 2910 | } |
| 2911 | } |
| 2912 | if (unaryOp == HLSLUnaryOp_Not) { |
| 2913 | unaryExpression->expressionType = HLSLType(HLSLBaseType_Bool); |
| 2914 | |
| 2915 | // Propagate constness. |
| 2916 | unaryExpression->expressionType.flags = unaryExpression->expression->expressionType.flags & HLSLTypeFlag_Const; |
| 2917 | } |
| 2918 | else { |
| 2919 | unaryExpression->expressionType = unaryExpression->expression->expressionType; |
| 2920 | } |
| 2921 | expression = unaryExpression; |
| 2922 | return true; |
| 2923 | } |
| 2924 | |
| 2925 | // Expressions inside parenthesis or casts. |
| 2926 | if (Accept('(')) { |
| 2927 | // Check for a casting operator. |
| 2928 | HLSLType type; |
| 2929 | if (AcceptType(false, type)) { |
| 2930 | // This is actually a type constructor like (float2(... |
| 2931 | if (Accept('(')) { |
| 2932 | needsEndParen = true; |
| 2933 | return ParsePartialConstructor(expression, type.baseType, type.typeName); |
| 2934 | } |
| 2935 | HLSLCastingExpression* castingExpression = m_tree->AddNode<HLSLCastingExpression>(fileName, line); |
| 2936 | castingExpression->type = type; |
| 2937 | expression = castingExpression; |
| 2938 | castingExpression->expressionType = type; |
| 2939 | return Expect(')') && ParseExpression(castingExpression->expression); |
| 2940 | } |
| 2941 | |
| 2942 | if (!ParseExpression(expression) || !Expect(')')) { |
| 2943 | return false; |
| 2944 | } |
| 2945 | } |
| 2946 | else { |
| 2947 | // Terminal values. |
| 2948 | float fValue = 0.0f; |
nothing calls this directly
no test coverage detected