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/builtin_decoration.h"
|
||||
#include "src/ast/decorated_variable.h"
|
||||
#include "src/ast/identifier_expression.h"
|
||||
#include "src/ast/location_decoration.h"
|
||||
#include "src/ast/set_decoration.h"
|
||||
#include "src/ast/struct.h"
|
||||
|
@ -76,7 +77,14 @@ bool GeneratorImpl::Generate(const ast::Module& module) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void GeneratorImpl::make_indent() {
|
||||
for (size_t i = 0; i < indent_; i++) {
|
||||
out_ << " ";
|
||||
}
|
||||
}
|
||||
|
||||
bool GeneratorImpl::EmitAliasType(const ast::type::AliasType* alias) {
|
||||
make_indent();
|
||||
out_ << "type " << alias->name() << " = ";
|
||||
if (!EmitType(alias->type())) {
|
||||
return false;
|
||||
|
@ -87,6 +95,7 @@ bool GeneratorImpl::EmitAliasType(const ast::type::AliasType* alias) {
|
|||
}
|
||||
|
||||
bool GeneratorImpl::EmitEntryPoint(const ast::EntryPoint* ep) {
|
||||
make_indent();
|
||||
out_ << "entry_point " << ep->stage() << " ";
|
||||
if (!ep->name().empty() && ep->name() != ep->function_name()) {
|
||||
out_ << R"(as ")" << ep->name() << R"(" )";
|
||||
|
@ -96,7 +105,25 @@ bool GeneratorImpl::EmitEntryPoint(const ast::EntryPoint* ep) {
|
|||
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) {
|
||||
make_indent();
|
||||
out_ << R"(import ")" << import->path() << R"(" as )" << import->name() << ";"
|
||||
<< std::endl;
|
||||
return true;
|
||||
|
@ -143,9 +170,10 @@ bool GeneratorImpl::EmitType(ast::type::Type* type) {
|
|||
out_ << "[[" << str->decoration() << "]] ";
|
||||
}
|
||||
out_ << "struct {" << std::endl;
|
||||
|
||||
increment_indent();
|
||||
for (const auto& mem : str->members()) {
|
||||
// TODO(dsinclair): This formats bad with nested structs
|
||||
out_ << " ";
|
||||
make_indent();
|
||||
if (!mem->decorations().empty()) {
|
||||
out_ << "[[";
|
||||
bool first = true;
|
||||
|
@ -169,6 +197,8 @@ bool GeneratorImpl::EmitType(ast::type::Type* type) {
|
|||
}
|
||||
out_ << ";" << std::endl;
|
||||
}
|
||||
decrement_indent();
|
||||
make_indent();
|
||||
|
||||
out_ << "}";
|
||||
} else if (type->IsU32()) {
|
||||
|
@ -191,6 +221,8 @@ bool GeneratorImpl::EmitType(ast::type::Type* type) {
|
|||
}
|
||||
|
||||
bool GeneratorImpl::EmitVariable(ast::Variable* var) {
|
||||
make_indent();
|
||||
|
||||
if (var->IsDecorated()) {
|
||||
if (!EmitVariableDecorations(var->AsDecorated())) {
|
||||
return false;
|
||||
|
@ -212,8 +244,10 @@ bool GeneratorImpl::EmitVariable(ast::Variable* var) {
|
|||
}
|
||||
|
||||
if (var->initializer() != nullptr) {
|
||||
// out_ << " = ";
|
||||
// EmitExpr(var-initializer());
|
||||
out_ << " = ";
|
||||
if (!EmitExpression(var->initializer())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
out_ << ";" << std::endl;
|
||||
|
||||
|
|
|
@ -47,6 +47,20 @@ class GeneratorImpl {
|
|||
/// @returns the error from the generator
|
||||
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
|
||||
/// @param alias the alias to generate
|
||||
/// @returns true if the alias was emitted
|
||||
|
@ -55,6 +69,10 @@ class GeneratorImpl {
|
|||
/// @param ep the entry point
|
||||
/// @returns true if the entry point was emitted
|
||||
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
|
||||
/// @param import the import to generate
|
||||
/// @returns true if the import was emitted
|
||||
|
@ -73,6 +91,7 @@ class GeneratorImpl {
|
|||
bool EmitVariableDecorations(ast::DecoratedVariable* var);
|
||||
|
||||
private:
|
||||
size_t indent_ = 0;
|
||||
std::ostringstream out_;
|
||||
std::string error_;
|
||||
};
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "src/ast/builtin.h"
|
||||
#include "src/ast/builtin_decoration.h"
|
||||
#include "src/ast/decorated_variable.h"
|
||||
#include "src/ast/identifier_expression.h"
|
||||
#include "src/ast/location_decoration.h"
|
||||
#include "src/ast/set_decoration.h"
|
||||
#include "src/ast/struct.h"
|
||||
|
@ -83,7 +84,7 @@ TEST_F(GeneratorImplTest, DISABLED_EmitAliasType_Struct) {
|
|||
GeneratorImpl g;
|
||||
ASSERT_TRUE(g.EmitAliasType(&alias));
|
||||
EXPECT_EQ(g.result(), R"(type a = struct {
|
||||
a: f32;
|
||||
a : f32;
|
||||
[[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 wgsl
|
||||
|
|
Loading…
Reference in New Issue