Add IdentifierExpression to WGSL writer.
This CL extends the WGSL writer to output IdentiferExpression and fills out the variable with initializer test case and implementation. Bug: tint:4 Change-Id: I9db9affb5ec4c4c109488f60bbc81bf3a96eee35 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/16744 Reviewed-by: David Neto <dneto@google.com>
This commit is contained in:
parent
d9e9ff3be5
commit
306a2f8381
|
@ -19,6 +19,7 @@
|
||||||
#include "src/ast/binding_decoration.h"
|
#include "src/ast/binding_decoration.h"
|
||||||
#include "src/ast/builtin_decoration.h"
|
#include "src/ast/builtin_decoration.h"
|
||||||
#include "src/ast/decorated_variable.h"
|
#include "src/ast/decorated_variable.h"
|
||||||
|
#include "src/ast/identifier_expression.h"
|
||||||
#include "src/ast/location_decoration.h"
|
#include "src/ast/location_decoration.h"
|
||||||
#include "src/ast/set_decoration.h"
|
#include "src/ast/set_decoration.h"
|
||||||
#include "src/ast/struct.h"
|
#include "src/ast/struct.h"
|
||||||
|
@ -76,7 +77,14 @@ bool GeneratorImpl::Generate(const ast::Module& module) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GeneratorImpl::make_indent() {
|
||||||
|
for (size_t i = 0; i < indent_; i++) {
|
||||||
|
out_ << " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool GeneratorImpl::EmitAliasType(const ast::type::AliasType* alias) {
|
bool GeneratorImpl::EmitAliasType(const ast::type::AliasType* alias) {
|
||||||
|
make_indent();
|
||||||
out_ << "type " << alias->name() << " = ";
|
out_ << "type " << alias->name() << " = ";
|
||||||
if (!EmitType(alias->type())) {
|
if (!EmitType(alias->type())) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -87,6 +95,7 @@ bool GeneratorImpl::EmitAliasType(const ast::type::AliasType* alias) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GeneratorImpl::EmitEntryPoint(const ast::EntryPoint* ep) {
|
bool GeneratorImpl::EmitEntryPoint(const ast::EntryPoint* ep) {
|
||||||
|
make_indent();
|
||||||
out_ << "entry_point " << ep->stage() << " ";
|
out_ << "entry_point " << ep->stage() << " ";
|
||||||
if (!ep->name().empty() && ep->name() != ep->function_name()) {
|
if (!ep->name().empty() && ep->name() != ep->function_name()) {
|
||||||
out_ << R"(as ")" << ep->name() << R"(" )";
|
out_ << R"(as ")" << ep->name() << R"(" )";
|
||||||
|
@ -96,7 +105,25 @@ bool GeneratorImpl::EmitEntryPoint(const ast::EntryPoint* ep) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GeneratorImpl::EmitExpression(ast::Expression* expr) {
|
||||||
|
if (expr->IsIdentifier()) {
|
||||||
|
bool first = true;
|
||||||
|
for (const auto& part : expr->AsIdentifier()->name()) {
|
||||||
|
if (!first) {
|
||||||
|
out_ << "::";
|
||||||
|
}
|
||||||
|
first = false;
|
||||||
|
out_ << part;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
error_ = "unknown expression type";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool GeneratorImpl::EmitImport(const ast::Import* import) {
|
bool GeneratorImpl::EmitImport(const ast::Import* import) {
|
||||||
|
make_indent();
|
||||||
out_ << R"(import ")" << import->path() << R"(" as )" << import->name() << ";"
|
out_ << R"(import ")" << import->path() << R"(" as )" << import->name() << ";"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
return true;
|
return true;
|
||||||
|
@ -143,9 +170,10 @@ bool GeneratorImpl::EmitType(ast::type::Type* type) {
|
||||||
out_ << "[[" << str->decoration() << "]] ";
|
out_ << "[[" << str->decoration() << "]] ";
|
||||||
}
|
}
|
||||||
out_ << "struct {" << std::endl;
|
out_ << "struct {" << std::endl;
|
||||||
|
|
||||||
|
increment_indent();
|
||||||
for (const auto& mem : str->members()) {
|
for (const auto& mem : str->members()) {
|
||||||
// TODO(dsinclair): This formats bad with nested structs
|
make_indent();
|
||||||
out_ << " ";
|
|
||||||
if (!mem->decorations().empty()) {
|
if (!mem->decorations().empty()) {
|
||||||
out_ << "[[";
|
out_ << "[[";
|
||||||
bool first = true;
|
bool first = true;
|
||||||
|
@ -169,6 +197,8 @@ bool GeneratorImpl::EmitType(ast::type::Type* type) {
|
||||||
}
|
}
|
||||||
out_ << ";" << std::endl;
|
out_ << ";" << std::endl;
|
||||||
}
|
}
|
||||||
|
decrement_indent();
|
||||||
|
make_indent();
|
||||||
|
|
||||||
out_ << "}";
|
out_ << "}";
|
||||||
} else if (type->IsU32()) {
|
} else if (type->IsU32()) {
|
||||||
|
@ -191,6 +221,8 @@ bool GeneratorImpl::EmitType(ast::type::Type* type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GeneratorImpl::EmitVariable(ast::Variable* var) {
|
bool GeneratorImpl::EmitVariable(ast::Variable* var) {
|
||||||
|
make_indent();
|
||||||
|
|
||||||
if (var->IsDecorated()) {
|
if (var->IsDecorated()) {
|
||||||
if (!EmitVariableDecorations(var->AsDecorated())) {
|
if (!EmitVariableDecorations(var->AsDecorated())) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -212,8 +244,10 @@ bool GeneratorImpl::EmitVariable(ast::Variable* var) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (var->initializer() != nullptr) {
|
if (var->initializer() != nullptr) {
|
||||||
// out_ << " = ";
|
out_ << " = ";
|
||||||
// EmitExpr(var-initializer());
|
if (!EmitExpression(var->initializer())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
out_ << ";" << std::endl;
|
out_ << ";" << std::endl;
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,20 @@ class GeneratorImpl {
|
||||||
/// @returns the error from the generator
|
/// @returns the error from the generator
|
||||||
std::string error() const { return error_; }
|
std::string error() const { return error_; }
|
||||||
|
|
||||||
|
/// Increment the emitter indent level
|
||||||
|
void increment_indent() { indent_ += 2; }
|
||||||
|
/// Decrement the emiter indent level
|
||||||
|
void decrement_indent() {
|
||||||
|
if (indent_ < 2) {
|
||||||
|
indent_ = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
indent_ -= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Writes the current indent to the output stream
|
||||||
|
void make_indent();
|
||||||
|
|
||||||
/// Handles generating an alias
|
/// Handles generating an alias
|
||||||
/// @param alias the alias to generate
|
/// @param alias the alias to generate
|
||||||
/// @returns true if the alias was emitted
|
/// @returns true if the alias was emitted
|
||||||
|
@ -55,6 +69,10 @@ class GeneratorImpl {
|
||||||
/// @param ep the entry point
|
/// @param ep the entry point
|
||||||
/// @returns true if the entry point was emitted
|
/// @returns true if the entry point was emitted
|
||||||
bool EmitEntryPoint(const ast::EntryPoint* ep);
|
bool EmitEntryPoint(const ast::EntryPoint* ep);
|
||||||
|
/// Handles generate an Expression
|
||||||
|
/// @param expr the expression
|
||||||
|
/// @returns true if the expression was emitted
|
||||||
|
bool EmitExpression(ast::Expression* expr);
|
||||||
/// Handles generating an import command
|
/// Handles generating an import command
|
||||||
/// @param import the import to generate
|
/// @param import the import to generate
|
||||||
/// @returns true if the import was emitted
|
/// @returns true if the import was emitted
|
||||||
|
@ -73,6 +91,7 @@ class GeneratorImpl {
|
||||||
bool EmitVariableDecorations(ast::DecoratedVariable* var);
|
bool EmitVariableDecorations(ast::DecoratedVariable* var);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
size_t indent_ = 0;
|
||||||
std::ostringstream out_;
|
std::ostringstream out_;
|
||||||
std::string error_;
|
std::string error_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "src/ast/builtin.h"
|
#include "src/ast/builtin.h"
|
||||||
#include "src/ast/builtin_decoration.h"
|
#include "src/ast/builtin_decoration.h"
|
||||||
#include "src/ast/decorated_variable.h"
|
#include "src/ast/decorated_variable.h"
|
||||||
|
#include "src/ast/identifier_expression.h"
|
||||||
#include "src/ast/location_decoration.h"
|
#include "src/ast/location_decoration.h"
|
||||||
#include "src/ast/set_decoration.h"
|
#include "src/ast/set_decoration.h"
|
||||||
#include "src/ast/struct.h"
|
#include "src/ast/struct.h"
|
||||||
|
@ -83,7 +84,7 @@ TEST_F(GeneratorImplTest, DISABLED_EmitAliasType_Struct) {
|
||||||
GeneratorImpl g;
|
GeneratorImpl g;
|
||||||
ASSERT_TRUE(g.EmitAliasType(&alias));
|
ASSERT_TRUE(g.EmitAliasType(&alias));
|
||||||
EXPECT_EQ(g.result(), R"(type a = struct {
|
EXPECT_EQ(g.result(), R"(type a = struct {
|
||||||
a: f32;
|
a : f32;
|
||||||
[[offset 4]] b : i32;
|
[[offset 4]] b : i32;
|
||||||
}
|
}
|
||||||
)");
|
)");
|
||||||
|
@ -322,9 +323,48 @@ TEST_F(GeneratorImplTest, EmitVariable_Decorated_Multiple) {
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(GeneratorImplTest, DISABLED_EmitVariable_Initializer) {}
|
TEST_F(GeneratorImplTest, EmitVariable_Initializer) {
|
||||||
|
auto ident = std::make_unique<ast::IdentifierExpression>("initializer");
|
||||||
|
|
||||||
TEST_F(GeneratorImplTest, DISABLED_EmitVariable_Const) {}
|
ast::type::F32Type f32;
|
||||||
|
ast::Variable v("a", ast::StorageClass::kNone, &f32);
|
||||||
|
v.set_initializer(std::move(ident));
|
||||||
|
|
||||||
|
GeneratorImpl g;
|
||||||
|
ASSERT_TRUE(g.EmitVariable(&v));
|
||||||
|
EXPECT_EQ(g.result(), R"(var a : f32 = initializer;
|
||||||
|
)");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(GeneratorImplTest, EmitVariable_Const) {
|
||||||
|
auto ident = std::make_unique<ast::IdentifierExpression>("initializer");
|
||||||
|
|
||||||
|
ast::type::F32Type f32;
|
||||||
|
ast::Variable v("a", ast::StorageClass::kNone, &f32);
|
||||||
|
v.set_initializer(std::move(ident));
|
||||||
|
v.set_is_const(true);
|
||||||
|
|
||||||
|
GeneratorImpl g;
|
||||||
|
ASSERT_TRUE(g.EmitVariable(&v));
|
||||||
|
EXPECT_EQ(g.result(), R"(const a : f32 = initializer;
|
||||||
|
)");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(GeneratorImplTest, EmitExpression_Identifier) {
|
||||||
|
ast::IdentifierExpression i("init");
|
||||||
|
|
||||||
|
GeneratorImpl g;
|
||||||
|
ASSERT_TRUE(g.EmitExpression(&i));
|
||||||
|
EXPECT_EQ(g.result(), "init");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(GeneratorImplTest, EmitExpression_Identifier_MultipleNames) {
|
||||||
|
ast::IdentifierExpression i({"std", "glsl", "init"});
|
||||||
|
|
||||||
|
GeneratorImpl g;
|
||||||
|
ASSERT_TRUE(g.EmitExpression(&i));
|
||||||
|
EXPECT_EQ(g.result(), "std::glsl::init");
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace wgsl
|
} // namespace wgsl
|
||||||
|
|
Loading…
Reference in New Issue