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_CODEGENERATOR 9 #define SKSL_CODEGENERATOR 10 11 #include "src/sksl/SkSLOutputStream.h" 12 #include "src/sksl/ir/SkSLProgram.h" 13 14 namespace SkSL { 15 16 /** 17 * Abstract superclass of all code generators, which take a Program as input and produce code as 18 * output. 19 */ 20 class CodeGenerator { 21 public: CodeGenerator(const Context * context,const Program * program,OutputStream * out)22 CodeGenerator(const Context* context, const Program* program, OutputStream* out) 23 : fContext(*context) 24 , fProgram(*program) 25 , fOut(out) {} 26 ~CodeGenerator()27 virtual ~CodeGenerator() {} 28 29 virtual bool generateCode() = 0; 30 31 // Intended for use by AutoOutputStream. outputStream()32 OutputStream* outputStream() { return fOut; } setOutputStream(OutputStream * output)33 void setOutputStream(OutputStream* output) { fOut = output; } 34 35 protected: 36 const Context& fContext; 37 const Program& fProgram; 38 OutputStream* fOut; 39 }; 40 41 class AutoOutputStream { 42 public: 43 // Maintains the current indentation level while writing to the new output stream. AutoOutputStream(CodeGenerator * codeGen,OutputStream * newOutput)44 AutoOutputStream(CodeGenerator* codeGen, OutputStream* newOutput) 45 : fCodeGen(codeGen) 46 , fOldOutput(codeGen->outputStream()) { 47 fCodeGen->setOutputStream(newOutput); 48 } 49 // Resets the indentation when entering the scope, and restores it when leaving. AutoOutputStream(CodeGenerator * codeGen,OutputStream * newOutput,int * indentationPtr)50 AutoOutputStream(CodeGenerator* codeGen, OutputStream* newOutput, int *indentationPtr) 51 : fCodeGen(codeGen) 52 , fOldOutput(codeGen->outputStream()) 53 , fIndentationPtr(indentationPtr) 54 , fOldIndentation(indentationPtr ? *indentationPtr : 0) { 55 fCodeGen->setOutputStream(newOutput); 56 *fIndentationPtr = 0; 57 } ~AutoOutputStream()58 ~AutoOutputStream() { 59 fCodeGen->setOutputStream(fOldOutput); 60 if (fIndentationPtr) { 61 *fIndentationPtr = fOldIndentation; 62 } 63 } 64 65 private: 66 CodeGenerator* fCodeGen = nullptr; 67 OutputStream* fOldOutput = nullptr; 68 int *fIndentationPtr = nullptr; 69 int fOldIndentation = 0; 70 }; 71 72 } // namespace SkSL 73 74 #endif 75