1 /* 2 * Copyright 2016 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SKSL_FORSTATEMENT 9 #define SKSL_FORSTATEMENT 10 11 #include "include/private/SkSLStatement.h" 12 #include "src/sksl/ir/SkSLExpression.h" 13 #include "src/sksl/ir/SkSLSymbolTable.h" 14 15 namespace SkSL { 16 17 /** 18 * The unrollability information for an ES2-compatible loop. 19 */ 20 struct LoopUnrollInfo { 21 const Variable* fIndex; 22 double fStart; 23 double fDelta; 24 int fCount; 25 }; 26 27 /** 28 * A 'for' statement. 29 */ 30 class ForStatement final : public Statement { 31 public: 32 inline static constexpr Kind kStatementKind = Kind::kFor; 33 ForStatement(int line,std::unique_ptr<Statement> initializer,std::unique_ptr<Expression> test,std::unique_ptr<Expression> next,std::unique_ptr<Statement> statement,std::unique_ptr<LoopUnrollInfo> unrollInfo,std::shared_ptr<SymbolTable> symbols)34 ForStatement(int line, 35 std::unique_ptr<Statement> initializer, 36 std::unique_ptr<Expression> test, 37 std::unique_ptr<Expression> next, 38 std::unique_ptr<Statement> statement, 39 std::unique_ptr<LoopUnrollInfo> unrollInfo, 40 std::shared_ptr<SymbolTable> symbols) 41 : INHERITED(line, kStatementKind) 42 , fSymbolTable(std::move(symbols)) 43 , fInitializer(std::move(initializer)) 44 , fTest(std::move(test)) 45 , fNext(std::move(next)) 46 , fStatement(std::move(statement)) 47 , fUnrollInfo(std::move(unrollInfo)) {} 48 49 // Creates an SkSL for loop; handles type-coercion and uses the ErrorReporter to report errors. 50 static std::unique_ptr<Statement> Convert(const Context& context, int line, 51 std::unique_ptr<Statement> initializer, 52 std::unique_ptr<Expression> test, 53 std::unique_ptr<Expression> next, 54 std::unique_ptr<Statement> statement, 55 std::shared_ptr<SymbolTable> symbolTable); 56 57 // Creates an SkSL while loop; handles type-coercion and uses the ErrorReporter for errors. 58 static std::unique_ptr<Statement> ConvertWhile(const Context& context, int line, 59 std::unique_ptr<Expression> test, 60 std::unique_ptr<Statement> statement, 61 std::shared_ptr<SymbolTable> symbolTable); 62 63 // Creates an SkSL for/while loop. Assumes properly coerced types and reports errors via assert. 64 static std::unique_ptr<Statement> Make(const Context& context, int line, 65 std::unique_ptr<Statement> initializer, 66 std::unique_ptr<Expression> test, 67 std::unique_ptr<Expression> next, 68 std::unique_ptr<Statement> statement, 69 std::unique_ptr<LoopUnrollInfo> unrollInfo, 70 std::shared_ptr<SymbolTable> symbolTable); 71 initializer()72 std::unique_ptr<Statement>& initializer() { 73 return fInitializer; 74 } 75 initializer()76 const std::unique_ptr<Statement>& initializer() const { 77 return fInitializer; 78 } 79 test()80 std::unique_ptr<Expression>& test() { 81 return fTest; 82 } 83 test()84 const std::unique_ptr<Expression>& test() const { 85 return fTest; 86 } 87 next()88 std::unique_ptr<Expression>& next() { 89 return fNext; 90 } 91 next()92 const std::unique_ptr<Expression>& next() const { 93 return fNext; 94 } 95 statement()96 std::unique_ptr<Statement>& statement() { 97 return fStatement; 98 } 99 statement()100 const std::unique_ptr<Statement>& statement() const { 101 return fStatement; 102 } 103 symbols()104 const std::shared_ptr<SymbolTable>& symbols() const { 105 return fSymbolTable; 106 } 107 108 /** Loop-unroll information is only supported in strict-ES2 code. Null is returned in ES3+. */ unrollInfo()109 const LoopUnrollInfo* unrollInfo() const { 110 return fUnrollInfo.get(); 111 } 112 113 std::unique_ptr<Statement> clone() const override; 114 115 String description() const override; 116 117 private: 118 std::shared_ptr<SymbolTable> fSymbolTable; 119 std::unique_ptr<Statement> fInitializer; 120 std::unique_ptr<Expression> fTest; 121 std::unique_ptr<Expression> fNext; 122 std::unique_ptr<Statement> fStatement; 123 std::unique_ptr<LoopUnrollInfo> fUnrollInfo; 124 125 using INHERITED = Statement; 126 }; 127 128 } // namespace SkSL 129 130 #endif 131