blob: 21806decfcb41ff3b521ed633ba57dc47bef39f3 [file] [log] [blame]
ethannicholasb3058bd2016-07-01 08:22:01 -07001/*
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 */
Ethan Nicholas0df1b042017-03-31 13:56:23 -04007
ethannicholasb3058bd2016-07-01 08:22:01 -07008#ifndef SKSL_CODEGENERATOR
9#define SKSL_CODEGENERATOR
10
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "src/sksl/SkSLOutputStream.h"
12#include "src/sksl/ir/SkSLProgram.h"
ethannicholasb3058bd2016-07-01 08:22:01 -070013
14namespace SkSL {
15
16/**
17 * Abstract superclass of all code generators, which take a Program as input and produce code as
18 * output.
19 */
20class CodeGenerator {
21public:
Ethan Nicholas0df1b042017-03-31 13:56:23 -040022 CodeGenerator(const Program* program, ErrorReporter* errors, OutputStream* out)
Ethan Nicholas941e7e22016-12-12 15:33:30 -050023 : fProgram(*program)
24 , fErrors(*errors)
Ethan Nicholas34b19c52020-09-14 11:33:47 -040025 , fOut(out) {}
Ethan Nicholas941e7e22016-12-12 15:33:30 -050026
ethannicholasf789b382016-08-03 12:43:36 -070027 virtual ~CodeGenerator() {}
Ethan Nicholas19671772016-11-28 16:30:17 -050028
Ethan Nicholas941e7e22016-12-12 15:33:30 -050029 virtual bool generateCode() = 0;
30
John Stiles44532372020-12-07 12:33:55 -050031 // Intended for use by AutoOutputStream.
32 OutputStream* outputStream() { return fOut; }
33 void setOutputStream(OutputStream* output) { fOut = output; }
Ethan Nicholas941e7e22016-12-12 15:33:30 -050034
John Stiles44532372020-12-07 12:33:55 -050035protected:
Ethan Nicholas941e7e22016-12-12 15:33:30 -050036 const Program& fProgram;
37 ErrorReporter& fErrors;
Ethan Nicholas0df1b042017-03-31 13:56:23 -040038 OutputStream* fOut;
ethannicholasb3058bd2016-07-01 08:22:01 -070039};
40
John Stiles44532372020-12-07 12:33:55 -050041class AutoOutputStream {
42public:
43 // Maintains the current indentation level while writing to the new output stream.
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.
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 }
58 ~AutoOutputStream() {
59 fCodeGen->setOutputStream(fOldOutput);
60 if (fIndentationPtr) {
61 *fIndentationPtr = fOldIndentation;
62 }
63 }
64
65private:
66 CodeGenerator* fCodeGen = nullptr;
67 OutputStream* fOldOutput = nullptr;
68 int *fIndentationPtr = nullptr;
69 int fOldIndentation = 0;
70};
71
John Stilesa6841be2020-08-06 14:11:56 -040072} // namespace SkSL
ethannicholasb3058bd2016-07-01 08:22:01 -070073
74#endif