From 21472aee755d4a6d234488ecc606ffe2ace4673b Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Sat, 4 Jun 2016 11:46:33 -0600 Subject: [PATCH] HLSL: Finish skeletan of the "statement" grammar. --- hlsl/hlslGrammar.cpp | 186 ++++++++++++++++++++++++++++++++++++++++++--------- hlsl/hlslGrammar.h | 9 ++- 2 files changed, 163 insertions(+), 32 deletions(-) diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp index ddb7078..31e67d3 100755 --- a/hlsl/hlslGrammar.cpp +++ b/hlsl/hlslGrammar.cpp @@ -472,7 +472,7 @@ bool HlslGrammar::acceptFunctionDefinition(TFunction& function, TIntermNode*& no node = parseContext.handleFunctionDefinition(token.loc, *functionDeclarator); // compound_statement - TIntermAggregate* functionBody = nullptr; + TIntermNode* functionBody = nullptr; if (acceptCompoundStatement(functionBody)) { node = intermediate.growAggregate(node, functionBody); intermediate.setAggregateOperator(node, EOpFunction, functionDeclarator->getType(), token.loc); @@ -690,8 +690,10 @@ bool HlslGrammar::acceptPostfixExpression(TIntermTyped*& node) // idToken will pick up either a variable or a function name in a function call HlslToken idToken; - // LEFT_PAREN expression RIGHT_PAREN + // Find something before the postfix operations, as they can't operate + // on nothing. So, no "return true", they fall through, only "return false". if (acceptTokenClass(EHTokLeftParen)) { + // LEFT_PAREN expression RIGHT_PAREN if (! acceptExpression(node)) { expected("expression"); return false; @@ -714,8 +716,12 @@ bool HlslGrammar::acceptPostfixExpression(TIntermTyped*& node) expected("function call arguments"); return false; } + } else { + // nothing found, can't post operate + return false; } + // Something was found, chain as many postfix operations as exist. do { TSourceLoc loc = token.loc; TOperator postOp = HlslOpMap::postUnary(peek()); @@ -867,8 +873,10 @@ bool HlslGrammar::acceptLiteral(TIntermTyped*& node) // compound_statement // : LEFT_CURLY statement statement ... RIGHT_CURLY // -bool HlslGrammar::acceptCompoundStatement(TIntermAggregate*& compoundStatement) +bool HlslGrammar::acceptCompoundStatement(TIntermNode*& retStatement) { + TIntermAggregate* compoundStatement = nullptr; + // LEFT_CURLY if (! acceptTokenClass(EHTokLeftBrace)) return false; @@ -882,54 +890,170 @@ bool HlslGrammar::acceptCompoundStatement(TIntermAggregate*& compoundStatement) if (compoundStatement) compoundStatement->setOperator(EOpSequence); + retStatement = compoundStatement; + // RIGHT_CURLY return acceptTokenClass(EHTokRightBrace); } // statement +// : attributes attributed_statement +// +// attributed_statement // : compound_statement -// | return SEMICOLON -// | return expression SEMICOLON +// | SEMICOLON // | expression SEMICOLON +// | declaration_statement +// | selection_statement +// | switch_statement +// | case_label +// | iteration_statement +// | jump_statement // bool HlslGrammar::acceptStatement(TIntermNode*& statement) { - // compound_statement - TIntermAggregate* compoundStatement = nullptr; - if (acceptCompoundStatement(compoundStatement)) { - statement = compoundStatement; - return true; - } + statement = nullptr; - // RETURN - if (acceptTokenClass(EHTokReturn)) { - // expression - TIntermTyped* node; - if (acceptExpression(node)) { - // hook it up - statement = intermediate.addBranch(EOpReturn, node, token.loc); - } else - statement = intermediate.addBranch(EOpReturn, token.loc); + // attributes + acceptAttributes(); - // SEMICOLON - if (! acceptTokenClass(EHTokSemicolon)) - return false; + // attributed_statement + switch (peek()) { + case EHTokLeftBrace: + return acceptCompoundStatement(statement); - return true; - } + case EHTokIf: + return acceptSelectionStatement(statement); - // expression - TIntermTyped* node; - if (acceptExpression(node)) - statement = node; + case EHTokSwitch: + return acceptSwitchStatement(statement); - // SEMICOLON - if (! acceptTokenClass(EHTokSemicolon)) + case EHTokFor: + case EHTokDo: + case EHTokWhile: + return acceptIterationStatement(statement); + + case EHTokContinue: + case EHTokBreak: + case EHTokDiscard: + case EHTokReturn: + return acceptJumpStatement(statement); + + case EHTokCase: + return acceptCaseLabel(statement); + + case EHTokSemicolon: + return acceptTokenClass(EHTokSemicolon); + + case EHTokRightBrace: + // Performance: not strictly necessary, but stops a bunch of hunting early, + // and is how sequences of statements end. return false; + default: + { + // declaration + if (acceptDeclaration(statement)) + return true; + + // expression + TIntermTyped* node; + if (acceptExpression(node)) + statement = node; + else + return false; + + // SEMICOLON (following an expression) + if (! acceptTokenClass(EHTokSemicolon)) { + expected("semicolon"); + return false; + } + } + } + return true; } +// attributes +// : list of zero or more of: LEFT_BRACKET attribute RIGHT_BRACKET +// +// attribute: +// : UNROLL +// | UNROLL LEFT_PAREN literal RIGHT_PAREN +// | FASTOPT +// | ALLOW_UAV_CONDITION +// | BRANCH +// | FLATTEN +// | FORCECASE +// | CALL +// +void HlslGrammar::acceptAttributes() +{ + // TODO +} + +bool HlslGrammar::acceptSelectionStatement(TIntermNode*& statement) +{ + return false; +} + +bool HlslGrammar::acceptSwitchStatement(TIntermNode*& statement) +{ + return false; +} + +bool HlslGrammar::acceptIterationStatement(TIntermNode*& statement) +{ + return false; +} + +// jump_statement +// : CONTINUE SEMICOLON +// | BREAK SEMICOLON +// | DISCARD SEMICOLON +// | RETURN SEMICOLON +// | RETURN expression SEMICOLON +// +bool HlslGrammar::acceptJumpStatement(TIntermNode*& statement) +{ + switch (peek()) { + case EHTokContinue: + case EHTokBreak: + case EHTokDiscard: + // TODO + return false; + + case EHTokReturn: + // return + if (acceptTokenClass(EHTokReturn)) { + // expression + TIntermTyped* node; + if (acceptExpression(node)) { + // hook it up + statement = intermediate.addBranch(EOpReturn, node, token.loc); + } else + statement = intermediate.addBranch(EOpReturn, token.loc); + + // SEMICOLON + if (! acceptTokenClass(EHTokSemicolon)) { + expected("semicolon"); + return false; + } + + return true; + } + + default: + return false; + } +} + + +bool HlslGrammar::acceptCaseLabel(TIntermNode*& statement) +{ + return false; +} + // COLON semantic bool HlslGrammar::acceptSemantic() { diff --git a/hlsl/hlslGrammar.h b/hlsl/hlslGrammar.h index d834aa9..7d337fd 100755 --- a/hlsl/hlslGrammar.h +++ b/hlsl/hlslGrammar.h @@ -73,8 +73,15 @@ namespace glslang { bool acceptFunctionCall(HlslToken, TIntermTyped*&); bool acceptArguments(TFunction*, TIntermTyped*&); bool acceptLiteral(TIntermTyped*&); - bool acceptCompoundStatement(TIntermAggregate*&); + bool acceptCompoundStatement(TIntermNode*&); bool acceptStatement(TIntermNode*&); + void acceptAttributes(); + bool acceptSelectionStatement(TIntermNode*&); + bool acceptSwitchStatement(TIntermNode*&); + bool acceptIterationStatement(TIntermNode*&); + bool acceptJumpStatement(TIntermNode*&); + bool acceptCaseLabel(TIntermNode*&); + bool acceptSemantic(); HlslParseContext& parseContext; // state of parsing and helper functions for building the intermediate -- 2.7.4