HLSL: Accept basic funtion definitions. (Not yet mapping input/output for entry...
authorJohn Kessenich <cepheus@frii.com>
Sun, 13 Mar 2016 23:58:25 +0000 (17:58 -0600)
committerJohn Kessenich <cepheus@frii.com>
Sun, 13 Mar 2016 23:58:25 +0000 (17:58 -0600)
Test/baseResults/hlsl.frag.out
Test/hlsl.frag
hlsl/hlslGrammar.cpp
hlsl/hlslGrammar.h

index b96e2ac..0fae4ae 100644 (file)
@@ -2,23 +2,23 @@ hlsl.frag
 Shader version: 100
 gl_FragCoord origin is upper left
 0:? Sequence
-0:5  move second child to first child (temp 4-component vector of float)
-0:5    'AmbientColor' (temp 4-component vector of float)
+0:1  move second child to first child (temp 4-component vector of float)
+0:1    'AmbientColor' (temp 4-component vector of float)
 0:?     Constant:
 0:?       1.000000
 0:?       0.500000
 0:?       0.000000
 0:?       1.000000
-0:6  move second child to first child (temp float)
-0:6    'AmbientIntensity' (temp float)
-0:6    Constant:
-0:6      0.100000
+0:8  Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float)
+0:5    Function Parameters: 
+0:5      'input' (temp 4-component vector of float)
+0:?     Sequence
+0:6      Branch: Return with expression
+0:6        add (temp 4-component vector of float)
+0:6          'input' (temp 4-component vector of float)
+0:6          'AmbientColor' (temp 4-component vector of float)
 0:?   Linker Objects
-0:?     'World' (temp 4X4 matrix of float)
-0:?     'View' (temp 4X4 matrix of float)
-0:?     'Projection' (temp 4X4 matrix of float)
 0:?     'AmbientColor' (temp 4-component vector of float)
-0:?     'AmbientIntensity' (temp float)
 
 
 Linked fragment stage:
@@ -27,27 +27,27 @@ Linked fragment stage:
 Shader version: 100
 gl_FragCoord origin is upper left
 0:? Sequence
-0:5  move second child to first child (temp 4-component vector of float)
-0:5    'AmbientColor' (temp 4-component vector of float)
+0:1  move second child to first child (temp 4-component vector of float)
+0:1    'AmbientColor' (temp 4-component vector of float)
 0:?     Constant:
 0:?       1.000000
 0:?       0.500000
 0:?       0.000000
 0:?       1.000000
-0:6  move second child to first child (temp float)
-0:6    'AmbientIntensity' (temp float)
-0:6    Constant:
-0:6      0.100000
+0:8  Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float)
+0:5    Function Parameters: 
+0:5      'input' (temp 4-component vector of float)
+0:?     Sequence
+0:6      Branch: Return with expression
+0:6        add (temp 4-component vector of float)
+0:6          'input' (temp 4-component vector of float)
+0:6          'AmbientColor' (temp 4-component vector of float)
 0:?   Linker Objects
-0:?     'World' (temp 4X4 matrix of float)
-0:?     'View' (temp 4X4 matrix of float)
-0:?     'Projection' (temp 4X4 matrix of float)
 0:?     'AmbientColor' (temp 4-component vector of float)
-0:?     'AmbientIntensity' (temp float)
 
 // Module Version 10000
 // Generated by (magic number): 80001
-// Id's are bound by 17
+// Id's are bound by 15
 
                               Capability Shader
                1:             ExtInstImport  "GLSL.std.450"
@@ -56,24 +56,19 @@ gl_FragCoord origin is upper left
                               ExecutionMode 4 OriginUpperLeft
                               Source HLSL 100
                               Name 4  "PixelShaderFunction"
-                              Name 10  "World"
-                              Name 11  "View"
-                              Name 12  "Projection"
-                              Name 14  "AmbientColor"
-                              Name 16  "AmbientIntensity"
+                              Name 9  "input"
+                              Name 11  "AmbientColor"
                2:             TypeVoid
                3:             TypeFunction 2
                6:             TypeFloat 32
                7:             TypeVector 6(float) 4
-               8:             TypeMatrix 7(fvec4) 4
-               9:             TypePointer Function 8
-              13:             TypePointer Function 7(fvec4)
-              15:             TypePointer Function 6(float)
+               8:             TypePointer Function 7(fvec4)
 4(PixelShaderFunction):           2 Function None 3
                5:             Label
-       10(World):      9(ptr) Variable Function
-        11(View):      9(ptr) Variable Function
-  12(Projection):      9(ptr) Variable Function
-14(AmbientColor):     13(ptr) Variable Function
-16(AmbientIntensity):     15(ptr) Variable Function
+        9(input):      8(ptr) Variable Function
+11(AmbientColor):      8(ptr) Variable Function
+              10:    7(fvec4) Load 9(input)
+              12:    7(fvec4) Load 11(AmbientColor)
+              13:    7(fvec4) FAdd 10 12
+                              ReturnValue 13
                               FunctionEnd
