From 5f934b039a0dfa1803805f8a7eceb776fe4f7049 Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Sun, 13 Mar 2016 17:58:25 -0600 Subject: [PATCH] HLSL: Accept basic funtion definitions. (Not yet mapping input/output for entry point.) --- Test/baseResults/hlsl.frag.out | 65 ++++++------ Test/hlsl.frag | 14 +-- hlsl/hlslGrammar.cpp | 231 +++++++++++++++++++++++++++++++++++------ hlsl/hlslGrammar.h | 6 +- 4 files changed, 240 insertions(+), 76 deletions(-) diff --git a/Test/baseResults/hlsl.frag.out b/Test/baseResults/hlsl.frag.out index b96e2ac..0fae4ae 100644 --- a/Test/baseResults/hlsl.frag.out +++ b/Test/baseResults/hlsl.frag.out @@ -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 diff --git a/Test/hlsl.frag b/Test/hlsl.frag index 9107248..7ee5849 100644 --- a/Test/hlsl.frag +++ b/Test/hlsl.frag @@ -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; +} diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp index 20d7bb3..86c27ee 100755 --- a/hlsl/hlslGrammar.cpp +++ b/hlsl/hlslGrammar.cpp @@ -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 diff --git a/hlsl/hlslGrammar.h b/hlsl/hlslGrammar.h index 8239d3e..baea5fe 100755 --- a/hlsl/hlslGrammar.h +++ b/hlsl/hlslGrammar.h @@ -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; -- 2.7.4