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;
const std::string *name;
} param_declarator;
// ### ast nodes...
ParameterDeclaration *param_declaration;
FunctionDeclaration *function_declaration;
};
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; }
Statement *&statement(int n) { return _symStack[_tos + n - 1].statement; }
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 const Token &tokenAt(int index) const { return _tokens.at(index); }
@@ -1123,7 +1125,7 @@ case $rule_number: {
declaration ::= function_prototype SEMICOLON ;
/.
case $rule_number: {
// ast(1) = new ...AST(...);
// nothing to do.
} break;
./
@@ -1144,77 +1146,124 @@ case $rule_number: {
declaration ::= type_qualifier IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE SEMICOLON ;
/.
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;
./
declaration ::= type_qualifier IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE IDENTIFIER SEMICOLON ;
/.
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;
./
declaration ::= type_qualifier IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE IDENTIFIER LEFT_BRACKET RIGHT_BRACKET SEMICOLON ;
/.
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;
./
declaration ::= type_qualifier IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET SEMICOLON ;
/.
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;
./
declaration ::= type_qualifier SEMICOLON ;
/.
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;
./
function_prototype ::= function_declarator RIGHT_PAREN ;
/.
case $rule_number: {
// ast(1) = new ...AST(...);
function(1)->finishParams();
} break;
./
function_declarator ::= function_header ;
/.
case $rule_number: {
// ast(1) = new ...AST(...);
// nothing to do.
} break;
./
function_declarator ::= function_header_with_parameters ;
/.
case $rule_number: {
// ast(1) = new ...AST(...);
// nothing to do.
} break;
./
function_header_with_parameters ::= function_header parameter_declaration ;
/.
case $rule_number: {
// ast(1) = new ...AST(...);
function(1)->params = makeAstNode< List<ParameterDeclaration *> >
(sym(2).param_declaration);
} break;
./
function_header_with_parameters ::= function_header_with_parameters COMMA parameter_declaration ;
/.
case $rule_number: {
// ast(1) = new ...AST(...);
function(1)->params = makeAstNode< List<ParameterDeclaration *> >
(function(1)->params, sym(3).param_declaration);
} break;
./
function_header ::= fully_specified_type IDENTIFIER LEFT_PAREN ;
/.
case $rule_number: {
// ast(1) = new ...AST(...);
function(1) = makeAstNode<FunctionDeclaration>(type(1), string(2));
} break;
./
@@ -2801,7 +2850,7 @@ case $rule_number: {
external_declaration ::= function_definition ;
/.
case $rule_number: {
// ast(1) = new ...AST(...);
// nothing to do.
} break;
./
@@ -2822,7 +2871,7 @@ case $rule_number: {
function_definition ::= function_prototype compound_statement_no_new_scope ;
/.
case $rule_number: {
// ast(1) = new ...AST(...);
function(1)->body = statement(2);
} break;
./

View File

@@ -394,6 +394,15 @@ void TypeDeclaration::accept0(Visitor *visitor)
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)
{
visitor->visit(this);
@@ -406,3 +415,13 @@ void InitDeclaration::accept0(Visitor *visitor)
accept(decls, visitor);
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 VariableDeclaration;
class TypeDeclaration;
class TypeAndVariableDeclaration;
class InvariantDeclaration;
class InitDeclaration;
class FunctionDeclaration;
class Visitor;
template <typename T>
@@ -215,8 +217,10 @@ public:
Kind_ParameterDeclaration,
Kind_VariableDeclaration,
Kind_TypeDeclaration,
Kind_TypeAndVariableDeclaration,
Kind_InvariantDeclaration,
Kind_InitDeclaration
Kind_InitDeclaration,
Kind_FunctionDeclaration
};
virtual TranslationUnit *asTranslationUnit() { return 0; }
@@ -258,8 +262,10 @@ public:
virtual ParameterDeclaration *asParameterDeclaration() { return 0; }
virtual VariableDeclaration *asVariableDeclaration() { return 0; }
virtual TypeDeclaration *asTypeDeclaration() { return 0; }
virtual TypeAndVariableDeclaration *asTypeAndVariableDeclaration() { return 0; }
virtual InvariantDeclaration *asInvariantDeclaration() { return 0; }
virtual InitDeclaration *asInitDeclaration() { return 0; }
virtual FunctionDeclaration *asFunctionDeclaration() { return 0; }
void accept(Visitor *visitor);
static void accept(AST *ast, Visitor *visitor);
@@ -953,6 +959,23 @@ public: // attributes
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
{
public:
@@ -981,6 +1004,28 @@ public: // attributes
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
#endif // GLSLAST_H

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -83,7 +83,8 @@ public:
Type *type;
const std::string *name;
} param_declarator;
// ### ast nodes...
ParameterDeclaration *param_declaration;
FunctionDeclaration *function_declaration;
};
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; }
Statement *&statement(int n) { return _symStack[_tos + n - 1].statement; }
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 const Token &tokenAt(int index) const { return _tokens.at(index); }