HLSL: Add basic declaration syntax and AST generation.
This commit is contained in:
parent
e01a9bc8c0
commit
87142c71fb
@ -5,7 +5,7 @@ Linked fragment stage:
|
|||||||
|
|
||||||
// Module Version 10000
|
// Module Version 10000
|
||||||
// Generated by (magic number): 80001
|
// Generated by (magic number): 80001
|
||||||
// Id's are bound by 6
|
// Id's are bound by 17
|
||||||
|
|
||||||
Capability Shader
|
Capability Shader
|
||||||
1: ExtInstImport "GLSL.std.450"
|
1: ExtInstImport "GLSL.std.450"
|
||||||
@ -14,8 +14,24 @@ Linked fragment stage:
|
|||||||
ExecutionMode 4 OriginUpperLeft
|
ExecutionMode 4 OriginUpperLeft
|
||||||
Source HLSL 100
|
Source HLSL 100
|
||||||
Name 4 "PixelShaderFunction"
|
Name 4 "PixelShaderFunction"
|
||||||
|
Name 10 "World"
|
||||||
|
Name 11 "View"
|
||||||
|
Name 12 "Projection"
|
||||||
|
Name 14 "AmbientColor"
|
||||||
|
Name 16 "AmbientIntensity"
|
||||||
2: TypeVoid
|
2: TypeVoid
|
||||||
3: TypeFunction 2
|
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)
|
||||||
4(PixelShaderFunction): 2 Function None 3
|
4(PixelShaderFunction): 2 Function None 3
|
||||||
5: Label
|
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
|
||||||
FunctionEnd
|
FunctionEnd
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
//float4x4 World;
|
float4x4 World;
|
||||||
//float4x4 View;
|
float4x4 View;
|
||||||
//float4x4 Projection;
|
float4x4 Projection;
|
||||||
//
|
|
||||||
//float4 AmbientColor = float4(1, 1, 1, 1);
|
float4 AmbientColor = float4(1, 1, 1, 1);
|
||||||
//float AmbientIntensity = 0.1;
|
float AmbientIntensity = 0.1;
|
||||||
//
|
|
||||||
//float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
|
//float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
|
||||||
//{
|
//{
|
||||||
// return AmbientColor * AmbientIntensity;
|
// return AmbientColor * AmbientIntensity;
|
||||||
|
|||||||
@ -83,11 +83,308 @@ bool HlslGrammar::acceptCompilationUnit()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// declaration
|
// declaration
|
||||||
// : dummy stub
|
// : 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
|
||||||
|
//
|
||||||
bool HlslGrammar::acceptDeclaration()
|
bool HlslGrammar::acceptDeclaration()
|
||||||
{
|
{
|
||||||
|
// fully_specified_type
|
||||||
|
TType type;
|
||||||
|
if (! acceptFullySpecifiedType(type))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// identifier
|
||||||
|
if (token.tokenClass == EHTokIdentifier) {
|
||||||
|
TSourceLoc declLoc = token.loc;
|
||||||
|
TString* declName = token.string;
|
||||||
advanceToken();
|
advanceToken();
|
||||||
|
|
||||||
|
// = expression
|
||||||
|
TIntermTyped* expressionNode = nullptr;
|
||||||
|
if (acceptTokenClass(EHTokEqual)) {
|
||||||
|
if (! acceptExpression(expressionNode)) {
|
||||||
|
expected("initializer");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ;
|
||||||
|
if (acceptTokenClass(EHTokSemicolon)) {
|
||||||
|
parseContext.declareVariable(declLoc, *declName, type, 0, expressionNode);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// no identifier, just ;
|
||||||
|
if (acceptTokenClass(EHTokSemicolon))
|
||||||
|
return true;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fully_specified_type
|
||||||
|
// : type_specifier
|
||||||
|
// | type_qualifier type_specifier
|
||||||
|
//
|
||||||
|
bool HlslGrammar::acceptFullySpecifiedType(TType& type)
|
||||||
|
{
|
||||||
|
// type_qualifier
|
||||||
|
TQualifier qualifier;
|
||||||
|
qualifier.clear();
|
||||||
|
acceptQualifier(qualifier);
|
||||||
|
|
||||||
|
// type_specifier
|
||||||
|
if (! acceptType(type))
|
||||||
|
return false;
|
||||||
|
type.getQualifier() = qualifier;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If token is a qualifier, return its token class and advance to the next
|
||||||
|
// qualifier. Otherwise, return false, and don't advance.
|
||||||
|
void HlslGrammar::acceptQualifier(TQualifier& qualifier)
|
||||||
|
{
|
||||||
|
switch (token.tokenClass) {
|
||||||
|
case EHTokUniform:
|
||||||
|
qualifier.storage = EvqUniform;
|
||||||
|
break;
|
||||||
|
case EHTokConst:
|
||||||
|
qualifier.storage = EvqConst;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
advanceToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If token is for a type, update 'type' with the type information,
|
||||||
|
// and return true and advance.
|
||||||
|
// Otherwise, return false, and don't advance
|
||||||
|
bool HlslGrammar::acceptType(TType& type)
|
||||||
|
{
|
||||||
|
if (! token.isType)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (token.tokenClass) {
|
||||||
|
case EHTokInt:
|
||||||
|
case EHTokInt1:
|
||||||
|
case EHTokDword:
|
||||||
|
new(&type) TType(EbtInt);
|
||||||
|
break;
|
||||||
|
case EHTokFloat:
|
||||||
|
case EHTokFloat1:
|
||||||
|
new(&type) TType(EbtFloat);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EHTokFloat2:
|
||||||
|
new(&type) TType(EbtFloat, EvqTemporary, 2);
|
||||||
|
break;
|
||||||
|
case EHTokFloat3:
|
||||||
|
new(&type) TType(EbtFloat, EvqTemporary, 3);
|
||||||
|
break;
|
||||||
|
case EHTokFloat4:
|
||||||
|
new(&type) TType(EbtFloat, EvqTemporary, 4);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EHTokInt2:
|
||||||
|
new(&type) TType(EbtInt, EvqTemporary, 2);
|
||||||
|
break;
|
||||||
|
case EHTokInt3:
|
||||||
|
new(&type) TType(EbtInt, EvqTemporary, 3);
|
||||||
|
break;
|
||||||
|
case EHTokInt4:
|
||||||
|
new(&type) TType(EbtInt, EvqTemporary, 4);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EHTokBool2:
|
||||||
|
new(&type) TType(EbtBool, EvqTemporary, 2);
|
||||||
|
break;
|
||||||
|
case EHTokBool3:
|
||||||
|
new(&type) TType(EbtBool, EvqTemporary, 3);
|
||||||
|
break;
|
||||||
|
case EHTokBool4:
|
||||||
|
new(&type) TType(EbtBool, EvqTemporary, 4);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EHTokFloat2x2:
|
||||||
|
new(&type) TType(EbtFloat, EvqTemporary, 0, 2, 2);
|
||||||
|
break;
|
||||||
|
case EHTokFloat2x3:
|
||||||
|
new(&type) TType(EbtFloat, EvqTemporary, 0, 3, 2);
|
||||||
|
break;
|
||||||
|
case EHTokFloat2x4:
|
||||||
|
new(&type) TType(EbtFloat, EvqTemporary, 0, 4, 2);
|
||||||
|
break;
|
||||||
|
case EHTokFloat3x2:
|
||||||
|
new(&type) TType(EbtFloat, EvqTemporary, 0, 2, 3);
|
||||||
|
break;
|
||||||
|
case EHTokFloat3x3:
|
||||||
|
new(&type) TType(EbtFloat, EvqTemporary, 0, 3, 3);
|
||||||
|
break;
|
||||||
|
case EHTokFloat3x4:
|
||||||
|
new(&type) TType(EbtFloat, EvqTemporary, 0, 4, 3);
|
||||||
|
break;
|
||||||
|
case EHTokFloat4x2:
|
||||||
|
new(&type) TType(EbtFloat, EvqTemporary, 0, 2, 4);
|
||||||
|
break;
|
||||||
|
case EHTokFloat4x3:
|
||||||
|
new(&type) TType(EbtFloat, EvqTemporary, 0, 3, 4);
|
||||||
|
break;
|
||||||
|
case EHTokFloat4x4:
|
||||||
|
new(&type) TType(EbtFloat, EvqTemporary, 0, 4, 4);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
advanceToken();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// expression
|
||||||
|
// : identifier
|
||||||
|
// | ( expression )
|
||||||
|
// | type(...) // constructor
|
||||||
|
// | literal
|
||||||
|
// | identifier + identifier
|
||||||
|
//
|
||||||
|
bool HlslGrammar::acceptExpression(TIntermTyped*& node)
|
||||||
|
{
|
||||||
|
// identifier
|
||||||
|
if (token.tokenClass == EHTokIdentifier) {
|
||||||
|
node = parseContext.handleVariable(token.loc, token.symbol, token.string);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ( expression )
|
||||||
|
if (acceptTokenClass(EHTokLeftParen)) {
|
||||||
|
if (! acceptExpression(node)) {
|
||||||
|
expected("expression");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (! acceptTokenClass(EHTokRightParen)) {
|
||||||
|
expected("right parenthesis");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// literal
|
||||||
|
if (acceptLiteral(node))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// type(...) // constructor
|
||||||
|
TType type;
|
||||||
|
if (acceptType(type)) {
|
||||||
|
TIntermSequence* arguments;
|
||||||
|
if (! acceptArguments(arguments)) {
|
||||||
|
expected("constructor arguments");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// identifier + 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// arguments
|
||||||
|
// : ( expression , expression, ... )
|
||||||
|
//
|
||||||
|
bool HlslGrammar::acceptArguments(TIntermSequence*& arguments)
|
||||||
|
{
|
||||||
|
if (! acceptTokenClass(EHTokLeftParen))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
do {
|
||||||
|
TIntermTyped* arg;
|
||||||
|
if (! acceptExpression(arg))
|
||||||
|
break;
|
||||||
|
if (! acceptTokenClass(EHTokComma))
|
||||||
|
break;
|
||||||
|
} while (true);
|
||||||
|
|
||||||
|
if (! acceptTokenClass(EHTokRightParen)) {
|
||||||
|
expected("right parenthesis");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HlslGrammar::acceptLiteral(TIntermTyped*& node)
|
||||||
|
{
|
||||||
|
switch (token.tokenClass) {
|
||||||
|
case EHTokIntConstant:
|
||||||
|
node = parseContext.intermediate.addConstantUnion(token.i, token.loc, true);
|
||||||
|
break;
|
||||||
|
case EHTokFloatConstant:
|
||||||
|
node = parseContext.intermediate.addConstantUnion(token.d, EbtFloat, token.loc, true);
|
||||||
|
break;
|
||||||
|
case EHTokDoubleConstant:
|
||||||
|
node = parseContext.intermediate.addConstantUnion(token.d, EbtDouble, token.loc, true);
|
||||||
|
break;
|
||||||
|
case EHTokBoolConstant:
|
||||||
|
node = parseContext.intermediate.addConstantUnion(token.b, token.loc, true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
advanceToken();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HlslGrammar::acceptOperator(TOperator& op)
|
||||||
|
{
|
||||||
|
switch (token.tokenClass) {
|
||||||
|
case EHTokPlus:
|
||||||
|
op = EOpAdd;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
advanceToken();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HlslGrammar::acceptCompoundStatement()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|||||||
@ -56,6 +56,14 @@ namespace glslang {
|
|||||||
|
|
||||||
bool acceptCompilationUnit();
|
bool acceptCompilationUnit();
|
||||||
bool acceptDeclaration();
|
bool acceptDeclaration();
|
||||||
|
bool acceptFullySpecifiedType(TType&);
|
||||||
|
void acceptQualifier(TQualifier&);
|
||||||
|
bool acceptType(TType&);
|
||||||
|
bool acceptCompoundStatement();
|
||||||
|
bool acceptExpression(TIntermTyped*&);
|
||||||
|
bool acceptArguments(TIntermSequence*&);
|
||||||
|
bool acceptLiteral(TIntermTyped*&);
|
||||||
|
bool acceptOperator(TOperator& op);
|
||||||
|
|
||||||
HlslScanContext& scanContext;
|
HlslScanContext& scanContext;
|
||||||
HlslParseContext& parseContext;
|
HlslParseContext& parseContext;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user