index 9107248..7ee5849 100644 (file)
@@ -1,11 +1,7 @@
-float4x4 World;
-float4x4 View;
-float4x4 Projection;
-
 float4 AmbientColor = float4(1, 0.5, 0, 1);
-float AmbientIntensity = 0.1;
+//float AmbientIntensity = 0.1;
 
-//float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
-//{
-//    return AmbientColor * AmbientIntensity;
-//}
+float4 PixelShaderFunction(float4 input) : COLOR0
+{
+    return input /* * AmbientIntensity */ + AmbientColor;
+}
index 20d7bb3..86c27ee 100755 (executable)
@@ -110,12 +110,12 @@ bool HlslGrammar::acceptCompilationUnit()
 }
 
 // declaration
-//      : SEMICOLON
+//      : ;
 //      : fully_specified_type ;
 //      | fully_specified_type identifier ;
 //      | fully_specified_type identifier = expression ;
-//      | fully_specified_type identifier function_parameters ;         // function prototype
-//      | fully_specified_type function_parameters compound_statement   // function definition
+//      | fully_specified_type identifier function_parameters ;                              // function prototype
+//      | fully_specified_type identifier function_parameters : semantic compound_statement  // function definition
 //
 // 'node' could get created if the declaration creates code, like an initializer
 // or a function body.
@@ -149,9 +149,34 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node)
             node = parseContext.declareVariable(declLoc, *declName, type, 0, expressionNode);
             return true;
         }
+
+        // function_parameters
+        TFunction* function = new TFunction(declName, type);
+        if (acceptFunctionParameters(*function)) {
+            // :
+            if (acceptTokenClass(EHTokColon)) {
+                // semantic
+                if (token.tokenClass == EHTokIdentifier) {
+                    TString* semantic = token.string;
+                    advanceToken();
+                } else {
+                    expected("semantic");
+                    return false;
+                }
+            }
+            // compound_statement
+            if (token.tokenClass == EHTokLeftBrace)
+                return acceptFunctionDefinition(*function, node);
+
+            // ;
+            if (acceptTokenClass(EHTokSemicolon))
+                return true;
+
+            return false;
+        }
     }
 
-    // no identifier, just ;
+    // ;   [ no identifier, just ; ]
     if (acceptTokenClass(EHTokSemicolon))
         return true;
 
@@ -281,19 +306,110 @@ bool HlslGrammar::acceptType(TType& type)
     return true;
 }
 
+// function_parameters
+//      : ( parameter_declaration , parameter_declaration ... )
+//
+bool HlslGrammar::acceptFunctionParameters(TFunction& function)
+{
+    // (
+    if (! acceptTokenClass(EHTokLeftParen))
+        return false;
+
+    do {
+        // parameter_declaration
+        if (! acceptParameterDeclaration(function))
+            break;
+
+        // ,
+        if (! acceptTokenClass(EHTokComma))
+            break;
+    } while (true);
+
+    // )
+    if (! acceptTokenClass(EHTokRightParen)) {
+        expected("right parenthesis");
+        return false;
+    }
+
+    return true;
+}
+
+// parameter_declaration
+//      : fully_specified_type
+//      | fully_specified_type identifier
+//
+bool HlslGrammar::acceptParameterDeclaration(TFunction& function)
+{
+    // fully_specified_type
+    TType* type = new TType;
+    if (! acceptFullySpecifiedType(*type))
+        return false;
+
+    // identifier
+    TString name;
+    if (token.tokenClass == EHTokIdentifier) {
+        name = *token.string;
+        advanceToken();
+    }
+
+    TParameter param = { token.string, type };
+    function.addParameter(param);
+
+    return true;
+}
+
+// Do the work to create the function definition in addition to
+// parsing the body (compound_statement).
+bool HlslGrammar::acceptFunctionDefinition(TFunction& function, TIntermNode*& node)
+{
+    TFunction* functionDeclarator = parseContext.handleFunctionDeclarator(token.loc, function, false /* not prototype */);
+
+    // This does a symbol table push
+    node = parseContext.handleFunctionDefinition(token.loc, *functionDeclarator);
+
+    // compound_statement
+    TIntermAggregate* functionBody = nullptr;
+    if (acceptCompoundStatement(functionBody)) {
+        node = parseContext.intermediate.growAggregate(node, functionBody);
+        parseContext.intermediate.setAggregateOperator(node, EOpFunction, functionDeclarator->getType(), token.loc);
+        node->getAsAggregate()->setName(functionDeclarator->getMangledName().c_str());
+        parseContext.symbolTable.pop(nullptr);
+
+        return true;
+    }
+
+    return false;
+}
+
 // expression
 //      : identifier
+//      | identifier operator identifier   // to be generalized to all expressions
 //      | ( expression )
 //      | type(...)                 // constructor
 //      | literal
