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 "src/sksl/SkSLPosition.h" 12 #include "src/sksl/ir/SkSLExpression.h" 13 #include "src/sksl/ir/SkSLIRNode.h" 14 #include "src/sksl/ir/SkSLStatement.h" 15 #include "src/sksl/ir/SkSLSymbolTable.h" 16 17 #include <memory> 18 #include <string> 19 #include <utility> 20 21 namespace SkSL { 22 23 class Context; 24 class Variable; 25 26 /** 27 * The unrollability information for an ES2-compatible loop. 28 */ 29 struct LoopUnrollInfo { 30 const Variable* fIndex; 31 double fStart; 32 double fDelta; 33 int fCount; 34 }; 35 36 /** 37 * A 'for' statement. 38 */ 39 class ForStatement final : public Statement { 40 public: 41 inline static constexpr Kind kIRNodeKind = Kind::kFor; 42 ForStatement(Position pos,ForLoopPositions forLoopPositions,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::unique_ptr<SymbolTable> symbols)43 ForStatement(Position pos, 44 ForLoopPositions forLoopPositions, 45 std::unique_ptr<Statement> initializer, 46 std::unique_ptr<Expression> test, 47 std::unique_ptr<Expression> next, 48 std::unique_ptr<Statement> statement, 49 std::unique_ptr<LoopUnrollInfo> unrollInfo, 50 std::unique_ptr<SymbolTable> symbols) 51 : INHERITED(pos, kIRNodeKind) 52 , fForLoopPositions(forLoopPositions) 53 , fSymbolTable(std::move(symbols)) 54 , fInitializer(std::move(initializer)) 55 , fTest(std::move(test)) 56 , fNext(std::move(next)) 57 , fStatement(std::move(statement)) 58 , fUnrollInfo(std::move(unrollInfo)) {} 59 60 // Creates an SkSL for loop; handles type-coercion and uses the ErrorReporter to report errors. 61 static std::unique_ptr<Statement> Convert(const Context& context, 62 Position pos, 63 ForLoopPositions forLoopPositions, 64 std::unique_ptr<Statement> initializer, 65 std::unique_ptr<Expression> test, 66 std::unique_ptr<Expression> next, 67 std::unique_ptr<Statement> statement, 68 std::unique_ptr<SymbolTable> symbolTable); 69 70 // Creates an SkSL while loop; handles type-coercion and uses the ErrorReporter for errors. 71 static std::unique_ptr<Statement> ConvertWhile(const Context& context, 72 Position pos, 73 std::unique_ptr<Expression> test, 74 std::unique_ptr<Statement> statement); 75 76 // Creates an SkSL for/while loop. Assumes properly coerced types and reports errors via assert. 77 static std::unique_ptr<Statement> Make(const Context& context, 78 Position pos, 79 ForLoopPositions forLoopPositions, 80 std::unique_ptr<Statement> initializer, 81 std::unique_ptr<Expression> test, 82 std::unique_ptr<Expression> next, 83 std::unique_ptr<Statement> statement, 84 std::unique_ptr<LoopUnrollInfo> unrollInfo, 85 std::unique_ptr<SymbolTable> symbolTable); 86 forLoopPositions()87 ForLoopPositions forLoopPositions() const { 88 return fForLoopPositions; 89 } 90 initializer()91 std::unique_ptr<Statement>& initializer() { 92 return fInitializer; 93 } 94 initializer()95 const std::unique_ptr<Statement>& initializer() const { 96 return fInitializer; 97 } 98 test()99 std::unique_ptr<Expression>& test() { 100 return fTest; 101 } 102 test()103 const std::unique_ptr<Expression>& test() const { 104 return fTest; 105 } 106 next()107 std::unique_ptr<Expression>& next() { 108 return fNext; 109 } 110 next()111 const std::unique_ptr<Expression>& next() const { 112 return fNext; 113 } 114 statement()115 std::unique_ptr<Statement>& statement() { 116 return fStatement; 117 } 118 statement()119 const std::unique_ptr<Statement>& statement() const { 120 return fStatement; 121 } 122 symbols()123 SymbolTable* symbols() const { 124 return fSymbolTable.get(); 125 } 126 127 /** Loop-unroll information is only supported in strict-ES2 code. Null is returned in ES3+. */ unrollInfo()128 const LoopUnrollInfo* unrollInfo() const { 129 return fUnrollInfo.get(); 130 } 131 132 std::string description() const override; 133 134 private: 135 ForLoopPositions fForLoopPositions; 136 std::unique_ptr<SymbolTable> fSymbolTable; 137 std::unique_ptr<Statement> fInitializer; 138 std::unique_ptr<Expression> fTest; 139 std::unique_ptr<Expression> fNext; 140 std::unique_ptr<Statement> fStatement; 141 std::unique_ptr<LoopUnrollInfo> fUnrollInfo; 142 143 using INHERITED = Statement; 144 }; 145 146 } // namespace SkSL 147 148 #endif 149