blob: 73c5cc912e65b940d940b058cbce15e6369e4c1a [file] [log] [blame]
Austin Engcc2516a2023-10-17 20:57:54 +00001// Copyright 2020 The Dawn & Tint Authors
Ryan Harrisondbc13af2022-02-21 15:19:07 +00002//
Austin Engcc2516a2023-10-17 20:57:54 +00003// Redistribution and use in source and binary forms, with or without
4// modification, are permitted provided that the following conditions are met:
Ryan Harrisondbc13af2022-02-21 15:19:07 +00005//
Austin Engcc2516a2023-10-17 20:57:54 +00006// 1. Redistributions of source code must retain the above copyright notice, this
7// list of conditions and the following disclaimer.
Ryan Harrisondbc13af2022-02-21 15:19:07 +00008//
Austin Engcc2516a2023-10-17 20:57:54 +00009// 2. Redistributions in binary form must reproduce the above copyright notice,
10// this list of conditions and the following disclaimer in the documentation
11// and/or other materials provided with the distribution.
12//
13// 3. Neither the name of the copyright holder nor the names of its
14// contributors may be used to endorse or promote products derived from
15// this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Ryan Harrisondbc13af2022-02-21 15:19:07 +000027
dan sinclairc1bf2252023-07-26 17:38:29 +000028#ifndef SRC_TINT_LANG_WGSL_WRITER_AST_PRINTER_AST_PRINTER_H_
29#define SRC_TINT_LANG_WGSL_WRITER_AST_PRINTER_AST_PRINTER_H_
Ryan Harrisondbc13af2022-02-21 15:19:07 +000030
Ben Claytonedc51ab2023-08-08 07:58:19 +000031#include "src/tint/lang/core/binary_op.h"
Ben Clayton7fd1c2a2023-08-01 00:37:35 +000032#include "src/tint/utils/generator/text_generator.h"
dan sinclair22b4dd22023-07-21 00:40:07 +000033#include "src/tint/utils/text/string_stream.h"
Ben Clayton5ed099a2023-07-25 18:52:03 +000034
35// Forward declarations
Ben Claytonae18c412023-07-29 13:00:40 +000036namespace tint {
37class Program;
38}
Ben Clayton5ed099a2023-07-25 18:52:03 +000039namespace tint::ast {
40class AssignmentStatement;
41class Attribute;
42class BinaryExpression;
Ben Clayton5ed099a2023-07-25 18:52:03 +000043class BitcastExpression;
44class BlockStatement;
45class BlockStatement;
46class BreakIfStatement;
47class BreakStatement;
48class CallExpression;
49class CaseStatement;
50class CompoundAssignmentStatement;
51class ConstAssert;
52class ContinueStatement;
53struct DiagnosticControl;
54class DiscardStatement;
55class Enable;
56class Expression;
57class ForLoopStatement;
58class Function;
59class Identifier;
60class IdentifierExpression;
61class IfStatement;
62class IncrementDecrementStatement;
63class IndexAccessorExpression;
64class LiteralExpression;
65class LoopStatement;
66class MemberAccessorExpression;
James Pricebdbeb352023-11-02 15:03:02 +000067class Requires;
Ben Clayton5ed099a2023-07-25 18:52:03 +000068class ReturnStatement;
69class Statement;
70class Statement;
71class Statement;
72class Struct;
73class SwitchStatement;
74class TypeDecl;
75class UnaryOpExpression;
76class Variable;
77class WhileStatement;
78} // namespace tint::ast
dan sinclairc1bf2252023-07-26 17:38:29 +000079
Ben Claytoncd52f382023-08-07 13:11:08 +000080namespace tint::core {
Ben Clayton0f8b6ef2023-08-10 14:12:42 +000081enum class TexelFormat : uint8_t;
Ben Claytoncd52f382023-08-07 13:11:08 +000082} // namespace tint::core
Ryan Harrisondbc13af2022-02-21 15:19:07 +000083
dan sinclairc1bf2252023-07-26 17:38:29 +000084namespace tint::wgsl::writer {
Ryan Harrisondbc13af2022-02-21 15:19:07 +000085
86/// Implementation class for WGSL generator
dan sinclairbae54e72023-07-28 15:01:54 +000087class ASTPrinter : public tint::TextGenerator {
dan sinclair41e4d9a2022-05-01 14:40:55 +000088 public:
89 /// Constructor
90 /// @param program the program
Ben Clayton5ed5cc42023-09-22 10:31:04 +000091 explicit ASTPrinter(const Program& program);
dan sinclairc1bf2252023-07-26 17:38:29 +000092 ~ASTPrinter() override;
Ryan Harrisondbc13af2022-02-21 15:19:07 +000093
dan sinclair41e4d9a2022-05-01 14:40:55 +000094 /// Generates the result data
James Priced3a56cb2023-08-02 19:46:00 +000095 /// @returns true on successful generation, false otherwise
96 bool Generate();
Ryan Harrisondbc13af2022-02-21 15:19:07 +000097
James Pricee8ea5792023-01-24 21:01:36 +000098 /// Handles generating a diagnostic control
Ben Clayton971318f2023-02-14 13:52:43 +000099 /// @param out the output stream
James Pricee8ea5792023-01-24 21:01:36 +0000100 /// @param diagnostic the diagnostic control node
dan sinclairbae54e72023-07-28 15:01:54 +0000101 void EmitDiagnosticControl(StringStream& out, const ast::DiagnosticControl& diagnostic);
James Pricee8ea5792023-01-24 21:01:36 +0000102 /// Handles generating an enable directive
Ben Clayton7f2b8cd2022-05-18 22:41:48 +0000103 /// @param enable the enable node
dan sinclair27c77222023-04-13 02:57:27 +0000104 void EmitEnable(const ast::Enable* enable);
James Pricebdbeb352023-11-02 15:03:02 +0000105 /// Handles generating a requires directive
106 /// @param req the requires node
107 void EmitRequires(const ast::Requires* req);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000108 /// Handles generating a declared type
109 /// @param ty the declared type to generate
dan sinclair27c77222023-04-13 02:57:27 +0000110 void EmitTypeDecl(const ast::TypeDecl* ty);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000111 /// Handles an index accessor expression
Ben Clayton971318f2023-02-14 13:52:43 +0000112 /// @param out the output stream
dan sinclair41e4d9a2022-05-01 14:40:55 +0000113 /// @param expr the expression to emit
dan sinclairbae54e72023-07-28 15:01:54 +0000114 void EmitIndexAccessor(StringStream& out, const ast::IndexAccessorExpression* expr);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000115 /// Handles an assignment statement
116 /// @param stmt the statement to emit
dan sinclair27c77222023-04-13 02:57:27 +0000117 void EmitAssign(const ast::AssignmentStatement* stmt);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000118 /// Handles generating a binary expression
Ben Clayton971318f2023-02-14 13:52:43 +0000119 /// @param out the output stream
dan sinclair41e4d9a2022-05-01 14:40:55 +0000120 /// @param expr the binary expression
dan sinclairbae54e72023-07-28 15:01:54 +0000121 void EmitBinary(StringStream& out, const ast::BinaryExpression* expr);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000122 /// Handles generating a binary operator
Ben Clayton971318f2023-02-14 13:52:43 +0000123 /// @param out the output stream
dan sinclair41e4d9a2022-05-01 14:40:55 +0000124 /// @param op the binary operator
Ben Claytonedc51ab2023-08-08 07:58:19 +0000125 void EmitBinaryOp(StringStream& out, const core::BinaryOp op);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000126 /// Handles a block statement
127 /// @param stmt the statement to emit
dan sinclair27c77222023-04-13 02:57:27 +0000128 void EmitBlock(const ast::BlockStatement* stmt);
James Priced9f65962023-02-01 23:14:10 +0000129 /// Handles emitting the start of a block statement (including attributes)
130 /// @param out the output stream to write the header to
131 /// @param stmt the block statement to emit the header for
dan sinclairbae54e72023-07-28 15:01:54 +0000132 void EmitBlockHeader(StringStream& out, const ast::BlockStatement* stmt);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000133 /// Handles a break statement
134 /// @param stmt the statement to emit
dan sinclair27c77222023-04-13 02:57:27 +0000135 void EmitBreak(const ast::BreakStatement* stmt);
dan sinclairb8b0c212022-10-20 22:45:50 +0000136 /// Handles a break-if statement
137 /// @param stmt the statement to emit
dan sinclair27c77222023-04-13 02:57:27 +0000138 void EmitBreakIf(const ast::BreakIfStatement* stmt);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000139 /// Handles generating a call expression
Ben Clayton971318f2023-02-14 13:52:43 +0000140 /// @param out the output stream
dan sinclair41e4d9a2022-05-01 14:40:55 +0000141 /// @param expr the call expression
dan sinclairbae54e72023-07-28 15:01:54 +0000142 void EmitCall(StringStream& out, const ast::CallExpression* expr);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000143 /// Handles a case statement
144 /// @param stmt the statement
dan sinclair27c77222023-04-13 02:57:27 +0000145 void EmitCase(const ast::CaseStatement* stmt);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000146 /// Handles a compound assignment statement
147 /// @param stmt the statement to emit
dan sinclair27c77222023-04-13 02:57:27 +0000148 void EmitCompoundAssign(const ast::CompoundAssignmentStatement* stmt);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000149 /// Handles generating a literal expression
Ben Clayton971318f2023-02-14 13:52:43 +0000150 /// @param out the output stream
dan sinclair41e4d9a2022-05-01 14:40:55 +0000151 /// @param expr the literal expression expression
dan sinclairbae54e72023-07-28 15:01:54 +0000152 void EmitLiteral(StringStream& out, const ast::LiteralExpression* expr);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000153 /// Handles a continue statement
154 /// @param stmt the statement to emit
dan sinclair27c77222023-04-13 02:57:27 +0000155 void EmitContinue(const ast::ContinueStatement* stmt);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000156 /// Handles generate an Expression
Ben Clayton971318f2023-02-14 13:52:43 +0000157 /// @param out the output stream
dan sinclair41e4d9a2022-05-01 14:40:55 +0000158 /// @param expr the expression
dan sinclairbae54e72023-07-28 15:01:54 +0000159 void EmitExpression(StringStream& out, const ast::Expression* expr);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000160 /// Handles generating a function
161 /// @param func the function to generate
dan sinclair27c77222023-04-13 02:57:27 +0000162 void EmitFunction(const ast::Function* func);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000163 /// Handles generating an identifier expression
Ben Clayton971318f2023-02-14 13:52:43 +0000164 /// @param out the output stream
dan sinclair41e4d9a2022-05-01 14:40:55 +0000165 /// @param expr the identifier expression
dan sinclairbae54e72023-07-28 15:01:54 +0000166 void EmitIdentifier(StringStream& out, const ast::IdentifierExpression* expr);
Ben Clayton1131d312023-02-10 19:24:24 +0000167 /// Handles generating an identifier
168 /// @param out the output of the expression stream
169 /// @param ident the identifier
dan sinclairbae54e72023-07-28 15:01:54 +0000170 void EmitIdentifier(StringStream& out, const ast::Identifier* ident);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000171 /// Handles an if statement
172 /// @param stmt the statement to emit
dan sinclair27c77222023-04-13 02:57:27 +0000173 void EmitIf(const ast::IfStatement* stmt);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000174 /// Handles an increment/decrement statement
175 /// @param stmt the statement to emit
dan sinclair27c77222023-04-13 02:57:27 +0000176 void EmitIncrementDecrement(const ast::IncrementDecrementStatement* stmt);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000177 /// Handles generating a discard statement
178 /// @param stmt the discard statement
dan sinclair27c77222023-04-13 02:57:27 +0000179 void EmitDiscard(const ast::DiscardStatement* stmt);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000180 /// Handles a loop statement
181 /// @param stmt the statement to emit
dan sinclair27c77222023-04-13 02:57:27 +0000182 void EmitLoop(const ast::LoopStatement* stmt);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000183 /// Handles a for-loop statement
184 /// @param stmt the statement to emit
dan sinclair27c77222023-04-13 02:57:27 +0000185 void EmitForLoop(const ast::ForLoopStatement* stmt);
dan sinclair49d1a2d2022-06-16 12:01:27 +0000186 /// Handles a while statement
187 /// @param stmt the statement to emit
dan sinclair27c77222023-04-13 02:57:27 +0000188 void EmitWhile(const ast::WhileStatement* stmt);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000189 /// Handles a member accessor expression
Ben Clayton971318f2023-02-14 13:52:43 +0000190 /// @param out the output stream
dan sinclair41e4d9a2022-05-01 14:40:55 +0000191 /// @param expr the member accessor expression
dan sinclairbae54e72023-07-28 15:01:54 +0000192 void EmitMemberAccessor(StringStream& out, const ast::MemberAccessorExpression* expr);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000193 /// Handles return statements
194 /// @param stmt the statement to emit
dan sinclair27c77222023-04-13 02:57:27 +0000195 void EmitReturn(const ast::ReturnStatement* stmt);
Ben Claytonc98d57d2023-01-24 14:59:43 +0000196 /// Handles const assertion statements
Ben Claytonb4744ac2022-08-03 07:01:08 +0000197 /// @param stmt the statement to emit
dan sinclair27c77222023-04-13 02:57:27 +0000198 void EmitConstAssert(const ast::ConstAssert* stmt);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000199 /// Handles statement
200 /// @param stmt the statement to emit
dan sinclair27c77222023-04-13 02:57:27 +0000201 void EmitStatement(const ast::Statement* stmt);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000202 /// Handles a statement list
203 /// @param stmts the statements to emit
dan sinclairbae54e72023-07-28 15:01:54 +0000204 void EmitStatements(VectorRef<const ast::Statement*> stmts);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000205 /// Handles a statement list with an increased indentation
206 /// @param stmts the statements to emit
dan sinclairbae54e72023-07-28 15:01:54 +0000207 void EmitStatementsWithIndent(VectorRef<const ast::Statement*> stmts);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000208 /// Handles generating a switch statement
209 /// @param stmt the statement to emit
dan sinclair27c77222023-04-13 02:57:27 +0000210 void EmitSwitch(const ast::SwitchStatement* stmt);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000211 /// Handles generating a struct declaration
212 /// @param str the struct
dan sinclair27c77222023-04-13 02:57:27 +0000213 void EmitStructType(const ast::Struct* str);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000214 /// Handles emitting an image format
Ben Clayton971318f2023-02-14 13:52:43 +0000215 /// @param out the output stream
dan sinclair41e4d9a2022-05-01 14:40:55 +0000216 /// @param fmt the format to generate
Ben Claytoncd52f382023-08-07 13:11:08 +0000217 void EmitImageFormat(StringStream& out, const core::TexelFormat fmt);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000218 /// Handles a unary op expression
Ben Clayton971318f2023-02-14 13:52:43 +0000219 /// @param out the output stream
dan sinclair41e4d9a2022-05-01 14:40:55 +0000220 /// @param expr the expression to emit
dan sinclairbae54e72023-07-28 15:01:54 +0000221 void EmitUnaryOp(StringStream& out, const ast::UnaryOpExpression* expr);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000222 /// Handles generating a variable
Ben Clayton971318f2023-02-14 13:52:43 +0000223 /// @param out the output stream
dan sinclair41e4d9a2022-05-01 14:40:55 +0000224 /// @param var the variable to generate
dan sinclairbae54e72023-07-28 15:01:54 +0000225 void EmitVariable(StringStream& out, const ast::Variable* var);
dan sinclair41e4d9a2022-05-01 14:40:55 +0000226 /// Handles generating a attribute list
Ben Clayton971318f2023-02-14 13:52:43 +0000227 /// @param out the output stream
dan sinclair41e4d9a2022-05-01 14:40:55 +0000228 /// @param attrs the attribute list
dan sinclairbae54e72023-07-28 15:01:54 +0000229 void EmitAttributes(StringStream& out, VectorRef<const ast::Attribute*> attrs);
Ben Clayton5ed099a2023-07-25 18:52:03 +0000230
231 private:
Ben Clayton5ed5cc42023-09-22 10:31:04 +0000232 const Program& program_;
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000233};
234
dan sinclairc1bf2252023-07-26 17:38:29 +0000235} // namespace tint::wgsl::writer
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000236
dan sinclairc1bf2252023-07-26 17:38:29 +0000237#endif // SRC_TINT_LANG_WGSL_WRITER_AST_PRINTER_AST_PRINTER_H_