-//      | identifier operator identifier   // to be generalized to all expressions
 //
 bool HlslGrammar::acceptExpression(TIntermTyped*& node)
 {
     // identifier
     if (token.tokenClass == EHTokIdentifier) {
-        node = parseContext.handleVariable(token.loc, token.symbol, token.string);
-        return true;
+        TIntermTyped* left = parseContext.handleVariable(token.loc, token.symbol, token.string);
+        advanceToken();
+
+        // operator?
+        TOperator op;
+        if (! acceptOperator(op))
+            return true;
+        TSourceLoc loc = token.loc;
+
+        // identifier
+        if (token.tokenClass == EHTokIdentifier) {
+            TIntermTyped* right = parseContext.handleVariable(token.loc, token.symbol, token.string);
+            advanceToken();
+            node = parseContext.intermediate.addBinaryMath(op, left, right, loc);
+            return true;
+        }
+
+        return false;
     }
 
     // ( expression )
@@ -318,28 +434,7 @@ bool HlslGrammar::acceptExpression(TIntermTyped*& node)
     if (acceptConstructor(node))
         return true;
 
-    // identifier operator identifier
-    if (token.tokenClass == EHTokIdentifier) {
-        TIntermTyped* left = parseContext.handleVariable(token.loc, token.symbol, token.string);
-        advanceToken();
-
-        // operator
-        TOperator op;
-        if (! acceptOperator(op))
-            return false;
-        TSourceLoc loc = token.loc;
-
-        // right
-        if (token.tokenClass == EHTokIdentifier) {
-            TIntermTyped* right = parseContext.handleVariable(token.loc, token.symbol, token.string);
-            advanceToken();
-            node = parseContext.intermediate.addBinaryMath(op, left, right, loc);
-        } else
-            return false;
-    } else
-        return false;
-
-    return true;
+    return false;
 }
 
 // constructor
@@ -430,12 +525,26 @@ bool HlslGrammar::acceptLiteral(TIntermTyped*& node)
     return true;
 }
 
+// operator
+//      : + | - | * | / | ...
 bool HlslGrammar::acceptOperator(TOperator& op)
 {
     switch (token.tokenClass) {
+    case EHTokEqual:
+        op = EOpAssign;
+        break;
     case EHTokPlus:
         op = EOpAdd;
         break;
+    case EHTokDash:
+        op = EOpSub;
+        break;
+    case EHTokStar:
+        op = EOpMul;
+        break;
+    case EHTokSlash:
+        op = EOpDiv;
+        break;
     default:
         return false;
     }
@@ -445,9 +554,69 @@ bool HlslGrammar::acceptOperator(TOperator& op)
     return true;
 }
 
-bool HlslGrammar::acceptCompoundStatement()
+// compound_statement
+//      : { statement statement ... }
+//
+bool HlslGrammar::acceptCompoundStatement(TIntermAggregate*& compoundStatement)
 {
-    return false;
+    // {
+    if (! acceptTokenClass(EHTokLeftBrace))
+        return false;
+
+    // statement statement ...
+    TIntermNode* statement = nullptr;
+    while (acceptStatement(statement)) {
+        // hook it up
+        compoundStatement = parseContext.intermediate.growAggregate(compoundStatement, statement);
+    }
+    compoundStatement->setOperator(EOpSequence);
+
+    // }
+    return acceptTokenClass(EHTokRightBrace);
+}
+
+// statement
+//      : compound_statement
+//      | return ;
+//      | return expression ;
+//      | expression ;
+//
+bool HlslGrammar::acceptStatement(TIntermNode*& statement)
+{
+    // compound_statement
+    TIntermAggregate* compoundStatement = nullptr;
+    if (acceptCompoundStatement(compoundStatement)) {
+        statement = compoundStatement;
+        return true;
+    }
+
+    // return
+    if (acceptTokenClass(EHTokReturn)) {
+        // expression
+        TIntermTyped* node;
+        if (acceptExpression(node)) {
+            // hook it up
+            statement = parseContext.intermediate.addBranch(EOpReturn, node, token.loc);
+        } else
+            statement = parseContext.intermediate.addBranch(EOpReturn, token.loc);
+
+        // ;
+        if (! acceptTokenClass(EHTokSemicolon))
+            return false;
+
+        return true;
+    }
+
+    // expression
+    TIntermTyped* node;
+    if (acceptExpression(node))
+        statement = node;
+
+    // ;
+    if (! acceptTokenClass(EHTokSemicolon))
+        return false;
+
+    return true;
 }
 
 } // end namespace glslang
index 8239d3e..baea5fe 100755 (executable)
@@ -59,12 +59,16 @@ namespace glslang {
         bool acceptFullySpecifiedType(TType&);
         void acceptQualifier(TQualifier&);
         bool acceptType(TType&);
-        bool acceptCompoundStatement();
+        bool acceptFunctionParameters(TFunction&);
+        bool acceptParameterDeclaration(TFunction&);
+        bool acceptFunctionDefinition(TFunction&, TIntermNode*&);
         bool acceptExpression(TIntermTyped*&);
         bool acceptConstructor(TIntermTyped*&);
         bool acceptArguments(TFunction*, TIntermAggregate*&);
         bool acceptLiteral(TIntermTyped*&);
         bool acceptOperator(TOperator& op);
+        bool acceptCompoundStatement(TIntermAggregate*&);
+        bool acceptStatement(TIntermNode*&);
 
         HlslScanContext& scanContext;
         HlslParseContext& parseContext;