initial checkin of SkSL compiler
BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1984363002 CQ_EXTRA_TRYBOTS=client.skia.compile:Build-Ubuntu-GCC-x86_64-Release-CMake-Trybot,Build-Mac-Clang-x86_64-Release-CMake-Trybot Review-Url: https://codereview.chromium.org/1984363002
This commit is contained in:
parent
e7d1b24ff0
commit
b3058bdb10
@ -59,6 +59,9 @@ remove_srcs (../src/ports/SkFontHost_fontconfig.cpp
|
||||
../src/ports/SkFontConfigInterface_direct_google3_factory.cpp)
|
||||
# Alternative font managers.
|
||||
remove_srcs (../src/ports/SkFontMgr_custom*.cpp)
|
||||
# skslc main()
|
||||
remove_srcs (../src/sksl/SkSLMain.cpp)
|
||||
|
||||
|
||||
# Skia sure ships a lot of code no one uses.
|
||||
remove_srcs (../src/animator/* ../src/*nacl* ../src/svg/* ../src/views/* ../src/xml/*)
|
||||
|
@ -88,6 +88,7 @@
|
||||
'utils.gyp:utils',
|
||||
'etc1.gyp:libetc1',
|
||||
'ktx.gyp:libSkKTX',
|
||||
'sksl.gyp:sksl',
|
||||
],
|
||||
'includes': [
|
||||
'gpu.gypi',
|
||||
@ -98,6 +99,7 @@
|
||||
'../src/core',
|
||||
'../src/gpu',
|
||||
'../src/image/',
|
||||
'../src/sksl',
|
||||
],
|
||||
'sources': [
|
||||
'<@(skgpu_sources)',
|
||||
|
@ -27,6 +27,7 @@
|
||||
'pathops_skpclip.gyp:*',
|
||||
'dm.gyp:dm',
|
||||
'fuzz.gyp:fuzz',
|
||||
'skslc.gyp:skslc',
|
||||
],
|
||||
'conditions': [
|
||||
[ 'skia_gpu == 0', {
|
||||
|
24
gyp/sksl.gyp
Normal file
24
gyp/sksl.gyp
Normal file
@ -0,0 +1,24 @@
|
||||
# Copyright 2016 Google Inc.
|
||||
#
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
{
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'sksl',
|
||||
'type': 'static_library',
|
||||
'standalone_static_library': 1,
|
||||
'includes': [
|
||||
'sksl.gypi',
|
||||
],
|
||||
'defines': [
|
||||
'SKIA'
|
||||
],
|
||||
'all_dependent_settings': {
|
||||
'include_dirs': [
|
||||
'../src/sksl',
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
22
gyp/sksl.gypi
Normal file
22
gyp/sksl.gypi
Normal file
@ -0,0 +1,22 @@
|
||||
# Copyright 2016 Google Inc.
|
||||
#
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
{
|
||||
'include_dirs': [
|
||||
'../include',
|
||||
'../include/config',
|
||||
'../include/core',
|
||||
'../include/private',
|
||||
'../src/sksl',
|
||||
],
|
||||
'sources': [
|
||||
'../src/sksl/SkSLCompiler.cpp',
|
||||
'../src/sksl/SkSLIRGenerator.cpp',
|
||||
'../src/sksl/SkSLParser.cpp',
|
||||
'../src/sksl/SkSLSPIRVCodeGenerator.cpp',
|
||||
'../src/sksl/SkSLUtil.cpp',
|
||||
'../src/sksl/ir/SkSLSymbolTable.cpp',
|
||||
'../src/sksl/ir/SkSLType.cpp',
|
||||
],
|
||||
}
|
28
gyp/skslc.gyp
Normal file
28
gyp/skslc.gyp
Normal file
@ -0,0 +1,28 @@
|
||||
# Copyright 2016 Google Inc.
|
||||
#
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
{
|
||||
'includes': [
|
||||
'apptype_console.gypi',
|
||||
],
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'skslc',
|
||||
'type': 'executable',
|
||||
'includes' : [
|
||||
'sksl.gypi',
|
||||
],
|
||||
'sources': [
|
||||
'../src/sksl/SkSLMain.cpp',
|
||||
],
|
||||
'configurations': {
|
||||
'Debug': {
|
||||
'defines': [
|
||||
'DEBUG',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
@ -36,6 +36,10 @@
|
||||
#include "vk/GrVkInterface.h"
|
||||
#include "vk/GrVkTypes.h"
|
||||
|
||||
#if USE_SKSL
|
||||
#include "SkSLCompiler.h"
|
||||
#endif
|
||||
|
||||
#define VK_CALL(X) GR_VK_CALL(this->vkInterface(), X)
|
||||
#define VK_CALL_RET(RET, X) GR_VK_CALL_RET(this->vkInterface(), RET, X)
|
||||
#define VK_CALL_ERRCHECK(X) GR_VK_CALL_ERRCHECK(this->vkInterface(), X)
|
||||
@ -110,7 +114,11 @@ GrVkGpu::GrVkGpu(GrContext* context, const GrContextOptions& options,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if USE_SKSL
|
||||
fCompiler = new SkSL::Compiler();
|
||||
#else
|
||||
fCompiler = shaderc_compiler_initialize();
|
||||
#endif
|
||||
|
||||
fVkCaps.reset(new GrVkCaps(options, this->vkInterface(), backendCtx->fPhysicalDevice,
|
||||
backendCtx->fFeatures, backendCtx->fExtensions));
|
||||
@ -176,7 +184,11 @@ GrVkGpu::~GrVkGpu() {
|
||||
|
||||
VK_CALL(DestroyCommandPool(fDevice, fCmdPool, nullptr));
|
||||
|
||||
#if USE_SKSL
|
||||
delete fCompiler;
|
||||
#else
|
||||
shaderc_compiler_release(fCompiler);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_VK_LAYERS
|
||||
if (fCallback) {
|
||||
|
@ -8,6 +8,8 @@
|
||||
#ifndef GrVkGpu_DEFINED
|
||||
#define GrVkGpu_DEFINED
|
||||
|
||||
#define USE_SKSL 1
|
||||
|
||||
#include "GrGpu.h"
|
||||
#include "GrGpuFactory.h"
|
||||
#include "vk/GrVkBackendContext.h"
|
||||
@ -18,7 +20,14 @@
|
||||
#include "GrVkVertexBuffer.h"
|
||||
#include "GrVkUtil.h"
|
||||
|
||||
#if USE_SKSL
|
||||
namespace SkSL {
|
||||
class Compiler;
|
||||
}
|
||||
#else
|
||||
#include "shaderc/shaderc.h"
|
||||
#endif
|
||||
|
||||
#include "vk/GrVkDefines.h"
|
||||
|
||||
class GrPipeline;
|
||||
@ -111,9 +120,15 @@ public:
|
||||
bool byRegion,
|
||||
VkImageMemoryBarrier* barrier) const;
|
||||
|
||||
#if USE_SKSL
|
||||
SkSL::Compiler* shaderCompiler() const {
|
||||
return fCompiler;
|
||||
}
|
||||
#else
|
||||
shaderc_compiler_t shadercCompiler() const {
|
||||
return fCompiler;
|
||||
}
|
||||
#endif
|
||||
|
||||
void submitSecondaryCommandBuffer(const GrVkSecondaryCommandBuffer*,
|
||||
const GrVkRenderPass*,
|
||||
@ -242,10 +257,13 @@ private:
|
||||
VkDebugReportCallbackEXT fCallback;
|
||||
#endif
|
||||
|
||||
#if USE_SKSL
|
||||
SkSL::Compiler* fCompiler;
|
||||
#else
|
||||
// Shaderc compiler used for compiling glsl in spirv. We only want to create the compiler once
|
||||
// since there is significant overhead to the first compile of any compiler.
|
||||
shaderc_compiler_t fCompiler;
|
||||
|
||||
#endif
|
||||
|
||||
typedef GrGpu INHERITED;
|
||||
};
|
||||
|
@ -9,6 +9,9 @@
|
||||
|
||||
#include "vk/GrVkGpu.h"
|
||||
#include "vk/GrVkRenderPass.h"
|
||||
#if USE_SKSL
|
||||
#include "SkSLCompiler.h"
|
||||
#endif
|
||||
|
||||
GrVkPipelineState* GrVkPipelineStateBuilder::CreatePipelineState(
|
||||
GrVkGpu* gpu,
|
||||
@ -72,6 +75,15 @@ VkShaderStageFlags visibility_to_vk_stage_flags(uint32_t visibility) {
|
||||
return flags;
|
||||
}
|
||||
|
||||
#if USE_SKSL
|
||||
SkSL::Program::Kind vk_shader_stage_to_skiasl_kind(VkShaderStageFlagBits stage) {
|
||||
if (VK_SHADER_STAGE_VERTEX_BIT == stage) {
|
||||
return SkSL::Program::kVertex_Kind;
|
||||
}
|
||||
SkASSERT(VK_SHADER_STAGE_FRAGMENT_BIT == stage);
|
||||
return SkSL::Program::kFragment_Kind;
|
||||
}
|
||||
#else
|
||||
shaderc_shader_kind vk_shader_stage_to_shaderc_kind(VkShaderStageFlagBits stage) {
|
||||
if (VK_SHADER_STAGE_VERTEX_BIT == stage) {
|
||||
return shaderc_glsl_vertex_shader;
|
||||
@ -79,7 +91,10 @@ shaderc_shader_kind vk_shader_stage_to_shaderc_kind(VkShaderStageFlagBits stage)
|
||||
SkASSERT(VK_SHADER_STAGE_FRAGMENT_BIT == stage);
|
||||
return shaderc_glsl_fragment_shader;
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
bool GrVkPipelineStateBuilder::CreateVkShaderModule(const GrVkGpu* gpu,
|
||||
VkShaderStageFlagBits stage,
|
||||
const GrGLSLShaderBuilder& builder,
|
||||
@ -99,13 +114,28 @@ bool GrVkPipelineStateBuilder::CreateVkShaderModule(const GrVkGpu* gpu,
|
||||
moduleCreateInfo.pNext = nullptr;
|
||||
moduleCreateInfo.flags = 0;
|
||||
|
||||
#if USE_SKSL
|
||||
std::string code;
|
||||
#else
|
||||
shaderc_compilation_result_t result = nullptr;
|
||||
#endif
|
||||
|
||||
if (gpu->vkCaps().canUseGLSLForShaderModule()) {
|
||||
moduleCreateInfo.codeSize = strlen(shaderString.c_str());
|
||||
moduleCreateInfo.pCode = (const uint32_t*)shaderString.c_str();
|
||||
} else {
|
||||
|
||||
#if USE_SKSL
|
||||
bool result = gpu->shaderCompiler()->toSPIRV(vk_shader_stage_to_skiasl_kind(stage),
|
||||
std::string(shaderString.c_str()),
|
||||
&code);
|
||||
if (!result) {
|
||||
SkDebugf("%s\n", gpu->shaderCompiler()->errorText().c_str());
|
||||
return false;
|
||||
}
|
||||
moduleCreateInfo.codeSize = code.size();
|
||||
moduleCreateInfo.pCode = (const uint32_t*) code.c_str();
|
||||
#else
|
||||
shaderc_compiler_t compiler = gpu->shadercCompiler();
|
||||
|
||||
shaderc_compile_options_t options = shaderc_compile_options_initialize();
|
||||
@ -125,18 +155,22 @@ bool GrVkPipelineStateBuilder::CreateVkShaderModule(const GrVkGpu* gpu,
|
||||
SkDebugf("%s\n", shaderc_result_get_error_message(result));
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#endif // SK_DEBUG
|
||||
|
||||
moduleCreateInfo.codeSize = shaderc_result_get_length(result);
|
||||
moduleCreateInfo.pCode = (const uint32_t*)shaderc_result_get_bytes(result);
|
||||
#endif // USE_SKSL
|
||||
}
|
||||
|
||||
VkResult err = GR_VK_CALL(gpu->vkInterface(), CreateShaderModule(gpu->device(),
|
||||
&moduleCreateInfo,
|
||||
nullptr,
|
||||
shaderModule));
|
||||
|
||||
if (!gpu->vkCaps().canUseGLSLForShaderModule()) {
|
||||
#if !USE_SKSL
|
||||
shaderc_result_release(result);
|
||||
#endif
|
||||
}
|
||||
if (err) {
|
||||
return false;
|
||||
|
131
src/sksl/GLSL.std.450.h
Normal file
131
src/sksl/GLSL.std.450.h
Normal file
@ -0,0 +1,131 @@
|
||||
/*
|
||||
** Copyright (c) 2014-2016 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
** of this software and/or associated documentation files (the "Materials"),
|
||||
** to deal in the Materials without restriction, including without limitation
|
||||
** the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
** and/or sell copies of the Materials, and to permit persons to whom the
|
||||
** Materials are furnished to do so, subject to the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included in
|
||||
** all copies or substantial portions of the Materials.
|
||||
**
|
||||
** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS
|
||||
** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND
|
||||
** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS
|
||||
** IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
#ifndef GLSLstd450_H
|
||||
#define GLSLstd450_H
|
||||
|
||||
static const int GLSLstd450Version = 100;
|
||||
static const int GLSLstd450Revision = 3;
|
||||
|
||||
enum GLSLstd450 {
|
||||
GLSLstd450Bad = 0, // Don't use
|
||||
|
||||
GLSLstd450Round = 1,
|
||||
GLSLstd450RoundEven = 2,
|
||||
GLSLstd450Trunc = 3,
|
||||
GLSLstd450FAbs = 4,
|
||||
GLSLstd450SAbs = 5,
|
||||
GLSLstd450FSign = 6,
|
||||
GLSLstd450SSign = 7,
|
||||
GLSLstd450Floor = 8,
|
||||
GLSLstd450Ceil = 9,
|
||||
GLSLstd450Fract = 10,
|
||||
|
||||
GLSLstd450Radians = 11,
|
||||
GLSLstd450Degrees = 12,
|
||||
GLSLstd450Sin = 13,
|
||||
GLSLstd450Cos = 14,
|
||||
GLSLstd450Tan = 15,
|
||||
GLSLstd450Asin = 16,
|
||||
GLSLstd450Acos = 17,
|
||||
GLSLstd450Atan = 18,
|
||||
GLSLstd450Sinh = 19,
|
||||
GLSLstd450Cosh = 20,
|
||||
GLSLstd450Tanh = 21,
|
||||
GLSLstd450Asinh = 22,
|
||||
GLSLstd450Acosh = 23,
|
||||
GLSLstd450Atanh = 24,
|
||||
GLSLstd450Atan2 = 25,
|
||||
|
||||
GLSLstd450Pow = 26,
|
||||
GLSLstd450Exp = 27,
|
||||
GLSLstd450Log = 28,
|
||||
GLSLstd450Exp2 = 29,
|
||||
GLSLstd450Log2 = 30,
|
||||
GLSLstd450Sqrt = 31,
|
||||
GLSLstd450InverseSqrt = 32,
|
||||
|
||||
GLSLstd450Determinant = 33,
|
||||
GLSLstd450MatrixInverse = 34,
|
||||
|
||||
GLSLstd450Modf = 35, // second operand needs an OpVariable to write to
|
||||
GLSLstd450ModfStruct = 36, // no OpVariable operand
|
||||
GLSLstd450FMin = 37,
|
||||
GLSLstd450UMin = 38,
|
||||
GLSLstd450SMin = 39,
|
||||
GLSLstd450FMax = 40,
|
||||
GLSLstd450UMax = 41,
|
||||
GLSLstd450SMax = 42,
|
||||
GLSLstd450FClamp = 43,
|
||||
GLSLstd450UClamp = 44,
|
||||
GLSLstd450SClamp = 45,
|
||||
GLSLstd450FMix = 46,
|
||||
GLSLstd450IMix = 47, // Reserved
|
||||
GLSLstd450Step = 48,
|
||||
GLSLstd450SmoothStep = 49,
|
||||
|
||||
GLSLstd450Fma = 50,
|
||||
GLSLstd450Frexp = 51, // second operand needs an OpVariable to write to
|
||||
GLSLstd450FrexpStruct = 52, // no OpVariable operand
|
||||
GLSLstd450Ldexp = 53,
|
||||
|
||||
GLSLstd450PackSnorm4x8 = 54,
|
||||
GLSLstd450PackUnorm4x8 = 55,
|
||||
GLSLstd450PackSnorm2x16 = 56,
|
||||
GLSLstd450PackUnorm2x16 = 57,
|
||||
GLSLstd450PackHalf2x16 = 58,
|
||||
GLSLstd450PackDouble2x32 = 59,
|
||||
GLSLstd450UnpackSnorm2x16 = 60,
|
||||
GLSLstd450UnpackUnorm2x16 = 61,
|
||||
GLSLstd450UnpackHalf2x16 = 62,
|
||||
GLSLstd450UnpackSnorm4x8 = 63,
|
||||
GLSLstd450UnpackUnorm4x8 = 64,
|
||||
GLSLstd450UnpackDouble2x32 = 65,
|
||||
|
||||
GLSLstd450Length = 66,
|
||||
GLSLstd450Distance = 67,
|
||||
GLSLstd450Cross = 68,
|
||||
GLSLstd450Normalize = 69,
|
||||
GLSLstd450FaceForward = 70,
|
||||
GLSLstd450Reflect = 71,
|
||||
GLSLstd450Refract = 72,
|
||||
|
||||
GLSLstd450FindILsb = 73,
|
||||
GLSLstd450FindSMsb = 74,
|
||||
GLSLstd450FindUMsb = 75,
|
||||
|
||||
GLSLstd450InterpolateAtCentroid = 76,
|
||||
GLSLstd450InterpolateAtSample = 77,
|
||||
GLSLstd450InterpolateAtOffset = 78,
|
||||
|
||||
GLSLstd450NMin = 79,
|
||||
GLSLstd450NMax = 80,
|
||||
GLSLstd450NClamp = 81,
|
||||
|
||||
GLSLstd450Count
|
||||
};
|
||||
|
||||
#endif // #ifndef GLSLstd450_H
|
30
src/sksl/SkSLCodeGenerator.h
Normal file
30
src/sksl/SkSLCodeGenerator.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_CODEGENERATOR
|
||||
#define SKSL_CODEGENERATOR
|
||||
|
||||
#include "ir/SkSLProgram.h"
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* Abstract superclass of all code generators, which take a Program as input and produce code as
|
||||
* output.
|
||||
*/
|
||||
class CodeGenerator {
|
||||
public:
|
||||
virtual ~CodeGenerator() {}
|
||||
|
||||
virtual void generateCode(Program& program, std::ostream& out) = 0;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
243
src/sksl/SkSLCompiler.cpp
Normal file
243
src/sksl/SkSLCompiler.cpp
Normal file
@ -0,0 +1,243 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "SkSLCompiler.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <streambuf>
|
||||
|
||||
#include "SkSLIRGenerator.h"
|
||||
#include "SkSLParser.h"
|
||||
#include "SkSLSPIRVCodeGenerator.h"
|
||||
#include "ir/SkSLExpression.h"
|
||||
#include "ir/SkSLIntLiteral.h"
|
||||
#include "ir/SkSLSymbolTable.h"
|
||||
#include "ir/SkSLVarDeclaration.h"
|
||||
#include "SkMutex.h"
|
||||
|
||||
#define STRINGIFY(x) #x
|
||||
|
||||
// include the built-in shader symbols as static strings
|
||||
|
||||
static std::string SKSL_INCLUDE =
|
||||
#include "sksl.include"
|
||||
;
|
||||
|
||||
static std::string SKSL_VERT_INCLUDE =
|
||||
#include "sksl_vert.include"
|
||||
;
|
||||
|
||||
static std::string SKSL_FRAG_INCLUDE =
|
||||
#include "sksl_frag.include"
|
||||
;
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
Compiler::Compiler()
|
||||
: fErrorCount(0) {
|
||||
auto types = std::shared_ptr<SymbolTable>(new SymbolTable(*this));
|
||||
auto symbols = std::shared_ptr<SymbolTable>(new SymbolTable(types, *this));
|
||||
fIRGenerator = new IRGenerator(symbols, *this);
|
||||
fTypes = types;
|
||||
#define ADD_TYPE(t) types->add(k ## t ## _Type->fName, k ## t ## _Type)
|
||||
ADD_TYPE(Void);
|
||||
ADD_TYPE(Float);
|
||||
ADD_TYPE(Vec2);
|
||||
ADD_TYPE(Vec3);
|
||||
ADD_TYPE(Vec4);
|
||||
ADD_TYPE(Double);
|
||||
ADD_TYPE(DVec2);
|
||||
ADD_TYPE(DVec3);
|
||||
ADD_TYPE(DVec4);
|
||||
ADD_TYPE(Int);
|
||||
ADD_TYPE(IVec2);
|
||||
ADD_TYPE(IVec3);
|
||||
ADD_TYPE(IVec4);
|
||||
ADD_TYPE(UInt);
|
||||
ADD_TYPE(UVec2);
|
||||
ADD_TYPE(UVec3);
|
||||
ADD_TYPE(UVec4);
|
||||
ADD_TYPE(Bool);
|
||||
ADD_TYPE(BVec2);
|
||||
ADD_TYPE(BVec3);
|
||||
ADD_TYPE(BVec4);
|
||||
ADD_TYPE(Mat2x2);
|
||||
ADD_TYPE(Mat2x3);
|
||||
ADD_TYPE(Mat2x4);
|
||||
ADD_TYPE(Mat3x2);
|
||||
ADD_TYPE(Mat3x3);
|
||||
ADD_TYPE(Mat3x4);
|
||||
ADD_TYPE(Mat4x2);
|
||||
ADD_TYPE(Mat4x3);
|
||||
ADD_TYPE(Mat4x4);
|
||||
ADD_TYPE(GenType);
|
||||
ADD_TYPE(GenDType);
|
||||
ADD_TYPE(GenIType);
|
||||
ADD_TYPE(GenUType);
|
||||
ADD_TYPE(GenBType);
|
||||
ADD_TYPE(Mat);
|
||||
ADD_TYPE(Vec);
|
||||
ADD_TYPE(GVec);
|
||||
ADD_TYPE(GVec2);
|
||||
ADD_TYPE(GVec3);
|
||||
ADD_TYPE(GVec4);
|
||||
ADD_TYPE(DVec);
|
||||
ADD_TYPE(IVec);
|
||||
ADD_TYPE(UVec);
|
||||
ADD_TYPE(BVec);
|
||||
|
||||
ADD_TYPE(Sampler1D);
|
||||
ADD_TYPE(Sampler2D);
|
||||
ADD_TYPE(Sampler3D);
|
||||
ADD_TYPE(SamplerCube);
|
||||
ADD_TYPE(Sampler2DRect);
|
||||
ADD_TYPE(Sampler1DArray);
|
||||
ADD_TYPE(Sampler2DArray);
|
||||
ADD_TYPE(SamplerCubeArray);
|
||||
ADD_TYPE(SamplerBuffer);
|
||||
ADD_TYPE(Sampler2DMS);
|
||||
ADD_TYPE(Sampler2DMSArray);
|
||||
|
||||
ADD_TYPE(GSampler1D);
|
||||
ADD_TYPE(GSampler2D);
|
||||
ADD_TYPE(GSampler3D);
|
||||
ADD_TYPE(GSamplerCube);
|
||||
ADD_TYPE(GSampler2DRect);
|
||||
ADD_TYPE(GSampler1DArray);
|
||||
ADD_TYPE(GSampler2DArray);
|
||||
ADD_TYPE(GSamplerCubeArray);
|
||||
ADD_TYPE(GSamplerBuffer);
|
||||
ADD_TYPE(GSampler2DMS);
|
||||
ADD_TYPE(GSampler2DMSArray);
|
||||
|
||||
ADD_TYPE(Sampler1DShadow);
|
||||
ADD_TYPE(Sampler2DShadow);
|
||||
ADD_TYPE(SamplerCubeShadow);
|
||||
ADD_TYPE(Sampler2DRectShadow);
|
||||
ADD_TYPE(Sampler1DArrayShadow);
|
||||
ADD_TYPE(Sampler2DArrayShadow);
|
||||
ADD_TYPE(SamplerCubeArrayShadow);
|
||||
ADD_TYPE(GSampler2DArrayShadow);
|
||||
ADD_TYPE(GSamplerCubeArrayShadow);
|
||||
|
||||
std::vector<std::unique_ptr<ProgramElement>> ignored;
|
||||
this->internalConvertProgram(SKSL_INCLUDE, &ignored);
|
||||
ASSERT(!fErrorCount);
|
||||
}
|
||||
|
||||
Compiler::~Compiler() {
|
||||
delete fIRGenerator;
|
||||
}
|
||||
|
||||
void Compiler::internalConvertProgram(std::string text,
|
||||
std::vector<std::unique_ptr<ProgramElement>>* result) {
|
||||
Parser parser(text, *fTypes, *this);
|
||||
std::vector<std::unique_ptr<ASTDeclaration>> parsed = parser.file();
|
||||
if (fErrorCount) {
|
||||
return;
|
||||
}
|
||||
for (size_t i = 0; i < parsed.size(); i++) {
|
||||
ASTDeclaration& decl = *parsed[i];
|
||||
switch (decl.fKind) {
|
||||
case ASTDeclaration::kVar_Kind: {
|
||||
std::unique_ptr<VarDeclaration> s = fIRGenerator->convertVarDeclaration(
|
||||
(ASTVarDeclaration&) decl,
|
||||
Variable::kGlobal_Storage);
|
||||
if (s) {
|
||||
result->push_back(std::move(s));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ASTDeclaration::kFunction_Kind: {
|
||||
std::unique_ptr<FunctionDefinition> f = fIRGenerator->convertFunction(
|
||||
(ASTFunction&) decl);
|
||||
if (f) {
|
||||
result->push_back(std::move(f));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ASTDeclaration::kInterfaceBlock_Kind: {
|
||||
std::unique_ptr<InterfaceBlock> i = fIRGenerator->convertInterfaceBlock(
|
||||
(ASTInterfaceBlock&) decl);
|
||||
if (i) {
|
||||
result->push_back(std::move(i));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ASTDeclaration::kExtension_Kind: {
|
||||
std::unique_ptr<Extension> e = fIRGenerator->convertExtension((ASTExtension&) decl);
|
||||
if (e) {
|
||||
result->push_back(std::move(e));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ABORT("unsupported declaration: %s\n", decl.description().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<Program> Compiler::convertProgram(Program::Kind kind, std::string text) {
|
||||
fErrorText = "";
|
||||
fErrorCount = 0;
|
||||
fIRGenerator->pushSymbolTable();
|
||||
std::vector<std::unique_ptr<ProgramElement>> result;
|
||||
switch (kind) {
|
||||
case Program::kVertex_Kind:
|
||||
this->internalConvertProgram(SKSL_VERT_INCLUDE, &result);
|
||||
break;
|
||||
case Program::kFragment_Kind:
|
||||
this->internalConvertProgram(SKSL_FRAG_INCLUDE, &result);
|
||||
break;
|
||||
}
|
||||
this->internalConvertProgram(text, &result);
|
||||
fIRGenerator->popSymbolTable();
|
||||
this->writeErrorCount();
|
||||
return std::unique_ptr<Program>(new Program(kind, std::move(result)));;
|
||||
}
|
||||
|
||||
void Compiler::error(Position position, std::string msg) {
|
||||
fErrorCount++;
|
||||
fErrorText += "error: " + position.description() + ": " + msg.c_str() + "\n";
|
||||
}
|
||||
|
||||
std::string Compiler::errorText() {
|
||||
std::string result = fErrorText;
|
||||
return result;
|
||||
}
|
||||
|
||||
void Compiler::writeErrorCount() {
|
||||
if (fErrorCount) {
|
||||
fErrorText += to_string(fErrorCount) + " error";
|
||||
if (fErrorCount > 1) {
|
||||
fErrorText += "s";
|
||||
}
|
||||
fErrorText += "\n";
|
||||
}
|
||||
}
|
||||
|
||||
#include <fstream>
|
||||
bool Compiler::toSPIRV(Program::Kind kind, std::string text, std::ostream& out) {
|
||||
auto program = this->convertProgram(kind, text);
|
||||
if (fErrorCount == 0) {
|
||||
SkSL::SPIRVCodeGenerator cg;
|
||||
cg.generateCode(*program.get(), out);
|
||||
ASSERT(!out.rdstate());
|
||||
}
|
||||
return fErrorCount == 0;
|
||||
}
|
||||
|
||||
bool Compiler::toSPIRV(Program::Kind kind, std::string text, std::string* out) {
|
||||
std::stringstream buffer;
|
||||
bool result = this->toSPIRV(kind, text, buffer);
|
||||
if (result) {
|
||||
*out = buffer.str();
|
||||
}
|
||||
return fErrorCount == 0;
|
||||
}
|
||||
|
||||
} // namespace
|
59
src/sksl/SkSLCompiler.h
Normal file
59
src/sksl/SkSLCompiler.h
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_COMPILER
|
||||
#define SKSL_COMPILER
|
||||
|
||||
#include <vector>
|
||||
#include "ir/SkSLProgram.h"
|
||||
#include "ir/SkSLSymbolTable.h"
|
||||
#include "SkSLErrorReporter.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
class IRGenerator;
|
||||
|
||||
/**
|
||||
* Main compiler entry point. This is a traditional compiler design which first parses the .sksl
|
||||
* file into an abstract syntax tree (a tree of ASTNodes), then performs semantic analysis to
|
||||
* produce a Program (a tree of IRNodes), then feeds the Program into a CodeGenerator to produce
|
||||
* compiled output.
|
||||
*/
|
||||
class Compiler : public ErrorReporter {
|
||||
public:
|
||||
Compiler();
|
||||
|
||||
~Compiler();
|
||||
|
||||
std::unique_ptr<Program> convertProgram(Program::Kind kind, std::string text);
|
||||
|
||||
bool toSPIRV(Program::Kind kind, std::string text, std::ostream& out);
|
||||
|
||||
bool toSPIRV(Program::Kind kind, std::string text, std::string* out);
|
||||
|
||||
void error(Position position, std::string msg) override;
|
||||
|
||||
std::string errorText();
|
||||
|
||||
void writeErrorCount();
|
||||
|
||||
private:
|
||||
|
||||
void internalConvertProgram(std::string text,
|
||||
std::vector<std::unique_ptr<ProgramElement>>* result);
|
||||
|
||||
std::shared_ptr<SymbolTable> fTypes;
|
||||
IRGenerator* fIRGenerator;
|
||||
std::string fSkiaVertText; // FIXME store parsed version instead
|
||||
|
||||
int fErrorCount;
|
||||
std::string fErrorText;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
27
src/sksl/SkSLErrorReporter.h
Normal file
27
src/sksl/SkSLErrorReporter.h
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ERRORREPORTER
|
||||
#define SKSL_ERRORREPORTER
|
||||
|
||||
#include "SkSLPosition.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* Interface for the compiler to report errors.
|
||||
*/
|
||||
class ErrorReporter {
|
||||
public:
|
||||
virtual ~ErrorReporter() {}
|
||||
|
||||
virtual void error(Position position, std::string msg) = 0;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
1217
src/sksl/SkSLIRGenerator.cpp
Normal file
1217
src/sksl/SkSLIRGenerator.cpp
Normal file
File diff suppressed because it is too large
Load Diff
122
src/sksl/SkSLIRGenerator.h
Normal file
122
src/sksl/SkSLIRGenerator.h
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_IRGENERATOR
|
||||
#define SKSL_IRGENERATOR
|
||||
|
||||
#include "SkSLErrorReporter.h"
|
||||
#include "ast/SkSLASTBinaryExpression.h"
|
||||
#include "ast/SkSLASTBlock.h"
|
||||
#include "ast/SkSLASTBreakStatement.h"
|
||||
#include "ast/SkSLASTCallSuffix.h"
|
||||
#include "ast/SkSLASTContinueStatement.h"
|
||||
#include "ast/SkSLASTDiscardStatement.h"
|
||||
#include "ast/SkSLASTDoStatement.h"
|
||||
#include "ast/SkSLASTExpression.h"
|
||||
#include "ast/SkSLASTExpressionStatement.h"
|
||||
#include "ast/SkSLASTExtension.h"
|
||||
#include "ast/SkSLASTForStatement.h"
|
||||
#include "ast/SkSLASTFunction.h"
|
||||
#include "ast/SkSLASTIdentifier.h"
|
||||
#include "ast/SkSLASTIfStatement.h"
|
||||
#include "ast/SkSLASTInterfaceBlock.h"
|
||||
#include "ast/SkSLASTModifiers.h"
|
||||
#include "ast/SkSLASTPrefixExpression.h"
|
||||
#include "ast/SkSLASTReturnStatement.h"
|
||||
#include "ast/SkSLASTStatement.h"
|
||||
#include "ast/SkSLASTSuffixExpression.h"
|
||||
#include "ast/SkSLASTTernaryExpression.h"
|
||||
#include "ast/SkSLASTVarDeclaration.h"
|
||||
#include "ast/SkSLASTVarDeclarationStatement.h"
|
||||
#include "ast/SkSLASTWhileStatement.h"
|
||||
#include "ir/SkSLBlock.h"
|
||||
#include "ir/SkSLExpression.h"
|
||||
#include "ir/SkSLExtension.h"
|
||||
#include "ir/SkSLFunctionDefinition.h"
|
||||
#include "ir/SkSLInterfaceBlock.h"
|
||||
#include "ir/SkSLModifiers.h"
|
||||
#include "ir/SkSLSymbolTable.h"
|
||||
#include "ir/SkSLStatement.h"
|
||||
#include "ir/SkSLType.h"
|
||||
#include "ir/SkSLTypeReference.h"
|
||||
#include "ir/SkSLVarDeclaration.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* Performs semantic analysis on an abstract syntax tree (AST) and produces the corresponding
|
||||
* (unoptimized) intermediate representation (IR).
|
||||
*/
|
||||
class IRGenerator {
|
||||
public:
|
||||
IRGenerator(std::shared_ptr<SymbolTable> root, ErrorReporter& errorReporter);
|
||||
|
||||
std::unique_ptr<VarDeclaration> convertVarDeclaration(const ASTVarDeclaration& decl,
|
||||
Variable::Storage storage);
|
||||
std::unique_ptr<FunctionDefinition> convertFunction(const ASTFunction& f);
|
||||
std::unique_ptr<Statement> convertStatement(const ASTStatement& statement);
|
||||
std::unique_ptr<Expression> convertExpression(const ASTExpression& expression);
|
||||
|
||||
private:
|
||||
void pushSymbolTable();
|
||||
void popSymbolTable();
|
||||
|
||||
std::shared_ptr<Type> convertType(const ASTType& type);
|
||||
std::unique_ptr<Expression> call(Position position,
|
||||
std::shared_ptr<FunctionDeclaration> function,
|
||||
std::vector<std::unique_ptr<Expression>> arguments);
|
||||
bool determineCallCost(std::shared_ptr<FunctionDeclaration> function,
|
||||
const std::vector<std::unique_ptr<Expression>>& arguments,
|
||||
int* outCost);
|
||||
std::unique_ptr<Expression> call(Position position, std::unique_ptr<Expression> function,
|
||||
std::vector<std::unique_ptr<Expression>> arguments);
|
||||
std::unique_ptr<Expression> coerce(std::unique_ptr<Expression> expr,
|
||||
std::shared_ptr<Type> type);
|
||||
std::unique_ptr<Block> convertBlock(const ASTBlock& block);
|
||||
std::unique_ptr<Statement> convertBreak(const ASTBreakStatement& b);
|
||||
std::unique_ptr<Expression> convertConstructor(Position position,
|
||||
std::shared_ptr<Type> type,
|
||||
std::vector<std::unique_ptr<Expression>> params);
|
||||
std::unique_ptr<Statement> convertContinue(const ASTContinueStatement& c);
|
||||
std::unique_ptr<Statement> convertDiscard(const ASTDiscardStatement& d);
|
||||
std::unique_ptr<Statement> convertDo(const ASTDoStatement& d);
|
||||
std::unique_ptr<Expression> convertBinaryExpression(const ASTBinaryExpression& expression);
|
||||
std::unique_ptr<Extension> convertExtension(const ASTExtension& e);
|
||||
std::unique_ptr<Statement> convertExpressionStatement(const ASTExpressionStatement& s);
|
||||
std::unique_ptr<Statement> convertFor(const ASTForStatement& f);
|
||||
std::unique_ptr<Expression> convertIdentifier(const ASTIdentifier& identifier);
|
||||
std::unique_ptr<Statement> convertIf(const ASTIfStatement& s);
|
||||
std::unique_ptr<Expression> convertIndex(std::unique_ptr<Expression> base,
|
||||
const ASTExpression& index);
|
||||
std::unique_ptr<InterfaceBlock> convertInterfaceBlock(const ASTInterfaceBlock& s);
|
||||
Modifiers convertModifiers(const ASTModifiers& m);
|
||||
std::unique_ptr<Expression> convertPrefixExpression(const ASTPrefixExpression& expression);
|
||||
std::unique_ptr<Statement> convertReturn(const ASTReturnStatement& r);
|
||||
std::unique_ptr<Expression> convertSuffixExpression(const ASTSuffixExpression& expression);
|
||||
std::unique_ptr<Expression> convertField(std::unique_ptr<Expression> base,
|
||||
const std::string& field);
|
||||
std::unique_ptr<Expression> convertSwizzle(std::unique_ptr<Expression> base,
|
||||
const std::string& fields);
|
||||
std::unique_ptr<Expression> convertTernaryExpression(const ASTTernaryExpression& expression);
|
||||
std::unique_ptr<Statement> convertVarDeclarationStatement(const ASTVarDeclarationStatement& s);
|
||||
std::unique_ptr<Statement> convertWhile(const ASTWhileStatement& w);
|
||||
|
||||
void checkValid(const Expression& expr);
|
||||
void markReadFrom(std::shared_ptr<Variable> var);
|
||||
void markWrittenTo(const Expression& expr);
|
||||
|
||||
std::shared_ptr<FunctionDeclaration> fCurrentFunction;
|
||||
std::shared_ptr<SymbolTable> fSymbolTable;
|
||||
ErrorReporter& fErrors;
|
||||
|
||||
friend class AutoSymbolTable;
|
||||
friend class Compiler;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
48
src/sksl/SkSLMain.cpp
Normal file
48
src/sksl/SkSLMain.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "stdio.h"
|
||||
#include <fstream>
|
||||
#include "SkSLCompiler.h"
|
||||
|
||||
/**
|
||||
* Very simple standalone executable to facilitate testing.
|
||||
*/
|
||||
int main(int argc, const char** argv) {
|
||||
if (argc != 3) {
|
||||
printf("usage: skslc <input> <output>\n");
|
||||
exit(1);
|
||||
}
|
||||
SkSL::Program::Kind kind;
|
||||
size_t len = strlen(argv[1]);
|
||||
if (len > 5 && !strcmp(argv[1] + strlen(argv[1]) - 5, ".vert")) {
|
||||
kind = SkSL::Program::kVertex_Kind;
|
||||
} else if (len > 5 && !strcmp(argv[1] + strlen(argv[1]) - 5, ".frag")) {
|
||||
kind = SkSL::Program::kFragment_Kind;
|
||||
} else {
|
||||
printf("input filename must end in '.vert' or '.frag'\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
std::ifstream in(argv[1]);
|
||||
std::string text((std::istreambuf_iterator<char>(in)),
|
||||
std::istreambuf_iterator<char>());
|
||||
if (in.rdstate()) {
|
||||
printf("error reading '%s'\n", argv[1]);
|
||||
exit(2);
|
||||
}
|
||||
std::ofstream out(argv[2], std::ofstream::binary);
|
||||
SkSL::Compiler compiler;
|
||||
if (!compiler.toSPIRV(kind, text, out)) {
|
||||
printf("%s", compiler.errorText().c_str());
|
||||
exit(3);
|
||||
}
|
||||
if (out.rdstate()) {
|
||||
printf("error writing '%s'\n", argv[2]);
|
||||
exit(4);
|
||||
}
|
||||
}
|
1389
src/sksl/SkSLParser.cpp
Normal file
1389
src/sksl/SkSLParser.cpp
Normal file
File diff suppressed because it is too large
Load Diff
209
src/sksl/SkSLParser.h
Normal file
209
src/sksl/SkSLParser.h
Normal file
@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_PARSER
|
||||
#define SKSL_PARSER
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <unordered_set>
|
||||
#include "SkSLErrorReporter.h"
|
||||
#include "SkSLToken.h"
|
||||
|
||||
struct yy_buffer_state;
|
||||
#define YY_TYPEDEF_YY_BUFFER_STATE
|
||||
typedef struct yy_buffer_state *YY_BUFFER_STATE;
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
struct ASTBlock;
|
||||
struct ASTBreakStatement;
|
||||
struct ASTContinueStatement;
|
||||
struct ASTDeclaration;
|
||||
struct ASTDiscardStatement;
|
||||
struct ASTDoStatement;
|
||||
struct ASTExpression;
|
||||
struct ASTExpressionStatement;
|
||||
struct ASTForStatement;
|
||||
struct ASTIfStatement;
|
||||
struct ASTInterfaceBlock;
|
||||
struct ASTLayout;
|
||||
struct ASTModifiers;
|
||||
struct ASTParameter;
|
||||
struct ASTReturnStatement;
|
||||
struct ASTStatement;
|
||||
struct ASTSuffix;
|
||||
struct ASTType;
|
||||
struct ASTWhileStatement;
|
||||
struct ASTVarDeclaration;
|
||||
class SymbolTable;
|
||||
|
||||
/**
|
||||
* Consumes .sksl text and produces an abstract syntax tree describing the contents.
|
||||
*/
|
||||
class Parser {
|
||||
public:
|
||||
Parser(std::string text, SymbolTable& types, ErrorReporter& errors);
|
||||
|
||||
~Parser();
|
||||
|
||||
/**
|
||||
* Consumes a complete .sksl file and produces a list of declarations. Errors are reported via
|
||||
* the ErrorReporter; the return value may contain some declarations even when errors have
|
||||
* occurred.
|
||||
*/
|
||||
std::vector<std::unique_ptr<ASTDeclaration>> file();
|
||||
|
||||
private:
|
||||
/**
|
||||
* Return the next token from the parse stream.
|
||||
*/
|
||||
Token nextToken();
|
||||
|
||||
/**
|
||||
* Push a token back onto the parse stream, so that it is the next one read. Only a single level
|
||||
* of pushback is supported (that is, it is an error to call pushback() twice in a row without
|
||||
* an intervening nextToken()).
|
||||
*/
|
||||
void pushback(Token t);
|
||||
|
||||
/**
|
||||
* Returns the next token without consuming it from the stream.
|
||||
*/
|
||||
Token peek();
|
||||
|
||||
/**
|
||||
* Reads the next token and generates an error if it is not the expected type. The 'expected'
|
||||
* string is part of the error message, which reads:
|
||||
*
|
||||
* "expected <expected>, but found '<actual text>'"
|
||||
*
|
||||
* If 'result' is non-null, it is set to point to the token that was read.
|
||||
* Returns true if the read token was as expected, false otherwise.
|
||||
*/
|
||||
bool expect(Token::Kind kind, std::string expected, Token* result = nullptr);
|
||||
|
||||
void error(Position p, std::string msg);
|
||||
|
||||
/**
|
||||
* Returns true if the 'name' identifier refers to a type name. For instance, isType("int") will
|
||||
* always return true.
|
||||
*/
|
||||
bool isType(std::string name);
|
||||
|
||||
// these functions parse individual grammar rules from the current parse position; you probably
|
||||
// don't need to call any of these outside of the parser. The function declarations in the .cpp
|
||||
// file have comments describing the grammar rules.
|
||||
|
||||
void precision();
|
||||
|
||||
std::unique_ptr<ASTDeclaration> directive();
|
||||
|
||||
std::unique_ptr<ASTDeclaration> declaration();
|
||||
|
||||
std::unique_ptr<ASTVarDeclaration> varDeclaration();
|
||||
|
||||
std::unique_ptr<ASTType> structDeclaration();
|
||||
|
||||
std::unique_ptr<ASTVarDeclaration> structVarDeclaration(ASTModifiers modifiers);
|
||||
|
||||
std::unique_ptr<ASTVarDeclaration> varDeclarationEnd(ASTModifiers modifiers,
|
||||
std::unique_ptr<ASTType> type,
|
||||
std::string name);
|
||||
|
||||
std::unique_ptr<ASTParameter> parameter();
|
||||
|
||||
int layoutInt();
|
||||
|
||||
ASTLayout layout();
|
||||
|
||||
ASTModifiers modifiers();
|
||||
|
||||
ASTModifiers modifiersWithDefaults(int defaultFlags);
|
||||
|
||||
std::unique_ptr<ASTStatement> statement();
|
||||
|
||||
std::unique_ptr<ASTType> type();
|
||||
|
||||
std::unique_ptr<ASTDeclaration> interfaceBlock(ASTModifiers mods);
|
||||
|
||||
std::unique_ptr<ASTIfStatement> ifStatement();
|
||||
|
||||
std::unique_ptr<ASTDoStatement> doStatement();
|
||||
|
||||
std::unique_ptr<ASTWhileStatement> whileStatement();
|
||||
|
||||
std::unique_ptr<ASTForStatement> forStatement();
|
||||
|
||||
std::unique_ptr<ASTReturnStatement> returnStatement();
|
||||
|
||||
std::unique_ptr<ASTBreakStatement> breakStatement();
|
||||
|
||||
std::unique_ptr<ASTContinueStatement> continueStatement();
|
||||
|
||||
std::unique_ptr<ASTDiscardStatement> discardStatement();
|
||||
|
||||
std::unique_ptr<ASTBlock> block();
|
||||
|
||||
std::unique_ptr<ASTExpressionStatement> expressionStatement();
|
||||
|
||||
std::unique_ptr<ASTExpression> expression();
|
||||
|
||||
std::unique_ptr<ASTExpression> assignmentExpression();
|
||||
|
||||
std::unique_ptr<ASTExpression> ternaryExpression();
|
||||
|
||||
std::unique_ptr<ASTExpression> logicalOrExpression();
|
||||
|
||||
std::unique_ptr<ASTExpression> logicalXorExpression();
|
||||
|
||||
std::unique_ptr<ASTExpression> logicalAndExpression();
|
||||
|
||||
std::unique_ptr<ASTExpression> bitwiseOrExpression();
|
||||
|
||||
std::unique_ptr<ASTExpression> bitwiseXorExpression();
|
||||
|
||||
std::unique_ptr<ASTExpression> bitwiseAndExpression();
|
||||
|
||||
std::unique_ptr<ASTExpression> equalityExpression();
|
||||
|
||||
std::unique_ptr<ASTExpression> relationalExpression();
|
||||
|
||||
std::unique_ptr<ASTExpression> shiftExpression();
|
||||
|
||||
std::unique_ptr<ASTExpression> additiveExpression();
|
||||
|
||||
std::unique_ptr<ASTExpression> multiplicativeExpression();
|
||||
|
||||
std::unique_ptr<ASTExpression> unaryExpression();
|
||||
|
||||
std::unique_ptr<ASTExpression> postfixExpression();
|
||||
|
||||
std::unique_ptr<ASTSuffix> suffix();
|
||||
|
||||
std::unique_ptr<ASTExpression> term();
|
||||
|
||||
bool intLiteral(int64_t* dest);
|
||||
|
||||
bool floatLiteral(double* dest);
|
||||
|
||||
bool boolLiteral(bool* dest);
|
||||
|
||||
bool identifier(std::string* dest);
|
||||
|
||||
|
||||
void* fScanner;
|
||||
YY_BUFFER_STATE fBuffer;
|
||||
Token fPushback;
|
||||
SymbolTable& fTypes;
|
||||
ErrorReporter& fErrors;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
38
src/sksl/SkSLPosition.h
Normal file
38
src/sksl/SkSLPosition.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_POSITION
|
||||
#define SKSL_POSITION
|
||||
|
||||
#include "SkSLUtil.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* Represents a position in the source code. Both line and column are one-based. Column is currently
|
||||
* ignored.
|
||||
*/
|
||||
struct Position {
|
||||
Position()
|
||||
: fLine(-1)
|
||||
, fColumn(-1) {}
|
||||
|
||||
Position(int line, int column)
|
||||
: fLine(line)
|
||||
, fColumn(column) {}
|
||||
|
||||
std::string description() const {
|
||||
return to_string(fLine);
|
||||
}
|
||||
|
||||
int fLine;
|
||||
int fColumn;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
2628
src/sksl/SkSLSPIRVCodeGenerator.cpp
Normal file
2628
src/sksl/SkSLSPIRVCodeGenerator.cpp
Normal file
File diff suppressed because it is too large
Load Diff
264
src/sksl/SkSLSPIRVCodeGenerator.h
Normal file
264
src/sksl/SkSLSPIRVCodeGenerator.h
Normal file
@ -0,0 +1,264 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_SPIRVCODEGENERATOR
|
||||
#define SKSL_SPIRVCODEGENERATOR
|
||||
|
||||
#include <sstream>
|
||||
#include <stack>
|
||||
#include <tuple>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "SkSLCodeGenerator.h"
|
||||
#include "ir/SkSLBinaryExpression.h"
|
||||
#include "ir/SkSLBoolLiteral.h"
|
||||
#include "ir/SkSLConstructor.h"
|
||||
#include "ir/SkSLFloatLiteral.h"
|
||||
#include "ir/SkSLIfStatement.h"
|
||||
#include "ir/SkSLIndexExpression.h"
|
||||
#include "ir/SkSLInterfaceBlock.h"
|
||||
#include "ir/SkSLIntLiteral.h"
|
||||
#include "ir/SkSLFieldAccess.h"
|
||||
#include "ir/SkSLForStatement.h"
|
||||
#include "ir/SkSLFunctionCall.h"
|
||||
#include "ir/SkSLFunctionDeclaration.h"
|
||||
#include "ir/SkSLFunctionDefinition.h"
|
||||
#include "ir/SkSLPrefixExpression.h"
|
||||
#include "ir/SkSLPostfixExpression.h"
|
||||
#include "ir/SkSLProgramElement.h"
|
||||
#include "ir/SkSLReturnStatement.h"
|
||||
#include "ir/SkSLStatement.h"
|
||||
#include "ir/SkSLSwizzle.h"
|
||||
#include "ir/SkSLTernaryExpression.h"
|
||||
#include "ir/SkSLVarDeclaration.h"
|
||||
#include "ir/SkSLVarDeclarationStatement.h"
|
||||
#include "ir/SkSLVariableReference.h"
|
||||
#include "spirv.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
#define kLast_Capability SpvCapabilityMultiViewport
|
||||
|
||||
/**
|
||||
* Converts a Program into a SPIR-V binary.
|
||||
*/
|
||||
class SPIRVCodeGenerator : public CodeGenerator {
|
||||
public:
|
||||
class LValue {
|
||||
public:
|
||||
virtual ~LValue() {}
|
||||
|
||||
// returns a pointer to the lvalue, if possible. If the lvalue cannot be directly referenced
|
||||
// by a pointer (e.g. vector swizzles), returns 0.
|
||||
virtual SpvId getPointer() = 0;
|
||||
|
||||
virtual SpvId load(std::ostream& out) = 0;
|
||||
|
||||
virtual void store(SpvId value, std::ostream& out) = 0;
|
||||
};
|
||||
|
||||
SPIRVCodeGenerator()
|
||||
: fCapabilities(1 << SpvCapabilityShader)
|
||||
, fIdCount(1)
|
||||
, fBoolTrue(0)
|
||||
, fBoolFalse(0)
|
||||
, fCurrentBlock(0) {
|
||||
this->setupIntrinsics();
|
||||
}
|
||||
|
||||
void generateCode(Program& program, std::ostream& out) override;
|
||||
|
||||
private:
|
||||
enum IntrinsicKind {
|
||||
kGLSL_STD_450_IntrinsicKind,
|
||||
kSPIRV_IntrinsicKind,
|
||||
kSpecial_IntrinsicKind
|
||||
};
|
||||
|
||||
enum SpecialIntrinsic {
|
||||
kAtan_SpecialIntrinsic,
|
||||
kTexture_SpecialIntrinsic,
|
||||
kTexture2D_SpecialIntrinsic,
|
||||
kTextureProj_SpecialIntrinsic
|
||||
};
|
||||
|
||||
void setupIntrinsics();
|
||||
|
||||
SpvId nextId();
|
||||
|
||||
SpvId getType(const Type& type);
|
||||
|
||||
SpvId getFunctionType(std::shared_ptr<FunctionDeclaration> function);
|
||||
|
||||
SpvId getPointerType(std::shared_ptr<Type> type, SpvStorageClass_ storageClass);
|
||||
|
||||
std::vector<SpvId> getAccessChain(Expression& expr, std::ostream& out);
|
||||
|
||||
void writeLayout(const Layout& layout, SpvId target);
|
||||
|
||||
void writeLayout(const Layout& layout, SpvId target, int member);
|
||||
|
||||
void writeStruct(const Type& type, SpvId resultId);
|
||||
|
||||
void writeProgramElement(ProgramElement& pe, std::ostream& out);
|
||||
|
||||
SpvId writeInterfaceBlock(InterfaceBlock& intf);
|
||||
|
||||
SpvId writeFunctionStart(std::shared_ptr<FunctionDeclaration> f, std::ostream& out);
|
||||
|
||||
SpvId writeFunctionDeclaration(std::shared_ptr<FunctionDeclaration> f, std::ostream& out);
|
||||
|
||||
SpvId writeFunction(FunctionDefinition& f, std::ostream& out);
|
||||
|
||||
void writeGlobalVars(VarDeclaration& v, std::ostream& out);
|
||||
|
||||
void writeVarDeclaration(VarDeclaration& decl, std::ostream& out);
|
||||
|
||||
SpvId writeVariableReference(VariableReference& ref, std::ostream& out);
|
||||
|
||||
std::unique_ptr<LValue> getLValue(Expression& value, std::ostream& out);
|
||||
|
||||
SpvId writeExpression(Expression& expr, std::ostream& out);
|
||||
|
||||
SpvId writeIntrinsicCall(FunctionCall& c, std::ostream& out);
|
||||
|
||||
SpvId writeFunctionCall(FunctionCall& c, std::ostream& out);
|
||||
|
||||
SpvId writeSpecialIntrinsic(FunctionCall& c, SpecialIntrinsic kind, std::ostream& out);
|
||||
|
||||
SpvId writeConstantVector(Constructor& c);
|
||||
|
||||
SpvId writeFloatConstructor(Constructor& c, std::ostream& out);
|
||||
|
||||
SpvId writeIntConstructor(Constructor& c, std::ostream& out);
|
||||
|
||||
SpvId writeMatrixConstructor(Constructor& c, std::ostream& out);
|
||||
|
||||
SpvId writeVectorConstructor(Constructor& c, std::ostream& out);
|
||||
|
||||
SpvId writeConstructor(Constructor& c, std::ostream& out);
|
||||
|
||||
SpvId writeFieldAccess(FieldAccess& f, std::ostream& out);
|
||||
|
||||
SpvId writeSwizzle(Swizzle& swizzle, std::ostream& out);
|
||||
|
||||
SpvId writeBinaryOperation(const Type& resultType, const Type& operandType, SpvId lhs,
|
||||
SpvId rhs, SpvOp_ ifFloat, SpvOp_ ifInt, SpvOp_ ifUInt,
|
||||
SpvOp_ ifBool, std::ostream& out);
|
||||
|
||||
SpvId writeBinaryOperation(BinaryExpression& expr, SpvOp_ ifFloat, SpvOp_ ifInt, SpvOp_ ifUInt,
|
||||
std::ostream& out);
|
||||
|
||||
SpvId writeBinaryExpression(BinaryExpression& b, std::ostream& out);
|
||||
|
||||
SpvId writeTernaryExpression(TernaryExpression& t, std::ostream& out);
|
||||
|
||||
SpvId writeIndexExpression(IndexExpression& expr, std::ostream& out);
|
||||
|
||||
SpvId writeLogicalAnd(BinaryExpression& b, std::ostream& out);
|
||||
|
||||
SpvId writeLogicalOr(BinaryExpression& o, std::ostream& out);
|
||||
|
||||
SpvId writePrefixExpression(PrefixExpression& p, std::ostream& out);
|
||||
|
||||
SpvId writePostfixExpression(PostfixExpression& p, std::ostream& out);
|
||||
|
||||
SpvId writeBoolLiteral(BoolLiteral& b);
|
||||
|
||||
SpvId writeIntLiteral(IntLiteral& i);
|
||||
|
||||
SpvId writeFloatLiteral(FloatLiteral& f);
|
||||
|
||||
void writeStatement(Statement& s, std::ostream& out);
|
||||
|
||||
void writeBlock(Block& b, std::ostream& out);
|
||||
|
||||
void writeIfStatement(IfStatement& stmt, std::ostream& out);
|
||||
|
||||
void writeForStatement(ForStatement& f, std::ostream& out);
|
||||
|
||||
void writeReturnStatement(ReturnStatement& r, std::ostream& out);
|
||||
|
||||
void writeCapabilities(std::ostream& out);
|
||||
|
||||
void writeInstructions(Program& program, std::ostream& out);
|
||||
|
||||
void writeOpCode(SpvOp_ opCode, int length, std::ostream& out);
|
||||
|
||||
void writeWord(int32_t word, std::ostream& out);
|
||||
|
||||
void writeString(const char* string, std::ostream& out);
|
||||
|
||||
void writeLabel(SpvId id, std::ostream& out);
|
||||
|
||||
void writeInstruction(SpvOp_ opCode, std::ostream& out);
|
||||
|
||||
void writeInstruction(SpvOp_ opCode, const char* string, std::ostream& out);
|
||||
|
||||
void writeInstruction(SpvOp_ opCode, int32_t word1, std::ostream& out);
|
||||
|
||||
void writeInstruction(SpvOp_ opCode, int32_t word1, const char* string, std::ostream& out);
|
||||
|
||||
void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, const char* string,
|
||||
std::ostream& out);
|
||||
|
||||
void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, std::ostream& out);
|
||||
|
||||
void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t word3,
|
||||
std::ostream& out);
|
||||
|
||||
void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t word3, int32_t word4,
|
||||
std::ostream& out);
|
||||
|
||||
void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t word3, int32_t word4,
|
||||
int32_t word5, std::ostream& out);
|
||||
|
||||
void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t word3, int32_t word4,
|
||||
int32_t word5, int32_t word6, std::ostream& out);
|
||||
|
||||
void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t word3, int32_t word4,
|
||||
int32_t word5, int32_t word6, int32_t word7, std::ostream& out);
|
||||
|
||||
void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t word3, int32_t word4,
|
||||
int32_t word5, int32_t word6, int32_t word7, int32_t word8,
|
||||
std::ostream& out);
|
||||
|
||||
uint64_t fCapabilities;
|
||||
SpvId fIdCount;
|
||||
SpvId fGLSLExtendedInstructions;
|
||||
typedef std::tuple<IntrinsicKind, int32_t, int32_t, int32_t, int32_t> Intrinsic;
|
||||
std::unordered_map<std::string, Intrinsic> fIntrinsicMap;
|
||||
std::unordered_map<std::shared_ptr<FunctionDeclaration>, SpvId> fFunctionMap;
|
||||
std::unordered_map<std::shared_ptr<Variable>, SpvId> fVariableMap;
|
||||
std::unordered_map<std::shared_ptr<Variable>, int32_t> fInterfaceBlockMap;
|
||||
std::unordered_map<std::string, SpvId> fTypeMap;
|
||||
std::stringstream fCapabilitiesBuffer;
|
||||
std::stringstream fGlobalInitializersBuffer;
|
||||
std::stringstream fConstantBuffer;
|
||||
std::stringstream fExternalFunctionsBuffer;
|
||||
std::stringstream fVariableBuffer;
|
||||
std::stringstream fNameBuffer;
|
||||
std::stringstream fDecorationBuffer;
|
||||
|
||||
SpvId fBoolTrue;
|
||||
SpvId fBoolFalse;
|
||||
std::unordered_map<int64_t, SpvId> fIntConstants;
|
||||
std::unordered_map<uint64_t, SpvId> fUIntConstants;
|
||||
std::unordered_map<float, SpvId> fFloatConstants;
|
||||
std::unordered_map<double, SpvId> fDoubleConstants;
|
||||
// label of the current block, or 0 if we are not in a block
|
||||
SpvId fCurrentBlock;
|
||||
std::stack<SpvId> fBreakTarget;
|
||||
std::stack<SpvId> fContinueTarget;
|
||||
|
||||
friend class PointerLValue;
|
||||
friend class SwizzleLValue;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
156
src/sksl/SkSLToken.h
Normal file
156
src/sksl/SkSLToken.h
Normal file
@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_TOKEN
|
||||
#define SKSL_TOKEN
|
||||
|
||||
#include "SkSLPosition.h"
|
||||
#include "SkSLUtil.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* Represents a lexical analysis token. Token is generally only used during the parse process, but
|
||||
* Token::Kind is also used to represent operator kinds.
|
||||
*/
|
||||
struct Token {
|
||||
enum Kind {
|
||||
END_OF_FILE,
|
||||
IDENTIFIER,
|
||||
INT_LITERAL,
|
||||
FLOAT_LITERAL,
|
||||
TRUE_LITERAL,
|
||||
FALSE_LITERAL,
|
||||
LPAREN,
|
||||
RPAREN,
|
||||
LBRACE,
|
||||
RBRACE,
|
||||
LBRACKET,
|
||||
RBRACKET,
|
||||
DOT,
|
||||
COMMA,
|
||||
PLUSPLUS,
|
||||
MINUSMINUS,
|
||||
PLUS,
|
||||
MINUS,
|
||||
STAR,
|
||||
SLASH,
|
||||
PERCENT,
|
||||
SHL,
|
||||
SHR,
|
||||
BITWISEOR,
|
||||
BITWISEXOR,
|
||||
BITWISEAND,
|
||||
LOGICALOR,
|
||||
LOGICALXOR,
|
||||
LOGICALAND,
|
||||
NOT,
|
||||
QUESTION,
|
||||
COLON,
|
||||
EQ,
|
||||
EQEQ,
|
||||
NEQ,
|
||||
GT,
|
||||
LT,
|
||||
GTEQ,
|
||||
LTEQ,
|
||||
PLUSEQ,
|
||||
MINUSEQ,
|
||||
STAREQ,
|
||||
SLASHEQ,
|
||||
PERCENTEQ,
|
||||
SHLEQ,
|
||||
SHREQ,
|
||||
BITWISEOREQ,
|
||||
BITWISEXOREQ,
|
||||
BITWISEANDEQ,
|
||||
LOGICALOREQ,
|
||||
LOGICALXOREQ,
|
||||
LOGICALANDEQ,
|
||||
SEMICOLON,
|
||||
IF,
|
||||
ELSE,
|
||||
FOR,
|
||||
WHILE,
|
||||
DO,
|
||||
RETURN,
|
||||
BREAK,
|
||||
CONTINUE,
|
||||
DISCARD,
|
||||
IN,
|
||||
OUT,
|
||||
INOUT,
|
||||
CONST,
|
||||
LOWP,
|
||||
MEDIUMP,
|
||||
HIGHP,
|
||||
UNIFORM,
|
||||
STRUCT,
|
||||
LAYOUT,
|
||||
DIRECTIVE,
|
||||
PRECISION,
|
||||
INVALID_TOKEN
|
||||
};
|
||||
|
||||
static std::string OperatorName(Kind kind) {
|
||||
switch (kind) {
|
||||
case Token::PLUS: return "+";
|
||||
case Token::MINUS: return "-";
|
||||
case Token::STAR: return "*";
|
||||
case Token::SLASH: return "/";
|
||||
case Token::PERCENT: return "%";
|
||||
case Token::SHL: return "<<";
|
||||
case Token::SHR: return ">>";
|
||||
case Token::LOGICALAND: return "&&";
|
||||
case Token::LOGICALOR: return "||";
|
||||
case Token::LOGICALXOR: return "^^";
|
||||
case Token::BITWISEAND: return "&";
|
||||
case Token::BITWISEOR: return "|";
|
||||
case Token::BITWISEXOR: return "^";
|
||||
case Token::EQ: return "=";
|
||||
case Token::EQEQ: return "==";
|
||||
case Token::NEQ: return "!=";
|
||||
case Token::LT: return "<";
|
||||
case Token::GT: return ">";
|
||||
case Token::LTEQ: return "<=";
|
||||
case Token::GTEQ: return ">=";
|
||||
case Token::PLUSEQ: return "+=";
|
||||
case Token::MINUSEQ: return "-=";
|
||||
case Token::STAREQ: return "*=";
|
||||
case Token::SLASHEQ: return "/=";
|
||||
case Token::PERCENTEQ: return "%=";
|
||||
case Token::SHLEQ: return "<<=";
|
||||
case Token::SHREQ: return ">>=";
|
||||
case Token::LOGICALANDEQ: return "&&=";
|
||||
case Token::LOGICALOREQ: return "||=";
|
||||
case Token::LOGICALXOREQ: return "^^=";
|
||||
case Token::BITWISEANDEQ: return "&=";
|
||||
case Token::BITWISEOREQ: return "|=";
|
||||
case Token::BITWISEXOREQ: return "^=";
|
||||
case Token::PLUSPLUS: return "++";
|
||||
case Token::MINUSMINUS: return "--";
|
||||
case Token::NOT: return "!";
|
||||
default:
|
||||
ABORT("unsupported operator: %d\n", kind);
|
||||
}
|
||||
}
|
||||
|
||||
Token() {
|
||||
}
|
||||
|
||||
Token(Position position, Kind kind, std::string text)
|
||||
: fPosition(position)
|
||||
, fKind(kind)
|
||||
, fText(std::move(text)) {}
|
||||
|
||||
Position fPosition;
|
||||
Kind fKind;
|
||||
std::string fText;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
#endif
|
33
src/sksl/SkSLUtil.cpp
Normal file
33
src/sksl/SkSLUtil.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "SkSLUtil.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
int stoi(std::string s) {
|
||||
return atoi(s.c_str());
|
||||
}
|
||||
|
||||
double stod(std::string s) {
|
||||
return atof(s.c_str());
|
||||
}
|
||||
|
||||
long stol(std::string s) {
|
||||
return atol(s.c_str());
|
||||
}
|
||||
|
||||
void sksl_abort() {
|
||||
#ifdef SKIA
|
||||
sk_abort_no_print();
|
||||
exit(1);
|
||||
#else
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace
|
60
src/sksl/SkSLUtil.h
Normal file
60
src/sksl/SkSLUtil.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_UTIL
|
||||
#define SKSL_UTIL
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include "stdlib.h"
|
||||
#include "assert.h"
|
||||
#include "SkTypes.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
// our own definitions of certain std:: functions, because they are not always present on Android
|
||||
|
||||
template <typename T> std::string to_string(T value) {
|
||||
#ifdef SK_BUILD_FOR_ANDROID
|
||||
std::stringstream buffer;
|
||||
buffer << value;
|
||||
return buffer.str();
|
||||
#else
|
||||
return std::to_string(value);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if _MSC_VER
|
||||
#define NORETURN __declspec(noreturn)
|
||||
#else
|
||||
#define NORETURN __attribute__((__noreturn__))
|
||||
#endif
|
||||
int stoi(std::string s);
|
||||
|
||||
double stod(std::string s);
|
||||
|
||||
long stol(std::string s);
|
||||
|
||||
NORETURN void sksl_abort();
|
||||
|
||||
} // namespace
|
||||
|
||||
#ifdef DEBUG
|
||||
#define ASSERT(x) assert(x)
|
||||
#define ASSERT_RESULT(x) ASSERT(x);
|
||||
#else
|
||||
#define ASSERT(x)
|
||||
#define ASSERT_RESULT(x) x
|
||||
#endif
|
||||
|
||||
#ifdef SKIA
|
||||
#define ABORT(...) { SkDebugf(__VA_ARGS__); sksl_abort(); }
|
||||
#else
|
||||
#define ABORT(...) { sksl_abort(); }
|
||||
#endif
|
||||
|
||||
#endif
|
42
src/sksl/ast/SkSLASTBinaryExpression.h
Normal file
42
src/sksl/ast/SkSLASTBinaryExpression.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ASTBINARYEXPRESSION
|
||||
#define SKSL_ASTBINARYEXPRESSION
|
||||
|
||||
#include "SkSLASTExpression.h"
|
||||
#include "../SkSLToken.h"
|
||||
#include <sstream>
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* Represents a binary operation, with the operator represented by the token's type.
|
||||
*/
|
||||
struct ASTBinaryExpression : public ASTExpression {
|
||||
ASTBinaryExpression(std::unique_ptr<ASTExpression> left, Token op,
|
||||
std::unique_ptr<ASTExpression> right)
|
||||
: INHERITED(op.fPosition, kBinary_Kind)
|
||||
, fLeft(std::move(left))
|
||||
, fOperator(op.fKind)
|
||||
, fRight(std::move(right)) {}
|
||||
|
||||
std::string description() const override {
|
||||
return "(" + fLeft->description() + " " + Token::OperatorName(fOperator) + " " +
|
||||
fRight->description() + ")";
|
||||
}
|
||||
|
||||
const std::unique_ptr<ASTExpression> fLeft;
|
||||
const Token::Kind fOperator;
|
||||
const std::unique_ptr<ASTExpression> fRight;
|
||||
|
||||
typedef ASTExpression INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
40
src/sksl/ast/SkSLASTBlock.h
Normal file
40
src/sksl/ast/SkSLASTBlock.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ASTBLOCK
|
||||
#define SKSL_ASTBLOCK
|
||||
|
||||
#include "SkSLASTStatement.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* Represents a curly-braced block of statements.
|
||||
*/
|
||||
struct ASTBlock : public ASTStatement {
|
||||
ASTBlock(Position position, std::vector<std::unique_ptr<ASTStatement>> statements)
|
||||
: INHERITED(position, kBlock_Kind)
|
||||
, fStatements(std::move(statements)) {}
|
||||
|
||||
std::string description() const override {
|
||||
std::string result("{");
|
||||
for (size_t i = 0; i < fStatements.size(); i++) {
|
||||
result += "\n";
|
||||
result += fStatements[i]->description();
|
||||
}
|
||||
result += "\n}\n";
|
||||
return result;
|
||||
}
|
||||
|
||||
const std::vector<std::unique_ptr<ASTStatement>> fStatements;
|
||||
|
||||
typedef ASTStatement INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
34
src/sksl/ast/SkSLASTBoolLiteral.h
Normal file
34
src/sksl/ast/SkSLASTBoolLiteral.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ASTBOOLLITERAL
|
||||
#define SKSL_ASTBOOLLITERAL
|
||||
|
||||
#include "SkSLASTExpression.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* Represents "true" or "false".
|
||||
*/
|
||||
struct ASTBoolLiteral : public ASTExpression {
|
||||
ASTBoolLiteral(Position position, bool value)
|
||||
: INHERITED(position, kBool_Kind)
|
||||
, fValue(value) {}
|
||||
|
||||
std::string description() const override {
|
||||
return fValue ? "true" : "false";
|
||||
}
|
||||
|
||||
const bool fValue;
|
||||
|
||||
typedef ASTExpression INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
31
src/sksl/ast/SkSLASTBreakStatement.h
Normal file
31
src/sksl/ast/SkSLASTBreakStatement.h
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ASTBREAKSTATEMENT
|
||||
#define SKSL_ASTBREAKSTATEMENT
|
||||
|
||||
#include "SkSLASTStatement.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A 'break' statement.
|
||||
*/
|
||||
struct ASTBreakStatement : public ASTStatement {
|
||||
ASTBreakStatement(Position position)
|
||||
: INHERITED(position, kBreak_Kind) {}
|
||||
|
||||
std::string description() const override {
|
||||
return "break;";
|
||||
}
|
||||
|
||||
typedef ASTStatement INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
44
src/sksl/ast/SkSLASTCallSuffix.h
Normal file
44
src/sksl/ast/SkSLASTCallSuffix.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ASTCALLSUFFIX
|
||||
#define SKSL_ASTCALLSUFFIX
|
||||
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include "SkSLASTSuffix.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A parenthesized list of arguments following an expression, indicating a function call.
|
||||
*/
|
||||
struct ASTCallSuffix : public ASTSuffix {
|
||||
ASTCallSuffix(Position position, std::vector<std::unique_ptr<ASTExpression>> arguments)
|
||||
: INHERITED(position, ASTSuffix::kCall_Kind)
|
||||
, fArguments(std::move(arguments)) {}
|
||||
|
||||
std::string description() const override {
|
||||
std::string result("(");
|
||||
std::string separator = "";
|
||||
for (size_t i = 0; i < fArguments.size(); ++i) {
|
||||
result += separator;
|
||||
separator = ", ";
|
||||
result += fArguments[i]->description();
|
||||
}
|
||||
result += ")";
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<ASTExpression>> fArguments;
|
||||
|
||||
typedef ASTSuffix INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
31
src/sksl/ast/SkSLASTContinueStatement.h
Normal file
31
src/sksl/ast/SkSLASTContinueStatement.h
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ASTCONTINUESTATEMENT
|
||||
#define SKSL_ASTCONTINUESTATEMENT
|
||||
|
||||
#include "SkSLASTStatement.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A 'continue' statement.
|
||||
*/
|
||||
struct ASTContinueStatement : public ASTStatement {
|
||||
ASTContinueStatement(Position position)
|
||||
: INHERITED(position, kContinue_Kind) {}
|
||||
|
||||
std::string description() const override {
|
||||
return "continue;";
|
||||
}
|
||||
|
||||
typedef ASTStatement INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
37
src/sksl/ast/SkSLASTDeclaration.h
Normal file
37
src/sksl/ast/SkSLASTDeclaration.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ASTDECLARATION
|
||||
#define SKSL_ASTDECLARATION
|
||||
|
||||
#include "SkSLASTPositionNode.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* Abstract supertype of declarations such as variables and functions.
|
||||
*/
|
||||
struct ASTDeclaration : public ASTPositionNode {
|
||||
enum Kind {
|
||||
kVar_Kind,
|
||||
kFunction_Kind,
|
||||
kInterfaceBlock_Kind,
|
||||
kExtension_Kind
|
||||
};
|
||||
|
||||
ASTDeclaration(Position position, Kind kind)
|
||||
: INHERITED(position)
|
||||
, fKind(kind) {}
|
||||
|
||||
Kind fKind;
|
||||
|
||||
typedef ASTPositionNode INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
31
src/sksl/ast/SkSLASTDiscardStatement.h
Normal file
31
src/sksl/ast/SkSLASTDiscardStatement.h
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ASTDISCARDSTATEMENT
|
||||
#define SKSL_ASTDISCARDSTATEMENT
|
||||
|
||||
#include "SkSLASTStatement.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A 'discard' statement.
|
||||
*/
|
||||
struct ASTDiscardStatement : public ASTStatement {
|
||||
ASTDiscardStatement(Position position)
|
||||
: INHERITED(position, kDiscard_Kind) {}
|
||||
|
||||
std::string description() const override {
|
||||
return "discard;";
|
||||
}
|
||||
|
||||
typedef ASTStatement INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
37
src/sksl/ast/SkSLASTDoStatement.h
Normal file
37
src/sksl/ast/SkSLASTDoStatement.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ASTDOSTATEMENT
|
||||
#define SKSL_ASTDOSTATEMENT
|
||||
|
||||
#include "SkSLASTStatement.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A 'do' loop.
|
||||
*/
|
||||
struct ASTDoStatement : public ASTStatement {
|
||||
ASTDoStatement(Position position, std::unique_ptr<ASTStatement> statement,
|
||||
std::unique_ptr<ASTExpression> test)
|
||||
: INHERITED(position, kDo_Kind)
|
||||
, fStatement(std::move(statement))
|
||||
, fTest(std::move(test)) {}
|
||||
|
||||
std::string description() const override {
|
||||
return "do " + fStatement->description() + " while (" + fTest->description() + ");";
|
||||
}
|
||||
|
||||
const std::unique_ptr<ASTStatement> fStatement;
|
||||
const std::unique_ptr<ASTExpression> fTest;
|
||||
|
||||
typedef ASTStatement INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
41
src/sksl/ast/SkSLASTExpression.h
Normal file
41
src/sksl/ast/SkSLASTExpression.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ASTEXPRESSION
|
||||
#define SKSL_ASTEXPRESSION
|
||||
|
||||
#include "SkSLASTPositionNode.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* Abstract supertype of all expressions.
|
||||
*/
|
||||
struct ASTExpression : public ASTPositionNode {
|
||||
enum Kind {
|
||||
kFloat_Kind,
|
||||
kIdentifier_Kind,
|
||||
kInt_Kind,
|
||||
kBool_Kind,
|
||||
kPrefix_Kind,
|
||||
kSuffix_Kind,
|
||||
kBinary_Kind,
|
||||
kTernary_Kind
|
||||
};
|
||||
|
||||
ASTExpression(Position position, Kind kind)
|
||||
: INHERITED(position)
|
||||
, fKind(kind) {}
|
||||
|
||||
const Kind fKind;
|
||||
|
||||
typedef ASTPositionNode INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
34
src/sksl/ast/SkSLASTExpressionStatement.h
Normal file
34
src/sksl/ast/SkSLASTExpressionStatement.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ASTEXPRESSIONSTATEMENT
|
||||
#define SKSL_ASTEXPRESSIONSTATEMENT
|
||||
|
||||
#include "SkSLASTStatement.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A lone expression being used as a statement.
|
||||
*/
|
||||
struct ASTExpressionStatement : public ASTStatement {
|
||||
ASTExpressionStatement(std::unique_ptr<ASTExpression> expression)
|
||||
: INHERITED(expression->fPosition, kExpression_Kind)
|
||||
, fExpression(std::move(expression)) {}
|
||||
|
||||
std::string description() const override {
|
||||
return fExpression->description() + ";";
|
||||
}
|
||||
|
||||
const std::unique_ptr<ASTExpression> fExpression;
|
||||
|
||||
typedef ASTStatement INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
34
src/sksl/ast/SkSLASTExtension.h
Normal file
34
src/sksl/ast/SkSLASTExtension.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ASTEXTENSION
|
||||
#define SKSL_ASTEXTENSION
|
||||
|
||||
#include "SkSLASTDeclaration.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* An extension declaration.
|
||||
*/
|
||||
struct ASTExtension : public ASTDeclaration {
|
||||
ASTExtension(Position position, std::string name)
|
||||
: INHERITED(position, kExtension_Kind)
|
||||
, fName(std::move(name)) {}
|
||||
|
||||
std::string description() const override {
|
||||
return "#extension " + fName + " : enable";
|
||||
}
|
||||
|
||||
const std::string fName;
|
||||
|
||||
typedef ASTDeclaration INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
35
src/sksl/ast/SkSLASTFieldSuffix.h
Normal file
35
src/sksl/ast/SkSLASTFieldSuffix.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ASTFIELDSUFFIX
|
||||
#define SKSL_ASTFIELDSUFFIX
|
||||
|
||||
#include "SkSLASTSuffix.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A dotted identifier of the form ".foo". We refer to these as "fields" at parse time even if it is
|
||||
* actually vector swizzle (which looks the same to the parser).
|
||||
*/
|
||||
struct ASTFieldSuffix : public ASTSuffix {
|
||||
ASTFieldSuffix(Position position, std::string field)
|
||||
: INHERITED(position, ASTSuffix::kField_Kind)
|
||||
, fField(std::move(field)) {}
|
||||
|
||||
std::string description() const override {
|
||||
return "." + fField;
|
||||
}
|
||||
|
||||
std::string fField;
|
||||
|
||||
typedef ASTSuffix INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
34
src/sksl/ast/SkSLASTFloatLiteral.h
Normal file
34
src/sksl/ast/SkSLASTFloatLiteral.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ASTFLOATLITERAL
|
||||
#define SKSL_ASTFLOATLITERAL
|
||||
|
||||
#include "SkSLASTExpression.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A literal floating point number.
|
||||
*/
|
||||
struct ASTFloatLiteral : public ASTExpression {
|
||||
ASTFloatLiteral(Position position, double value)
|
||||
: INHERITED(position, kFloat_Kind)
|
||||
, fValue(value) {}
|
||||
|
||||
std::string description() const override {
|
||||
return to_string(fValue);
|
||||
}
|
||||
|
||||
const double fValue;
|
||||
|
||||
typedef ASTExpression INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
56
src/sksl/ast/SkSLASTForStatement.h
Normal file
56
src/sksl/ast/SkSLASTForStatement.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ASTFORSTATEMENT
|
||||
#define SKSL_ASTFORSTATEMENT
|
||||
|
||||
#include "SkSLASTStatement.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A 'for' loop.
|
||||
*/
|
||||
struct ASTForStatement : public ASTStatement {
|
||||
ASTForStatement(Position position, std::unique_ptr<ASTStatement> initializer,
|
||||
std::unique_ptr<ASTExpression> test, std::unique_ptr<ASTExpression> next,
|
||||
std::unique_ptr<ASTStatement> statement)
|
||||
: INHERITED(position, kFor_Kind)
|
||||
, fInitializer(std::move(initializer))
|
||||
, fTest(std::move(test))
|
||||
, fNext(std::move(next))
|
||||
, fStatement(std::move(statement)) {}
|
||||
|
||||
std::string description() const override {
|
||||
std::string result = "for (";
|
||||
if (fInitializer) {
|
||||
result.append(fInitializer->description());
|
||||
}
|
||||
result += " ";
|
||||
if (fTest) {
|
||||
result.append(fTest->description());
|
||||
}
|
||||
result += "; ";
|
||||
if (fNext) {
|
||||
result.append(fNext->description());
|
||||
}
|
||||
result += ") ";
|
||||
result += fStatement->description();
|
||||
return result;
|
||||
}
|
||||
|
||||
const std::unique_ptr<ASTStatement> fInitializer;
|
||||
const std::unique_ptr<ASTExpression> fTest;
|
||||
const std::unique_ptr<ASTExpression> fNext;
|
||||
const std::unique_ptr<ASTStatement> fStatement;
|
||||
|
||||
typedef ASTStatement INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
57
src/sksl/ast/SkSLASTFunction.h
Normal file
57
src/sksl/ast/SkSLASTFunction.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ASTFUNCTION
|
||||
#define SKSL_ASTFUNCTION
|
||||
|
||||
#include "SkSLASTBlock.h"
|
||||
#include "SkSLASTDeclaration.h"
|
||||
#include "SkSLASTParameter.h"
|
||||
#include "SkSLASTType.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A function declaration or definition. The fBody field will be null for declarations.
|
||||
*/
|
||||
struct ASTFunction : public ASTDeclaration {
|
||||
ASTFunction(Position position, std::unique_ptr<ASTType> returnType, std::string name,
|
||||
std::vector<std::unique_ptr<ASTParameter>> parameters,
|
||||
std::unique_ptr<ASTBlock> body)
|
||||
: INHERITED(position, kFunction_Kind)
|
||||
, fReturnType(std::move(returnType))
|
||||
, fName(std::move(name))
|
||||
, fParameters(std::move(parameters))
|
||||
, fBody(std::move(body)) {}
|
||||
|
||||
std::string description() const override {
|
||||
std::string result = fReturnType->description() + " " + fName + "(";
|
||||
for (size_t i = 0; i < fParameters.size(); i++) {
|
||||
if (i > 0) {
|
||||
result += ", ";
|
||||
}
|
||||
result += fParameters[i]->description();
|
||||
}
|
||||
if (fBody) {
|
||||
result += ") " + fBody->description();
|
||||
} else {
|
||||
result += ");";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const std::unique_ptr<ASTType> fReturnType;
|
||||
const std::string fName;
|
||||
const std::vector<std::unique_ptr<ASTParameter>> fParameters;
|
||||
const std::unique_ptr<ASTBlock> fBody;
|
||||
|
||||
typedef ASTDeclaration INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
34
src/sksl/ast/SkSLASTIdentifier.h
Normal file
34
src/sksl/ast/SkSLASTIdentifier.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ASTIDENTIFIER
|
||||
#define SKSL_ASTIDENTIFIER
|
||||
|
||||
#include "SkSLASTExpression.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* An identifier in an expression context.
|
||||
*/
|
||||
struct ASTIdentifier : public ASTExpression {
|
||||
ASTIdentifier(Position position, std::string text)
|
||||
: INHERITED(position, kIdentifier_Kind)
|
||||
, fText(std::move(text)) {}
|
||||
|
||||
std::string description() const override {
|
||||
return fText;
|
||||
}
|
||||
|
||||
const std::string fText;
|
||||
|
||||
typedef ASTExpression INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
47
src/sksl/ast/SkSLASTIfStatement.h
Normal file
47
src/sksl/ast/SkSLASTIfStatement.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ASTIFSTATEMENT
|
||||
#define SKSL_ASTIFSTATEMENT
|
||||
|
||||
#include "SkSLASTStatement.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* An 'if' statement.
|
||||
*/
|
||||
struct ASTIfStatement : public ASTStatement {
|
||||
ASTIfStatement(Position position, std::unique_ptr<ASTExpression> test,
|
||||
std::unique_ptr<ASTStatement> ifTrue, std::unique_ptr<ASTStatement> ifFalse)
|
||||
: INHERITED(position, kIf_Kind)
|
||||
, fTest(std::move(test))
|
||||
, fIfTrue(std::move(ifTrue))
|
||||
, fIfFalse(std::move(ifFalse)) {}
|
||||
|
||||
std::string description() const override {
|
||||
std::string result("if (");
|
||||
result += fTest->description();
|
||||
result += ") ";
|
||||
result += fIfTrue->description();
|
||||
if (fIfFalse) {
|
||||
result += " else ";
|
||||
result += fIfFalse->description();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const std::unique_ptr<ASTExpression> fTest;
|
||||
const std::unique_ptr<ASTStatement> fIfTrue;
|
||||
const std::unique_ptr<ASTStatement> fIfFalse;
|
||||
|
||||
typedef ASTStatement INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
35
src/sksl/ast/SkSLASTIndexSuffix.h
Normal file
35
src/sksl/ast/SkSLASTIndexSuffix.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ASTINDEXSUFFIX
|
||||
#define SKSL_ASTINDEXSUFFIX
|
||||
|
||||
#include "SkSLASTExpression.h"
|
||||
#include "SkSLASTSuffix.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A bracketed expression, as in '[0]', indicating an array access.
|
||||
*/
|
||||
struct ASTIndexSuffix : public ASTSuffix {
|
||||
ASTIndexSuffix(std::unique_ptr<ASTExpression> expression)
|
||||
: INHERITED(expression->fPosition, ASTSuffix::kIndex_Kind)
|
||||
, fExpression(std::move(expression)) {}
|
||||
|
||||
std::string description() const override {
|
||||
return "[" + fExpression->description() + "]";
|
||||
}
|
||||
|
||||
std::unique_ptr<ASTExpression> fExpression;
|
||||
|
||||
typedef ASTSuffix INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
35
src/sksl/ast/SkSLASTIntLiteral.h
Normal file
35
src/sksl/ast/SkSLASTIntLiteral.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ASTINTLITERAL
|
||||
#define SKSL_ASTINTLITERAL
|
||||
|
||||
#include "SkSLASTExpression.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A literal integer. At the AST level, integer literals are always positive; a negative number will
|
||||
* appear as a unary minus being applied to an integer literal.
|
||||
*/
|
||||
struct ASTIntLiteral : public ASTExpression {
|
||||
ASTIntLiteral(Position position, uint64_t value)
|
||||
: INHERITED(position, kInt_Kind)
|
||||
, fValue(value) {}
|
||||
|
||||
std::string description() const override {
|
||||
return to_string(fValue);
|
||||
}
|
||||
|
||||
const uint64_t fValue;
|
||||
|
||||
typedef ASTExpression INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
58
src/sksl/ast/SkSLASTInterfaceBlock.h
Normal file
58
src/sksl/ast/SkSLASTInterfaceBlock.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ASTINTERFACEBLOCK
|
||||
#define SKSL_ASTINTERFACEBLOCK
|
||||
|
||||
#include "SkSLASTVarDeclaration.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* An interface block, as in:
|
||||
*
|
||||
* out gl_PerVertex {
|
||||
* layout(builtin=0) vec4 gl_Position;
|
||||
* layout(builtin=1) float gl_PointSize;
|
||||
* };
|
||||
*/
|
||||
struct ASTInterfaceBlock : public ASTDeclaration {
|
||||
// valueName is empty when it was not present in the source
|
||||
ASTInterfaceBlock(Position position,
|
||||
ASTModifiers modifiers,
|
||||
std::string interfaceName,
|
||||
std::string valueName,
|
||||
std::vector<std::unique_ptr<ASTVarDeclaration>> declarations)
|
||||
: INHERITED(position, kInterfaceBlock_Kind)
|
||||
, fModifiers(modifiers)
|
||||
, fInterfaceName(std::move(interfaceName))
|
||||
, fValueName(std::move(valueName))
|
||||
, fDeclarations(std::move(declarations)) {}
|
||||
|
||||
std::string description() const override {
|
||||
std::string result = fModifiers.description() + fInterfaceName + " {\n";
|
||||
for (size_t i = 0; i < fDeclarations.size(); i++) {
|
||||
result += fDeclarations[i]->description() + "\n";
|
||||
}
|
||||
result += "}";
|
||||
if (fValueName.length()) {
|
||||
result += " " + fValueName;
|
||||
}
|
||||
return result + ";";
|
||||
}
|
||||
|
||||
const ASTModifiers fModifiers;
|
||||
const std::string fInterfaceName;
|
||||
const std::string fValueName;
|
||||
const std::vector<std::unique_ptr<ASTVarDeclaration>> fDeclarations;
|
||||
|
||||
typedef ASTDeclaration INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
68
src/sksl/ast/SkSLASTLayout.h
Normal file
68
src/sksl/ast/SkSLASTLayout.h
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ASTLAYOUT
|
||||
#define SKSL_ASTLAYOUT
|
||||
|
||||
#include "SkSLASTNode.h"
|
||||
#include "SkSLUtil.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* Represents a layout block appearing before a variable declaration, as in:
|
||||
*
|
||||
* layout (location = 0) int x;
|
||||
*/
|
||||
struct ASTLayout : public ASTNode {
|
||||
// For all parameters, a -1 means no value
|
||||
ASTLayout(int location, int binding, int index, int set, int builtin)
|
||||
: fLocation(location)
|
||||
, fBinding(binding)
|
||||
, fIndex(index)
|
||||
, fSet(set)
|
||||
, fBuiltin(builtin) {}
|
||||
|
||||
std::string description() const {
|
||||
std::string result;
|
||||
std::string separator;
|
||||
if (fLocation >= 0) {
|
||||
result += separator + "location = " + to_string(fLocation);
|
||||
separator = ", ";
|
||||
}
|
||||
if (fBinding >= 0) {
|
||||
result += separator + "binding = " + to_string(fBinding);
|
||||
separator = ", ";
|
||||
}
|
||||
if (fIndex >= 0) {
|
||||
result += separator + "index = " + to_string(fIndex);
|
||||
separator = ", ";
|
||||
}
|
||||
if (fSet >= 0) {
|
||||
result += separator + "set = " + to_string(fSet);
|
||||
separator = ", ";
|
||||
}
|
||||
if (fBuiltin >= 0) {
|
||||
result += separator + "builtin = " + to_string(fBuiltin);
|
||||
separator = ", ";
|
||||
}
|
||||
if (result.length() > 0) {
|
||||
result = "layout (" + result + ")";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const int fLocation;
|
||||
const int fBinding;
|
||||
const int fIndex;
|
||||
const int fSet;
|
||||
const int fBuiltin;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
70
src/sksl/ast/SkSLASTModifiers.h
Normal file
70
src/sksl/ast/SkSLASTModifiers.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ASTMODIFIERS
|
||||
#define SKSL_ASTMODIFIERS
|
||||
|
||||
#include "SkSLASTLayout.h"
|
||||
#include "SkSLASTNode.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A set of modifier keywords (in, out, uniform, etc.) appearing before a declaration.
|
||||
*/
|
||||
struct ASTModifiers : public ASTNode {
|
||||
enum Flag {
|
||||
kNo_Flag = 0,
|
||||
kConst_Flag = 1,
|
||||
kIn_Flag = 2,
|
||||
kOut_Flag = 4,
|
||||
kLowp_Flag = 8,
|
||||
kMediump_Flag = 16,
|
||||
kHighp_Flag = 32,
|
||||
kUniform_Flag = 64
|
||||
};
|
||||
|
||||
ASTModifiers(ASTLayout layout, int flags)
|
||||
: fLayout(layout)
|
||||
, fFlags(flags) {}
|
||||
|
||||
std::string description() const override {
|
||||
std::string result = fLayout.description();
|
||||
if (fFlags & kUniform_Flag) {
|
||||
result += "uniform ";
|
||||
}
|
||||
if (fFlags & kConst_Flag) {
|
||||
result += "const ";
|
||||
}
|
||||
if (fFlags & kLowp_Flag) {
|
||||
result += "lowp ";
|
||||
}
|
||||
if (fFlags & kMediump_Flag) {
|
||||
result += "mediump ";
|
||||
}
|
||||
if (fFlags & kHighp_Flag) {
|
||||
result += "highp ";
|
||||
}
|
||||
|
||||
if ((fFlags & kIn_Flag) && (fFlags & kOut_Flag)) {
|
||||
result += "inout ";
|
||||
} else if (fFlags & kIn_Flag) {
|
||||
result += "in ";
|
||||
} else if (fFlags & kOut_Flag) {
|
||||
result += "out ";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const ASTLayout fLayout;
|
||||
const int fFlags;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
28
src/sksl/ast/SkSLASTNode.h
Normal file
28
src/sksl/ast/SkSLASTNode.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ASTNODE
|
||||
#define SKSL_ASTNODE
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* Represents a node in the abstract syntax tree (AST). The AST is based directly on the parse tree;
|
||||
* it is a parsed-but-not-yet-analyzed version of the program.
|
||||
*/
|
||||
struct ASTNode {
|
||||
virtual ~ASTNode() {}
|
||||
|
||||
virtual std::string description() const = 0;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
48
src/sksl/ast/SkSLASTParameter.h
Normal file
48
src/sksl/ast/SkSLASTParameter.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ASTPARAMETER
|
||||
#define SKSL_ASTPARAMETER
|
||||
|
||||
#include "SkSLASTModifiers.h"
|
||||
#include "SkSLASTType.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A declaration of a parameter, as part of a function declaration.
|
||||
*/
|
||||
struct ASTParameter : public ASTPositionNode {
|
||||
// 'sizes' is a list of the array sizes appearing on a parameter, in source order.
|
||||
// e.g. int x[3][1] would have sizes [3, 1].
|
||||
ASTParameter(Position position, ASTModifiers modifiers, std::unique_ptr<ASTType> type,
|
||||
std::string name, std::vector<int> sizes)
|
||||
: INHERITED(position)
|
||||
, fModifiers(modifiers)
|
||||
, fType(std::move(type))
|
||||
, fName(std::move(name))
|
||||
, fSizes(std::move(sizes)) {}
|
||||
|
||||
std::string description() const override {
|
||||
std::string result = fModifiers.description() + fType->description() + " " + fName;
|
||||
for (int size : fSizes) {
|
||||
result += "[" + to_string(size) + "]";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const ASTModifiers fModifiers;
|
||||
const std::unique_ptr<ASTType> fType;
|
||||
const std::string fName;
|
||||
const std::vector<int> fSizes;
|
||||
|
||||
typedef ASTPositionNode INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
28
src/sksl/ast/SkSLASTPositionNode.h
Normal file
28
src/sksl/ast/SkSLASTPositionNode.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ASTPOSITIONNODE
|
||||
#define SKSL_ASTPOSITIONNODE
|
||||
|
||||
#include "SkSLASTNode.h"
|
||||
#include "../SkSLPosition.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* An AST node with an associated position in the source.
|
||||
*/
|
||||
struct ASTPositionNode : public ASTNode {
|
||||
ASTPositionNode(Position position)
|
||||
: fPosition(position) {}
|
||||
|
||||
const Position fPosition;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
37
src/sksl/ast/SkSLASTPrefixExpression.h
Normal file
37
src/sksl/ast/SkSLASTPrefixExpression.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ASTPREFIXEXPRESSION
|
||||
#define SKSL_ASTPREFIXEXPRESSION
|
||||
|
||||
#include "SkSLASTExpression.h"
|
||||
#include "../SkSLToken.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* An expression modified by a unary operator appearing in front of it, such as '-x' or '!inside'.
|
||||
*/
|
||||
struct ASTPrefixExpression : public ASTExpression {
|
||||
ASTPrefixExpression(Token op, std::unique_ptr<ASTExpression> operand)
|
||||
: INHERITED(op.fPosition, kPrefix_Kind)
|
||||
, fOperator(op.fKind)
|
||||
, fOperand(std::move(operand)) {}
|
||||
|
||||
std::string description() const override {
|
||||
return Token::OperatorName(fOperator) + fOperand->description();
|
||||
}
|
||||
|
||||
const Token::Kind fOperator;
|
||||
const std::unique_ptr<ASTExpression> fOperand;
|
||||
|
||||
typedef ASTExpression INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
39
src/sksl/ast/SkSLASTReturnStatement.h
Normal file
39
src/sksl/ast/SkSLASTReturnStatement.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ASTRETURNSTATEMENT
|
||||
#define SKSL_ASTRETURNSTATEMENT
|
||||
|
||||
#include "SkSLASTStatement.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A 'return' statement.
|
||||
*/
|
||||
struct ASTReturnStatement : public ASTStatement {
|
||||
// expression may be null
|
||||
ASTReturnStatement(Position position, std::unique_ptr<ASTExpression> expression)
|
||||
: INHERITED(position, kReturn_Kind)
|
||||
, fExpression(std::move(expression)) {}
|
||||
|
||||
std::string description() const override {
|
||||
std::string result("return");
|
||||
if (fExpression) {
|
||||
result += " " + fExpression->description();
|
||||
}
|
||||
return result + ";";
|
||||
}
|
||||
|
||||
const std::unique_ptr<ASTExpression> fExpression;
|
||||
|
||||
typedef ASTStatement INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
46
src/sksl/ast/SkSLASTStatement.h
Normal file
46
src/sksl/ast/SkSLASTStatement.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ASTSTATEMENT
|
||||
#define SKSL_ASTSTATEMENT
|
||||
|
||||
#include <vector>
|
||||
#include "SkSLASTPositionNode.h"
|
||||
#include "SkSLASTExpression.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* Abstract supertype of all statements.
|
||||
*/
|
||||
struct ASTStatement : public ASTPositionNode {
|
||||
enum Kind {
|
||||
kBlock_Kind,
|
||||
kVarDeclaration_Kind,
|
||||
kExpression_Kind,
|
||||
kIf_Kind,
|
||||
kFor_Kind,
|
||||
kWhile_Kind,
|
||||
kDo_Kind,
|
||||
kReturn_Kind,
|
||||
kBreak_Kind,
|
||||
kContinue_Kind,
|
||||
kDiscard_Kind
|
||||
};
|
||||
|
||||
ASTStatement(Position position, Kind kind)
|
||||
: INHERITED(position)
|
||||
, fKind(kind) {}
|
||||
|
||||
Kind fKind;
|
||||
|
||||
typedef ASTPositionNode INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
51
src/sksl/ast/SkSLASTSuffix.h
Normal file
51
src/sksl/ast/SkSLASTSuffix.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ASTSUFFIX
|
||||
#define SKSL_ASTSUFFIX
|
||||
|
||||
#include "SkSLASTPositionNode.h"
|
||||
#include "SkSLASTExpression.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* This and its subclasses represents expression suffixes, such as '[0]' or '.rgb'. Suffixes are not
|
||||
* expressions in and of themselves; they are attached to expressions to modify them.
|
||||
*/
|
||||
struct ASTSuffix : public ASTPositionNode {
|
||||
enum Kind {
|
||||
kIndex_Kind,
|
||||
kCall_Kind,
|
||||
kField_Kind,
|
||||
kPostIncrement_Kind,
|
||||
kPostDecrement_Kind
|
||||
};
|
||||
|
||||
ASTSuffix(Position position, Kind kind)
|
||||
: INHERITED(position)
|
||||
, fKind(kind) {}
|
||||
|
||||
std::string description() const override {
|
||||
switch (fKind) {
|
||||
case kPostIncrement_Kind:
|
||||
return "++";
|
||||
case kPostDecrement_Kind:
|
||||
return "--";
|
||||
default:
|
||||
ABORT("unsupported suffix operator");
|
||||
}
|
||||
}
|
||||
|
||||
Kind fKind;
|
||||
|
||||
typedef ASTPositionNode INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
37
src/sksl/ast/SkSLASTSuffixExpression.h
Normal file
37
src/sksl/ast/SkSLASTSuffixExpression.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ASTSUFFIXEXPRESSION
|
||||
#define SKSL_ASTSUFFIXEXPRESSION
|
||||
|
||||
#include "SkSLASTSuffix.h"
|
||||
#include "SkSLASTExpression.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* An expression with an associated suffix.
|
||||
*/
|
||||
struct ASTSuffixExpression : public ASTExpression {
|
||||
ASTSuffixExpression(std::unique_ptr<ASTExpression> base, std::unique_ptr<ASTSuffix> suffix)
|
||||
: INHERITED(base->fPosition, kSuffix_Kind)
|
||||
, fBase(std::move(base))
|
||||
, fSuffix(std::move(suffix)) {}
|
||||
|
||||
std::string description() const override {
|
||||
return fBase->description() + fSuffix->description();
|
||||
}
|
||||
|
||||
const std::unique_ptr<ASTExpression> fBase;
|
||||
const std::unique_ptr<ASTSuffix> fSuffix;
|
||||
|
||||
typedef ASTExpression INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
41
src/sksl/ast/SkSLASTTernaryExpression.h
Normal file
41
src/sksl/ast/SkSLASTTernaryExpression.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ASTTERNARYEXPRESSION
|
||||
#define SKSL_ASTTERNARYEXPRESSION
|
||||
|
||||
#include "SkSLASTExpression.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A ternary expression (test ? ifTrue : ifFalse).
|
||||
*/
|
||||
struct ASTTernaryExpression : public ASTExpression {
|
||||
ASTTernaryExpression(std::unique_ptr<ASTExpression> test,
|
||||
std::unique_ptr<ASTExpression> ifTrue,
|
||||
std::unique_ptr<ASTExpression> ifFalse)
|
||||
: INHERITED(test->fPosition, kTernary_Kind)
|
||||
, fTest(std::move(test))
|
||||
, fIfTrue(std::move(ifTrue))
|
||||
, fIfFalse(std::move(ifFalse)) {}
|
||||
|
||||
std::string description() const override {
|
||||
return "(" + fTest->description() + " ? " + fIfTrue->description() + " : " +
|
||||
fIfFalse->description() + ")";
|
||||
}
|
||||
|
||||
const std::unique_ptr<ASTExpression> fTest;
|
||||
const std::unique_ptr<ASTExpression> fIfTrue;
|
||||
const std::unique_ptr<ASTExpression> fIfFalse;
|
||||
|
||||
typedef ASTExpression INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
40
src/sksl/ast/SkSLASTType.h
Normal file
40
src/sksl/ast/SkSLASTType.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ASTTYPE
|
||||
#define SKSL_ASTTYPE
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A type, such as 'int' or 'struct foo'.
|
||||
*/
|
||||
struct ASTType : public ASTPositionNode {
|
||||
enum Kind {
|
||||
kIdentifier_Kind,
|
||||
kStruct_Kind
|
||||
};
|
||||
|
||||
ASTType(Position position, std::string name, Kind kind)
|
||||
: INHERITED(position)
|
||||
, fName(std::move(name))
|
||||
, fKind(kind) {}
|
||||
|
||||
std::string description() const override {
|
||||
return fName;
|
||||
}
|
||||
|
||||
const std::string fName;
|
||||
|
||||
const Kind fKind;
|
||||
|
||||
typedef ASTPositionNode INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
71
src/sksl/ast/SkSLASTVarDeclaration.h
Normal file
71
src/sksl/ast/SkSLASTVarDeclaration.h
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ASTVARDECLARATION
|
||||
#define SKSL_ASTVARDECLARATION
|
||||
|
||||
#include "SkSLASTDeclaration.h"
|
||||
#include "SkSLASTModifiers.h"
|
||||
#include "SkSLASTStatement.h"
|
||||
#include "SkSLASTType.h"
|
||||
#include "../SkSLUtil.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A variable declaration, which may consist of multiple individual variables. For instance
|
||||
* 'int x, y = 1, z[4][2]' is a single ASTVarDeclaration. This declaration would have a type of
|
||||
* 'int', names ['x', 'y', 'z'], sizes of [[], [], [4, 2]], and values of [null, 1, null].
|
||||
*/
|
||||
struct ASTVarDeclaration : public ASTDeclaration {
|
||||
ASTVarDeclaration(ASTModifiers modifiers,
|
||||
std::unique_ptr<ASTType> type,
|
||||
std::vector<std::string> names,
|
||||
std::vector<std::vector<std::unique_ptr<ASTExpression>>> sizes,
|
||||
std::vector<std::unique_ptr<ASTExpression>> values)
|
||||
: INHERITED(type->fPosition, kVar_Kind)
|
||||
, fModifiers(modifiers)
|
||||
, fType(std::move(type))
|
||||
, fNames(std::move(names))
|
||||
, fSizes(std::move(sizes))
|
||||
, fValues(std::move(values)) {
|
||||
ASSERT(fNames.size() == fValues.size());
|
||||
}
|
||||
|
||||
std::string description() const override {
|
||||
std::string result = fModifiers.description() + fType->description() + " ";
|
||||
std::string separator = "";
|
||||
for (size_t i = 0; i < fNames.size(); i++) {
|
||||
result += separator;
|
||||
separator = ", ";
|
||||
result += fNames[i];
|
||||
for (size_t j = 0; j < fSizes[i].size(); j++) {
|
||||
if (fSizes[i][j]) {
|
||||
result += "[" + fSizes[i][j]->description() + "]";
|
||||
} else {
|
||||
result += "[]";
|
||||
}
|
||||
}
|
||||
if (fValues[i]) {
|
||||
result += " = " + fValues[i]->description();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const ASTModifiers fModifiers;
|
||||
const std::unique_ptr<ASTType> fType;
|
||||
const std::vector<std::string> fNames;
|
||||
const std::vector<std::vector<std::unique_ptr<ASTExpression>>> fSizes;
|
||||
const std::vector<std::unique_ptr<ASTExpression>> fValues;
|
||||
|
||||
typedef ASTDeclaration INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
35
src/sksl/ast/SkSLASTVarDeclarationStatement.h
Normal file
35
src/sksl/ast/SkSLASTVarDeclarationStatement.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ASTVARDECLARATIONSTATEMENT
|
||||
#define SKSL_ASTVARDECLARATIONSTATEMENT
|
||||
|
||||
#include "SkSLASTStatement.h"
|
||||
#include "SkSLASTVarDeclaration.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A variable declaration appearing as a statement within a function.
|
||||
*/
|
||||
struct ASTVarDeclarationStatement : public ASTStatement {
|
||||
ASTVarDeclarationStatement(std::unique_ptr<ASTVarDeclaration> decl)
|
||||
: INHERITED(decl->fPosition, kVarDeclaration_Kind)
|
||||
, fDeclaration(std::move(decl)) {}
|
||||
|
||||
std::string description() const override {
|
||||
return fDeclaration->description() + ";";
|
||||
}
|
||||
|
||||
std::unique_ptr<ASTVarDeclaration> fDeclaration;
|
||||
|
||||
typedef ASTStatement INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
37
src/sksl/ast/SkSLASTWhileStatement.h
Normal file
37
src/sksl/ast/SkSLASTWhileStatement.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_ASTWHILESTATEMENT
|
||||
#define SKSL_ASTWHILESTATEMENT
|
||||
|
||||
#include "SkSLASTStatement.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A 'while' statement.
|
||||
*/
|
||||
struct ASTWhileStatement : public ASTStatement {
|
||||
ASTWhileStatement(Position position, std::unique_ptr<ASTExpression> test,
|
||||
std::unique_ptr<ASTStatement> statement)
|
||||
: INHERITED(position, kWhile_Kind)
|
||||
, fTest(std::move(test))
|
||||
, fStatement(std::move(statement)) {}
|
||||
|
||||
std::string description() const override {
|
||||
return "while (" + fTest->description() + ") " + fStatement->description();
|
||||
}
|
||||
|
||||
const std::unique_ptr<ASTExpression> fTest;
|
||||
const std::unique_ptr<ASTStatement> fStatement;
|
||||
|
||||
typedef ASTStatement INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
41
src/sksl/ir/SkSLBinaryExpression.h
Normal file
41
src/sksl/ir/SkSLBinaryExpression.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_BINARYEXPRESSION
|
||||
#define SKSL_BINARYEXPRESSION
|
||||
|
||||
#include "SkSLExpression.h"
|
||||
#include "../SkSLToken.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A binary operation.
|
||||
*/
|
||||
struct BinaryExpression : public Expression {
|
||||
BinaryExpression(Position position, std::unique_ptr<Expression> left, Token::Kind op,
|
||||
std::unique_ptr<Expression> right, std::shared_ptr<Type> type)
|
||||
: INHERITED(position, kBinary_Kind, type)
|
||||
, fLeft(std::move(left))
|
||||
, fOperator(op)
|
||||
, fRight(std::move(right)) {}
|
||||
|
||||
virtual std::string description() const override {
|
||||
return "(" + fLeft->description() + " " + Token::OperatorName(fOperator) + " " +
|
||||
fRight->description() + ")";
|
||||
}
|
||||
|
||||
const std::unique_ptr<Expression> fLeft;
|
||||
const Token::Kind fOperator;
|
||||
const std::unique_ptr<Expression> fRight;
|
||||
|
||||
typedef Expression INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
40
src/sksl/ir/SkSLBlock.h
Normal file
40
src/sksl/ir/SkSLBlock.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_BLOCK
|
||||
#define SKSL_BLOCK
|
||||
|
||||
#include "SkSLStatement.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A block of multiple statements functioning as a single statement.
|
||||
*/
|
||||
struct Block : public Statement {
|
||||
Block(Position position, std::vector<std::unique_ptr<Statement>> statements)
|
||||
: INHERITED(position, kBlock_Kind)
|
||||
, fStatements(std::move(statements)) {}
|
||||
|
||||
std::string description() const override {
|
||||
std::string result = "{";
|
||||
for (size_t i = 0; i < fStatements.size(); i++) {
|
||||
result += "\n";
|
||||
result += fStatements[i]->description();
|
||||
}
|
||||
result += "\n}\n";
|
||||
return result;
|
||||
}
|
||||
|
||||
const std::vector<std::unique_ptr<Statement>> fStatements;
|
||||
|
||||
typedef Statement INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
38
src/sksl/ir/SkSLBoolLiteral.h
Normal file
38
src/sksl/ir/SkSLBoolLiteral.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_BOOLLITERAL
|
||||
#define SKSL_BOOLLITERAL
|
||||
|
||||
#include "SkSLExpression.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* Represents 'true' or 'false'.
|
||||
*/
|
||||
struct BoolLiteral : public Expression {
|
||||
BoolLiteral(Position position, bool value)
|
||||
: INHERITED(position, kBoolLiteral_Kind, kBool_Type)
|
||||
, fValue(value) {}
|
||||
|
||||
std::string description() const override {
|
||||
return fValue ? "true" : "false";
|
||||
}
|
||||
|
||||
bool isConstant() const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
const bool fValue;
|
||||
|
||||
typedef Expression INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
32
src/sksl/ir/SkSLBreakStatement.h
Normal file
32
src/sksl/ir/SkSLBreakStatement.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_BREAKSTATEMENT
|
||||
#define SKSL_BREAKSTATEMENT
|
||||
|
||||
#include "SkSLExpression.h"
|
||||
#include "SkSLStatement.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A 'break' statement.
|
||||
*/
|
||||
struct BreakStatement : public Statement {
|
||||
BreakStatement(Position position)
|
||||
: INHERITED(position, kBreak_Kind) {}
|
||||
|
||||
std::string description() const override {
|
||||
return "break;";
|
||||
}
|
||||
|
||||
typedef Statement INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
52
src/sksl/ir/SkSLConstructor.h
Normal file
52
src/sksl/ir/SkSLConstructor.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_CONSTRUCTOR
|
||||
#define SKSL_CONSTRUCTOR
|
||||
|
||||
#include "SkSLExpression.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* Represents the construction of a compound type, such as "vec2(x, y)".
|
||||
*/
|
||||
struct Constructor : public Expression {
|
||||
Constructor(Position position, std::shared_ptr<Type> type,
|
||||
std::vector<std::unique_ptr<Expression>> arguments)
|
||||
: INHERITED(position, kConstructor_Kind, std::move(type))
|
||||
, fArguments(std::move(arguments)) {}
|
||||
|
||||
std::string description() const override {
|
||||
std::string result = fType->description() + "(";
|
||||
std::string separator = "";
|
||||
for (size_t i = 0; i < fArguments.size(); i++) {
|
||||
result += separator;
|
||||
result += fArguments[i]->description();
|
||||
separator = ", ";
|
||||
}
|
||||
result += ")";
|
||||
return result;
|
||||
}
|
||||
|
||||
bool isConstant() const override {
|
||||
for (size_t i = 0; i < fArguments.size(); i++) {
|
||||
if (!fArguments[i]->isConstant()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::vector<std::unique_ptr<Expression>> fArguments;
|
||||
|
||||
typedef Expression INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
32
src/sksl/ir/SkSLContinueStatement.h
Normal file
32
src/sksl/ir/SkSLContinueStatement.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_CONTINUESTATEMENT
|
||||
#define SKSL_CONTINUESTATEMENT
|
||||
|
||||
#include "SkSLExpression.h"
|
||||
#include "SkSLStatement.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A 'continue' statement.
|
||||
*/
|
||||
struct ContinueStatement : public Statement {
|
||||
ContinueStatement(Position position)
|
||||
: INHERITED(position, kContinue_Kind) {}
|
||||
|
||||
std::string description() const override {
|
||||
return "continue;";
|
||||
}
|
||||
|
||||
typedef Statement INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
32
src/sksl/ir/SkSLDiscardStatement.h
Normal file
32
src/sksl/ir/SkSLDiscardStatement.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_DISCARDSTATEMENT
|
||||
#define SKSL_DISCARDSTATEMENT
|
||||
|
||||
#include "SkSLExpression.h"
|
||||
#include "SkSLStatement.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A 'discard' statement.
|
||||
*/
|
||||
struct DiscardStatement : public Statement {
|
||||
DiscardStatement(Position position)
|
||||
: INHERITED(position, kDiscard_Kind) {}
|
||||
|
||||
std::string description() const override {
|
||||
return "discard;";
|
||||
}
|
||||
|
||||
typedef Statement INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
38
src/sksl/ir/SkSLDoStatement.h
Normal file
38
src/sksl/ir/SkSLDoStatement.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_DOSTATEMENT
|
||||
#define SKSL_DOSTATEMENT
|
||||
|
||||
#include "SkSLExpression.h"
|
||||
#include "SkSLStatement.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A 'do' statement.
|
||||
*/
|
||||
struct DoStatement : public Statement {
|
||||
DoStatement(Position position, std::unique_ptr<Statement> statement,
|
||||
std::unique_ptr<Expression> test)
|
||||
: INHERITED(position, kDo_Kind)
|
||||
, fStatement(std::move(statement))
|
||||
, fTest(std::move(test)) {}
|
||||
|
||||
std::string description() const override {
|
||||
return "do " + fStatement->description() + " while (" + fTest->description() + ");";
|
||||
}
|
||||
|
||||
const std::unique_ptr<Statement> fStatement;
|
||||
const std::unique_ptr<Expression> fTest;
|
||||
|
||||
typedef Statement INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
55
src/sksl/ir/SkSLExpression.h
Normal file
55
src/sksl/ir/SkSLExpression.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_EXPRESSION
|
||||
#define SKSL_EXPRESSION
|
||||
|
||||
#include "SkSLIRNode.h"
|
||||
#include "SkSLType.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* Abstract supertype of all expressions.
|
||||
*/
|
||||
struct Expression : public IRNode {
|
||||
enum Kind {
|
||||
kBinary_Kind,
|
||||
kBoolLiteral_Kind,
|
||||
kConstructor_Kind,
|
||||
kIntLiteral_Kind,
|
||||
kFieldAccess_Kind,
|
||||
kFloatLiteral_Kind,
|
||||
kFunctionReference_Kind,
|
||||
kFunctionCall_Kind,
|
||||
kIndex_Kind,
|
||||
kPrefix_Kind,
|
||||
kPostfix_Kind,
|
||||
kSwizzle_Kind,
|
||||
kVariableReference_Kind,
|
||||
kTernary_Kind,
|
||||
kTypeReference_Kind,
|
||||
};
|
||||
|
||||
Expression(Position position, Kind kind, std::shared_ptr<Type> type)
|
||||
: INHERITED(position)
|
||||
, fKind(kind)
|
||||
, fType(std::move(type)) {}
|
||||
|
||||
virtual bool isConstant() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
const Kind fKind;
|
||||
const std::shared_ptr<Type> fType;
|
||||
|
||||
typedef IRNode INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
35
src/sksl/ir/SkSLExpressionStatement.h
Normal file
35
src/sksl/ir/SkSLExpressionStatement.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_EXPRESSIONSTATEMENT
|
||||
#define SKSL_EXPRESSIONSTATEMENT
|
||||
|
||||
#include "SkSLExpression.h"
|
||||
#include "SkSLStatement.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A lone expression being used as a statement.
|
||||
*/
|
||||
struct ExpressionStatement : public Statement {
|
||||
ExpressionStatement(std::unique_ptr<Expression> expression)
|
||||
: INHERITED(expression->fPosition, kExpression_Kind)
|
||||
, fExpression(std::move(expression)) {}
|
||||
|
||||
std::string description() const override {
|
||||
return fExpression->description() + ";";
|
||||
}
|
||||
|
||||
const std::unique_ptr<Expression> fExpression;
|
||||
|
||||
typedef Statement INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
34
src/sksl/ir/SkSLExtension.h
Normal file
34
src/sksl/ir/SkSLExtension.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_EXTENSION
|
||||
#define SKSL_EXTENSION
|
||||
|
||||
#include "SkSLProgramElement.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* An extension declaration.
|
||||
*/
|
||||
struct Extension : public ProgramElement {
|
||||
Extension(Position position, std::string name)
|
||||
: INHERITED(position, kExtension_Kind)
|
||||
, fName(std::move(name)) {}
|
||||
|
||||
std::string description() const override {
|
||||
return "#extension " + fName + " : enable";
|
||||
}
|
||||
|
||||
const std::string fName;
|
||||
|
||||
typedef ProgramElement INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
41
src/sksl/ir/SkSLField.h
Normal file
41
src/sksl/ir/SkSLField.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_FIELD
|
||||
#define SKSL_FIELD
|
||||
|
||||
#include "SkSLModifiers.h"
|
||||
#include "SkSLPosition.h"
|
||||
#include "SkSLSymbol.h"
|
||||
#include "SkSLType.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A symbol which should be interpreted as a field access. Fields are added to the symboltable
|
||||
* whenever a bare reference to an identifier should refer to a struct field; in GLSL, this is the
|
||||
* result of declaring anonymous interface blocks.
|
||||
*/
|
||||
struct Field : public Symbol {
|
||||
Field(Position position, std::shared_ptr<Variable> owner, int fieldIndex)
|
||||
: INHERITED(position, kField_Kind, owner->fType->fields()[fieldIndex].fName)
|
||||
, fOwner(owner)
|
||||
, fFieldIndex(fieldIndex) {}
|
||||
|
||||
virtual std::string description() const override {
|
||||
return fOwner->description() + "." + fOwner->fType->fields()[fFieldIndex].fName;
|
||||
}
|
||||
|
||||
const std::shared_ptr<Variable> fOwner;
|
||||
const int fFieldIndex;
|
||||
|
||||
typedef Symbol INHERITED;
|
||||
};
|
||||
|
||||
} // namespace SkSL
|
||||
|
||||
#endif
|
37
src/sksl/ir/SkSLFieldAccess.h
Normal file
37
src/sksl/ir/SkSLFieldAccess.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_FIELDACCESS
|
||||
#define SKSL_FIELDACCESS
|
||||
|
||||
#include "SkSLExpression.h"
|
||||
#include "SkSLUtil.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* An expression which extracts a field from a struct, as in 'foo.bar'.
|
||||
*/
|
||||
struct FieldAccess : public Expression {
|
||||
FieldAccess(std::unique_ptr<Expression> base, int fieldIndex)
|
||||
: INHERITED(base->fPosition, kFieldAccess_Kind, base->fType->fields()[fieldIndex].fType)
|
||||
, fBase(std::move(base))
|
||||
, fFieldIndex(fieldIndex) {}
|
||||
|
||||
virtual std::string description() const override {
|
||||
return fBase->description() + "." + fBase->fType->fields()[fFieldIndex].fName;
|
||||
}
|
||||
|
||||
const std::unique_ptr<Expression> fBase;
|
||||
const int fFieldIndex;
|
||||
|
||||
typedef Expression INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
38
src/sksl/ir/SkSLFloatLiteral.h
Normal file
38
src/sksl/ir/SkSLFloatLiteral.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_FLOATLITERAL
|
||||
#define SKSL_FLOATLITERAL
|
||||
|
||||
#include "SkSLExpression.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A literal floating point number.
|
||||
*/
|
||||
struct FloatLiteral : public Expression {
|
||||
FloatLiteral(Position position, double value)
|
||||
: INHERITED(position, kFloatLiteral_Kind, kFloat_Type)
|
||||
, fValue(value) {}
|
||||
|
||||
virtual std::string description() const override {
|
||||
return to_string(fValue);
|
||||
}
|
||||
|
||||
bool isConstant() const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
const double fValue;
|
||||
|
||||
typedef Expression INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
56
src/sksl/ir/SkSLForStatement.h
Normal file
56
src/sksl/ir/SkSLForStatement.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_FORSTATEMENT
|
||||
#define SKSL_FORSTATEMENT
|
||||
|
||||
#include "SkSLExpression.h"
|
||||
#include "SkSLStatement.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A 'for' statement.
|
||||
*/
|
||||
struct ForStatement : public Statement {
|
||||
ForStatement(Position position, std::unique_ptr<Statement> initializer,
|
||||
std::unique_ptr<Expression> test, std::unique_ptr<Expression> next,
|
||||
std::unique_ptr<Statement> statement)
|
||||
: INHERITED(position, kFor_Kind)
|
||||
, fInitializer(std::move(initializer))
|
||||
, fTest(std::move(test))
|
||||
, fNext(std::move(next))
|
||||
, fStatement(std::move(statement)) {}
|
||||
|
||||
std::string description() const override {
|
||||
std::string result = "for (";
|
||||
if (fInitializer) {
|
||||
result += fInitializer->description();
|
||||
}
|
||||
result += " ";
|
||||
if (fTest) {
|
||||
result += fTest->description();
|
||||
}
|
||||
result += "; ";
|
||||
if (fNext) {
|
||||
result += fNext->description();
|
||||
}
|
||||
result += ") " + fStatement->description();
|
||||
return result;
|
||||
}
|
||||
|
||||
const std::unique_ptr<Statement> fInitializer;
|
||||
const std::unique_ptr<Expression> fTest;
|
||||
const std::unique_ptr<Expression> fNext;
|
||||
const std::unique_ptr<Statement> fStatement;
|
||||
|
||||
typedef Statement INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
46
src/sksl/ir/SkSLFunctionCall.h
Normal file
46
src/sksl/ir/SkSLFunctionCall.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_FUNCTIONCALL
|
||||
#define SKSL_FUNCTIONCALL
|
||||
|
||||
#include "SkSLExpression.h"
|
||||
#include "SkSLFunctionDeclaration.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A function invocation.
|
||||
*/
|
||||
struct FunctionCall : public Expression {
|
||||
FunctionCall(Position position, std::shared_ptr<FunctionDeclaration> function,
|
||||
std::vector<std::unique_ptr<Expression>> arguments)
|
||||
: INHERITED(position, kFunctionCall_Kind, function->fReturnType)
|
||||
, fFunction(std::move(function))
|
||||
, fArguments(std::move(arguments)) {}
|
||||
|
||||
std::string description() const override {
|
||||
std::string result = fFunction->fName + "(";
|
||||
std::string separator = "";
|
||||
for (size_t i = 0; i < fArguments.size(); i++) {
|
||||
result += separator;
|
||||
result += fArguments[i]->description();
|
||||
separator = ", ";
|
||||
}
|
||||
result += ")";
|
||||
return result;
|
||||
}
|
||||
|
||||
const std::shared_ptr<FunctionDeclaration> fFunction;
|
||||
const std::vector<std::unique_ptr<Expression>> fArguments;
|
||||
|
||||
typedef Expression INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
55
src/sksl/ir/SkSLFunctionDeclaration.h
Normal file
55
src/sksl/ir/SkSLFunctionDeclaration.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_FUNCTIONDECLARATION
|
||||
#define SKSL_FUNCTIONDECLARATION
|
||||
|
||||
#include "SkSLModifiers.h"
|
||||
#include "SkSLSymbol.h"
|
||||
#include "SkSLType.h"
|
||||
#include "SkSLVariable.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A function declaration (not a definition -- does not contain a body).
|
||||
*/
|
||||
struct FunctionDeclaration : public Symbol {
|
||||
FunctionDeclaration(Position position, std::string name,
|
||||
std::vector<std::shared_ptr<Variable>> parameters,
|
||||
std::shared_ptr<Type> returnType)
|
||||
: INHERITED(position, kFunctionDeclaration_Kind, std::move(name))
|
||||
, fDefined(false)
|
||||
, fParameters(parameters)
|
||||
, fReturnType(returnType) {}
|
||||
|
||||
std::string description() const override {
|
||||
std::string result = fReturnType->description() + " " + fName + "(";
|
||||
std::string separator = "";
|
||||
for (auto p : fParameters) {
|
||||
result += separator;
|
||||
separator = ", ";
|
||||
result += p->description();
|
||||
}
|
||||
result += ")";
|
||||
return result;
|
||||
}
|
||||
|
||||
bool matches(FunctionDeclaration& f) {
|
||||
return fName == f.fName && fParameters == f.fParameters;
|
||||
}
|
||||
|
||||
mutable bool fDefined;
|
||||
const std::vector<std::shared_ptr<Variable>> fParameters;
|
||||
const std::shared_ptr<Type> fReturnType;
|
||||
|
||||
typedef Symbol INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
39
src/sksl/ir/SkSLFunctionDefinition.h
Normal file
39
src/sksl/ir/SkSLFunctionDefinition.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_FUNCTIONDEFINITION
|
||||
#define SKSL_FUNCTIONDEFINITION
|
||||
|
||||
#include "SkSLBlock.h"
|
||||
#include "SkSLFunctionDeclaration.h"
|
||||
#include "SkSLProgramElement.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A function definition (a declaration plus an associated block of code).
|
||||
*/
|
||||
struct FunctionDefinition : public ProgramElement {
|
||||
FunctionDefinition(Position position, std::shared_ptr<FunctionDeclaration> declaration,
|
||||
std::unique_ptr<Block> body)
|
||||
: INHERITED(position, kFunction_Kind)
|
||||
, fDeclaration(std::move(declaration))
|
||||
, fBody(std::move(body)) {}
|
||||
|
||||
std::string description() const override {
|
||||
return fDeclaration->description() + " " + fBody->description();
|
||||
}
|
||||
|
||||
const std::shared_ptr<FunctionDeclaration> fDeclaration;
|
||||
const std::unique_ptr<Block> fBody;
|
||||
|
||||
typedef ProgramElement INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
36
src/sksl/ir/SkSLFunctionReference.h
Normal file
36
src/sksl/ir/SkSLFunctionReference.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_FUNCTIONREFERENCE
|
||||
#define SKSL_FUNCTIONREFERENCE
|
||||
|
||||
#include "SkSLExpression.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* An identifier referring to a function name. This is an intermediate value: FunctionReferences are
|
||||
* always eventually replaced by FunctionCalls in valid programs.
|
||||
*/
|
||||
struct FunctionReference : public Expression {
|
||||
FunctionReference(Position position, std::vector<std::shared_ptr<FunctionDeclaration>> function)
|
||||
: INHERITED(position, kFunctionReference_Kind, kInvalid_Type)
|
||||
, fFunctions(function) {}
|
||||
|
||||
virtual std::string description() const override {
|
||||
ASSERT(false);
|
||||
return "<function>";
|
||||
}
|
||||
|
||||
const std::vector<std::shared_ptr<FunctionDeclaration>> fFunctions;
|
||||
|
||||
typedef Expression INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
32
src/sksl/ir/SkSLIRNode.h
Normal file
32
src/sksl/ir/SkSLIRNode.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_IRNODE
|
||||
#define SKSL_IRNODE
|
||||
|
||||
#include "../SkSLPosition.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* Represents a node in the intermediate representation (IR) tree. The IR is a fully-resolved
|
||||
* version of the program (all types determined, everything validated), ready for code generation.
|
||||
*/
|
||||
struct IRNode {
|
||||
IRNode(Position position)
|
||||
: fPosition(position) {}
|
||||
|
||||
virtual ~IRNode() {}
|
||||
|
||||
virtual std::string description() const = 0;
|
||||
|
||||
const Position fPosition;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
44
src/sksl/ir/SkSLIfStatement.h
Normal file
44
src/sksl/ir/SkSLIfStatement.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_IFSTATEMENT
|
||||
#define SKSL_IFSTATEMENT
|
||||
|
||||
#include "SkSLExpression.h"
|
||||
#include "SkSLStatement.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* An 'if' statement.
|
||||
*/
|
||||
struct IfStatement : public Statement {
|
||||
IfStatement(Position position, std::unique_ptr<Expression> test,
|
||||
std::unique_ptr<Statement> ifTrue, std::unique_ptr<Statement> ifFalse)
|
||||
: INHERITED(position, kIf_Kind)
|
||||
, fTest(std::move(test))
|
||||
, fIfTrue(std::move(ifTrue))
|
||||
, fIfFalse(std::move(ifFalse)) {}
|
||||
|
||||
std::string description() const override {
|
||||
std::string result = "if (" + fTest->description() + ") " + fIfTrue->description();
|
||||
if (fIfFalse) {
|
||||
result += " else " + fIfFalse->description();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const std::unique_ptr<Expression> fTest;
|
||||
const std::unique_ptr<Statement> fIfTrue;
|
||||
const std::unique_ptr<Statement> fIfFalse;
|
||||
|
||||
typedef Statement INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
64
src/sksl/ir/SkSLIndexExpression.h
Normal file
64
src/sksl/ir/SkSLIndexExpression.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_INDEX
|
||||
#define SKSL_INDEX
|
||||
|
||||
#include "SkSLExpression.h"
|
||||
#include "SkSLUtil.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* Given a type, returns the type that will result from extracting an array value from it.
|
||||
*/
|
||||
static std::shared_ptr<Type> index_type(const Type& type) {
|
||||
if (type.kind() == Type::kMatrix_Kind) {
|
||||
if (type.componentType() == kFloat_Type) {
|
||||
switch (type.columns()) {
|
||||
case 2: return kVec2_Type;
|
||||
case 3: return kVec3_Type;
|
||||
case 4: return kVec4_Type;
|
||||
default: ASSERT(false);
|
||||
}
|
||||
} else {
|
||||
ASSERT(type.componentType() == kDouble_Type);
|
||||
switch (type.columns()) {
|
||||
case 2: return kDVec2_Type;
|
||||
case 3: return kDVec3_Type;
|
||||
case 4: return kDVec4_Type;
|
||||
default: ASSERT(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
return type.componentType();
|
||||
}
|
||||
|
||||
/**
|
||||
* An expression which extracts a value from an array or matrix, as in 'm[2]'.
|
||||
*/
|
||||
struct IndexExpression : public Expression {
|
||||
IndexExpression(std::unique_ptr<Expression> base, std::unique_ptr<Expression> index)
|
||||
: INHERITED(base->fPosition, kIndex_Kind, index_type(*base->fType))
|
||||
, fBase(std::move(base))
|
||||
, fIndex(std::move(index)) {
|
||||
ASSERT(fIndex->fType == kInt_Type);
|
||||
}
|
||||
|
||||
std::string description() const override {
|
||||
return fBase->description() + "[" + fIndex->description() + "]";
|
||||
}
|
||||
|
||||
const std::unique_ptr<Expression> fBase;
|
||||
const std::unique_ptr<Expression> fIndex;
|
||||
|
||||
typedef Expression INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
40
src/sksl/ir/SkSLIntLiteral.h
Normal file
40
src/sksl/ir/SkSLIntLiteral.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_INTLITERAL
|
||||
#define SKSL_INTLITERAL
|
||||
|
||||
#include "SkSLExpression.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A literal integer.
|
||||
*/
|
||||
struct IntLiteral : public Expression {
|
||||
// FIXME: we will need to revisit this if/when we add full support for both signed and unsigned
|
||||
// 64-bit integers, but for right now an int64_t will hold every value we care about
|
||||
IntLiteral(Position position, int64_t value)
|
||||
: INHERITED(position, kIntLiteral_Kind, kInt_Type)
|
||||
, fValue(value) {}
|
||||
|
||||
virtual std::string description() const override {
|
||||
return to_string(fValue);
|
||||
}
|
||||
|
||||
bool isConstant() const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
const int64_t fValue;
|
||||
|
||||
typedef Expression INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
49
src/sksl/ir/SkSLInterfaceBlock.h
Normal file
49
src/sksl/ir/SkSLInterfaceBlock.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_INTERFACEBLOCK
|
||||
#define SKSL_INTERFACEBLOCK
|
||||
|
||||
#include "SkSLProgramElement.h"
|
||||
#include "SkSLVarDeclaration.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* An interface block, as in:
|
||||
*
|
||||
* out gl_PerVertex {
|
||||
* layout(builtin=0) vec4 gl_Position;
|
||||
* layout(builtin=1) float gl_PointSize;
|
||||
* };
|
||||
*
|
||||
* At the IR level, this is represented by a single variable of struct type.
|
||||
*/
|
||||
struct InterfaceBlock : public ProgramElement {
|
||||
InterfaceBlock(Position position, std::shared_ptr<Variable> var)
|
||||
: INHERITED(position, kInterfaceBlock_Kind)
|
||||
, fVariable(std::move(var)) {
|
||||
ASSERT(fVariable->fType->kind() == Type::kStruct_Kind);
|
||||
}
|
||||
|
||||
std::string description() const override {
|
||||
std::string result = fVariable->fModifiers.description() + fVariable->fName + " {\n";
|
||||
for (size_t i = 0; i < fVariable->fType->fields().size(); i++) {
|
||||
result += fVariable->fType->fields()[i].description() + "\n";
|
||||
}
|
||||
result += "};";
|
||||
return result;
|
||||
}
|
||||
|
||||
const std::shared_ptr<Variable> fVariable;
|
||||
|
||||
typedef ProgramElement INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
83
src/sksl/ir/SkSLLayout.h
Normal file
83
src/sksl/ir/SkSLLayout.h
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_LAYOUT
|
||||
#define SKSL_LAYOUT
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* Represents a layout block appearing before a variable declaration, as in:
|
||||
*
|
||||
* layout (location = 0) int x;
|
||||
*/
|
||||
struct Layout {
|
||||
Layout(const ASTLayout& layout)
|
||||
: fLocation(layout.fLocation)
|
||||
, fBinding(layout.fBinding)
|
||||
, fIndex(layout.fIndex)
|
||||
, fSet(layout.fSet)
|
||||
, fBuiltin(layout.fBuiltin) {}
|
||||
|
||||
Layout(int location, int binding, int index, int set, int builtin)
|
||||
: fLocation(location)
|
||||
, fBinding(binding)
|
||||
, fIndex(index)
|
||||
, fSet(set)
|
||||
, fBuiltin(builtin) {}
|
||||
|
||||
std::string description() const {
|
||||
std::string result;
|
||||
std::string separator;
|
||||
if (fLocation >= 0) {
|
||||
result += separator + "location = " + to_string(fLocation);
|
||||
separator = ", ";
|
||||
}
|
||||
if (fBinding >= 0) {
|
||||
result += separator + "binding = " + to_string(fBinding);
|
||||
separator = ", ";
|
||||
}
|
||||
if (fIndex >= 0) {
|
||||
result += separator + "index = " + to_string(fIndex);
|
||||
separator = ", ";
|
||||
}
|
||||
if (fSet >= 0) {
|
||||
result += separator + "set = " + to_string(fSet);
|
||||
separator = ", ";
|
||||
}
|
||||
if (fBuiltin >= 0) {
|
||||
result += separator + "builtin = " + to_string(fBuiltin);
|
||||
separator = ", ";
|
||||
}
|
||||
if (result.length() > 0) {
|
||||
result = "layout (" + result + ")";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool operator==(const Layout& other) const {
|
||||
return fLocation == other.fLocation &&
|
||||
fBinding == other.fBinding &&
|
||||
fIndex == other.fIndex &&
|
||||
fSet == other.fSet &&
|
||||
fBuiltin == other.fBuiltin;
|
||||
}
|
||||
|
||||
bool operator!=(const Layout& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
const int fLocation;
|
||||
const int fBinding;
|
||||
const int fIndex;
|
||||
const int fSet;
|
||||
const int fBuiltin;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
82
src/sksl/ir/SkSLModifiers.h
Normal file
82
src/sksl/ir/SkSLModifiers.h
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_MODIFIERS
|
||||
#define SKSL_MODIFIERS
|
||||
|
||||
#include "../ast/SkSLASTModifiers.h"
|
||||
#include "SkSLLayout.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A set of modifier keywords (in, out, uniform, etc.) appearing before a declaration.
|
||||
*/
|
||||
struct Modifiers {
|
||||
enum Flag {
|
||||
kNo_Flag = ASTModifiers::kNo_Flag,
|
||||
kConst_Flag = ASTModifiers::kConst_Flag,
|
||||
kIn_Flag = ASTModifiers::kIn_Flag,
|
||||
kOut_Flag = ASTModifiers::kOut_Flag,
|
||||
kLowp_Flag = ASTModifiers::kLowp_Flag,
|
||||
kMediump_Flag = ASTModifiers::kMediump_Flag,
|
||||
kHighp_Flag = ASTModifiers::kHighp_Flag,
|
||||
kUniform_Flag = ASTModifiers::kUniform_Flag
|
||||
};
|
||||
|
||||
Modifiers(const ASTModifiers& modifiers)
|
||||
: fLayout(modifiers.fLayout)
|
||||
, fFlags(modifiers.fFlags) {}
|
||||
|
||||
Modifiers(Layout& layout, int flags)
|
||||
: fLayout(layout)
|
||||
, fFlags(flags) {}
|
||||
|
||||
std::string description() const {
|
||||
std::string result = fLayout.description();
|
||||
if (fFlags & kUniform_Flag) {
|
||||
result += "uniform ";
|
||||
}
|
||||
if (fFlags & kConst_Flag) {
|
||||
result += "const ";
|
||||
}
|
||||
if (fFlags & kLowp_Flag) {
|
||||
result += "lowp ";
|
||||
}
|
||||
if (fFlags & kMediump_Flag) {
|
||||
result += "mediump ";
|
||||
}
|
||||
if (fFlags & kHighp_Flag) {
|
||||
result += "highp ";
|
||||
}
|
||||
|
||||
if ((fFlags & kIn_Flag) && (fFlags & kOut_Flag)) {
|
||||
result += "inout ";
|
||||
} else if (fFlags & kIn_Flag) {
|
||||
result += "in ";
|
||||
} else if (fFlags & kOut_Flag) {
|
||||
result += "out ";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool operator==(const Modifiers& other) const {
|
||||
return fLayout == other.fLayout && fFlags == other.fFlags;
|
||||
}
|
||||
|
||||
bool operator!=(const Modifiers& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
const Layout fLayout;
|
||||
const int fFlags;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
36
src/sksl/ir/SkSLPostfixExpression.h
Normal file
36
src/sksl/ir/SkSLPostfixExpression.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_POSTFIXEXPRESSION
|
||||
#define SKSL_POSTFIXEXPRESSION
|
||||
|
||||
#include "SkSLExpression.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* An expression modified by a unary operator appearing after it, such as 'i++'.
|
||||
*/
|
||||
struct PostfixExpression : public Expression {
|
||||
PostfixExpression(std::unique_ptr<Expression> operand, Token::Kind op)
|
||||
: INHERITED(operand->fPosition, kPostfix_Kind, operand->fType)
|
||||
, fOperand(std::move(operand))
|
||||
, fOperator(op) {}
|
||||
|
||||
virtual std::string description() const override {
|
||||
return fOperand->description() + Token::OperatorName(fOperator);
|
||||
}
|
||||
|
||||
const std::unique_ptr<Expression> fOperand;
|
||||
const Token::Kind fOperator;
|
||||
|
||||
typedef Expression INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
36
src/sksl/ir/SkSLPrefixExpression.h
Normal file
36
src/sksl/ir/SkSLPrefixExpression.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_PREFIXEXPRESSION
|
||||
#define SKSL_PREFIXEXPRESSION
|
||||
|
||||
#include "SkSLExpression.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* An expression modified by a unary operator appearing before it, such as '!flag'.
|
||||
*/
|
||||
struct PrefixExpression : public Expression {
|
||||
PrefixExpression(Token::Kind op, std::unique_ptr<Expression> operand)
|
||||
: INHERITED(operand->fPosition, kPrefix_Kind, operand->fType)
|
||||
, fOperand(std::move(operand))
|
||||
, fOperator(op) {}
|
||||
|
||||
virtual std::string description() const override {
|
||||
return Token::OperatorName(fOperator) + fOperand->description();
|
||||
}
|
||||
|
||||
const std::unique_ptr<Expression> fOperand;
|
||||
const Token::Kind fOperator;
|
||||
|
||||
typedef Expression INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
38
src/sksl/ir/SkSLProgram.h
Normal file
38
src/sksl/ir/SkSLProgram.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_PROGRAM
|
||||
#define SKSL_PROGRAM
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include "SkSLProgramElement.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* Represents a fully-digested program, ready for code generation.
|
||||
*/
|
||||
struct Program {
|
||||
enum Kind {
|
||||
kFragment_Kind,
|
||||
kVertex_Kind
|
||||
};
|
||||
|
||||
Program(Kind kind, std::vector<std::unique_ptr<ProgramElement>> elements)
|
||||
: fKind(kind)
|
||||
, fElements(std::move(elements)) {}
|
||||
|
||||
Kind fKind;
|
||||
|
||||
std::vector<std::unique_ptr<ProgramElement>> fElements;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
37
src/sksl/ir/SkSLProgramElement.h
Normal file
37
src/sksl/ir/SkSLProgramElement.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_PROGRAMELEMENT
|
||||
#define SKSL_PROGRAMELEMENT
|
||||
|
||||
#include "SkSLIRNode.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* Represents a top-level element (e.g. function or global variable) in a program.
|
||||
*/
|
||||
struct ProgramElement : public IRNode {
|
||||
enum Kind {
|
||||
kVar_Kind,
|
||||
kFunction_Kind,
|
||||
kInterfaceBlock_Kind,
|
||||
kExtension_Kind
|
||||
};
|
||||
|
||||
ProgramElement(Position position, Kind kind)
|
||||
: INHERITED(position)
|
||||
, fKind(kind) {}
|
||||
|
||||
Kind fKind;
|
||||
|
||||
typedef IRNode INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
42
src/sksl/ir/SkSLReturnStatement.h
Normal file
42
src/sksl/ir/SkSLReturnStatement.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_RETURNSTATEMENT
|
||||
#define SKSL_RETURNSTATEMENT
|
||||
|
||||
#include "SkSLExpression.h"
|
||||
#include "SkSLStatement.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A 'return' statement.
|
||||
*/
|
||||
struct ReturnStatement : public Statement {
|
||||
ReturnStatement(Position position)
|
||||
: INHERITED(position, kReturn_Kind) {}
|
||||
|
||||
ReturnStatement(std::unique_ptr<Expression> expression)
|
||||
: INHERITED(expression->fPosition, kReturn_Kind)
|
||||
, fExpression(std::move(expression)) {}
|
||||
|
||||
std::string description() const override {
|
||||
if (fExpression) {
|
||||
return "return " + fExpression->description() + ";";
|
||||
} else {
|
||||
return "return;";
|
||||
}
|
||||
}
|
||||
|
||||
const std::unique_ptr<Expression> fExpression;
|
||||
|
||||
typedef Statement INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
45
src/sksl/ir/SkSLStatement.h
Normal file
45
src/sksl/ir/SkSLStatement.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_STATEMENT
|
||||
#define SKSL_STATEMENT
|
||||
|
||||
#include "SkSLIRNode.h"
|
||||
#include "SkSLType.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* Abstract supertype of all statements.
|
||||
*/
|
||||
struct Statement : public IRNode {
|
||||
enum Kind {
|
||||
kBlock_Kind,
|
||||
kBreak_Kind,
|
||||
kContinue_Kind,
|
||||
kDiscard_Kind,
|
||||
kDo_Kind,
|
||||
kExpression_Kind,
|
||||
kFor_Kind,
|
||||
kIf_Kind,
|
||||
kReturn_Kind,
|
||||
kVarDeclaration_Kind,
|
||||
kWhile_Kind
|
||||
};
|
||||
|
||||
Statement(Position position, Kind kind)
|
||||
: INHERITED(position)
|
||||
, fKind(kind) {}
|
||||
|
||||
const Kind fKind;
|
||||
|
||||
typedef IRNode INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
88
src/sksl/ir/SkSLSwizzle.h
Normal file
88
src/sksl/ir/SkSLSwizzle.h
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_SWIZZLE
|
||||
#define SKSL_SWIZZLE
|
||||
|
||||
#include "SkSLExpression.h"
|
||||
#include "SkSLUtil.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* Given a type and a swizzle component count, returns the type that will result from swizzling. For
|
||||
* instance, swizzling a vec3 with two components will result in a vec2. It is possible to swizzle
|
||||
* with more components than the source vector, as in 'vec2(1).xxxx'.
|
||||
*/
|
||||
static std::shared_ptr<Type> get_type(Expression& value,
|
||||
size_t count) {
|
||||
std::shared_ptr<Type> base = value.fType->componentType();
|
||||
if (count == 1) {
|
||||
return base;
|
||||
}
|
||||
if (base == kFloat_Type) {
|
||||
switch (count) {
|
||||
case 2: return kVec2_Type;
|
||||
case 3: return kVec3_Type;
|
||||
case 4: return kVec4_Type;
|
||||
}
|
||||
} else if (base == kDouble_Type) {
|
||||
switch (count) {
|
||||
case 2: return kDVec2_Type;
|
||||
case 3: return kDVec3_Type;
|
||||
case 4: return kDVec4_Type;
|
||||
}
|
||||
} else if (base == kInt_Type) {
|
||||
switch (count) {
|
||||
case 2: return kIVec2_Type;
|
||||
case 3: return kIVec3_Type;
|
||||
case 4: return kIVec4_Type;
|
||||
}
|
||||
} else if (base == kUInt_Type) {
|
||||
switch (count) {
|
||||
case 2: return kUVec2_Type;
|
||||
case 3: return kUVec3_Type;
|
||||
case 4: return kUVec4_Type;
|
||||
}
|
||||
} else if (base == kBool_Type) {
|
||||
switch (count) {
|
||||
case 2: return kBVec2_Type;
|
||||
case 3: return kBVec3_Type;
|
||||
case 4: return kBVec4_Type;
|
||||
}
|
||||
}
|
||||
ABORT("cannot swizzle %s\n", value.description().c_str());
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a vector swizzle operation such as 'vec2(1, 2, 3).zyx'.
|
||||
*/
|
||||
struct Swizzle : public Expression {
|
||||
Swizzle(std::unique_ptr<Expression> base, std::vector<int> components)
|
||||
: INHERITED(base->fPosition, kSwizzle_Kind, get_type(*base, components.size()))
|
||||
, fBase(std::move(base))
|
||||
, fComponents(std::move(components)) {
|
||||
ASSERT(fComponents.size() >= 1 && fComponents.size() <= 4);
|
||||
}
|
||||
|
||||
std::string description() const override {
|
||||
std::string result = fBase->description() + ".";
|
||||
for (int x : fComponents) {
|
||||
result += "xyzw"[x];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const std::unique_ptr<Expression> fBase;
|
||||
const std::vector<int> fComponents;
|
||||
|
||||
typedef Expression INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
40
src/sksl/ir/SkSLSymbol.h
Normal file
40
src/sksl/ir/SkSLSymbol.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_SYMBOL
|
||||
#define SKSL_SYMBOL
|
||||
|
||||
#include "SkSLIRNode.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* Represents a symboltable entry.
|
||||
*/
|
||||
struct Symbol : public IRNode {
|
||||
enum Kind {
|
||||
kFunctionDeclaration_Kind,
|
||||
kUnresolvedFunction_Kind,
|
||||
kType_Kind,
|
||||
kVariable_Kind,
|
||||
kField_Kind
|
||||
};
|
||||
|
||||
Symbol(Position position, Kind kind, std::string name)
|
||||
: INHERITED(position)
|
||||
, fKind(kind)
|
||||
, fName(std::move(name)) {}
|
||||
|
||||
const Kind fKind;
|
||||
const std::string fName;
|
||||
|
||||
typedef IRNode INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
85
src/sksl/ir/SkSLSymbolTable.cpp
Normal file
85
src/sksl/ir/SkSLSymbolTable.cpp
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "SkSLSymbolTable.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
std::vector<std::shared_ptr<FunctionDeclaration>> SymbolTable::GetFunctions(
|
||||
const std::shared_ptr<Symbol>& s) {
|
||||
switch (s->fKind) {
|
||||
case Symbol::kFunctionDeclaration_Kind:
|
||||
return { std::static_pointer_cast<FunctionDeclaration>(s) };
|
||||
case Symbol::kUnresolvedFunction_Kind:
|
||||
return ((UnresolvedFunction&) *s).fFunctions;
|
||||
default:
|
||||
return { };
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<Symbol> SymbolTable::operator[](const std::string& name) {
|
||||
const auto& entry = fSymbols.find(name);
|
||||
if (entry == fSymbols.end()) {
|
||||
if (fParent) {
|
||||
return (*fParent)[name];
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
if (fParent) {
|
||||
auto functions = GetFunctions(entry->second);
|
||||
if (functions.size() > 0) {
|
||||
bool modified = false;
|
||||
std::shared_ptr<Symbol> previous = (*fParent)[name];
|
||||
if (previous) {
|
||||
auto previousFunctions = GetFunctions(previous);
|
||||
for (const std::shared_ptr<FunctionDeclaration>& prev : previousFunctions) {
|
||||
bool found = false;
|
||||
for (const std::shared_ptr<FunctionDeclaration>& current : functions) {
|
||||
if (current->matches(*prev)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
functions.push_back(prev);
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
if (modified) {
|
||||
ASSERT(functions.size() > 1);
|
||||
return std::shared_ptr<Symbol>(new UnresolvedFunction(functions));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return entry->second;
|
||||
}
|
||||
|
||||
void SymbolTable::add(const std::string& name, std::shared_ptr<Symbol> symbol) {
|
||||
const auto& existing = fSymbols.find(name);
|
||||
if (existing == fSymbols.end()) {
|
||||
fSymbols[name] = symbol;
|
||||
} else if (symbol->fKind == Symbol::kFunctionDeclaration_Kind) {
|
||||
const std::shared_ptr<Symbol>& oldSymbol = existing->second;
|
||||
if (oldSymbol->fKind == Symbol::kFunctionDeclaration_Kind) {
|
||||
std::vector<std::shared_ptr<FunctionDeclaration>> functions;
|
||||
functions.push_back(std::static_pointer_cast<FunctionDeclaration>(oldSymbol));
|
||||
functions.push_back(std::static_pointer_cast<FunctionDeclaration>(symbol));
|
||||
fSymbols[name].reset(new UnresolvedFunction(std::move(functions)));
|
||||
} else if (oldSymbol->fKind == Symbol::kUnresolvedFunction_Kind) {
|
||||
std::vector<std::shared_ptr<FunctionDeclaration>> functions;
|
||||
for (const auto& f : ((UnresolvedFunction&) *oldSymbol).fFunctions) {
|
||||
functions.push_back(f);
|
||||
}
|
||||
functions.push_back(std::static_pointer_cast<FunctionDeclaration>(symbol));
|
||||
fSymbols[name].reset(new UnresolvedFunction(std::move(functions)));
|
||||
}
|
||||
} else {
|
||||
fErrorReporter.error(symbol->fPosition, "symbol '" + name + "' was already defined");
|
||||
}
|
||||
}
|
||||
} // namespace
|
49
src/sksl/ir/SkSLSymbolTable.h
Normal file
49
src/sksl/ir/SkSLSymbolTable.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_SYMBOLTABLE
|
||||
#define SKSL_SYMBOLTABLE
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include "SkSLErrorReporter.h"
|
||||
#include "SkSLSymbol.h"
|
||||
#include "SkSLUnresolvedFunction.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* Maps identifiers to symbols. Functions, in particular, are mapped to either FunctionDeclaration
|
||||
* or UnresolvedFunction depending on whether they are overloaded or not.
|
||||
*/
|
||||
class SymbolTable {
|
||||
public:
|
||||
SymbolTable(ErrorReporter& errorReporter)
|
||||
: fErrorReporter(errorReporter) {}
|
||||
|
||||
SymbolTable(std::shared_ptr<SymbolTable> parent, ErrorReporter& errorReporter)
|
||||
: fParent(parent)
|
||||
, fErrorReporter(errorReporter) {}
|
||||
|
||||
std::shared_ptr<Symbol> operator[](const std::string& name);
|
||||
|
||||
void add(const std::string& name, std::shared_ptr<Symbol> symbol);
|
||||
|
||||
const std::shared_ptr<SymbolTable> fParent;
|
||||
|
||||
private:
|
||||
static std::vector<std::shared_ptr<FunctionDeclaration>> GetFunctions(
|
||||
const std::shared_ptr<Symbol>& s);
|
||||
|
||||
std::unordered_map<std::string, std::shared_ptr<Symbol>> fSymbols;
|
||||
|
||||
ErrorReporter& fErrorReporter;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
43
src/sksl/ir/SkSLTernaryExpression.h
Normal file
43
src/sksl/ir/SkSLTernaryExpression.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKSL_TERNARYEXPRESSION
|
||||
#define SKSL_TERNARYEXPRESSION
|
||||
|
||||
#include "SkSLExpression.h"
|
||||
#include "../SkSLPosition.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* A ternary expression (test ? ifTrue : ifFalse).
|
||||
*/
|
||||
struct TernaryExpression : public Expression {
|
||||
TernaryExpression(Position position, std::unique_ptr<Expression> test,
|
||||
std::unique_ptr<Expression> ifTrue, std::unique_ptr<Expression> ifFalse)
|
||||
: INHERITED(position, kTernary_Kind, ifTrue->fType)
|
||||
, fTest(std::move(test))
|
||||
, fIfTrue(std::move(ifTrue))
|
||||
, fIfFalse(std::move(ifFalse)) {
|
||||
ASSERT(fIfTrue->fType == fIfFalse->fType);
|
||||
}
|
||||
|
||||
std::string description() const override {
|
||||
return "(" + fTest->description() + " ? " + fIfTrue->description() + " : " +
|
||||
fIfFalse->description() + ")";
|
||||
}
|
||||
|
||||
const std::unique_ptr<Expression> fTest;
|
||||
const std::unique_ptr<Expression> fIfTrue;
|
||||
const std::unique_ptr<Expression> fIfFalse;
|
||||
|
||||
typedef Expression INHERITED;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
258
src/sksl/ir/SkSLType.cpp
Normal file
258
src/sksl/ir/SkSLType.cpp
Normal file
@ -0,0 +1,258 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "SkSLType.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
bool Type::determineCoercionCost(std::shared_ptr<Type> other, int* outCost) const {
|
||||
if (this == other.get()) {
|
||||
*outCost = 0;
|
||||
return true;
|
||||
}
|
||||
if (this->kind() == kVector_Kind && other->kind() == kVector_Kind) {
|
||||
if (this->columns() == other->columns()) {
|
||||
return this->componentType()->determineCoercionCost(other->componentType(), outCost);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (this->kind() == kMatrix_Kind) {
|
||||
if (this->columns() == other->columns() &&
|
||||
this->rows() == other->rows()) {
|
||||
return this->componentType()->determineCoercionCost(other->componentType(), outCost);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
for (size_t i = 0; i < fCoercibleTypes.size(); i++) {
|
||||
if (fCoercibleTypes[i] == other) {
|
||||
*outCost = (int) i + 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::shared_ptr<Type> Type::toCompound(int columns, int rows) {
|
||||
ASSERT(this->kind() == Type::kScalar_Kind);
|
||||
if (columns == 1 && rows == 1) {
|
||||
return std::shared_ptr<Type>(this);
|
||||
}
|
||||
if (*this == *kFloat_Type) {
|
||||
switch (rows) {
|
||||
case 1:
|
||||
switch (columns) {
|
||||
case 2: return kVec2_Type;
|
||||
case 3: return kVec3_Type;
|
||||
case 4: return kVec4_Type;
|
||||
default: ABORT("unsupported vector column count (%d)", columns);
|
||||
}
|
||||
case 2:
|
||||
switch (columns) {
|
||||
case 2: return kMat2x2_Type;
|
||||
case 3: return kMat3x2_Type;
|
||||
case 4: return kMat4x2_Type;
|
||||
default: ABORT("unsupported matrix column count (%d)", columns);
|
||||
}
|
||||
case 3:
|
||||
switch (columns) {
|
||||
case 2: return kMat2x3_Type;
|
||||
case 3: return kMat3x3_Type;
|
||||
case 4: return kMat4x3_Type;
|
||||
default: ABORT("unsupported matrix column count (%d)", columns);
|
||||
}
|
||||
case 4:
|
||||
switch (columns) {
|
||||
case 2: return kMat2x4_Type;
|
||||
case 3: return kMat3x4_Type;
|
||||
case 4: return kMat4x4_Type;
|
||||
default: ABORT("unsupported matrix column count (%d)", columns);
|
||||
}
|
||||
default: ABORT("unsupported row count (%d)", rows);
|
||||
}
|
||||
} else if (*this == *kDouble_Type) {
|
||||
switch (rows) {
|
||||
case 1:
|
||||
switch (columns) {
|
||||
case 2: return kDVec2_Type;
|
||||
case 3: return kDVec3_Type;
|
||||
case 4: return kDVec4_Type;
|
||||
default: ABORT("unsupported vector column count (%d)", columns);
|
||||
}
|
||||
case 2:
|
||||
switch (columns) {
|
||||
case 2: return kDMat2x2_Type;
|
||||
case 3: return kDMat3x2_Type;
|
||||
case 4: return kDMat4x2_Type;
|
||||
default: ABORT("unsupported matrix column count (%d)", columns);
|
||||
}
|
||||
case 3:
|
||||
switch (columns) {
|
||||
case 2: return kDMat2x3_Type;
|
||||
case 3: return kDMat3x3_Type;
|
||||
case 4: return kDMat4x3_Type;
|
||||
default: ABORT("unsupported matrix column count (%d)", columns);
|
||||
}
|
||||
case 4:
|
||||
switch (columns) {
|
||||
case 2: return kDMat2x4_Type;
|
||||
case 3: return kDMat3x4_Type;
|
||||
case 4: return kDMat4x4_Type;
|
||||
default: ABORT("unsupported matrix column count (%d)", columns);
|
||||
}
|
||||
default: ABORT("unsupported row count (%d)", rows);
|
||||
}
|
||||
} else if (*this == *kInt_Type) {
|
||||
switch (rows) {
|
||||
case 1:
|
||||
switch (columns) {
|
||||
case 2: return kIVec2_Type;
|
||||
case 3: return kIVec3_Type;
|
||||
case 4: return kIVec4_Type;
|
||||
default: ABORT("unsupported vector column count (%d)", columns);
|
||||
}
|
||||
default: ABORT("unsupported row count (%d)", rows);
|
||||
}
|
||||
} else if (*this == *kUInt_Type) {
|
||||
switch (rows) {
|
||||
case 1:
|
||||
switch (columns) {
|
||||
case 2: return kUVec2_Type;
|
||||
case 3: return kUVec3_Type;
|
||||
case 4: return kUVec4_Type;
|
||||
default: ABORT("unsupported vector column count (%d)", columns);
|
||||
}
|
||||
default: ABORT("unsupported row count (%d)", rows);
|
||||
}
|
||||
}
|
||||
ABORT("unsupported scalar_to_compound type %s", this->description().c_str());
|
||||
}
|
||||
|
||||
const std::shared_ptr<Type> kVoid_Type(new Type("void"));
|
||||
|
||||
const std::shared_ptr<Type> kDouble_Type(new Type("double", true));
|
||||
const std::shared_ptr<Type> kDVec2_Type(new Type("dvec2", kDouble_Type, 2));
|
||||
const std::shared_ptr<Type> kDVec3_Type(new Type("dvec3", kDouble_Type, 3));
|
||||
const std::shared_ptr<Type> kDVec4_Type(new Type("dvec4", kDouble_Type, 4));
|
||||
|
||||
const std::shared_ptr<Type> kFloat_Type(new Type("float", true, { kDouble_Type }));
|
||||
const std::shared_ptr<Type> kVec2_Type(new Type("vec2", kFloat_Type, 2));
|
||||
const std::shared_ptr<Type> kVec3_Type(new Type("vec3", kFloat_Type, 3));
|
||||
const std::shared_ptr<Type> kVec4_Type(new Type("vec4", kFloat_Type, 4));
|
||||
|
||||
const std::shared_ptr<Type> kUInt_Type(new Type("uint", true, { kFloat_Type, kDouble_Type }));
|
||||
const std::shared_ptr<Type> kUVec2_Type(new Type("uvec2", kUInt_Type, 2));
|
||||
const std::shared_ptr<Type> kUVec3_Type(new Type("uvec3", kUInt_Type, 3));
|
||||
const std::shared_ptr<Type> kUVec4_Type(new Type("uvec4", kUInt_Type, 4));
|
||||
|
||||
const std::shared_ptr<Type> kInt_Type(new Type("int", true, { kUInt_Type, kFloat_Type,
|
||||
kDouble_Type }));
|
||||
const std::shared_ptr<Type> kIVec2_Type(new Type("ivec2", kInt_Type, 2));
|
||||
const std::shared_ptr<Type> kIVec3_Type(new Type("ivec3", kInt_Type, 3));
|
||||
const std::shared_ptr<Type> kIVec4_Type(new Type("ivec4", kInt_Type, 4));
|
||||
|
||||
const std::shared_ptr<Type> kBool_Type(new Type("bool", false));
|
||||
const std::shared_ptr<Type> kBVec2_Type(new Type("bvec2", kBool_Type, 2));
|
||||
const std::shared_ptr<Type> kBVec3_Type(new Type("bvec3", kBool_Type, 3));
|
||||
const std::shared_ptr<Type> kBVec4_Type(new Type("bvec4", kBool_Type, 4));
|
||||
|
||||
const std::shared_ptr<Type> kMat2x2_Type(new Type("mat2", kFloat_Type, 2, 2));
|
||||
const std::shared_ptr<Type> kMat2x3_Type(new Type("mat2x3", kFloat_Type, 2, 3));
|
||||
const std::shared_ptr<Type> kMat2x4_Type(new Type("mat2x4", kFloat_Type, 2, 4));
|
||||
const std::shared_ptr<Type> kMat3x2_Type(new Type("mat3x2", kFloat_Type, 3, 2));
|
||||
const std::shared_ptr<Type> kMat3x3_Type(new Type("mat3", kFloat_Type, 3, 3));
|
||||
const std::shared_ptr<Type> kMat3x4_Type(new Type("mat3x4", kFloat_Type, 3, 4));
|
||||
const std::shared_ptr<Type> kMat4x2_Type(new Type("mat4x2", kFloat_Type, 4, 2));
|
||||
const std::shared_ptr<Type> kMat4x3_Type(new Type("mat4x3", kFloat_Type, 4, 3));
|
||||
const std::shared_ptr<Type> kMat4x4_Type(new Type("mat4", kFloat_Type, 4, 4));
|
||||
|
||||
const std::shared_ptr<Type> kDMat2x2_Type(new Type("dmat2", kFloat_Type, 2, 2));
|
||||
const std::shared_ptr<Type> kDMat2x3_Type(new Type("dmat2x3", kFloat_Type, 2, 3));
|
||||
const std::shared_ptr<Type> kDMat2x4_Type(new Type("dmat2x4", kFloat_Type, 2, 4));
|
||||
const std::shared_ptr<Type> kDMat3x2_Type(new Type("dmat3x2", kFloat_Type, 3, 2));
|
||||
const std::shared_ptr<Type> kDMat3x3_Type(new Type("dmat3", kFloat_Type, 3, 3));
|
||||
const std::shared_ptr<Type> kDMat3x4_Type(new Type("dmat3x4", kFloat_Type, 3, 4));
|
||||
const std::shared_ptr<Type> kDMat4x2_Type(new Type("dmat4x2", kFloat_Type, 4, 2));
|
||||
const std::shared_ptr<Type> kDMat4x3_Type(new Type("dmat4x3", kFloat_Type, 4, 3));
|
||||
const std::shared_ptr<Type> kDMat4x4_Type(new Type("dmat4", kFloat_Type, 4, 4));
|
||||
|
||||
const std::shared_ptr<Type> kSampler1D_Type(new Type("sampler1D", SpvDim1D, false, false, false, true));
|
||||
const std::shared_ptr<Type> kSampler2D_Type(new Type("sampler2D", SpvDim2D, false, false, false, true));
|
||||
const std::shared_ptr<Type> kSampler3D_Type(new Type("sampler3D", SpvDim3D, false, false, false, true));
|
||||
const std::shared_ptr<Type> kSamplerCube_Type(new Type("samplerCube"));
|
||||
const std::shared_ptr<Type> kSampler2DRect_Type(new Type("sampler2DRect"));
|
||||
const std::shared_ptr<Type> kSampler1DArray_Type(new Type("sampler1DArray"));
|
||||
const std::shared_ptr<Type> kSampler2DArray_Type(new Type("sampler2DArray"));
|
||||
const std::shared_ptr<Type> kSamplerCubeArray_Type(new Type("samplerCubeArray"));
|
||||
const std::shared_ptr<Type> kSamplerBuffer_Type(new Type("samplerBuffer"));
|
||||
const std::shared_ptr<Type> kSampler2DMS_Type(new Type("sampler2DMS"));
|
||||
const std::shared_ptr<Type> kSampler2DMSArray_Type(new Type("sampler2DMSArray"));
|
||||
const std::shared_ptr<Type> kSampler1DShadow_Type(new Type("sampler1DShadow"));
|
||||
const std::shared_ptr<Type> kSampler2DShadow_Type(new Type("sampler2DShadow"));
|
||||
const std::shared_ptr<Type> kSamplerCubeShadow_Type(new Type("samplerCubeShadow"));
|
||||
const std::shared_ptr<Type> kSampler2DRectShadow_Type(new Type("sampler2DRectShadow"));
|
||||
const std::shared_ptr<Type> kSampler1DArrayShadow_Type(new Type("sampler1DArrayShadow"));
|
||||
const std::shared_ptr<Type> kSampler2DArrayShadow_Type(new Type("sampler2DArrayShadow"));
|
||||
const std::shared_ptr<Type> kSamplerCubeArrayShadow_Type(new Type("samplerCubeArrayShadow"));
|
||||
|
||||
static std::vector<std::shared_ptr<Type>> type(std::shared_ptr<Type> t) {
|
||||
return { t, t, t, t };
|
||||
}
|
||||
|
||||
// FIXME figure out what we're supposed to do with the gsampler et al. types
|
||||
const std::shared_ptr<Type> kGSampler1D_Type(new Type("$gsampler1D", type(kSampler1D_Type)));
|
||||
const std::shared_ptr<Type> kGSampler2D_Type(new Type("$gsampler2D", type(kSampler2D_Type)));
|
||||
const std::shared_ptr<Type> kGSampler3D_Type(new Type("$gsampler3D", type(kSampler3D_Type)));
|
||||
const std::shared_ptr<Type> kGSamplerCube_Type(new Type("$gsamplerCube", type(kSamplerCube_Type)));
|
||||
const std::shared_ptr<Type> kGSampler2DRect_Type(new Type("$gsampler2DRect",
|
||||
type(kSampler2DRect_Type)));
|
||||
const std::shared_ptr<Type> kGSampler1DArray_Type(new Type("$gsampler1DArray",
|
||||
type(kSampler1DArray_Type)));
|
||||
const std::shared_ptr<Type> kGSampler2DArray_Type(new Type("$gsampler2DArray",
|
||||
type(kSampler2DArray_Type)));
|
||||
const std::shared_ptr<Type> kGSamplerCubeArray_Type(new Type("$gsamplerCubeArray",
|
||||
type(kSamplerCubeArray_Type)));
|
||||
const std::shared_ptr<Type> kGSamplerBuffer_Type(new Type("$gsamplerBuffer",
|
||||
type(kSamplerBuffer_Type)));
|
||||
const std::shared_ptr<Type> kGSampler2DMS_Type(new Type("$gsampler2DMS",
|
||||
type(kSampler2DMS_Type)));
|
||||
const std::shared_ptr<Type> kGSampler2DMSArray_Type(new Type("$gsampler2DMSArray",
|
||||
type(kSampler2DMSArray_Type)));
|
||||
const std::shared_ptr<Type> kGSampler2DArrayShadow_Type(new Type("$gsampler2DArrayShadow",
|
||||
type(kSampler2DArrayShadow_Type)));
|
||||
const std::shared_ptr<Type> kGSamplerCubeArrayShadow_Type(new Type("$gsamplerCubeArrayShadow",
|
||||
type(kSamplerCubeArrayShadow_Type)));
|
||||
|
||||
const std::shared_ptr<Type> kGenType_Type(new Type("$genType", { kFloat_Type, kVec2_Type,
|
||||
kVec3_Type, kVec4_Type }));
|
||||
const std::shared_ptr<Type> kGenDType_Type(new Type("$genDType", { kDouble_Type, kDVec2_Type,
|
||||
kDVec3_Type, kDVec4_Type }));
|
||||
const std::shared_ptr<Type> kGenIType_Type(new Type("$genIType", { kInt_Type, kIVec2_Type,
|
||||
kIVec3_Type, kIVec4_Type }));
|
||||
const std::shared_ptr<Type> kGenUType_Type(new Type("$genUType", { kUInt_Type, kUVec2_Type,
|
||||
kUVec3_Type, kUVec4_Type }));
|
||||
const std::shared_ptr<Type> kGenBType_Type(new Type("$genBType", { kBool_Type, kBVec2_Type,
|
||||
kBVec3_Type, kBVec4_Type }));
|
||||
|
||||
const std::shared_ptr<Type> kMat_Type(new Type("$mat"));
|
||||
|
||||
const std::shared_ptr<Type> kVec_Type(new Type("$vec", { kVec2_Type, kVec2_Type, kVec3_Type,
|
||||
kVec4_Type }));
|
||||
|
||||
const std::shared_ptr<Type> kGVec_Type(new Type("$gvec"));
|
||||
const std::shared_ptr<Type> kGVec2_Type(new Type("$gvec2"));
|
||||
const std::shared_ptr<Type> kGVec3_Type(new Type("$gvec3"));
|
||||
const std::shared_ptr<Type> kGVec4_Type(new Type("$gvec4", type(kVec4_Type)));
|
||||
const std::shared_ptr<Type> kDVec_Type(new Type("$dvec"));
|
||||
const std::shared_ptr<Type> kIVec_Type(new Type("$ivec"));
|
||||
const std::shared_ptr<Type> kUVec_Type(new Type("$uvec"));
|
||||
|
||||
const std::shared_ptr<Type> kBVec_Type(new Type("$bvec", { kBVec2_Type, kBVec2_Type,
|
||||
kBVec3_Type, kBVec4_Type }));
|
||||
|
||||
const std::shared_ptr<Type> kInvalid_Type(new Type("<INVALID>"));
|
||||
|
||||
} // namespace
|
438
src/sksl/ir/SkSLType.h
Normal file
438
src/sksl/ir/SkSLType.h
Normal file
@ -0,0 +1,438 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKIASL_TYPE
|
||||
#define SKIASL_TYPE
|
||||
|
||||
#include "SkSLModifiers.h"
|
||||
#include "SkSLSymbol.h"
|
||||
#include "../SkSLPosition.h"
|
||||
#include "../SkSLUtil.h"
|
||||
#include "../spirv.h"
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* Represents a type, such as int or vec4.
|
||||
*/
|
||||
class Type : public Symbol {
|
||||
public:
|
||||
struct Field {
|
||||
Field(Modifiers modifiers, std::string name, std::shared_ptr<Type> type)
|
||||
: fModifiers(modifiers)
|
||||
, fName(std::move(name))
|
||||
, fType(std::move(type)) {}
|
||||
|
||||
const std::string description() {
|
||||
return fType->description() + " " + fName + ";";
|
||||
}
|
||||
|
||||
const Modifiers fModifiers;
|
||||
const std::string fName;
|
||||
const std::shared_ptr<Type> fType;
|
||||
};
|
||||
|
||||
enum Kind {
|
||||
kScalar_Kind,
|
||||
kVector_Kind,
|
||||
kMatrix_Kind,
|
||||
kArray_Kind,
|
||||
kStruct_Kind,
|
||||
kGeneric_Kind,
|
||||
kSampler_Kind,
|
||||
kOther_Kind
|
||||
};
|
||||
|
||||
// Create an "other" (special) type with the given name. These types cannot be directly
|
||||
// referenced from user code.
|
||||
Type(std::string name)
|
||||
: INHERITED(Position(), kType_Kind, std::move(name))
|
||||
, fTypeKind(kOther_Kind) {}
|
||||
|
||||
// Create a generic type which maps to the listed types.
|
||||
Type(std::string name, std::vector<std::shared_ptr<Type>> types)
|
||||
: INHERITED(Position(), kType_Kind, std::move(name))
|
||||
, fTypeKind(kGeneric_Kind)
|
||||
, fCoercibleTypes(std::move(types)) {
|
||||
ASSERT(fCoercibleTypes.size() == 4);
|
||||
}
|
||||
|
||||
// Create a struct type with the given fields.
|
||||
Type(std::string name, std::vector<Field> fields)
|
||||
: INHERITED(Position(), kType_Kind, std::move(name))
|
||||
, fTypeKind(kStruct_Kind)
|
||||
, fFields(std::move(fields)) {}
|
||||
|
||||
// Create a scalar type.
|
||||
Type(std::string name, bool isNumber)
|
||||
: INHERITED(Position(), kType_Kind, std::move(name))
|
||||
, fTypeKind(kScalar_Kind)
|
||||
, fIsNumber(isNumber)
|
||||
, fColumns(1)
|
||||
, fRows(1) {}
|
||||
|
||||
// Create a scalar type which can be coerced to the listed types.
|
||||
Type(std::string name, bool isNumber, std::vector<std::shared_ptr<Type>> coercibleTypes)
|
||||
: INHERITED(Position(), kType_Kind, std::move(name))
|
||||
, fTypeKind(kScalar_Kind)
|
||||
, fIsNumber(isNumber)
|
||||
, fCoercibleTypes(std::move(coercibleTypes))
|
||||
, fColumns(1)
|
||||
, fRows(1) {}
|
||||
|
||||
// Create a vector type.
|
||||
Type(std::string name, std::shared_ptr<Type> componentType, int columns)
|
||||
: Type(name, kVector_Kind, componentType, columns) {}
|
||||
|
||||
// Create a vector or array type.
|
||||
Type(std::string name, Kind kind, std::shared_ptr<Type> componentType, int columns)
|
||||
: INHERITED(Position(), kType_Kind, std::move(name))
|
||||
, fTypeKind(kind)
|
||||
, fComponentType(std::move(componentType))
|
||||
, fColumns(columns)
|
||||
, fRows(1)
|
||||
, fDimensions(SpvDim1D) {}
|
||||
|
||||
// Create a matrix type.
|
||||
Type(std::string name, std::shared_ptr<Type> componentType, int columns, int rows)
|
||||
: INHERITED(Position(), kType_Kind, std::move(name))
|
||||
, fTypeKind(kMatrix_Kind)
|
||||
, fComponentType(std::move(componentType))
|
||||
, fColumns(columns)
|
||||
, fRows(rows)
|
||||
, fDimensions(SpvDim1D) {}
|
||||
|
||||
// Create a sampler type.
|
||||
Type(std::string name, SpvDim_ dimensions, bool isDepth, bool isArrayed, bool isMultisampled,
|
||||
bool isSampled)
|
||||
: INHERITED(Position(), kType_Kind, std::move(name))
|
||||
, fTypeKind(kSampler_Kind)
|
||||
, fDimensions(dimensions)
|
||||
, fIsDepth(isDepth)
|
||||
, fIsArrayed(isArrayed)
|
||||
, fIsMultisampled(isMultisampled)
|
||||
, fIsSampled(isSampled) {}
|
||||
|
||||
std::string name() const {
|
||||
return fName;
|
||||
}
|
||||
|
||||
std::string description() const override {
|
||||
return fName;
|
||||
}
|
||||
|
||||
bool operator==(const Type& other) const {
|
||||
return fName == other.fName;
|
||||
}
|
||||
|
||||
bool operator!=(const Type& other) const {
|
||||
return fName != other.fName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the category (scalar, vector, matrix, etc.) of this type.
|
||||
*/
|
||||
Kind kind() const {
|
||||
return fTypeKind;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this is a numeric scalar type.
|
||||
*/
|
||||
bool isNumber() const {
|
||||
return fIsNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if an instance of this type can be freely coerced (implicitly converted) to
|
||||
* another type.
|
||||
*/
|
||||
bool canCoerceTo(std::shared_ptr<Type> other) const {
|
||||
int cost;
|
||||
return determineCoercionCost(other, &cost);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the "cost" of coercing (implicitly converting) this type to another type. The cost
|
||||
* is a number with no particular meaning other than that lower costs are preferable to higher
|
||||
* costs. Returns true if a conversion is possible, false otherwise. The value of the out
|
||||
* parameter is undefined if false is returned.
|
||||
*/
|
||||
bool determineCoercionCost(std::shared_ptr<Type> other, int* outCost) const;
|
||||
|
||||
/**
|
||||
* For matrices and vectors, returns the type of individual cells (e.g. mat2 has a component
|
||||
* type of kFloat_Type). For all other types, causes an assertion failure.
|
||||
*/
|
||||
std::shared_ptr<Type> componentType() const {
|
||||
ASSERT(fComponentType);
|
||||
return fComponentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* For matrices and vectors, returns the number of columns (e.g. both mat3 and vec3 return 3).
|
||||
* For scalars, returns 1. For arrays, returns either the size of the array (if known) or -1.
|
||||
* For all other types, causes an assertion failure.
|
||||
*/
|
||||
int columns() const {
|
||||
ASSERT(fTypeKind == kScalar_Kind || fTypeKind == kVector_Kind ||
|
||||
fTypeKind == kMatrix_Kind || fTypeKind == kArray_Kind);
|
||||
return fColumns;
|
||||
}
|
||||
|
||||
/**
|
||||
* For matrices, returns the number of rows (e.g. mat2x4 returns 4). For vectors and scalars,
|
||||
* returns 1. For all other types, causes an assertion failure.
|
||||
*/
|
||||
int rows() const {
|
||||
ASSERT(fRows > 0);
|
||||
return fRows;
|
||||
}
|
||||
|
||||
std::vector<Field> fields() const {
|
||||
ASSERT(fTypeKind == kStruct_Kind);
|
||||
return fFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* For generic types, returns the types that this generic type can substitute for. For other
|
||||
* types, returns a list of other types that this type can be coerced into.
|
||||
*/
|
||||
std::vector<std::shared_ptr<Type>> coercibleTypes() const {
|
||||
ASSERT(fCoercibleTypes.size() > 0);
|
||||
return fCoercibleTypes;
|
||||
}
|
||||
|
||||
int dimensions() const {
|
||||
ASSERT(fTypeKind == kSampler_Kind);
|
||||
return fDimensions;
|
||||
}
|
||||
|
||||
bool isDepth() const {
|
||||
ASSERT(fTypeKind == kSampler_Kind);
|
||||
return fIsDepth;
|
||||
}
|
||||
|
||||
bool isArrayed() const {
|
||||
ASSERT(fTypeKind == kSampler_Kind);
|
||||
return fIsArrayed;
|
||||
}
|
||||
|
||||
bool isMultisampled() const {
|
||||
ASSERT(fTypeKind == kSampler_Kind);
|
||||
return fIsMultisampled;
|
||||
}
|
||||
|
||||
bool isSampled() const {
|
||||
ASSERT(fTypeKind == kSampler_Kind);
|
||||
return fIsSampled;
|
||||
}
|
||||
|
||||
static size_t vector_alignment(size_t componentSize, int columns) {
|
||||
return componentSize * (columns + columns % 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type's required alignment (when putting this type into a struct, the offset must
|
||||
* be a multiple of the alignment).
|
||||
*/
|
||||
size_t alignment() const {
|
||||
// See OpenGL Spec 7.6.2.2 Standard Uniform Block Layout
|
||||
switch (fTypeKind) {
|
||||
case kScalar_Kind:
|
||||
return this->size();
|
||||
case kVector_Kind:
|
||||
return vector_alignment(fComponentType->size(), fColumns);
|
||||
case kMatrix_Kind:
|
||||
return (vector_alignment(fComponentType->size(), fRows) + 15) & ~15;
|
||||
case kArray_Kind:
|
||||
// round up to next multiple of 16
|
||||
return (fComponentType->alignment() + 15) & ~15;
|
||||
case kStruct_Kind: {
|
||||
size_t result = 16;
|
||||
for (size_t i = 0; i < fFields.size(); i++) {
|
||||
size_t alignment = fFields[i].fType->alignment();
|
||||
if (alignment > result) {
|
||||
result = alignment;
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
ABORT(("cannot determine size of type " + fName).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For matrices and arrays, returns the number of bytes from the start of one entry (row, in
|
||||
* the case of matrices) to the start of the next.
|
||||
*/
|
||||
size_t stride() const {
|
||||
switch (fTypeKind) {
|
||||
case kMatrix_Kind: // fall through
|
||||
case kArray_Kind:
|
||||
return this->alignment();
|
||||
default:
|
||||
ABORT("type does not have a stride");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of this type in bytes.
|
||||
*/
|
||||
size_t size() const {
|
||||
switch (fTypeKind) {
|
||||
case kScalar_Kind:
|
||||
// FIXME need to take precision into account, once we figure out how we want to
|
||||
// handle it...
|
||||
return 4;
|
||||
case kVector_Kind:
|
||||
return fColumns * fComponentType->size();
|
||||
case kMatrix_Kind:
|
||||
return vector_alignment(fComponentType->size(), fRows) * fColumns;
|
||||
case kArray_Kind:
|
||||
return fColumns * this->stride();
|
||||
case kStruct_Kind: {
|
||||
size_t total = 0;
|
||||
for (size_t i = 0; i < fFields.size(); i++) {
|
||||
size_t alignment = fFields[i].fType->alignment();
|
||||
if (total % alignment != 0) {
|
||||
total += alignment - total % alignment;
|
||||
}
|
||||
ASSERT(false);
|
||||
ASSERT(total % alignment == 0);
|
||||
total += fFields[i].fType->size();
|
||||
}
|
||||
return total;
|
||||
}
|
||||
default:
|
||||
ABORT(("cannot determine size of type " + fName).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the corresponding vector or matrix type with the specified number of columns and
|
||||
* rows.
|
||||
*/
|
||||
std::shared_ptr<Type> toCompound(int columns, int rows);
|
||||
|
||||
private:
|
||||
typedef Symbol INHERITED;
|
||||
|
||||
const Kind fTypeKind;
|
||||
const bool fIsNumber = false;
|
||||
const std::shared_ptr<Type> fComponentType = nullptr;
|
||||
const std::vector<std::shared_ptr<Type>> fCoercibleTypes = { };
|
||||
const int fColumns = -1;
|
||||
const int fRows = -1;
|
||||
const std::vector<Field> fFields = { };
|
||||
const SpvDim_ fDimensions = SpvDim1D;
|
||||
const bool fIsDepth = false;
|
||||
const bool fIsArrayed = false;
|
||||
const bool fIsMultisampled = false;
|
||||
const bool fIsSampled = false;
|
||||
};
|
||||
|
||||
extern const std::shared_ptr<Type> kVoid_Type;
|
||||
|
||||
extern const std::shared_ptr<Type> kFloat_Type;
|
||||
extern const std::shared_ptr<Type> kVec2_Type;
|
||||
extern const std::shared_ptr<Type> kVec3_Type;
|
||||
extern const std::shared_ptr<Type> kVec4_Type;
|
||||
extern const std::shared_ptr<Type> kDouble_Type;
|
||||
extern const std::shared_ptr<Type> kDVec2_Type;
|
||||
extern const std::shared_ptr<Type> kDVec3_Type;
|
||||
extern const std::shared_ptr<Type> kDVec4_Type;
|
||||
extern const std::shared_ptr<Type> kInt_Type;
|
||||
extern const std::shared_ptr<Type> kIVec2_Type;
|
||||
extern const std::shared_ptr<Type> kIVec3_Type;
|
||||
extern const std::shared_ptr<Type> kIVec4_Type;
|
||||
extern const std::shared_ptr<Type> kUInt_Type;
|
||||
extern const std::shared_ptr<Type> kUVec2_Type;
|
||||
extern const std::shared_ptr<Type> kUVec3_Type;
|
||||
extern const std::shared_ptr<Type> kUVec4_Type;
|
||||
extern const std::shared_ptr<Type> kBool_Type;
|
||||
extern const std::shared_ptr<Type> kBVec2_Type;
|
||||
extern const std::shared_ptr<Type> kBVec3_Type;
|
||||
extern const std::shared_ptr<Type> kBVec4_Type;
|
||||
|
||||
extern const std::shared_ptr<Type> kMat2x2_Type;
|
||||
extern const std::shared_ptr<Type> kMat2x3_Type;
|
||||
extern const std::shared_ptr<Type> kMat2x4_Type;
|
||||
extern const std::shared_ptr<Type> kMat3x2_Type;
|
||||
extern const std::shared_ptr<Type> kMat3x3_Type;
|
||||
extern const std::shared_ptr<Type> kMat3x4_Type;
|
||||
extern const std::shared_ptr<Type> kMat4x2_Type;
|
||||
extern const std::shared_ptr<Type> kMat4x3_Type;
|
||||
extern const std::shared_ptr<Type> kMat4x4_Type;
|
||||
|
||||
extern const std::shared_ptr<Type> kDMat2x2_Type;
|
||||
extern const std::shared_ptr<Type> kDMat2x3_Type;
|
||||
extern const std::shared_ptr<Type> kDMat2x4_Type;
|
||||
extern const std::shared_ptr<Type> kDMat3x2_Type;
|
||||
extern const std::shared_ptr<Type> kDMat3x3_Type;
|
||||
extern const std::shared_ptr<Type> kDMat3x4_Type;
|
||||
extern const std::shared_ptr<Type> kDMat4x2_Type;
|
||||
extern const std::shared_ptr<Type> kDMat4x3_Type;
|
||||
extern const std::shared_ptr<Type> kDMat4x4_Type;
|
||||
|
||||
extern const std::shared_ptr<Type> kSampler1D_Type;
|
||||
extern const std::shared_ptr<Type> kSampler2D_Type;
|
||||
extern const std::shared_ptr<Type> kSampler3D_Type;
|
||||
extern const std::shared_ptr<Type> kSamplerCube_Type;
|
||||
extern const std::shared_ptr<Type> kSampler2DRect_Type;
|
||||
extern const std::shared_ptr<Type> kSampler1DArray_Type;
|
||||
extern const std::shared_ptr<Type> kSampler2DArray_Type;
|
||||
extern const std::shared_ptr<Type> kSamplerCubeArray_Type;
|
||||
extern const std::shared_ptr<Type> kSamplerBuffer_Type;
|
||||
extern const std::shared_ptr<Type> kSampler2DMS_Type;
|
||||
extern const std::shared_ptr<Type> kSampler2DMSArray_Type;
|
||||
|
||||
extern const std::shared_ptr<Type> kGSampler1D_Type;
|
||||
extern const std::shared_ptr<Type> kGSampler2D_Type;
|
||||
extern const std::shared_ptr<Type> kGSampler3D_Type;
|
||||
extern const std::shared_ptr<Type> kGSamplerCube_Type;
|
||||
extern const std::shared_ptr<Type> kGSampler2DRect_Type;
|
||||
extern const std::shared_ptr<Type> kGSampler1DArray_Type;
|
||||
extern const std::shared_ptr<Type> kGSampler2DArray_Type;
|
||||
extern const std::shared_ptr<Type> kGSamplerCubeArray_Type;
|
||||
extern const std::shared_ptr<Type> kGSamplerBuffer_Type;
|
||||
extern const std::shared_ptr<Type> kGSampler2DMS_Type;
|
||||
extern const std::shared_ptr<Type> kGSampler2DMSArray_Type;
|
||||
|
||||
extern const std::shared_ptr<Type> kSampler1DShadow_Type;
|
||||
extern const std::shared_ptr<Type> kSampler2DShadow_Type;
|
||||
extern const std::shared_ptr<Type> kSamplerCubeShadow_Type;
|
||||
extern const std::shared_ptr<Type> kSampler2DRectShadow_Type;
|
||||
extern const std::shared_ptr<Type> kSampler1DArrayShadow_Type;
|
||||
extern const std::shared_ptr<Type> kSampler2DArrayShadow_Type;
|
||||
extern const std::shared_ptr<Type> kSamplerCubeArrayShadow_Type;
|
||||
extern const std::shared_ptr<Type> kGSampler2DArrayShadow_Type;
|
||||
extern const std::shared_ptr<Type> kGSamplerCubeArrayShadow_Type;
|
||||
|
||||
extern const std::shared_ptr<Type> kGenType_Type;
|
||||
extern const std::shared_ptr<Type> kGenDType_Type;
|
||||
extern const std::shared_ptr<Type> kGenIType_Type;
|
||||
extern const std::shared_ptr<Type> kGenUType_Type;
|
||||
extern const std::shared_ptr<Type> kGenBType_Type;
|
||||
extern const std::shared_ptr<Type> kMat_Type;
|
||||
extern const std::shared_ptr<Type> kVec_Type;
|
||||
extern const std::shared_ptr<Type> kGVec_Type;
|
||||
extern const std::shared_ptr<Type> kGVec2_Type;
|
||||
extern const std::shared_ptr<Type> kGVec3_Type;
|
||||
extern const std::shared_ptr<Type> kGVec4_Type;
|
||||
extern const std::shared_ptr<Type> kDVec_Type;
|
||||
extern const std::shared_ptr<Type> kIVec_Type;
|
||||
extern const std::shared_ptr<Type> kUVec_Type;
|
||||
extern const std::shared_ptr<Type> kBVec_Type;
|
||||
|
||||
extern const std::shared_ptr<Type> kInvalid_Type;
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user