GLSL AST nodes for function and struct decls

This commit is contained in:
Rhys Weatherley
2010-11-18 13:01:27 +10:00
parent 0fa980028e
commit 2fab4ba8ad
6 changed files with 515 additions and 347 deletions

View File

@@ -292,7 +292,8 @@ public:
Type *type; Type *type;
const std::string *name; const std::string *name;
} param_declarator; } param_declarator;
// ### ast nodes... ParameterDeclaration *param_declaration;
FunctionDeclaration *function_declaration;
}; };
Parser(Engine *engine, const char *source, unsigned size, int variant); Parser(Engine *engine, const char *source, unsigned size, int variant);
@@ -308,6 +309,7 @@ private:
Expression *&expression(int n) { return _symStack[_tos + n - 1].expression; } Expression *&expression(int n) { return _symStack[_tos + n - 1].expression; }
Statement *&statement(int n) { return _symStack[_tos + n - 1].statement; } Statement *&statement(int n) { return _symStack[_tos + n - 1].statement; }
Type *&type(int n) { return _symStack[_tos + n - 1].type; } Type *&type(int n) { return _symStack[_tos + n - 1].type; }
FunctionDeclaration *&function(int n) { return _symStack[_tos + n - 1].function_declaration; }
inline int consumeToken() { return _index++; } inline int consumeToken() { return _index++; }
inline const Token &tokenAt(int index) const { return _tokens.at(index); } inline const Token &tokenAt(int index) const { return _tokens.at(index); }
@@ -1123,7 +1125,7 @@ case $rule_number: {
declaration ::= function_prototype SEMICOLON ; declaration ::= function_prototype SEMICOLON ;
/. /.
case $rule_number: { case $rule_number: {
// ast(1) = new ...AST(...); // nothing to do.
} break; } break;
./ ./
@@ -1144,77 +1146,124 @@ case $rule_number: {
declaration ::= type_qualifier IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE SEMICOLON ; declaration ::= type_qualifier IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE SEMICOLON ;
/. /.
case $rule_number: { case $rule_number: {
// ast(1) = new ...AST(...); if (sym(1).type_qualifier.qualifier != QualifiedType::Struct) {
// TODO: issue an error if the qualifier is not "struct".
}
Type *type = makeAstNode<StructType>(string(2), sym(4).field_list);
ast(1) = makeAstNode<TypeDeclaration>(type);
} break; } break;
./ ./
declaration ::= type_qualifier IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE IDENTIFIER SEMICOLON ; declaration ::= type_qualifier IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE IDENTIFIER SEMICOLON ;
/. /.
case $rule_number: { case $rule_number: {
// ast(1) = new ...AST(...); if ((sym(1).type_qualifier.qualifier & QualifiedType::Struct) == 0) {
// TODO: issue an error if the qualifier does not contain "struct".
}
Type *type = makeAstNode<StructType>(string(2), sym(4).field_list);
Type *qualtype = type;
if (sym(1).type_qualifier.qualifier != QualifiedType::Struct) {
qualtype = makeAstNode<QualifiedType>
(sym(1).type_qualifier.qualifier & ~QualifiedType::Struct, qualtype,
sym(1).type_qualifier.layout_list);
}
ast(1) = makeAstNode<TypeAndVariableDeclaration>
(makeAstNode<TypeDeclaration>(type),
makeAstNode<VariableDeclaration>(qualtype, string(6)));
} break; } break;
./ ./
declaration ::= type_qualifier IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE IDENTIFIER LEFT_BRACKET RIGHT_BRACKET SEMICOLON ; declaration ::= type_qualifier IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE IDENTIFIER LEFT_BRACKET RIGHT_BRACKET SEMICOLON ;
/. /.
case $rule_number: { case $rule_number: {
// ast(1) = new ...AST(...); if ((sym(1).type_qualifier.qualifier & QualifiedType::Struct) == 0) {
// TODO: issue an error if the qualifier does not contain "struct".
}
Type *type = makeAstNode<StructType>(string(2), sym(4).field_list);
Type *qualtype = type;
if (sym(1).type_qualifier.qualifier != QualifiedType::Struct) {
qualtype = makeAstNode<QualifiedType>
(sym(1).type_qualifier.qualifier & ~QualifiedType::Struct, qualtype,
sym(1).type_qualifier.layout_list);
}
ast(1) = makeAstNode<TypeAndVariableDeclaration>
(makeAstNode<TypeDeclaration>(type),
makeAstNode<VariableDeclaration>
(makeAstNode<ArrayType>(qualtype), string(6)));
} break; } break;
./ ./
declaration ::= type_qualifier IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET SEMICOLON ; declaration ::= type_qualifier IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET SEMICOLON ;
/. /.
case $rule_number: { case $rule_number: {
// ast(1) = new ...AST(...); if ((sym(1).type_qualifier.qualifier & QualifiedType::Struct) == 0) {
// TODO: issue an error if the qualifier does not contain "struct".
}
Type *type = makeAstNode<StructType>(string(2), sym(4).field_list);
Type *qualtype = type;
if (sym(1).type_qualifier.qualifier != QualifiedType::Struct) {
qualtype = makeAstNode<QualifiedType>
(sym(1).type_qualifier.qualifier & ~QualifiedType::Struct, qualtype,
sym(1).type_qualifier.layout_list);
}
ast(1) = makeAstNode<TypeAndVariableDeclaration>
(makeAstNode<TypeDeclaration>(type),
makeAstNode<VariableDeclaration>
(makeAstNode<ArrayType>(qualtype, expression(8)), string(6)));
} break; } break;
./ ./
declaration ::= type_qualifier SEMICOLON ; declaration ::= type_qualifier SEMICOLON ;
/. /.
case $rule_number: { case $rule_number: {
// ast(1) = new ...AST(...); Type *type = makeAstNode<QualifiedType>
(sym(1).type_qualifier.qualifier, (Type *)0,
sym(1).type_qualifier.layout_list);
ast(1) = makeAstNode<TypeDeclaration>(type);
} break; } break;
./ ./
function_prototype ::= function_declarator RIGHT_PAREN ; function_prototype ::= function_declarator RIGHT_PAREN ;
/. /.
case $rule_number: { case $rule_number: {
// ast(1) = new ...AST(...); function(1)->finishParams();
} break; } break;
./ ./
function_declarator ::= function_header ; function_declarator ::= function_header ;
/. /.
case $rule_number: { case $rule_number: {
// ast(1) = new ...AST(...); // nothing to do.
} break; } break;
./ ./
function_declarator ::= function_header_with_parameters ; function_declarator ::= function_header_with_parameters ;
/. /.
case $rule_number: { case $rule_number: {
// ast(1) = new ...AST(...); // nothing to do.
} break; } break;
./ ./
function_header_with_parameters ::= function_header parameter_declaration ; function_header_with_parameters ::= function_header parameter_declaration ;
/. /.
case $rule_number: { case $rule_number: {
// ast(1) = new ...AST(...); function(1)->params = makeAstNode< List<ParameterDeclaration *> >
(sym(2).param_declaration);
} break; } break;
./ ./
function_header_with_parameters ::= function_header_with_parameters COMMA parameter_declaration ; function_header_with_parameters ::= function_header_with_parameters COMMA parameter_declaration ;
/. /.
case $rule_number: { case $rule_number: {
// ast(1) = new ...AST(...); function(1)->params = makeAstNode< List<ParameterDeclaration *> >
(function(1)->params, sym(3).param_declaration);
} break; } break;
./ ./
function_header ::= fully_specified_type IDENTIFIER LEFT_PAREN ; function_header ::= fully_specified_type IDENTIFIER LEFT_PAREN ;
/. /.
case $rule_number: { case $rule_number: {
// ast(1) = new ...AST(...); function(1) = makeAstNode<FunctionDeclaration>(type(1), string(2));
} break; } break;
./ ./
@@ -2801,7 +2850,7 @@ case $rule_number: {
external_declaration ::= function_definition ; external_declaration ::= function_definition ;
/. /.
case $rule_number: { case $rule_number: {
// ast(1) = new ...AST(...); // nothing to do.
} break; } break;
./ ./
@@ -2822,7 +2871,7 @@ case $rule_number: {
function_definition ::= function_prototype compound_statement_no_new_scope ; function_definition ::= function_prototype compound_statement_no_new_scope ;
/. /.
case $rule_number: { case $rule_number: {
// ast(1) = new ...AST(...); function(1)->body = statement(2);
} break; } break;
./ ./

View File

@@ -394,6 +394,15 @@ void TypeDeclaration::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void TypeAndVariableDeclaration::accept0(Visitor *visitor)
{
if (visitor->visit(this)) {
accept(typeDecl, visitor);
accept(varDecl, visitor);
}
visitor->endVisit(this);
}
void InvariantDeclaration::accept0(Visitor *visitor) void InvariantDeclaration::accept0(Visitor *visitor)
{ {
visitor->visit(this); visitor->visit(this);
@@ -406,3 +415,13 @@ void InitDeclaration::accept0(Visitor *visitor)
accept(decls, visitor); accept(decls, visitor);
visitor->endVisit(this); visitor->endVisit(this);
} }
void FunctionDeclaration::accept0(Visitor *visitor)
{
if (visitor->visit(this)) {
accept(returnType, visitor);
accept(params, visitor);
accept(body, visitor);
}
visitor->endVisit(this);
}

View File

@@ -71,8 +71,10 @@ class PrecisionDeclaration;
class ParameterDeclaration; class ParameterDeclaration;
class VariableDeclaration; class VariableDeclaration;
class TypeDeclaration; class TypeDeclaration;
class TypeAndVariableDeclaration;
class InvariantDeclaration; class InvariantDeclaration;
class InitDeclaration; class InitDeclaration;
class FunctionDeclaration;
class Visitor; class Visitor;
template <typename T> template <typename T>
@@ -215,8 +217,10 @@ public:
Kind_ParameterDeclaration, Kind_ParameterDeclaration,
Kind_VariableDeclaration, Kind_VariableDeclaration,
Kind_TypeDeclaration, Kind_TypeDeclaration,
Kind_TypeAndVariableDeclaration,
Kind_InvariantDeclaration, Kind_InvariantDeclaration,
Kind_InitDeclaration Kind_InitDeclaration,
Kind_FunctionDeclaration
}; };
virtual TranslationUnit *asTranslationUnit() { return 0; } virtual TranslationUnit *asTranslationUnit() { return 0; }
@@ -258,8 +262,10 @@ public:
virtual ParameterDeclaration *asParameterDeclaration() { return 0; } virtual ParameterDeclaration *asParameterDeclaration() { return 0; }
virtual VariableDeclaration *asVariableDeclaration() { return 0; } virtual VariableDeclaration *asVariableDeclaration() { return 0; }
virtual TypeDeclaration *asTypeDeclaration() { return 0; } virtual TypeDeclaration *asTypeDeclaration() { return 0; }
virtual TypeAndVariableDeclaration *asTypeAndVariableDeclaration() { return 0; }
virtual InvariantDeclaration *asInvariantDeclaration() { return 0; } virtual InvariantDeclaration *asInvariantDeclaration() { return 0; }
virtual InitDeclaration *asInitDeclaration() { return 0; } virtual InitDeclaration *asInitDeclaration() { return 0; }
virtual FunctionDeclaration *asFunctionDeclaration() { return 0; }
void accept(Visitor *visitor); void accept(Visitor *visitor);
static void accept(AST *ast, Visitor *visitor); static void accept(AST *ast, Visitor *visitor);
@@ -953,6 +959,23 @@ public: // attributes
Type *type; Type *type;
}; };
class TypeAndVariableDeclaration: public Declaration
{
public:
TypeAndVariableDeclaration(TypeDeclaration *_typeDecl,
VariableDeclaration *_varDecl)
: Declaration(Kind_TypeAndVariableDeclaration)
, typeDecl(_typeDecl), varDecl(_varDecl) {}
virtual TypeAndVariableDeclaration *asTypeAndVariableDeclaration() { return this; }
virtual void accept0(Visitor *visitor);
public: // attributes
TypeDeclaration *typeDecl;
VariableDeclaration *varDecl;
};
class InvariantDeclaration: public Declaration class InvariantDeclaration: public Declaration
{ {
public: public:
@@ -981,6 +1004,28 @@ public: // attributes
List<Declaration *> *decls; List<Declaration *> *decls;
}; };
class FunctionDeclaration : public Declaration
{
public:
FunctionDeclaration(Type *_returnType, const std::string *_name)
: Declaration(Kind_FunctionDeclaration), returnType(_returnType)
, name(_name), params(0), body(0) {}
virtual FunctionDeclaration *asFunctionDeclaration() { return this; }
virtual void accept0(Visitor *visitor);
void finishParams() { params = finish(params); }
bool isPrototype() const { return body == 0; }
public: // attributes
Type *returnType;
const std::string *name;
List<ParameterDeclaration *> *params;
Statement *body;
};
} // namespace GLSL } // namespace GLSL
#endif // GLSLAST_H #endif // GLSLAST_H

View File

@@ -138,11 +138,17 @@ public:
virtual bool visit(TypeDeclaration *) { return true; } virtual bool visit(TypeDeclaration *) { return true; }
virtual void endVisit(TypeDeclaration *) {} virtual void endVisit(TypeDeclaration *) {}
virtual bool visit(TypeAndVariableDeclaration *) { return true; }
virtual void endVisit(TypeAndVariableDeclaration *) {}
virtual bool visit(InvariantDeclaration *) { return true; } virtual bool visit(InvariantDeclaration *) { return true; }
virtual void endVisit(InvariantDeclaration *) {} virtual void endVisit(InvariantDeclaration *) {}
virtual bool visit(InitDeclaration *) { return true; } virtual bool visit(InitDeclaration *) { return true; }
virtual void endVisit(InitDeclaration *) {} virtual void endVisit(InitDeclaration *) {}
virtual bool visit(FunctionDeclaration *) { return true; }
virtual void endVisit(FunctionDeclaration *) {}
}; };
} // namespace GLSL } // namespace GLSL

File diff suppressed because it is too large Load Diff

View File

@@ -83,7 +83,8 @@ public:
Type *type; Type *type;
const std::string *name; const std::string *name;
} param_declarator; } param_declarator;
// ### ast nodes... ParameterDeclaration *param_declaration;
FunctionDeclaration *function_declaration;
}; };
Parser(Engine *engine, const char *source, unsigned size, int variant); Parser(Engine *engine, const char *source, unsigned size, int variant);
@@ -99,6 +100,7 @@ private:
Expression *&expression(int n) { return _symStack[_tos + n - 1].expression; } Expression *&expression(int n) { return _symStack[_tos + n - 1].expression; }
Statement *&statement(int n) { return _symStack[_tos + n - 1].statement; } Statement *&statement(int n) { return _symStack[_tos + n - 1].statement; }
Type *&type(int n) { return _symStack[_tos + n - 1].type; } Type *&type(int n) { return _symStack[_tos + n - 1].type; }
FunctionDeclaration *&function(int n) { return _symStack[_tos + n - 1].function_declaration; }
inline int consumeToken() { return _index++; } inline int consumeToken() { return _index++; }
inline const Token &tokenAt(int index) const { return _tokens.at(index); } inline const Token &tokenAt(int index) const { return _tokens.at(index); }