Revert "Revert "Switch to the new SkSL lexer.""
This reverts commit 358515491a
.
Bug: skia:
Change-Id: I013fac0ed83774d8ae7c6ee6819045cab37f5e97
Reviewed-on: https://skia-review.googlesource.com/45180
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
parent
9194706e8c
commit
5b5f096a03
36
BUILD.gn
36
BUILD.gn
@ -45,6 +45,7 @@ declare_args() {
|
||||
skia_vulkan_sdk = getenv("VULKAN_SDK")
|
||||
skia_qt_path = getenv("QT_PATH")
|
||||
skia_compile_processors = false
|
||||
skia_lex = false
|
||||
|
||||
skia_jumper_clang = ""
|
||||
skia_jumper_objdump = ""
|
||||
@ -411,7 +412,7 @@ optional("fontmgr_fuchsia") {
|
||||
]
|
||||
}
|
||||
|
||||
if (skia_compile_processors) {
|
||||
if (skia_lex) {
|
||||
executable("sksllex") {
|
||||
sources = [
|
||||
"src/sksl/lex/Main.cpp",
|
||||
@ -422,6 +423,38 @@ if (skia_compile_processors) {
|
||||
include_dirs = [ "src/sksl/lex" ]
|
||||
}
|
||||
|
||||
action("run_sksllex") {
|
||||
script = "gn/run_sksllex.py"
|
||||
sources = [
|
||||
"src/sksl/lex/layout.lex",
|
||||
"src/sksl/lex/sksl.lex",
|
||||
]
|
||||
|
||||
# GN insists its outputs should go somewhere underneath target_out_dir, so we trick it with a
|
||||
# path that starts with target_out_dir and then uses ".." to back up into the src dir.
|
||||
outputs = [
|
||||
"$target_out_dir/" +
|
||||
rebase_path("src/sksl/lex/SkSLLexer.h", target_out_dir),
|
||||
# the script also modifies the corresponding .cpp file, but if we tell GN that it gets
|
||||
# confused due to the same file being named by two different paths
|
||||
]
|
||||
sksllex_path = "$root_out_dir/"
|
||||
sksllex_path += "sksllex"
|
||||
if (host_os == "win") {
|
||||
sksllex_path += ".exe"
|
||||
}
|
||||
args = [
|
||||
rebase_path(sksllex_path),
|
||||
rebase_path("bin/clang-format"),
|
||||
rebase_path("src"),
|
||||
]
|
||||
}
|
||||
} else {
|
||||
group("run_sksllex") {
|
||||
}
|
||||
}
|
||||
|
||||
if (skia_compile_processors) {
|
||||
executable("skslc") {
|
||||
defines = [ "SKSL_STANDALONE" ]
|
||||
sources = [
|
||||
@ -482,6 +515,7 @@ optional("gpu") {
|
||||
enabled = skia_enable_gpu
|
||||
deps = [
|
||||
":compile_processors",
|
||||
":run_sksllex",
|
||||
]
|
||||
public_defines = []
|
||||
|
||||
|
34
gn/run_sksllex.py
Normal file
34
gn/run_sksllex.py
Normal file
@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2017 Google Inc.
|
||||
#
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
sksllex = sys.argv[1]
|
||||
clangFormat = sys.argv[2]
|
||||
src = sys.argv[3]
|
||||
try:
|
||||
subprocess.check_output([sksllex, src + "/sksl/lex/sksl.lex", "Lexer",
|
||||
"Token", src + "/sksl/SkSLLexer.h", src +
|
||||
"/sksl/SkSLLexer.cpp"])
|
||||
subprocess.check_call(clangFormat + " -i \"" + src + "/sksl/SkSLLexer.h\"",
|
||||
shell=True)
|
||||
subprocess.check_call(clangFormat + " -i \"" + src +
|
||||
"/sksl/SkSLLexer.cpp\"", shell=True)
|
||||
subprocess.check_output([sksllex, src + "/sksl/lex/layout.lex",
|
||||
"LayoutLexer", "LayoutToken",
|
||||
src + "/sksl/SkSLLayoutLexer.h",
|
||||
src + "/sksl/SkSLLayoutLexer.cpp"])
|
||||
subprocess.check_call(clangFormat + " -i \"" + src +
|
||||
"/sksl/SkSLLayoutLexer.h\"", shell=True)
|
||||
subprocess.check_call(clangFormat + " -i \"" + src +
|
||||
"/sksl/SkSLLayoutLexer.cpp\"", shell=True)
|
||||
except subprocess.CalledProcessError as err:
|
||||
print("### Lexer error:")
|
||||
print(err.output)
|
||||
exit(1)
|
@ -9,15 +9,16 @@ _src = get_path_info("../src", "abspath")
|
||||
skia_sksl_sources = [
|
||||
"$_src/sksl/SkSLCFGGenerator.cpp",
|
||||
"$_src/sksl/SkSLCompiler.cpp",
|
||||
"$_src/sksl/SkSLIRGenerator.cpp",
|
||||
"$_src/sksl/SkSLParser.cpp",
|
||||
"$_src/sksl/SkSLCPPCodeGenerator.cpp",
|
||||
"$_src/sksl/SkSLHCodeGenerator.cpp",
|
||||
"$_src/sksl/SkSLGLSLCodeGenerator.cpp",
|
||||
"$_src/sksl/SkSLHCodeGenerator.cpp",
|
||||
"$_src/sksl/SkSLIRGenerator.cpp",
|
||||
"$_src/sksl/SkSLLexer.cpp",
|
||||
"$_src/sksl/SkSLLayoutLexer.cpp",
|
||||
"$_src/sksl/SkSLParser.cpp",
|
||||
"$_src/sksl/SkSLSPIRVCodeGenerator.cpp",
|
||||
"$_src/sksl/SkSLString.cpp",
|
||||
"$_src/sksl/SkSLUtil.cpp",
|
||||
"$_src/sksl/lex.layout.cpp",
|
||||
"$_src/sksl/ir/SkSLSymbolTable.cpp",
|
||||
"$_src/sksl/ir/SkSLSetting.cpp",
|
||||
"$_src/sksl/ir/SkSLType.cpp",
|
||||
|
@ -130,7 +130,7 @@ std::unique_ptr<GrFragmentProcessor> GrAlphaThresholdFragmentProcessor::TestCrea
|
||||
GrProcessorTestData* testData) {
|
||||
sk_sp<GrTextureProxy> bmpProxy = testData->textureProxy(GrProcessorUnitTest::kSkiaPMTextureIdx);
|
||||
sk_sp<GrTextureProxy> maskProxy = testData->textureProxy(GrProcessorUnitTest::kAlphaTextureIdx);
|
||||
|
||||
// Make the inner and outer thresholds be in (0, 1) exclusive and be sorted correctly.
|
||||
float innerThresh = testData->fRandom->nextUScalar1() * .99f + 0.005f;
|
||||
float outerThresh = testData->fRandom->nextUScalar1() * .99f + 0.005f;
|
||||
const int kMaxWidth = 1000;
|
||||
|
@ -13,11 +13,13 @@
|
||||
|
||||
#include "GrResourceProvider.h"
|
||||
|
||||
// Computes an unnormalized half kernel (right side). Returns the summation of all the half
|
||||
// kernel values.
|
||||
static float make_unnormalized_half_kernel(float* halfKernel, int halfKernelSize, float sigma) {
|
||||
const float invSigma = 1.f / sigma;
|
||||
const float b = -0.5f * invSigma * invSigma;
|
||||
float tot = 0.0f;
|
||||
|
||||
// Compute half kernel values at half pixel steps out from the center.
|
||||
float t = 0.5f;
|
||||
for (int i = 0; i < halfKernelSize; ++i) {
|
||||
float value = expf(t * t * b);
|
||||
@ -28,8 +30,11 @@ static float make_unnormalized_half_kernel(float* halfKernel, int halfKernelSize
|
||||
return tot;
|
||||
}
|
||||
|
||||
// Create a Gaussian half-kernel (right side) and a summed area table given a sigma and number
|
||||
// of discrete steps. The half kernel is normalized to sum to 0.5.
|
||||
static void make_half_kernel_and_summed_table(float* halfKernel, float* summedHalfKernel,
|
||||
int halfKernelSize, float sigma) {
|
||||
// The half kernel should sum to 0.5 not 1.0.
|
||||
const float tot = 2.f * make_unnormalized_half_kernel(halfKernel, halfKernelSize, sigma);
|
||||
float sum = 0.f;
|
||||
for (int i = 0; i < halfKernelSize; ++i) {
|
||||
@ -39,6 +44,8 @@ static void make_half_kernel_and_summed_table(float* halfKernel, float* summedHa
|
||||
}
|
||||
}
|
||||
|
||||
// Applies the 1D half kernel vertically at points along the x axis to a circle centered at the
|
||||
// origin with radius circleR.
|
||||
void apply_kernel_in_y(float* results, int numSteps, float firstX, float circleR,
|
||||
int halfKernelSize, const float* summedHalfKernelTable) {
|
||||
float x = firstX;
|
||||
@ -48,7 +55,8 @@ void apply_kernel_in_y(float* results, int numSteps, float firstX, float circleR
|
||||
continue;
|
||||
}
|
||||
float y = sqrtf(circleR * circleR - x * x);
|
||||
|
||||
// In the column at x we exit the circle at +y and -y
|
||||
// The summed table entry j is actually reflects an offset of j + 0.5.
|
||||
y -= 0.5f;
|
||||
int yInt = SkScalarFloorToInt(y);
|
||||
SkASSERT(yInt >= -1);
|
||||
@ -64,6 +72,10 @@ void apply_kernel_in_y(float* results, int numSteps, float firstX, float circleR
|
||||
}
|
||||
}
|
||||
|
||||
// Apply a Gaussian at point (evalX, 0) to a circle centered at the origin with radius circleR.
|
||||
// This relies on having a half kernel computed for the Gaussian and a table of applications of
|
||||
// the half kernel in y to columns at (evalX - halfKernel, evalX - halfKernel + 1, ..., evalX +
|
||||
// halfKernel) passed in as yKernelEvaluations.
|
||||
static uint8_t eval_at(float evalX, float circleR, const float* halfKernel, int halfKernelSize,
|
||||
const float* yKernelEvaluations) {
|
||||
float acc = 0;
|
||||
@ -83,18 +95,28 @@ static uint8_t eval_at(float evalX, float circleR, const float* halfKernel, int
|
||||
float verticalEval = yKernelEvaluations[i + halfKernelSize];
|
||||
acc += verticalEval * halfKernel[i];
|
||||
}
|
||||
|
||||
// Since we applied a half kernel in y we multiply acc by 2 (the circle is symmetric about
|
||||
// the x axis).
|
||||
return SkUnitScalarClampToByte(2.f * acc);
|
||||
}
|
||||
|
||||
// This function creates a profile of a blurred circle. It does this by computing a kernel for
|
||||
// half the Gaussian and a matching summed area table. The summed area table is used to compute
|
||||
// an array of vertical applications of the half kernel to the circle along the x axis. The
|
||||
// table of y evaluations has 2 * k + n entries where k is the size of the half kernel and n is
|
||||
// the size of the profile being computed. Then for each of the n profile entries we walk out k
|
||||
// steps in each horizontal direction multiplying the corresponding y evaluation by the half
|
||||
// kernel entry and sum these values to compute the profile entry.
|
||||
static uint8_t* create_circle_profile(float sigma, float circleR, int profileTextureWidth) {
|
||||
const int numSteps = profileTextureWidth;
|
||||
uint8_t* weights = new uint8_t[numSteps];
|
||||
|
||||
// The full kernel is 6 sigmas wide.
|
||||
int halfKernelSize = SkScalarCeilToInt(6.0f * sigma);
|
||||
|
||||
// round up to next multiple of 2 and then divide by 2
|
||||
halfKernelSize = ((halfKernelSize + 1) & ~1) >> 1;
|
||||
|
||||
// Number of x steps at which to apply kernel in y to cover all the profile samples in x.
|
||||
int numYSteps = numSteps + 2 * halfKernelSize;
|
||||
|
||||
SkAutoTArray<float> bulkAlloc(halfKernelSize + halfKernelSize + numYSteps);
|
||||
@ -110,34 +132,36 @@ static uint8_t* create_circle_profile(float sigma, float circleR, int profileTex
|
||||
float evalX = i + 0.5f;
|
||||
weights[i] = eval_at(evalX, circleR, halfKernel, halfKernelSize, yEvals + i);
|
||||
}
|
||||
|
||||
// Ensure the tail of the Gaussian goes to zero.
|
||||
weights[numSteps - 1] = 0;
|
||||
return weights;
|
||||
}
|
||||
|
||||
static uint8_t* create_half_plane_profile(int profileWidth) {
|
||||
SkASSERT(!(profileWidth & 0x1));
|
||||
|
||||
// The full kernel is 6 sigmas wide.
|
||||
float sigma = profileWidth / 6.f;
|
||||
int halfKernelSize = profileWidth / 2;
|
||||
|
||||
SkAutoTArray<float> halfKernel(halfKernelSize);
|
||||
uint8_t* profile = new uint8_t[profileWidth];
|
||||
|
||||
// The half kernel should sum to 0.5.
|
||||
const float tot = 2.f * make_unnormalized_half_kernel(halfKernel.get(), halfKernelSize, sigma);
|
||||
float sum = 0.f;
|
||||
|
||||
// Populate the profile from the right edge to the middle.
|
||||
for (int i = 0; i < halfKernelSize; ++i) {
|
||||
halfKernel[halfKernelSize - i - 1] /= tot;
|
||||
sum += halfKernel[halfKernelSize - i - 1];
|
||||
profile[profileWidth - i - 1] = SkUnitScalarClampToByte(sum);
|
||||
}
|
||||
|
||||
// Populate the profile from the middle to the left edge (by flipping the half kernel and
|
||||
// continuing the summation).
|
||||
for (int i = 0; i < halfKernelSize; ++i) {
|
||||
sum += halfKernel[i];
|
||||
profile[halfKernelSize - i - 1] = SkUnitScalarClampToByte(sum);
|
||||
}
|
||||
|
||||
// Ensure tail goes to 0.
|
||||
profile[profileWidth - 1] = 0;
|
||||
return profile;
|
||||
}
|
||||
@ -146,9 +170,13 @@ static sk_sp<GrTextureProxy> create_profile_texture(GrResourceProvider* resource
|
||||
const SkRect& circle, float sigma,
|
||||
float* solidRadius, float* textureRadius) {
|
||||
float circleR = circle.width() / 2.0f;
|
||||
|
||||
// Profile textures are cached by the ratio of sigma to circle radius and by the size of the
|
||||
// profile texture (binned by powers of 2).
|
||||
SkScalar sigmaToCircleRRatio = sigma / circleR;
|
||||
|
||||
// When sigma is really small this becomes a equivalent to convolving a Gaussian with a
|
||||
// half-plane. Similarly, in the extreme high ratio cases circle becomes a point WRT to the
|
||||
// Guassian and the profile texture is a just a Gaussian evaluation. However, we haven't yet
|
||||
// implemented this latter optimization.
|
||||
sigmaToCircleRRatio = SkTMin(sigmaToCircleRRatio, 8.f);
|
||||
SkFixed sigmaToCircleRRatioFixed;
|
||||
static const SkScalar kHalfPlaneThreshold = 0.1f;
|
||||
@ -159,8 +187,10 @@ static sk_sp<GrTextureProxy> create_profile_texture(GrResourceProvider* resource
|
||||
*solidRadius = circleR - 3 * sigma;
|
||||
*textureRadius = 6 * sigma;
|
||||
} else {
|
||||
// Convert to fixed point for the key.
|
||||
sigmaToCircleRRatioFixed = SkScalarToFixed(sigmaToCircleRRatio);
|
||||
|
||||
// We shave off some bits to reduce the number of unique entries. We could probably
|
||||
// shave off more than we do.
|
||||
sigmaToCircleRRatioFixed &= ~0xff;
|
||||
sigmaToCircleRRatio = SkFixedToScalar(sigmaToCircleRRatioFixed);
|
||||
sigma = circleR * sigmaToCircleRRatio;
|
||||
@ -188,6 +218,7 @@ static sk_sp<GrTextureProxy> create_profile_texture(GrResourceProvider* resource
|
||||
if (useHalfPlaneApprox) {
|
||||
profile.reset(create_half_plane_profile(kProfileTextureWidth));
|
||||
} else {
|
||||
// Rescale params to the size of the texture we're creating.
|
||||
SkScalar scale = kProfileTextureWidth / *textureRadius;
|
||||
profile.reset(
|
||||
create_circle_profile(sigma * scale, circleR * scale, kProfileTextureWidth));
|
||||
|
@ -72,7 +72,9 @@ private:
|
||||
if (radii != prevRadii || center != prevCenter) {
|
||||
float invRXSqd;
|
||||
float invRYSqd;
|
||||
|
||||
// If we're using a scale factor to work around precision issues, choose the larger
|
||||
// radius as the scale factor. The inv radii need to be pre-adjusted by the scale
|
||||
// factor.
|
||||
if (scale.isValid()) {
|
||||
if (radii.fX > radii.fY) {
|
||||
invRXSqd = 1.f;
|
||||
|
@ -30,6 +30,7 @@ public:
|
||||
GrSamplerState::Filter::kNearest)));
|
||||
}
|
||||
|
||||
/* clamp mode */
|
||||
static std::unique_ptr<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> proxy,
|
||||
sk_sp<GrColorSpaceXform>
|
||||
colorSpaceXform,
|
||||
|
@ -319,7 +319,7 @@ void CFGGenerator::addExpression(CFG& cfg, std::unique_ptr<Expression>* e, bool
|
||||
break;
|
||||
}
|
||||
default:
|
||||
this->addExpression(cfg, &b->fLeft, !Token::IsAssignment(b->fOperator));
|
||||
this->addExpression(cfg, &b->fLeft, !Compiler::IsAssignment(b->fOperator));
|
||||
this->addExpression(cfg, &b->fRight, constantPropagate);
|
||||
cfg.fBlocks[cfg.fCurrent].fNodes.push_back({
|
||||
BasicBlock::Node::kExpression_Kind,
|
||||
|
@ -14,7 +14,7 @@ namespace SkSL {
|
||||
|
||||
static bool needs_uniform_var(const Variable& var) {
|
||||
return (var.fModifiers.fFlags & Modifiers::kUniform_Flag) &&
|
||||
strcmp(var.fType.fName.c_str(), "colorSpaceXform");
|
||||
var.fType.fName != "colorSpaceXform";
|
||||
}
|
||||
|
||||
CPPCodeGenerator::CPPCodeGenerator(const Context* context, const Program* program,
|
||||
@ -58,7 +58,7 @@ void CPPCodeGenerator::writeType(const Type& type) {
|
||||
if (type.kind() == Type::kStruct_Kind) {
|
||||
INHERITED::writeType(type);
|
||||
} else {
|
||||
this->write(type.name());
|
||||
this->write(type.fName);
|
||||
}
|
||||
}
|
||||
void CPPCodeGenerator::writeBinaryExpression(const BinaryExpression& b,
|
||||
@ -87,7 +87,7 @@ void CPPCodeGenerator::writeIndexExpression(const IndexExpression& i) {
|
||||
if (SK_TRANSFORMEDCOORDS2D_BUILTIN == builtin) {
|
||||
this->write("%s");
|
||||
if (i.fIndex->fKind != Expression::kIntLiteral_Kind) {
|
||||
fErrors.error(i.fIndex->fPosition,
|
||||
fErrors.error(i.fIndex->fOffset,
|
||||
"index into sk_TransformedCoords2D must be an integer literal");
|
||||
return;
|
||||
}
|
||||
@ -104,7 +104,7 @@ void CPPCodeGenerator::writeIndexExpression(const IndexExpression& i) {
|
||||
} else if (SK_TEXTURESAMPLERS_BUILTIN == builtin) {
|
||||
this->write("%s");
|
||||
if (i.fIndex->fKind != Expression::kIntLiteral_Kind) {
|
||||
fErrors.error(i.fIndex->fPosition,
|
||||
fErrors.error(i.fIndex->fOffset,
|
||||
"index into sk_TextureSamplers must be an integer literal");
|
||||
return;
|
||||
}
|
||||
@ -118,16 +118,15 @@ void CPPCodeGenerator::writeIndexExpression(const IndexExpression& i) {
|
||||
}
|
||||
|
||||
static const char* default_value(const Type& type) {
|
||||
const char* name = type.name().c_str();
|
||||
if (!strcmp(name, "float")) {
|
||||
if (type.fName == "float") {
|
||||
return "0.0";
|
||||
} else if (!strcmp(name, "float2")) {
|
||||
} else if (type.fName == "float2") {
|
||||
return "float2(0.0)";
|
||||
} else if (!strcmp(name, "float3")) {
|
||||
} else if (type.fName == "float3") {
|
||||
return "float30.0)";
|
||||
} else if (!strcmp(name, "float4")) {
|
||||
} else if (type.fName == "float4") {
|
||||
return "float4(0.0)";
|
||||
} else if (!strcmp(name, "floatt4x4") || !strcmp(name, "colorSpaceXform")) {
|
||||
} else if (type.fName == "floatt4x4" || type.fName == "colorSpaceXform") {
|
||||
return "float4x4(1.0)";
|
||||
}
|
||||
ABORT("unsupported default_value type\n");
|
||||
@ -155,7 +154,8 @@ void CPPCodeGenerator::writeRuntimeValue(const Type& type, const String& cppCode
|
||||
fFormatArgs.push_back(cppCode + ".fX");
|
||||
fFormatArgs.push_back(cppCode + ".fY");
|
||||
} else {
|
||||
printf("%s\n", type.name().c_str());
|
||||
this->write(type.fName);
|
||||
this->write("\n");
|
||||
ABORT("unsupported runtime value type\n");
|
||||
}
|
||||
}
|
||||
@ -227,11 +227,11 @@ void CPPCodeGenerator::writeVariableReference(const VariableReference& ref) {
|
||||
}
|
||||
fFormatArgs.push_back(code);
|
||||
} else if (SectionAndParameterHelper::IsParameter(ref.fVariable)) {
|
||||
const char* name = ref.fVariable.fName.c_str();
|
||||
String name(ref.fVariable.fName);
|
||||
this->writeRuntimeValue(ref.fVariable.fType,
|
||||
String::printf("_outer.%s()", name).c_str());
|
||||
String::printf("_outer.%s()", name.c_str()).c_str());
|
||||
} else {
|
||||
this->write(ref.fVariable.fName.c_str());
|
||||
this->write(ref.fVariable.fName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -358,14 +358,16 @@ void CPPCodeGenerator::addUniform(const Variable& var) {
|
||||
var.fType == *fContext.fColorSpaceXform_Type) {
|
||||
type = "kMat44f_GrSLType";
|
||||
} else {
|
||||
ABORT("unsupported uniform type: %s %s;\n", var.fType.name().c_str(), var.fName.c_str());
|
||||
ABORT("unsupported uniform type: %s %s;\n", String(var.fType.fName).c_str(),
|
||||
String(var.fName).c_str());
|
||||
}
|
||||
if (var.fModifiers.fLayout.fWhen.size()) {
|
||||
this->writef(" if (%s) {\n ", var.fModifiers.fLayout.fWhen.c_str());
|
||||
}
|
||||
const char* name = var.fName.c_str();
|
||||
String name(var.fName);
|
||||
this->writef(" %sVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, %s, "
|
||||
"%s, \"%s\");\n", HCodeGenerator::FieldName(name).c_str(), type, precision, name);
|
||||
"%s, \"%s\");\n", HCodeGenerator::FieldName(name.c_str()).c_str(), type, precision,
|
||||
name.c_str());
|
||||
if (var.fModifiers.fLayout.fWhen.size()) {
|
||||
this->write(" }\n");
|
||||
}
|
||||
@ -380,7 +382,7 @@ void CPPCodeGenerator::writePrivateVars() {
|
||||
if (is_private(*decl.fVar)) {
|
||||
this->writef("%s %s;\n",
|
||||
HCodeGenerator::FieldType(decl.fVar->fType).c_str(),
|
||||
decl.fVar->fName.c_str());
|
||||
String(decl.fVar->fName).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -395,7 +397,7 @@ void CPPCodeGenerator::writePrivateVarValues() {
|
||||
VarDeclaration& decl = (VarDeclaration&) *raw;
|
||||
if (is_private(*decl.fVar) && decl.fValue) {
|
||||
this->writef("%s = %s;\n",
|
||||
decl.fVar->fName.c_str(),
|
||||
String(decl.fVar->fName).c_str(),
|
||||
decl.fValue->description().c_str());
|
||||
}
|
||||
}
|
||||
@ -414,12 +416,12 @@ bool CPPCodeGenerator::writeEmitCode(std::vector<const Variable*>& uniforms) {
|
||||
this->addUniform(*u);
|
||||
if (u->fType == *fContext.fColorSpaceXform_Type) {
|
||||
if (fNeedColorSpaceHelper) {
|
||||
fErrors.error(u->fPosition, "only a single ColorSpaceXform is supported");
|
||||
fErrors.error(u->fOffset, "only a single ColorSpaceXform is supported");
|
||||
}
|
||||
fNeedColorSpaceHelper = true;
|
||||
this->writef(" fColorSpaceHelper.emitCode(args.fUniformHandler, "
|
||||
"_outer.%s().get());\n",
|
||||
u->fName.c_str());
|
||||
String(u->fName).c_str());
|
||||
}
|
||||
}
|
||||
this->writeSection(EMIT_CODE_SECTION);
|
||||
@ -453,7 +455,8 @@ void CPPCodeGenerator::writeSetData(std::vector<const Variable*>& uniforms) {
|
||||
wroteProcessor = true;
|
||||
this->writef(" {\n");
|
||||
}
|
||||
const char* name = u->fName.c_str();
|
||||
String nameString(u->fName);
|
||||
const char* name = nameString.c_str();
|
||||
if (u->fType == *fContext.fFloat4_Type) {
|
||||
this->writef(" const SkRect %sValue = _outer.%s();\n"
|
||||
" %s.set4fv(%sVar, 1, (float*) &%sValue);\n",
|
||||
@ -485,13 +488,13 @@ void CPPCodeGenerator::writeSetData(std::vector<const Variable*>& uniforms) {
|
||||
const VarDeclarations* decls = (const VarDeclarations*) p.get();
|
||||
for (const auto& raw : decls->fVars) {
|
||||
VarDeclaration& decl = (VarDeclaration&) *raw;
|
||||
String nameString(decl.fVar->fName);
|
||||
const char* name = nameString.c_str();
|
||||
if (needs_uniform_var(*decl.fVar)) {
|
||||
const char* name = decl.fVar->fName.c_str();
|
||||
this->writef(" UniformHandle& %s = %sVar;\n"
|
||||
" (void) %s;\n",
|
||||
name, HCodeGenerator::FieldName(name).c_str(), name);
|
||||
} else if (SectionAndParameterHelper::IsParameter(*decl.fVar)) {
|
||||
const char* name = decl.fVar->fName.c_str();
|
||||
if (!wroteProcessor) {
|
||||
this->writef(" const %s& _outer = _proc.cast<%s>();\n", fullName,
|
||||
fullName);
|
||||
@ -512,14 +515,14 @@ void CPPCodeGenerator::writeSetData(std::vector<const Variable*>& uniforms) {
|
||||
void CPPCodeGenerator::writeClone() {
|
||||
if (!this->writeSection(CLONE_SECTION)) {
|
||||
if (fSectionAndParameterHelper.getSection(FIELDS_SECTION)) {
|
||||
fErrors.error(Position(1, 1), "fragment processors with custom @fields must also have "
|
||||
"a custom @clone");
|
||||
fErrors.error(0, "fragment processors with custom @fields must also have a custom"
|
||||
"@clone");
|
||||
}
|
||||
this->writef("%s::%s(const %s& src)\n"
|
||||
": INHERITED(src.optimizationFlags())", fFullName.c_str(), fFullName.c_str(),
|
||||
fFullName.c_str());
|
||||
for (const auto& param : fSectionAndParameterHelper.getParameters()) {
|
||||
String fieldName = HCodeGenerator::FieldName(param->fName.c_str());
|
||||
String fieldName = HCodeGenerator::FieldName(String(param->fName).c_str());
|
||||
this->writef("\n, %s(%s)",
|
||||
fieldName.c_str(),
|
||||
("src." + fieldName).c_str());
|
||||
@ -535,7 +538,7 @@ void CPPCodeGenerator::writeClone() {
|
||||
for (const auto& param : fSectionAndParameterHelper.getParameters()) {
|
||||
if (param->fType.kind() == Type::kSampler_Kind) {
|
||||
this->writef(" this->addTextureSampler(&%s);\n",
|
||||
HCodeGenerator::FieldName(param->fName.c_str()).c_str());
|
||||
HCodeGenerator::FieldName(String(param->fName).c_str()).c_str());
|
||||
}
|
||||
}
|
||||
for (const Section* s : fSectionAndParameterHelper.getSections(COORD_TRANSFORM_SECTION)) {
|
||||
@ -572,7 +575,8 @@ void CPPCodeGenerator::writeGetKey() {
|
||||
"GrProcessorKeyBuilder* b) const {\n",
|
||||
fFullName.c_str());
|
||||
for (const auto& param : fSectionAndParameterHelper.getParameters()) {
|
||||
const char* name = param->fName.c_str();
|
||||
String nameString(param->fName);
|
||||
const char* name = nameString.c_str();
|
||||
if (param->fType == *fContext.fColorSpaceXform_Type) {
|
||||
this->writef(" b->add32(GrColorSpaceXform::XformKey(%s.get()));\n",
|
||||
HCodeGenerator::FieldName(name).c_str());
|
||||
@ -580,7 +584,7 @@ void CPPCodeGenerator::writeGetKey() {
|
||||
}
|
||||
if (param->fModifiers.fLayout.fKey != Layout::kNo_Key &&
|
||||
(param->fModifiers.fFlags & Modifiers::kUniform_Flag)) {
|
||||
fErrors.error(param->fPosition,
|
||||
fErrors.error(param->fOffset,
|
||||
"layout(key) may not be specified on uniforms");
|
||||
}
|
||||
switch (param->fModifiers.fLayout.fKey) {
|
||||
@ -608,7 +612,7 @@ void CPPCodeGenerator::writeGetKey() {
|
||||
break;
|
||||
case Layout::kIdentity_Key:
|
||||
if (param->fType.kind() != Type::kMatrix_Kind) {
|
||||
fErrors.error(param->fPosition,
|
||||
fErrors.error(param->fOffset,
|
||||
"layout(key=identity) requires matrix type");
|
||||
}
|
||||
this->writef(" b->add32(%s.isIdentity() ? 1 : 0);\n",
|
||||
@ -656,15 +660,15 @@ bool CPPCodeGenerator::generateCode() {
|
||||
this->writeSetData(uniforms);
|
||||
this->writePrivateVars();
|
||||
for (const auto& u : uniforms) {
|
||||
const char* name = u->fName.c_str();
|
||||
if (needs_uniform_var(*u) && !(u->fModifiers.fFlags & Modifiers::kIn_Flag)) {
|
||||
this->writef(" UniformHandle %sVar;\n", HCodeGenerator::FieldName(name).c_str());
|
||||
this->writef(" UniformHandle %sVar;\n",
|
||||
HCodeGenerator::FieldName(String(u->fName).c_str()).c_str());
|
||||
}
|
||||
}
|
||||
for (const auto& param : fSectionAndParameterHelper.getParameters()) {
|
||||
const char* name = param->fName.c_str();
|
||||
if (needs_uniform_var(*param)) {
|
||||
this->writef(" UniformHandle %sVar;\n", HCodeGenerator::FieldName(name).c_str());
|
||||
this->writef(" UniformHandle %sVar;\n",
|
||||
HCodeGenerator::FieldName(String(param->fName).c_str()).c_str());
|
||||
}
|
||||
}
|
||||
if (fNeedColorSpaceHelper) {
|
||||
@ -681,7 +685,8 @@ bool CPPCodeGenerator::generateCode() {
|
||||
" (void) that;\n",
|
||||
fullName, fullName, fullName);
|
||||
for (const auto& param : fSectionAndParameterHelper.getParameters()) {
|
||||
const char* name = param->fName.c_str();
|
||||
String nameString(param->fName);
|
||||
const char* name = nameString.c_str();
|
||||
this->writef(" if (%s != that.%s) return false;\n",
|
||||
HCodeGenerator::FieldName(name).c_str(),
|
||||
HCodeGenerator::FieldName(name).c_str());
|
||||
|
@ -51,7 +51,6 @@ static const char* SKSL_FP_INCLUDE =
|
||||
#include "sksl_fp.include"
|
||||
;
|
||||
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
Compiler::Compiler(Flags flags)
|
||||
@ -187,20 +186,23 @@ Compiler::Compiler(Flags flags)
|
||||
ADD_TYPE(GSamplerCubeArrayShadow);
|
||||
ADD_TYPE(ColorSpaceXform);
|
||||
|
||||
String skCapsName("sk_Caps");
|
||||
Variable* skCaps = new Variable(Position(), Modifiers(), skCapsName,
|
||||
StringFragment skCapsName("sk_Caps");
|
||||
Variable* skCaps = new Variable(-1, Modifiers(), skCapsName,
|
||||
*fContext.fSkCaps_Type, Variable::kGlobal_Storage);
|
||||
fIRGenerator->fSymbolTable->add(skCapsName, std::unique_ptr<Symbol>(skCaps));
|
||||
|
||||
String skArgsName("sk_Args");
|
||||
Variable* skArgs = new Variable(Position(), Modifiers(), skArgsName,
|
||||
StringFragment skArgsName("sk_Args");
|
||||
Variable* skArgs = new Variable(-1, Modifiers(), skArgsName,
|
||||
*fContext.fSkArgs_Type, Variable::kGlobal_Storage);
|
||||
fIRGenerator->fSymbolTable->add(skArgsName, std::unique_ptr<Symbol>(skArgs));
|
||||
|
||||
Modifiers::Flag ignored1;
|
||||
std::vector<std::unique_ptr<ProgramElement>> ignored2;
|
||||
fIRGenerator->convertProgram(String(SKSL_INCLUDE), *fTypes, &ignored1, &ignored2);
|
||||
fIRGenerator->convertProgram(SKSL_INCLUDE, strlen(SKSL_INCLUDE), *fTypes, &ignored1, &ignored2);
|
||||
fIRGenerator->fSymbolTable->markAllFunctionsBuiltin();
|
||||
if (fErrorCount) {
|
||||
printf("Unexpected errors: %s\n", fErrorText.c_str());
|
||||
}
|
||||
ASSERT(!fErrorCount);
|
||||
}
|
||||
|
||||
@ -260,7 +262,7 @@ void Compiler::addDefinitions(const BasicBlock::Node& node,
|
||||
BinaryExpression* b = (BinaryExpression*) expr;
|
||||
if (b->fOperator == Token::EQ) {
|
||||
this->addDefinition(b->fLeft.get(), &b->fRight, definitions);
|
||||
} else if (Token::IsAssignment(b->fOperator)) {
|
||||
} else if (Compiler::IsAssignment(b->fOperator)) {
|
||||
this->addDefinition(
|
||||
b->fLeft.get(),
|
||||
(std::unique_ptr<Expression>*) &fContext.fDefined_Expression,
|
||||
@ -401,7 +403,7 @@ static bool is_dead(const Expression& lvalue) {
|
||||
* to a dead target and lack of side effects on the left hand side.
|
||||
*/
|
||||
static bool dead_assignment(const BinaryExpression& b) {
|
||||
if (!Token::IsAssignment(b.fOperator)) {
|
||||
if (!Compiler::IsAssignment(b.fOperator)) {
|
||||
return false;
|
||||
}
|
||||
return is_dead(*b.fLeft);
|
||||
@ -540,7 +542,7 @@ void delete_right(BasicBlock* b,
|
||||
static std::unique_ptr<Expression> construct(const Type& type, std::unique_ptr<Expression> v) {
|
||||
std::vector<std::unique_ptr<Expression>> args;
|
||||
args.push_back(std::move(v));
|
||||
auto result = std::unique_ptr<Expression>(new Constructor(Position(), type, std::move(args)));
|
||||
auto result = std::unique_ptr<Expression>(new Constructor(-1, type, std::move(args)));
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -642,7 +644,7 @@ void Compiler::simplifyExpression(DefinitionMap& definitions,
|
||||
if (var.fStorage == Variable::kLocal_Storage && !definitions[&var] &&
|
||||
(*undefinedVariables).find(&var) == (*undefinedVariables).end()) {
|
||||
(*undefinedVariables).insert(&var);
|
||||
this->error(expr->fPosition,
|
||||
this->error(expr->fOffset,
|
||||
"'" + var.fName + "' has not been assigned");
|
||||
}
|
||||
break;
|
||||
@ -877,7 +879,7 @@ static std::unique_ptr<Statement> block_for_case(SwitchStatement* s, SwitchCase*
|
||||
for (const auto& s : statementPtrs) {
|
||||
statements.push_back(std::move(*s));
|
||||
}
|
||||
return std::unique_ptr<Statement>(new Block(Position(), std::move(statements), s->fSymbols));
|
||||
return std::unique_ptr<Statement>(new Block(-1, std::move(statements), s->fSymbols));
|
||||
}
|
||||
|
||||
void Compiler::simplifyStatement(DefinitionMap& definitions,
|
||||
@ -964,7 +966,7 @@ void Compiler::simplifyStatement(DefinitionMap& definitions,
|
||||
break;
|
||||
} else {
|
||||
if (s.fIsStatic && !(fFlags & kPermitInvalidStaticTests_Flag)) {
|
||||
this->error(s.fPosition,
|
||||
this->error(s.fOffset,
|
||||
"static switch contains non-static conditional break");
|
||||
s.fIsStatic = false;
|
||||
}
|
||||
@ -980,7 +982,7 @@ void Compiler::simplifyStatement(DefinitionMap& definitions,
|
||||
(*iter)->setStatement(std::move(newBlock));
|
||||
} else {
|
||||
if (s.fIsStatic && !(fFlags & kPermitInvalidStaticTests_Flag)) {
|
||||
this->error(s.fPosition,
|
||||
this->error(s.fOffset,
|
||||
"static switch contains non-static conditional break");
|
||||
s.fIsStatic = false;
|
||||
}
|
||||
@ -1022,16 +1024,16 @@ void Compiler::scanCFG(FunctionDefinition& f) {
|
||||
for (size_t i = 0; i < cfg.fBlocks.size(); i++) {
|
||||
if (i != cfg.fStart && !cfg.fBlocks[i].fEntrances.size() &&
|
||||
cfg.fBlocks[i].fNodes.size()) {
|
||||
Position p;
|
||||
int offset;
|
||||
switch (cfg.fBlocks[i].fNodes[0].fKind) {
|
||||
case BasicBlock::Node::kStatement_Kind:
|
||||
p = (*cfg.fBlocks[i].fNodes[0].statement())->fPosition;
|
||||
offset = (*cfg.fBlocks[i].fNodes[0].statement())->fOffset;
|
||||
break;
|
||||
case BasicBlock::Node::kExpression_Kind:
|
||||
p = (*cfg.fBlocks[i].fNodes[0].expression())->fPosition;
|
||||
offset = (*cfg.fBlocks[i].fNodes[0].expression())->fOffset;
|
||||
break;
|
||||
}
|
||||
this->error(p, String("unreachable"));
|
||||
this->error(offset, String("unreachable"));
|
||||
}
|
||||
}
|
||||
if (fErrorCount) {
|
||||
@ -1081,14 +1083,14 @@ void Compiler::scanCFG(FunctionDefinition& f) {
|
||||
case Statement::kIf_Kind:
|
||||
if (((const IfStatement&) s).fIsStatic &&
|
||||
!(fFlags & kPermitInvalidStaticTests_Flag)) {
|
||||
this->error(s.fPosition, "static if has non-static test");
|
||||
this->error(s.fOffset, "static if has non-static test");
|
||||
}
|
||||
++iter;
|
||||
break;
|
||||
case Statement::kSwitch_Kind:
|
||||
if (((const SwitchStatement&) s).fIsStatic &&
|
||||
!(fFlags & kPermitInvalidStaticTests_Flag)) {
|
||||
this->error(s.fPosition, "static switch has non-static test");
|
||||
this->error(s.fOffset, "static switch has non-static test");
|
||||
}
|
||||
++iter;
|
||||
break;
|
||||
@ -1121,7 +1123,7 @@ void Compiler::scanCFG(FunctionDefinition& f) {
|
||||
// check for missing return
|
||||
if (f.fDeclaration.fReturnType != *fContext.fVoid_Type) {
|
||||
if (cfg.fBlocks[cfg.fExit].fEntrances.size()) {
|
||||
this->error(f.fPosition, String("function can exit without returning a value"));
|
||||
this->error(f.fOffset, String("function can exit without returning a value"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1135,21 +1137,28 @@ std::unique_ptr<Program> Compiler::convertProgram(Program::Kind kind, String tex
|
||||
Modifiers::Flag ignored;
|
||||
switch (kind) {
|
||||
case Program::kVertex_Kind:
|
||||
fIRGenerator->convertProgram(String(SKSL_VERT_INCLUDE), *fTypes, &ignored, &elements);
|
||||
fIRGenerator->convertProgram(SKSL_VERT_INCLUDE, strlen(SKSL_VERT_INCLUDE), *fTypes,
|
||||
&ignored, &elements);
|
||||
break;
|
||||
case Program::kFragment_Kind:
|
||||
fIRGenerator->convertProgram(String(SKSL_FRAG_INCLUDE), *fTypes, &ignored, &elements);
|
||||
fIRGenerator->convertProgram(SKSL_FRAG_INCLUDE, strlen(SKSL_FRAG_INCLUDE), *fTypes,
|
||||
&ignored, &elements);
|
||||
break;
|
||||
case Program::kGeometry_Kind:
|
||||
fIRGenerator->convertProgram(String(SKSL_GEOM_INCLUDE), *fTypes, &ignored, &elements);
|
||||
fIRGenerator->convertProgram(SKSL_GEOM_INCLUDE, strlen(SKSL_GEOM_INCLUDE), *fTypes,
|
||||
&ignored, &elements);
|
||||
break;
|
||||
case Program::kFragmentProcessor_Kind:
|
||||
fIRGenerator->convertProgram(String(SKSL_FP_INCLUDE), *fTypes, &ignored, &elements);
|
||||
fIRGenerator->convertProgram(SKSL_FP_INCLUDE, strlen(SKSL_FP_INCLUDE), *fTypes,
|
||||
&ignored, &elements);
|
||||
break;
|
||||
}
|
||||
fIRGenerator->fSymbolTable->markAllFunctionsBuiltin();
|
||||
Modifiers::Flag defaultPrecision;
|
||||
fIRGenerator->convertProgram(text, *fTypes, &defaultPrecision, &elements);
|
||||
std::unique_ptr<String> textPtr(new String(std::move(text)));
|
||||
fSource = textPtr.get();
|
||||
fIRGenerator->convertProgram(textPtr->c_str(), textPtr->size(), *fTypes, &defaultPrecision,
|
||||
&elements);
|
||||
if (!fErrorCount) {
|
||||
for (auto& element : elements) {
|
||||
if (element->fKind == ProgramElement::kFunction_Kind) {
|
||||
@ -1157,11 +1166,13 @@ std::unique_ptr<Program> Compiler::convertProgram(Program::Kind kind, String tex
|
||||
}
|
||||
}
|
||||
}
|
||||
auto result = std::unique_ptr<Program>(new Program(kind, settings, defaultPrecision, &fContext,
|
||||
auto result = std::unique_ptr<Program>(new Program(kind, std::move(textPtr), settings,
|
||||
defaultPrecision, &fContext,
|
||||
std::move(elements),
|
||||
fIRGenerator->fSymbolTable,
|
||||
fIRGenerator->fInputs));
|
||||
fIRGenerator->finish();
|
||||
fSource = nullptr;
|
||||
this->writeErrorCount();
|
||||
if (fErrorCount) {
|
||||
return nullptr;
|
||||
@ -1172,8 +1183,10 @@ std::unique_ptr<Program> Compiler::convertProgram(Program::Kind kind, String tex
|
||||
bool Compiler::toSPIRV(const Program& program, OutputStream& out) {
|
||||
#ifdef SK_ENABLE_SPIRV_VALIDATION
|
||||
StringStream buffer;
|
||||
fSource = program.fSource.get();
|
||||
SPIRVCodeGenerator cg(&fContext, &program, this, &buffer);
|
||||
bool result = cg.generateCode();
|
||||
fSource = nullptr;
|
||||
if (result) {
|
||||
spvtools::SpirvTools tools(SPV_ENV_VULKAN_1_0);
|
||||
const String& data = buffer.str();
|
||||
@ -1188,8 +1201,10 @@ bool Compiler::toSPIRV(const Program& program, OutputStream& out) {
|
||||
out.write(data.c_str(), data.size());
|
||||
}
|
||||
#else
|
||||
fSource = program.fSource.get();
|
||||
SPIRVCodeGenerator cg(&fContext, &program, this, &out);
|
||||
bool result = cg.generateCode();
|
||||
fSource = nullptr;
|
||||
#endif
|
||||
this->writeErrorCount();
|
||||
return result;
|
||||
@ -1205,8 +1220,10 @@ bool Compiler::toSPIRV(const Program& program, String* out) {
|
||||
}
|
||||
|
||||
bool Compiler::toGLSL(const Program& program, OutputStream& out) {
|
||||
fSource = program.fSource.get();
|
||||
GLSLCodeGenerator cg(&fContext, &program, this, &out);
|
||||
bool result = cg.generateCode();
|
||||
fSource = nullptr;
|
||||
this->writeErrorCount();
|
||||
return result;
|
||||
}
|
||||
@ -1221,22 +1238,111 @@ bool Compiler::toGLSL(const Program& program, String* out) {
|
||||
}
|
||||
|
||||
bool Compiler::toCPP(const Program& program, String name, OutputStream& out) {
|
||||
fSource = program.fSource.get();
|
||||
CPPCodeGenerator cg(&fContext, &program, this, name, &out);
|
||||
bool result = cg.generateCode();
|
||||
fSource = nullptr;
|
||||
this->writeErrorCount();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Compiler::toH(const Program& program, String name, OutputStream& out) {
|
||||
fSource = program.fSource.get();
|
||||
HCodeGenerator cg(&program, this, name, &out);
|
||||
bool result = cg.generateCode();
|
||||
fSource = nullptr;
|
||||
this->writeErrorCount();
|
||||
return result;
|
||||
}
|
||||
|
||||
void Compiler::error(Position position, String msg) {
|
||||
const char* Compiler::OperatorName(Token::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::LOGICALNOT: return "!";
|
||||
case Token::LOGICALAND: return "&&";
|
||||
case Token::LOGICALOR: return "||";
|
||||
case Token::LOGICALXOR: return "^^";
|
||||
case Token::BITWISENOT: 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::COMMA: return ",";
|
||||
default:
|
||||
ABORT("unsupported operator: %d\n", kind);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Compiler::IsAssignment(Token::Kind op) {
|
||||
switch (op) {
|
||||
case Token::EQ: // fall through
|
||||
case Token::PLUSEQ: // fall through
|
||||
case Token::MINUSEQ: // fall through
|
||||
case Token::STAREQ: // fall through
|
||||
case Token::SLASHEQ: // fall through
|
||||
case Token::PERCENTEQ: // fall through
|
||||
case Token::SHLEQ: // fall through
|
||||
case Token::SHREQ: // fall through
|
||||
case Token::BITWISEOREQ: // fall through
|
||||
case Token::BITWISEXOREQ: // fall through
|
||||
case Token::BITWISEANDEQ: // fall through
|
||||
case Token::LOGICALOREQ: // fall through
|
||||
case Token::LOGICALXOREQ: // fall through
|
||||
case Token::LOGICALANDEQ:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Position Compiler::position(int offset) {
|
||||
ASSERT(fSource);
|
||||
int line = 1;
|
||||
int column = 1;
|
||||
for (int i = 0; i < offset; i++) {
|
||||
if ((*fSource)[i] == '\n') {
|
||||
++line;
|
||||
column = 1;
|
||||
}
|
||||
else {
|
||||
++column;
|
||||
}
|
||||
}
|
||||
return Position(line, column);
|
||||
}
|
||||
|
||||
void Compiler::error(int offset, String msg) {
|
||||
fErrorCount++;
|
||||
fErrorText += "error: " + position.description() + ": " + msg.c_str() + "\n";
|
||||
Position pos = this->position(offset);
|
||||
fErrorText += "error: " + to_string(pos.fLine) + ": " + msg.c_str() + "\n";
|
||||
}
|
||||
|
||||
String Compiler::errorText() {
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include "SkSLCFGGenerator.h"
|
||||
#include "SkSLContext.h"
|
||||
#include "SkSLErrorReporter.h"
|
||||
#include "SkSLIRGenerator.h"
|
||||
|
||||
#define SK_FRAGCOLOR_BUILTIN 10001
|
||||
#define SK_IN_BUILTIN 10002
|
||||
@ -70,7 +69,7 @@ public:
|
||||
|
||||
bool toH(const Program& program, String name, OutputStream& out);
|
||||
|
||||
void error(Position position, String msg) override;
|
||||
void error(int offset, String msg) override;
|
||||
|
||||
String errorText();
|
||||
|
||||
@ -80,6 +79,10 @@ public:
|
||||
return fErrorCount;
|
||||
}
|
||||
|
||||
static const char* OperatorName(Token::Kind token);
|
||||
|
||||
static bool IsAssignment(Token::Kind token);
|
||||
|
||||
private:
|
||||
void addDefinition(const Expression* lvalue, std::unique_ptr<Expression>* expr,
|
||||
DefinitionMap* definitions);
|
||||
@ -114,11 +117,14 @@ private:
|
||||
|
||||
void scanCFG(FunctionDefinition& f);
|
||||
|
||||
Position position(int offset);
|
||||
|
||||
std::shared_ptr<SymbolTable> fTypes;
|
||||
IRGenerator* fIRGenerator;
|
||||
String fSkiaVertText; // FIXME store parsed version instead
|
||||
int fFlags;
|
||||
|
||||
const String* fSource;
|
||||
Context fContext;
|
||||
int fErrorCount;
|
||||
String fErrorText;
|
||||
|
@ -19,172 +19,172 @@ namespace SkSL {
|
||||
class Context {
|
||||
public:
|
||||
Context()
|
||||
: fInvalid_Type(new Type(String("<INVALID>")))
|
||||
, fVoid_Type(new Type(String("void")))
|
||||
, fDouble_Type(new Type(String("double"), Type::kFloat_NumberKind))
|
||||
, fDouble2_Type(new Type(String("double2"), *fDouble_Type, 2))
|
||||
, fDouble3_Type(new Type(String("double3"), *fDouble_Type, 3))
|
||||
, fDouble4_Type(new Type(String("double4"), *fDouble_Type, 4))
|
||||
, fFloat_Type(new Type(String("float"), Type::kFloat_NumberKind))
|
||||
, fFloat2_Type(new Type(String("float2"), *fFloat_Type, 2))
|
||||
, fFloat3_Type(new Type(String("float3"), *fFloat_Type, 3))
|
||||
, fFloat4_Type(new Type(String("float4"), *fFloat_Type, 4))
|
||||
, fHalf_Type(new Type(String("half"), Type::kFloat_NumberKind))
|
||||
, fHalf2_Type(new Type(String("half2"), *fHalf_Type, 2))
|
||||
, fHalf3_Type(new Type(String("half3"), *fHalf_Type, 3))
|
||||
, fHalf4_Type(new Type(String("half4"), *fHalf_Type, 4))
|
||||
, fUInt_Type(new Type(String("uint"), Type::kUnsigned_NumberKind))
|
||||
, fUInt2_Type(new Type(String("uint2"), *fUInt_Type, 2))
|
||||
, fUInt3_Type(new Type(String("uint3"), *fUInt_Type, 3))
|
||||
, fUInt4_Type(new Type(String("uint4"), *fUInt_Type, 4))
|
||||
, fInt_Type(new Type(String("int"), Type::kSigned_NumberKind))
|
||||
, fInt2_Type(new Type(String("int2"), *fInt_Type, 2))
|
||||
, fInt3_Type(new Type(String("int3"), *fInt_Type, 3))
|
||||
, fInt4_Type(new Type(String("int4"), *fInt_Type, 4))
|
||||
, fUShort_Type(new Type(String("ushort"), Type::kUnsigned_NumberKind))
|
||||
, fUShort2_Type(new Type(String("ushort2"), *fUShort_Type, 2))
|
||||
, fUShort3_Type(new Type(String("ushort3"), *fUShort_Type, 3))
|
||||
, fUShort4_Type(new Type(String("ushort4"), *fUShort_Type, 4))
|
||||
, fShort_Type(new Type(String("short"), Type::kSigned_NumberKind))
|
||||
, fShort2_Type(new Type(String("short2"), *fShort_Type, 2))
|
||||
, fShort3_Type(new Type(String("short3"), *fShort_Type, 3))
|
||||
, fShort4_Type(new Type(String("short4"), *fShort_Type, 4))
|
||||
, fBool_Type(new Type(String("bool"), Type::kNonnumeric_NumberKind))
|
||||
, fBool2_Type(new Type(String("bool2"), *fBool_Type, 2))
|
||||
, fBool3_Type(new Type(String("bool3"), *fBool_Type, 3))
|
||||
, fBool4_Type(new Type(String("bool4"), *fBool_Type, 4))
|
||||
, fFloat2x2_Type(new Type(String("float2x2"), *fFloat_Type, 2, 2))
|
||||
, fFloat2x3_Type(new Type(String("float2x3"), *fFloat_Type, 2, 3))
|
||||
, fFloat2x4_Type(new Type(String("float2x4"), *fFloat_Type, 2, 4))
|
||||
, fFloat3x2_Type(new Type(String("float3x2"), *fFloat_Type, 3, 2))
|
||||
, fFloat3x3_Type(new Type(String("float3x3"), *fFloat_Type, 3, 3))
|
||||
, fFloat3x4_Type(new Type(String("float3x4"), *fFloat_Type, 3, 4))
|
||||
, fFloat4x2_Type(new Type(String("float4x2"), *fFloat_Type, 4, 2))
|
||||
, fFloat4x3_Type(new Type(String("float4x3"), *fFloat_Type, 4, 3))
|
||||
, fFloat4x4_Type(new Type(String("float4x4"), *fFloat_Type, 4, 4))
|
||||
, fHalf2x2_Type(new Type(String("half2x2"), *fHalf_Type, 2, 2))
|
||||
, fHalf2x3_Type(new Type(String("half2x3"), *fHalf_Type, 2, 3))
|
||||
, fHalf2x4_Type(new Type(String("half2x4"), *fHalf_Type, 2, 4))
|
||||
, fHalf3x2_Type(new Type(String("half3x2"), *fHalf_Type, 3, 2))
|
||||
, fHalf3x3_Type(new Type(String("half3x3"), *fHalf_Type, 3, 3))
|
||||
, fHalf3x4_Type(new Type(String("half3x4"), *fHalf_Type, 3, 4))
|
||||
, fHalf4x2_Type(new Type(String("half4x2"), *fHalf_Type, 4, 2))
|
||||
, fHalf4x3_Type(new Type(String("half4x3"), *fHalf_Type, 4, 3))
|
||||
, fHalf4x4_Type(new Type(String("half4x4"), *fHalf_Type, 4, 4))
|
||||
, fDouble2x2_Type(new Type(String("double2x2"), *fDouble_Type, 2, 2))
|
||||
, fDouble2x3_Type(new Type(String("double2x3"), *fDouble_Type, 2, 3))
|
||||
, fDouble2x4_Type(new Type(String("double2x4"), *fDouble_Type, 2, 4))
|
||||
, fDouble3x2_Type(new Type(String("double3x2"), *fDouble_Type, 3, 2))
|
||||
, fDouble3x3_Type(new Type(String("double3x3"), *fDouble_Type, 3, 3))
|
||||
, fDouble3x4_Type(new Type(String("double3x4"), *fDouble_Type, 3, 4))
|
||||
, fDouble4x2_Type(new Type(String("double4x2"), *fDouble_Type, 4, 2))
|
||||
, fDouble4x3_Type(new Type(String("double4x3"), *fDouble_Type, 4, 3))
|
||||
, fDouble4x4_Type(new Type(String("double4x4"), *fDouble_Type, 4, 4))
|
||||
, fSampler1D_Type(new Type(String("sampler1D"), SpvDim1D, false, false, false, true))
|
||||
, fSampler2D_Type(new Type(String("sampler2D"), SpvDim2D, false, false, false, true))
|
||||
, fSampler3D_Type(new Type(String("sampler3D"), SpvDim3D, false, false, false, true))
|
||||
, fSamplerExternalOES_Type(new Type(String("samplerExternalOES"), SpvDim2D, false, false,
|
||||
: fInvalid_Type(new Type("<INVALID>"))
|
||||
, fVoid_Type(new Type("void"))
|
||||
, fDouble_Type(new Type("double", Type::kFloat_NumberKind))
|
||||
, fDouble2_Type(new Type("double2", *fDouble_Type, 2))
|
||||
, fDouble3_Type(new Type("double3", *fDouble_Type, 3))
|
||||
, fDouble4_Type(new Type("double4", *fDouble_Type, 4))
|
||||
, fFloat_Type(new Type("float", Type::kFloat_NumberKind))
|
||||
, fFloat2_Type(new Type("float2", *fFloat_Type, 2))
|
||||
, fFloat3_Type(new Type("float3", *fFloat_Type, 3))
|
||||
, fFloat4_Type(new Type("float4", *fFloat_Type, 4))
|
||||
, fHalf_Type(new Type("half", Type::kFloat_NumberKind))
|
||||
, fHalf2_Type(new Type("half2", *fHalf_Type, 2))
|
||||
, fHalf3_Type(new Type("half3", *fHalf_Type, 3))
|
||||
, fHalf4_Type(new Type("half4", *fHalf_Type, 4))
|
||||
, fUInt_Type(new Type("uint", Type::kUnsigned_NumberKind))
|
||||
, fUInt2_Type(new Type("uint2", *fUInt_Type, 2))
|
||||
, fUInt3_Type(new Type("uint3", *fUInt_Type, 3))
|
||||
, fUInt4_Type(new Type("uint4", *fUInt_Type, 4))
|
||||
, fInt_Type(new Type("int", Type::kSigned_NumberKind))
|
||||
, fInt2_Type(new Type("int2", *fInt_Type, 2))
|
||||
, fInt3_Type(new Type("int3", *fInt_Type, 3))
|
||||
, fInt4_Type(new Type("int4", *fInt_Type, 4))
|
||||
, fUShort_Type(new Type("ushort", Type::kUnsigned_NumberKind))
|
||||
, fUShort2_Type(new Type("ushort2", *fUShort_Type, 2))
|
||||
, fUShort3_Type(new Type("ushort3", *fUShort_Type, 3))
|
||||
, fUShort4_Type(new Type("ushort4", *fUShort_Type, 4))
|
||||
, fShort_Type(new Type("short", Type::kSigned_NumberKind))
|
||||
, fShort2_Type(new Type("short2", *fShort_Type, 2))
|
||||
, fShort3_Type(new Type("short3", *fShort_Type, 3))
|
||||
, fShort4_Type(new Type("short4", *fShort_Type, 4))
|
||||
, fBool_Type(new Type("bool", Type::kNonnumeric_NumberKind))
|
||||
, fBool2_Type(new Type("bool2", *fBool_Type, 2))
|
||||
, fBool3_Type(new Type("bool3", *fBool_Type, 3))
|
||||
, fBool4_Type(new Type("bool4", *fBool_Type, 4))
|
||||
, fFloat2x2_Type(new Type("float2x2", *fFloat_Type, 2, 2))
|
||||
, fFloat2x3_Type(new Type("float2x3", *fFloat_Type, 2, 3))
|
||||
, fFloat2x4_Type(new Type("float2x4", *fFloat_Type, 2, 4))
|
||||
, fFloat3x2_Type(new Type("float3x2", *fFloat_Type, 3, 2))
|
||||
, fFloat3x3_Type(new Type("float3x3", *fFloat_Type, 3, 3))
|
||||
, fFloat3x4_Type(new Type("float3x4", *fFloat_Type, 3, 4))
|
||||
, fFloat4x2_Type(new Type("float4x2", *fFloat_Type, 4, 2))
|
||||
, fFloat4x3_Type(new Type("float4x3", *fFloat_Type, 4, 3))
|
||||
, fFloat4x4_Type(new Type("float4x4", *fFloat_Type, 4, 4))
|
||||
, fHalf2x2_Type(new Type("half2x2", *fHalf_Type, 2, 2))
|
||||
, fHalf2x3_Type(new Type("half2x3", *fHalf_Type, 2, 3))
|
||||
, fHalf2x4_Type(new Type("half2x4", *fHalf_Type, 2, 4))
|
||||
, fHalf3x2_Type(new Type("half3x2", *fHalf_Type, 3, 2))
|
||||
, fHalf3x3_Type(new Type("half3x3", *fHalf_Type, 3, 3))
|
||||
, fHalf3x4_Type(new Type("half3x4", *fHalf_Type, 3, 4))
|
||||
, fHalf4x2_Type(new Type("half4x2", *fHalf_Type, 4, 2))
|
||||
, fHalf4x3_Type(new Type("half4x3", *fHalf_Type, 4, 3))
|
||||
, fHalf4x4_Type(new Type("half4x4", *fHalf_Type, 4, 4))
|
||||
, fDouble2x2_Type(new Type("double2x2", *fDouble_Type, 2, 2))
|
||||
, fDouble2x3_Type(new Type("double2x3", *fDouble_Type, 2, 3))
|
||||
, fDouble2x4_Type(new Type("double2x4", *fDouble_Type, 2, 4))
|
||||
, fDouble3x2_Type(new Type("double3x2", *fDouble_Type, 3, 2))
|
||||
, fDouble3x3_Type(new Type("double3x3", *fDouble_Type, 3, 3))
|
||||
, fDouble3x4_Type(new Type("double3x4", *fDouble_Type, 3, 4))
|
||||
, fDouble4x2_Type(new Type("double4x2", *fDouble_Type, 4, 2))
|
||||
, fDouble4x3_Type(new Type("double4x3", *fDouble_Type, 4, 3))
|
||||
, fDouble4x4_Type(new Type("double4x4", *fDouble_Type, 4, 4))
|
||||
, fSampler1D_Type(new Type("sampler1D", SpvDim1D, false, false, false, true))
|
||||
, fSampler2D_Type(new Type("sampler2D", SpvDim2D, false, false, false, true))
|
||||
, fSampler3D_Type(new Type("sampler3D", SpvDim3D, false, false, false, true))
|
||||
, fSamplerExternalOES_Type(new Type("samplerExternalOES", SpvDim2D, false, false,
|
||||
false, true))
|
||||
, fSamplerCube_Type(new Type(String("samplerCube"), SpvDimCube, false, false, false, true))
|
||||
, fSampler2DRect_Type(new Type(String("sampler2DRect"), SpvDimRect, false, false, false, true))
|
||||
, fSampler1DArray_Type(new Type(String("sampler1DArray")))
|
||||
, fSampler2DArray_Type(new Type(String("sampler2DArray")))
|
||||
, fSamplerCubeArray_Type(new Type(String("samplerCubeArray")))
|
||||
, fSamplerBuffer_Type(new Type(String("samplerBuffer"), SpvDimBuffer, false, false, false,
|
||||
, fSamplerCube_Type(new Type("samplerCube", SpvDimCube, false, false, false, true))
|
||||
, fSampler2DRect_Type(new Type("sampler2DRect", SpvDimRect, false, false, false, true))
|
||||
, fSampler1DArray_Type(new Type("sampler1DArray"))
|
||||
, fSampler2DArray_Type(new Type("sampler2DArray"))
|
||||
, fSamplerCubeArray_Type(new Type("samplerCubeArray"))
|
||||
, fSamplerBuffer_Type(new Type("samplerBuffer", SpvDimBuffer, false, false, false,
|
||||
true))
|
||||
, fSampler2DMS_Type(new Type(String("sampler2DMS")))
|
||||
, fSampler2DMSArray_Type(new Type(String("sampler2DMSArray")))
|
||||
, fSampler1DShadow_Type(new Type(String("sampler1DShadow")))
|
||||
, fSampler2DShadow_Type(new Type(String("sampler2DShadow")))
|
||||
, fSamplerCubeShadow_Type(new Type(String("samplerCubeShadow")))
|
||||
, fSampler2DRectShadow_Type(new Type(String("sampler2DRectShadow")))
|
||||
, fSampler1DArrayShadow_Type(new Type(String("sampler1DArrayShadow")))
|
||||
, fSampler2DArrayShadow_Type(new Type(String("sampler2DArrayShadow")))
|
||||
, fSamplerCubeArrayShadow_Type(new Type(String("samplerCubeArrayShadow")))
|
||||
, fSampler2DMS_Type(new Type("sampler2DMS"))
|
||||
, fSampler2DMSArray_Type(new Type("sampler2DMSArray"))
|
||||
, fSampler1DShadow_Type(new Type("sampler1DShadow"))
|
||||
, fSampler2DShadow_Type(new Type("sampler2DShadow"))
|
||||
, fSamplerCubeShadow_Type(new Type("samplerCubeShadow"))
|
||||
, fSampler2DRectShadow_Type(new Type("sampler2DRectShadow"))
|
||||
, fSampler1DArrayShadow_Type(new Type("sampler1DArrayShadow"))
|
||||
, fSampler2DArrayShadow_Type(new Type("sampler2DArrayShadow"))
|
||||
, fSamplerCubeArrayShadow_Type(new Type("samplerCubeArrayShadow"))
|
||||
|
||||
// Related to below FIXME, gsampler*s don't currently expand to cover integer case.
|
||||
, fISampler2D_Type(new Type(String("isampler2D"), SpvDim2D, false, false, false, true))
|
||||
, fISampler2D_Type(new Type("isampler2D", SpvDim2D, false, false, false, true))
|
||||
|
||||
// FIXME express these as "gimage2D" that expand to image2D, iimage2D, and uimage2D.
|
||||
, fImage2D_Type(new Type(String("image2D"), SpvDim2D, false, false, false, true))
|
||||
, fIImage2D_Type(new Type(String("iimage2D"), SpvDim2D, false, false, false, true))
|
||||
, fImage2D_Type(new Type("image2D", SpvDim2D, false, false, false, true))
|
||||
, fIImage2D_Type(new Type("iimage2D", SpvDim2D, false, false, false, true))
|
||||
|
||||
// FIXME express these as "gsubpassInput" that expand to subpassInput, isubpassInput,
|
||||
// and usubpassInput.
|
||||
, fSubpassInput_Type(new Type(String("subpassInput"), SpvDimSubpassData, false, false,
|
||||
false, false))
|
||||
, fSubpassInputMS_Type(new Type(String("subpassInputMS"), SpvDimSubpassData, false, false,
|
||||
true, false))
|
||||
, fSubpassInput_Type(new Type("subpassInput", SpvDimSubpassData, false, false,
|
||||
false, false))
|
||||
, fSubpassInputMS_Type(new Type("subpassInputMS", SpvDimSubpassData, false, false,
|
||||
true, false))
|
||||
|
||||
// FIXME figure out what we're supposed to do with the gsampler et al. types)
|
||||
, fGSampler1D_Type(new Type(String("$gsampler1D"), static_type(*fSampler1D_Type)))
|
||||
, fGSampler2D_Type(new Type(String("$gsampler2D"), static_type(*fSampler2D_Type)))
|
||||
, fGSampler3D_Type(new Type(String("$gsampler3D"), static_type(*fSampler3D_Type)))
|
||||
, fGSamplerCube_Type(new Type(String("$gsamplerCube"), static_type(*fSamplerCube_Type)))
|
||||
, fGSampler2DRect_Type(new Type(String("$gsampler2DRect"), static_type(*fSampler2DRect_Type)))
|
||||
, fGSampler1DArray_Type(new Type(String("$gsampler1DArray"),
|
||||
, fGSampler1D_Type(new Type("$gsampler1D", static_type(*fSampler1D_Type)))
|
||||
, fGSampler2D_Type(new Type("$gsampler2D", static_type(*fSampler2D_Type)))
|
||||
, fGSampler3D_Type(new Type("$gsampler3D", static_type(*fSampler3D_Type)))
|
||||
, fGSamplerCube_Type(new Type("$gsamplerCube", static_type(*fSamplerCube_Type)))
|
||||
, fGSampler2DRect_Type(new Type("$gsampler2DRect", static_type(*fSampler2DRect_Type)))
|
||||
, fGSampler1DArray_Type(new Type("$gsampler1DArray",
|
||||
static_type(*fSampler1DArray_Type)))
|
||||
, fGSampler2DArray_Type(new Type(String("$gsampler2DArray"),
|
||||
, fGSampler2DArray_Type(new Type("$gsampler2DArray",
|
||||
static_type(*fSampler2DArray_Type)))
|
||||
, fGSamplerCubeArray_Type(new Type(String("$gsamplerCubeArray"),
|
||||
, fGSamplerCubeArray_Type(new Type("$gsamplerCubeArray",
|
||||
static_type(*fSamplerCubeArray_Type)))
|
||||
, fGSamplerBuffer_Type(new Type(String("$gsamplerBuffer"), static_type(*fSamplerBuffer_Type)))
|
||||
, fGSampler2DMS_Type(new Type(String("$gsampler2DMS"), static_type(*fSampler2DMS_Type)))
|
||||
, fGSampler2DMSArray_Type(new Type(String("$gsampler2DMSArray"),
|
||||
, fGSamplerBuffer_Type(new Type("$gsamplerBuffer", static_type(*fSamplerBuffer_Type)))
|
||||
, fGSampler2DMS_Type(new Type("$gsampler2DMS", static_type(*fSampler2DMS_Type)))
|
||||
, fGSampler2DMSArray_Type(new Type("$gsampler2DMSArray",
|
||||
static_type(*fSampler2DMSArray_Type)))
|
||||
, fGSampler2DArrayShadow_Type(new Type(String("$gsampler2DArrayShadow"),
|
||||
, fGSampler2DArrayShadow_Type(new Type("$gsampler2DArrayShadow",
|
||||
static_type(*fSampler2DArrayShadow_Type)))
|
||||
, fGSamplerCubeArrayShadow_Type(new Type(String("$gsamplerCubeArrayShadow"),
|
||||
, fGSamplerCubeArrayShadow_Type(new Type("$gsamplerCubeArrayShadow",
|
||||
static_type(*fSamplerCubeArrayShadow_Type)))
|
||||
, fGenType_Type(new Type(String("$genType"), { fFloat_Type.get(), fFloat2_Type.get(),
|
||||
fFloat3_Type.get(), fFloat4_Type.get() }))
|
||||
, fGenHType_Type(new Type(String("$genHType"), { fHalf_Type.get(), fHalf2_Type.get(),
|
||||
fHalf3_Type.get(), fHalf4_Type.get() }))
|
||||
, fGenDType_Type(new Type(String("$genDType"), { fDouble_Type.get(), fDouble2_Type.get(),
|
||||
fDouble3_Type.get(), fDouble4_Type.get() }))
|
||||
, fGenIType_Type(new Type(String("$genIType"), { fInt_Type.get(), fInt2_Type.get(),
|
||||
fInt3_Type.get(), fInt4_Type.get() }))
|
||||
, fGenUType_Type(new Type(String("$genUType"), { fUInt_Type.get(), fUInt2_Type.get(),
|
||||
fUInt3_Type.get(), fUInt4_Type.get() }))
|
||||
, fGenBType_Type(new Type(String("$genBType"), { fBool_Type.get(), fBool2_Type.get(),
|
||||
fBool3_Type.get(), fBool4_Type.get() }))
|
||||
, fMat_Type(new Type(String("$mat"), { fFloat2x2_Type.get(), fFloat2x3_Type.get(),
|
||||
fFloat2x4_Type.get(), fFloat3x2_Type.get(),
|
||||
fFloat3x3_Type.get(), fFloat3x4_Type.get(),
|
||||
fFloat4x2_Type.get(), fFloat4x3_Type.get(),
|
||||
fFloat4x4_Type.get(), fHalf2x2_Type.get(),
|
||||
fHalf2x3_Type.get(), fHalf2x4_Type.get(),
|
||||
fHalf3x2_Type.get(), fHalf3x3_Type.get(),
|
||||
fHalf3x4_Type.get(), fHalf4x2_Type.get(),
|
||||
fHalf4x3_Type.get(), fHalf4x4_Type.get(),
|
||||
fDouble2x2_Type.get(), fDouble2x3_Type.get(),
|
||||
fDouble2x4_Type.get(), fDouble3x2_Type.get(),
|
||||
fDouble3x3_Type.get(), fDouble3x4_Type.get(),
|
||||
fDouble4x2_Type.get(), fDouble4x3_Type.get(),
|
||||
fDouble4x4_Type.get() }))
|
||||
, fVec_Type(new Type(String("$vec"), { fInvalid_Type.get(), fFloat2_Type.get(),
|
||||
, fGenType_Type(new Type("$genType", { fFloat_Type.get(), fFloat2_Type.get(),
|
||||
fFloat3_Type.get(), fFloat4_Type.get() }))
|
||||
, fGVec_Type(new Type(String("$gvec")))
|
||||
, fGVec2_Type(new Type(String("$gfloat2")))
|
||||
, fGVec3_Type(new Type(String("$gfloat3")))
|
||||
, fGVec4_Type(new Type(String("$gfloat4"), static_type(*fFloat4_Type)))
|
||||
, fHVec_Type(new Type(String("$hvec"), { fInvalid_Type.get(), fHalf2_Type.get(),
|
||||
, fGenHType_Type(new Type("$genHType", { fHalf_Type.get(), fHalf2_Type.get(),
|
||||
fHalf3_Type.get(), fHalf4_Type.get() }))
|
||||
, fDVec_Type(new Type(String("$dvec"), { fInvalid_Type.get(), fDouble2_Type.get(),
|
||||
, fGenDType_Type(new Type("$genDType", { fDouble_Type.get(), fDouble2_Type.get(),
|
||||
fDouble3_Type.get(), fDouble4_Type.get() }))
|
||||
, fIVec_Type(new Type(String("$ivec"), { fInvalid_Type.get(), fInt2_Type.get(),
|
||||
, fGenIType_Type(new Type("$genIType", { fInt_Type.get(), fInt2_Type.get(),
|
||||
fInt3_Type.get(), fInt4_Type.get() }))
|
||||
, fUVec_Type(new Type(String("$uvec"), { fInvalid_Type.get(), fUInt2_Type.get(),
|
||||
, fGenUType_Type(new Type("$genUType", { fUInt_Type.get(), fUInt2_Type.get(),
|
||||
fUInt3_Type.get(), fUInt4_Type.get() }))
|
||||
, fSVec_Type(new Type(String("$svec"), { fInvalid_Type.get(), fShort2_Type.get(),
|
||||
fShort3_Type.get(), fShort4_Type.get() }))
|
||||
, fUSVec_Type(new Type(String("$usvec"), { fInvalid_Type.get(), fUShort2_Type.get(),
|
||||
fUShort3_Type.get(), fUShort4_Type.get() }))
|
||||
, fBVec_Type(new Type(String("$bvec"), { fInvalid_Type.get(), fBool2_Type.get(),
|
||||
, fGenBType_Type(new Type("$genBType", { fBool_Type.get(), fBool2_Type.get(),
|
||||
fBool3_Type.get(), fBool4_Type.get() }))
|
||||
, fSkCaps_Type(new Type(String("$sk_Caps")))
|
||||
, fSkArgs_Type(new Type(String("$sk_Args")))
|
||||
, fColorSpaceXform_Type(new Type(String("colorSpaceXform"), *fFloat_Type, 4, 4))
|
||||
, fMat_Type(new Type("$mat", { fFloat2x2_Type.get(), fFloat2x3_Type.get(),
|
||||
fFloat2x4_Type.get(), fFloat3x2_Type.get(),
|
||||
fFloat3x3_Type.get(), fFloat3x4_Type.get(),
|
||||
fFloat4x2_Type.get(), fFloat4x3_Type.get(),
|
||||
fFloat4x4_Type.get(), fHalf2x2_Type.get(),
|
||||
fHalf2x3_Type.get(), fHalf2x4_Type.get(),
|
||||
fHalf3x2_Type.get(), fHalf3x3_Type.get(),
|
||||
fHalf3x4_Type.get(), fHalf4x2_Type.get(),
|
||||
fHalf4x3_Type.get(), fHalf4x4_Type.get(),
|
||||
fDouble2x2_Type.get(), fDouble2x3_Type.get(),
|
||||
fDouble2x4_Type.get(), fDouble3x2_Type.get(),
|
||||
fDouble3x3_Type.get(), fDouble3x4_Type.get(),
|
||||
fDouble4x2_Type.get(), fDouble4x3_Type.get(),
|
||||
fDouble4x4_Type.get() }))
|
||||
, fVec_Type(new Type("$vec", { fInvalid_Type.get(), fFloat2_Type.get(),
|
||||
fFloat3_Type.get(), fFloat4_Type.get() }))
|
||||
, fGVec_Type(new Type("$gvec"))
|
||||
, fGVec2_Type(new Type("$gfloat2"))
|
||||
, fGVec3_Type(new Type("$gfloat3"))
|
||||
, fGVec4_Type(new Type("$gfloat4", static_type(*fFloat4_Type)))
|
||||
, fHVec_Type(new Type("$hvec", { fInvalid_Type.get(), fHalf2_Type.get(),
|
||||
fHalf3_Type.get(), fHalf4_Type.get() }))
|
||||
, fDVec_Type(new Type("$dvec", { fInvalid_Type.get(), fDouble2_Type.get(),
|
||||
fDouble3_Type.get(), fDouble4_Type.get() }))
|
||||
, fIVec_Type(new Type("$ivec", { fInvalid_Type.get(), fInt2_Type.get(),
|
||||
fInt3_Type.get(), fInt4_Type.get() }))
|
||||
, fUVec_Type(new Type("$uvec", { fInvalid_Type.get(), fUInt2_Type.get(),
|
||||
fUInt3_Type.get(), fUInt4_Type.get() }))
|
||||
, fSVec_Type(new Type("$svec", { fInvalid_Type.get(), fShort2_Type.get(),
|
||||
fShort3_Type.get(), fShort4_Type.get() }))
|
||||
, fUSVec_Type(new Type("$usvec", { fInvalid_Type.get(), fUShort2_Type.get(),
|
||||
fUShort3_Type.get(), fUShort4_Type.get() }))
|
||||
, fBVec_Type(new Type("$bvec", { fInvalid_Type.get(), fBool2_Type.get(),
|
||||
fBool3_Type.get(), fBool4_Type.get() }))
|
||||
, fSkCaps_Type(new Type("$sk_Caps"))
|
||||
, fSkArgs_Type(new Type("$sk_Args"))
|
||||
, fColorSpaceXform_Type(new Type("colorSpaceXform", *fFloat_Type, 4, 4))
|
||||
, fDefined_Expression(new Defined(*fInvalid_Type)) {}
|
||||
|
||||
static std::vector<const Type*> static_type(const Type& t) {
|
||||
@ -343,14 +343,14 @@ private:
|
||||
class Defined : public Expression {
|
||||
public:
|
||||
Defined(const Type& type)
|
||||
: INHERITED(Position(), kDefined_Kind, type) {}
|
||||
: INHERITED(-1, kDefined_Kind, type) {}
|
||||
|
||||
bool hasSideEffects() const override {
|
||||
return false;
|
||||
}
|
||||
|
||||
String description() const override {
|
||||
return String("<defined>");
|
||||
return "<defined>";
|
||||
}
|
||||
|
||||
typedef Expression INHERITED;
|
||||
|
@ -19,11 +19,11 @@ class ErrorReporter {
|
||||
public:
|
||||
virtual ~ErrorReporter() {}
|
||||
|
||||
void error(Position position, const char* msg) {
|
||||
this->error(position, String(msg));
|
||||
void error(int offset, const char* msg) {
|
||||
this->error(offset, String(msg));
|
||||
}
|
||||
|
||||
virtual void error(Position position, String msg) = 0;
|
||||
virtual void error(int offset, String msg) = 0;
|
||||
|
||||
virtual int errorCount() = 0;
|
||||
};
|
||||
|
@ -42,6 +42,19 @@ void GLSLCodeGenerator::write(const String& s) {
|
||||
this->write(s.c_str());
|
||||
}
|
||||
|
||||
void GLSLCodeGenerator::write(StringFragment s) {
|
||||
if (!s.fLength) {
|
||||
return;
|
||||
}
|
||||
if (fAtLineStart) {
|
||||
for (int i = 0; i < fIndentation; i++) {
|
||||
fOut->writeText(" ");
|
||||
}
|
||||
}
|
||||
fOut->write(s.fChars, s.fLength);
|
||||
fAtLineStart = false;
|
||||
}
|
||||
|
||||
void GLSLCodeGenerator::writeLine(const String& s) {
|
||||
this->writeLine(s.c_str());
|
||||
}
|
||||
@ -51,7 +64,9 @@ void GLSLCodeGenerator::writeLine() {
|
||||
}
|
||||
|
||||
void GLSLCodeGenerator::writeExtension(const Extension& ext) {
|
||||
this->writeLine("#extension " + ext.fName + " : enable");
|
||||
this->write("#extension ");
|
||||
this->write(ext.fName);
|
||||
this->writeLine(" : enable");
|
||||
}
|
||||
|
||||
void GLSLCodeGenerator::writeType(const Type& type) {
|
||||
@ -59,19 +74,23 @@ void GLSLCodeGenerator::writeType(const Type& type) {
|
||||
for (const Type* search : fWrittenStructs) {
|
||||
if (*search == type) {
|
||||
// already written
|
||||
this->write(type.name());
|
||||
this->write(type.fName);
|
||||
return;
|
||||
}
|
||||
}
|
||||
fWrittenStructs.push_back(&type);
|
||||
this->writeLine("struct " + type.name() + " {");
|
||||
this->write("struct ");
|
||||
this->write(type.fName);
|
||||
this->writeLine(" {");
|
||||
fIndentation++;
|
||||
for (const auto& f : type.fields()) {
|
||||
this->writeModifiers(f.fModifiers, false);
|
||||
this->writeTypePrecision(*f.fType);
|
||||
// sizes (which must be static in structs) are part of the type name here
|
||||
this->writeType(*f.fType);
|
||||
this->writeLine(" " + f.fName + ";");
|
||||
this->write(" ");
|
||||
this->write(f.fName);
|
||||
this->writeLine(";");
|
||||
}
|
||||
fIndentation--;
|
||||
this->write("}");
|
||||
@ -138,12 +157,12 @@ void GLSLCodeGenerator::writeType(const Type& type) {
|
||||
this->write("uint");
|
||||
}
|
||||
else {
|
||||
this->write(type.name());
|
||||
this->write(type.fName);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
this->write(type.name());
|
||||
this->write(type.fName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -210,8 +229,8 @@ void GLSLCodeGenerator::writeMinAbsHack(Expression& absExpr, Expression& otherEx
|
||||
ASSERT(!fProgram.fSettings.fCaps->canUseMinAndAbsTogether());
|
||||
String tmpVar1 = "minAbsHackVar" + to_string(fVarCount++);
|
||||
String tmpVar2 = "minAbsHackVar" + to_string(fVarCount++);
|
||||
this->fFunctionHeader += " " + absExpr.fType.name() + " " + tmpVar1 + ";\n";
|
||||
this->fFunctionHeader += " " + otherExpr.fType.name() + " " + tmpVar2 + ";\n";
|
||||
this->fFunctionHeader += String(" ") + absExpr.fType.fName + " " + tmpVar1 + ";\n";
|
||||
this->fFunctionHeader += String(" ") + otherExpr.fType.fName + " " + tmpVar2 + ";\n";
|
||||
this->write("((" + tmpVar1 + " = ");
|
||||
this->writeExpression(absExpr, kTopLevel_Precedence);
|
||||
this->write(") < (" + tmpVar2 + " = ");
|
||||
@ -503,7 +522,9 @@ void GLSLCodeGenerator::writeBinaryExpression(const BinaryExpression& b,
|
||||
this->write("(");
|
||||
}
|
||||
this->writeExpression(*b.fLeft, precedence);
|
||||
this->write(" " + Token::OperatorName(b.fOperator) + " ");
|
||||
this->write(" ");
|
||||
this->write(Compiler::OperatorName(b.fOperator));
|
||||
this->write(" ");
|
||||
this->writeExpression(*b.fRight, precedence);
|
||||
if (precedence >= parentPrecedence) {
|
||||
this->write(")");
|
||||
@ -530,7 +551,7 @@ void GLSLCodeGenerator::writePrefixExpression(const PrefixExpression& p,
|
||||
if (kPrefix_Precedence >= parentPrecedence) {
|
||||
this->write("(");
|
||||
}
|
||||
this->write(Token::OperatorName(p.fOperator));
|
||||
this->write(Compiler::OperatorName(p.fOperator));
|
||||
this->writeExpression(*p.fOperand, kPrefix_Precedence);
|
||||
if (kPrefix_Precedence >= parentPrecedence) {
|
||||
this->write(")");
|
||||
@ -543,7 +564,7 @@ void GLSLCodeGenerator::writePostfixExpression(const PostfixExpression& p,
|
||||
this->write("(");
|
||||
}
|
||||
this->writeExpression(*p.fOperand, kPostfix_Precedence);
|
||||
this->write(Token::OperatorName(p.fOperator));
|
||||
this->write(Compiler::OperatorName(p.fOperator));
|
||||
if (kPostfix_Precedence >= parentPrecedence) {
|
||||
this->write(")");
|
||||
}
|
||||
|
@ -90,6 +90,8 @@ protected:
|
||||
|
||||
void write(const String& s);
|
||||
|
||||
void write(StringFragment s);
|
||||
|
||||
void writeLine(const String& s);
|
||||
|
||||
virtual void writeHeader();
|
||||
|
@ -23,17 +23,17 @@ HCodeGenerator::HCodeGenerator(const Program* program, ErrorReporter* errors, St
|
||||
, fSectionAndParameterHelper(*program, *errors) {}
|
||||
|
||||
String HCodeGenerator::ParameterType(const Type& type) {
|
||||
if (type.fName == "float2") {
|
||||
if (type.name() == "float2") {
|
||||
return "SkPoint";
|
||||
} else if (type.fName == "int4") {
|
||||
} else if (type.name() == "int4") {
|
||||
return "SkIRect";
|
||||
} else if (type.fName == "float4") {
|
||||
} else if (type.name() == "float4") {
|
||||
return "SkRect";
|
||||
} else if (type.fName == "float4x4") {
|
||||
} else if (type.name() == "float4x4") {
|
||||
return "SkMatrix44";
|
||||
} else if (type.kind() == Type::kSampler_Kind) {
|
||||
return "sk_sp<GrTextureProxy>";
|
||||
} else if (type.fName == "colorSpaceXform") {
|
||||
} else if (type.name() == "colorSpaceXform") {
|
||||
return "sk_sp<GrColorSpaceXform>";
|
||||
}
|
||||
return type.name();
|
||||
@ -127,7 +127,7 @@ void HCodeGenerator::writeMake() {
|
||||
separator = "";
|
||||
for (const auto& param : fSectionAndParameterHelper.getParameters()) {
|
||||
this->writef("%s%s %s", separator, ParameterType(param->fType).c_str(),
|
||||
param->fName.c_str());
|
||||
String(param->fName).c_str());
|
||||
separator = ", ";
|
||||
}
|
||||
this->writeSection(CONSTRUCTOR_PARAMS_SECTION, separator);
|
||||
@ -136,7 +136,7 @@ void HCodeGenerator::writeMake() {
|
||||
fFullName.c_str());
|
||||
separator = "";
|
||||
for (const auto& param : fSectionAndParameterHelper.getParameters()) {
|
||||
this->writef("%s%s", separator, param->fName.c_str());
|
||||
this->writef("%s%s", separator, String(param->fName).c_str());
|
||||
separator = ", ";
|
||||
}
|
||||
this->writeExtraConstructorParams(separator);
|
||||
@ -148,7 +148,7 @@ void HCodeGenerator::writeMake() {
|
||||
void HCodeGenerator::failOnSection(const char* section, const char* msg) {
|
||||
std::vector<const Section*> s = fSectionAndParameterHelper.getSections(section);
|
||||
if (s.size()) {
|
||||
fErrors.error(s[0]->fPosition, String("@") + section + " " + msg);
|
||||
fErrors.error(s[0]->fOffset, String("@") + section + " " + msg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -165,7 +165,7 @@ void HCodeGenerator::writeConstructor() {
|
||||
const char* separator = "";
|
||||
for (const auto& param : fSectionAndParameterHelper.getParameters()) {
|
||||
this->writef("%s%s %s", separator, ParameterType(param->fType).c_str(),
|
||||
param->fName.c_str());
|
||||
String(param->fName).c_str());
|
||||
separator = ", ";
|
||||
}
|
||||
this->writeSection(CONSTRUCTOR_PARAMS_SECTION, separator);
|
||||
@ -177,7 +177,8 @@ void HCodeGenerator::writeConstructor() {
|
||||
this->writef(")");
|
||||
this->writeSection(INITIALIZERS_SECTION, "\n , ");
|
||||
for (const auto& param : fSectionAndParameterHelper.getParameters()) {
|
||||
const char* name = param->fName.c_str();
|
||||
String nameString(param->fName);
|
||||
const char* name = nameString.c_str();
|
||||
if (param->fType.kind() == Type::kSampler_Kind) {
|
||||
this->writef("\n , %s(std::move(%s)", FieldName(name).c_str(), name);
|
||||
for (const Section* s : fSectionAndParameterHelper.getSections(
|
||||
@ -201,7 +202,7 @@ void HCodeGenerator::writeConstructor() {
|
||||
for (const auto& param : fSectionAndParameterHelper.getParameters()) {
|
||||
if (param->fType.kind() == Type::kSampler_Kind) {
|
||||
this->writef(" this->addTextureSampler(&%s);\n",
|
||||
FieldName(param->fName.c_str()).c_str());
|
||||
FieldName(String(param->fName).c_str()).c_str());
|
||||
}
|
||||
}
|
||||
for (const Section* s : fSectionAndParameterHelper.getSections(COORD_TRANSFORM_SECTION)) {
|
||||
@ -216,8 +217,8 @@ void HCodeGenerator::writeConstructor() {
|
||||
void HCodeGenerator::writeFields() {
|
||||
this->writeSection(FIELDS_SECTION);
|
||||
for (const auto& param : fSectionAndParameterHelper.getParameters()) {
|
||||
const char* name = param->fName.c_str();
|
||||
this->writef(" %s %s;\n", FieldType(param->fType).c_str(), FieldName(name).c_str());
|
||||
this->writef(" %s %s;\n", FieldType(param->fType).c_str(),
|
||||
FieldName(String(param->fName).c_str()).c_str());
|
||||
}
|
||||
for (const Section* s : fSectionAndParameterHelper.getSections(COORD_TRANSFORM_SECTION)) {
|
||||
this->writef(" GrCoordTransform %sCoordTransform;\n",
|
||||
@ -245,7 +246,8 @@ bool HCodeGenerator::generateCode() {
|
||||
if (param->fType.kind() == Type::kSampler_Kind) {
|
||||
continue;
|
||||
}
|
||||
const char* name = param->fName.c_str();
|
||||
String nameString(param->fName);
|
||||
const char* name = nameString.c_str();
|
||||
this->writef(" %s %s() const { return %s; }\n",
|
||||
FieldType(param->fType).c_str(), name, FieldName(name).c_str());
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -61,7 +61,8 @@ public:
|
||||
IRGenerator(const Context* context, std::shared_ptr<SymbolTable> root,
|
||||
ErrorReporter& errorReporter);
|
||||
|
||||
void convertProgram(String text,
|
||||
void convertProgram(const char* text,
|
||||
size_t length,
|
||||
SymbolTable& types,
|
||||
Modifiers::Flag* defaultPrecision,
|
||||
std::vector<std::unique_ptr<ProgramElement>>* result);
|
||||
@ -103,26 +104,26 @@ private:
|
||||
const ASTModifiersDeclaration& m);
|
||||
|
||||
const Type* convertType(const ASTType& type);
|
||||
std::unique_ptr<Expression> call(Position position,
|
||||
std::unique_ptr<Expression> call(int offset,
|
||||
const FunctionDeclaration& function,
|
||||
std::vector<std::unique_ptr<Expression>> arguments);
|
||||
int callCost(const FunctionDeclaration& function,
|
||||
const std::vector<std::unique_ptr<Expression>>& arguments);
|
||||
std::unique_ptr<Expression> call(Position position, std::unique_ptr<Expression> function,
|
||||
std::unique_ptr<Expression> call(int offset, std::unique_ptr<Expression> function,
|
||||
std::vector<std::unique_ptr<Expression>> arguments);
|
||||
int coercionCost(const Expression& expr, const Type& type);
|
||||
std::unique_ptr<Expression> coerce(std::unique_ptr<Expression> expr, const Type& type);
|
||||
std::unique_ptr<Block> convertBlock(const ASTBlock& block);
|
||||
std::unique_ptr<Statement> convertBreak(const ASTBreakStatement& b);
|
||||
std::unique_ptr<Expression> convertNumberConstructor(
|
||||
Position position,
|
||||
int offset,
|
||||
const Type& type,
|
||||
std::vector<std::unique_ptr<Expression>> params);
|
||||
std::unique_ptr<Expression> convertCompoundConstructor(
|
||||
Position position,
|
||||
int offset,
|
||||
const Type& type,
|
||||
std::vector<std::unique_ptr<Expression>> params);
|
||||
std::unique_ptr<Expression> convertConstructor(Position position,
|
||||
std::unique_ptr<Expression> convertConstructor(int offset,
|
||||
const Type& type,
|
||||
std::vector<std::unique_ptr<Expression>> params);
|
||||
std::unique_ptr<Statement> convertContinue(const ASTContinueStatement& c);
|
||||
@ -142,13 +143,13 @@ private:
|
||||
std::unique_ptr<Expression> convertPrefixExpression(const ASTPrefixExpression& expression);
|
||||
std::unique_ptr<Statement> convertReturn(const ASTReturnStatement& r);
|
||||
std::unique_ptr<Section> convertSection(const ASTSection& e);
|
||||
std::unique_ptr<Expression> getCap(Position position, String name);
|
||||
std::unique_ptr<Expression> getArg(Position position, String name);
|
||||
std::unique_ptr<Expression> getCap(int offset, String name);
|
||||
std::unique_ptr<Expression> getArg(int offset, String name);
|
||||
std::unique_ptr<Expression> convertSuffixExpression(const ASTSuffixExpression& expression);
|
||||
std::unique_ptr<Expression> convertField(std::unique_ptr<Expression> base,
|
||||
const String& field);
|
||||
StringFragment field);
|
||||
std::unique_ptr<Expression> convertSwizzle(std::unique_ptr<Expression> base,
|
||||
const String& fields);
|
||||
StringFragment 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);
|
||||
|
1343
src/sksl/SkSLLayoutLexer.cpp
Normal file
1343
src/sksl/SkSLLayoutLexer.cpp
Normal file
File diff suppressed because it is too large
Load Diff
95
src/sksl/SkSLLayoutLexer.h
Normal file
95
src/sksl/SkSLLayoutLexer.h
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2017 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
/*****************************************************************************************
|
||||
******************** This file was generated by sksllex. Do not edit. *******************
|
||||
*****************************************************************************************/
|
||||
#ifndef SKSL_LayoutLexer
|
||||
#define SKSL_LayoutLexer
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
namespace SkSL {
|
||||
|
||||
struct LayoutToken {
|
||||
enum Kind {
|
||||
#undef END_OF_FILE
|
||||
END_OF_FILE,
|
||||
#undef LOCATION
|
||||
LOCATION,
|
||||
#undef OFFSET
|
||||
OFFSET,
|
||||
#undef BINDING
|
||||
BINDING,
|
||||
#undef INDEX
|
||||
INDEX,
|
||||
#undef SET
|
||||
SET,
|
||||
#undef BUILTIN
|
||||
BUILTIN,
|
||||
#undef INPUT_ATTACHMENT_INDEX
|
||||
INPUT_ATTACHMENT_INDEX,
|
||||
#undef ORIGIN_UPPER_LEFT
|
||||
ORIGIN_UPPER_LEFT,
|
||||
#undef OVERRIDE_COVERAGE
|
||||
OVERRIDE_COVERAGE,
|
||||
#undef BLEND_SUPPORT_ALL_EQUATIONS
|
||||
BLEND_SUPPORT_ALL_EQUATIONS,
|
||||
#undef PUSH_CONSTANT
|
||||
PUSH_CONSTANT,
|
||||
#undef POINTS
|
||||
POINTS,
|
||||
#undef LINES
|
||||
LINES,
|
||||
#undef LINE_STRIP
|
||||
LINE_STRIP,
|
||||
#undef LINES_ADJACENCY
|
||||
LINES_ADJACENCY,
|
||||
#undef TRIANGLES
|
||||
TRIANGLES,
|
||||
#undef TRIANGLE_STRIP
|
||||
TRIANGLE_STRIP,
|
||||
#undef TRIANGLES_ADJACENCY
|
||||
TRIANGLES_ADJACENCY,
|
||||
#undef MAX_VERTICES
|
||||
MAX_VERTICES,
|
||||
#undef INVOCATIONS
|
||||
INVOCATIONS,
|
||||
#undef WHEN
|
||||
WHEN,
|
||||
#undef KEY
|
||||
KEY,
|
||||
#undef INVALID
|
||||
INVALID,
|
||||
};
|
||||
|
||||
LayoutToken() : fKind(Kind::INVALID), fOffset(-1), fLength(-1) {}
|
||||
|
||||
LayoutToken(Kind kind, int offset, int length)
|
||||
: fKind(kind), fOffset(offset), fLength(length) {}
|
||||
|
||||
Kind fKind;
|
||||
int fOffset;
|
||||
int fLength;
|
||||
};
|
||||
|
||||
class LayoutLexer {
|
||||
public:
|
||||
void start(const char* text, size_t length) {
|
||||
fText = text;
|
||||
fLength = length;
|
||||
fOffset = 0;
|
||||
}
|
||||
|
||||
LayoutToken next();
|
||||
|
||||
private:
|
||||
const char* fText;
|
||||
int fLength;
|
||||
int fOffset;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
#endif
|
1925
src/sksl/SkSLLexer.cpp
Normal file
1925
src/sksl/SkSLLexer.cpp
Normal file
File diff suppressed because it is too large
Load Diff
238
src/sksl/SkSLLexer.h
Normal file
238
src/sksl/SkSLLexer.h
Normal file
@ -0,0 +1,238 @@
|
||||
/*
|
||||
* Copyright 2017 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
/*****************************************************************************************
|
||||
******************** This file was generated by sksllex. Do not edit. *******************
|
||||
*****************************************************************************************/
|
||||
#ifndef SKSL_Lexer
|
||||
#define SKSL_Lexer
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
namespace SkSL {
|
||||
|
||||
struct Token {
|
||||
enum Kind {
|
||||
#undef END_OF_FILE
|
||||
END_OF_FILE,
|
||||
#undef FLOAT_LITERAL
|
||||
FLOAT_LITERAL,
|
||||
#undef INT_LITERAL
|
||||
INT_LITERAL,
|
||||
#undef TRUE_LITERAL
|
||||
TRUE_LITERAL,
|
||||
#undef FALSE_LITERAL
|
||||
FALSE_LITERAL,
|
||||
#undef IF
|
||||
IF,
|
||||
#undef STATIC_IF
|
||||
STATIC_IF,
|
||||
#undef ELSE
|
||||
ELSE,
|
||||
#undef FOR
|
||||
FOR,
|
||||
#undef WHILE
|
||||
WHILE,
|
||||
#undef DO
|
||||
DO,
|
||||
#undef SWITCH
|
||||
SWITCH,
|
||||
#undef STATIC_SWITCH
|
||||
STATIC_SWITCH,
|
||||
#undef CASE
|
||||
CASE,
|
||||
#undef DEFAULT
|
||||
DEFAULT,
|
||||
#undef BREAK
|
||||
BREAK,
|
||||
#undef CONTINUE
|
||||
CONTINUE,
|
||||
#undef DISCARD
|
||||
DISCARD,
|
||||
#undef RETURN
|
||||
RETURN,
|
||||
#undef IN
|
||||
IN,
|
||||
#undef OUT
|
||||
OUT,
|
||||
#undef INOUT
|
||||
INOUT,
|
||||
#undef UNIFORM
|
||||
UNIFORM,
|
||||
#undef CONST
|
||||
CONST,
|
||||
#undef LOWP
|
||||
LOWP,
|
||||
#undef MEDIUMP
|
||||
MEDIUMP,
|
||||
#undef HIGHP
|
||||
HIGHP,
|
||||
#undef FLAT
|
||||
FLAT,
|
||||
#undef NOPERSPECTIVE
|
||||
NOPERSPECTIVE,
|
||||
#undef READONLY
|
||||
READONLY,
|
||||
#undef WRITEONLY
|
||||
WRITEONLY,
|
||||
#undef COHERENT
|
||||
COHERENT,
|
||||
#undef VOLATILE
|
||||
VOLATILE,
|
||||
#undef RESTRICT
|
||||
RESTRICT,
|
||||
#undef BUFFER
|
||||
BUFFER,
|
||||
#undef HASSIDEEFFECTS
|
||||
HASSIDEEFFECTS,
|
||||
#undef STRUCT
|
||||
STRUCT,
|
||||
#undef LAYOUT
|
||||
LAYOUT,
|
||||
#undef PRECISION
|
||||
PRECISION,
|
||||
#undef IDENTIFIER
|
||||
IDENTIFIER,
|
||||
#undef DIRECTIVE
|
||||
DIRECTIVE,
|
||||
#undef SECTION
|
||||
SECTION,
|
||||
#undef LPAREN
|
||||
LPAREN,
|
||||
#undef RPAREN
|
||||
RPAREN,
|
||||
#undef LBRACE
|
||||
LBRACE,
|
||||
#undef RBRACE
|
||||
RBRACE,
|
||||
#undef LBRACKET
|
||||
LBRACKET,
|
||||
#undef RBRACKET
|
||||
RBRACKET,
|
||||
#undef DOT
|
||||
DOT,
|
||||
#undef COMMA
|
||||
COMMA,
|
||||
#undef PLUSPLUS
|
||||
PLUSPLUS,
|
||||
#undef MINUSMINUS
|
||||
MINUSMINUS,
|
||||
#undef PLUS
|
||||
PLUS,
|
||||
#undef MINUS
|
||||
MINUS,
|
||||
#undef STAR
|
||||
STAR,
|
||||
#undef SLASH
|
||||
SLASH,
|
||||
#undef PERCENT
|
||||
PERCENT,
|
||||
#undef SHL
|
||||
SHL,
|
||||
#undef SHR
|
||||
SHR,
|
||||
#undef BITWISEOR
|
||||
BITWISEOR,
|
||||
#undef BITWISEXOR
|
||||
BITWISEXOR,
|
||||
#undef BITWISEAND
|
||||
BITWISEAND,
|
||||
#undef BITWISENOT
|
||||
BITWISENOT,
|
||||
#undef LOGICALOR
|
||||
LOGICALOR,
|
||||
#undef LOGICALXOR
|
||||
LOGICALXOR,
|
||||
#undef LOGICALAND
|
||||
LOGICALAND,
|
||||
#undef LOGICALNOT
|
||||
LOGICALNOT,
|
||||
#undef QUESTION
|
||||
QUESTION,
|
||||
#undef COLON
|
||||
COLON,
|
||||
#undef EQ
|
||||
EQ,
|
||||
#undef EQEQ
|
||||
EQEQ,
|
||||
#undef NEQ
|
||||
NEQ,
|
||||
#undef GT
|
||||
GT,
|
||||
#undef LT
|
||||
LT,
|
||||
#undef GTEQ
|
||||
GTEQ,
|
||||
#undef LTEQ
|
||||
LTEQ,
|
||||
#undef PLUSEQ
|
||||
PLUSEQ,
|
||||
#undef MINUSEQ
|
||||
MINUSEQ,
|
||||
#undef STAREQ
|
||||
STAREQ,
|
||||
#undef SLASHEQ
|
||||
SLASHEQ,
|
||||
#undef PERCENTEQ
|
||||
PERCENTEQ,
|
||||
#undef SHLEQ
|
||||
SHLEQ,
|
||||
#undef SHREQ
|
||||
SHREQ,
|
||||
#undef BITWISEOREQ
|
||||
BITWISEOREQ,
|
||||
#undef BITWISEXOREQ
|
||||
BITWISEXOREQ,
|
||||
#undef BITWISEANDEQ
|
||||
BITWISEANDEQ,
|
||||
#undef LOGICALOREQ
|
||||
LOGICALOREQ,
|
||||
#undef LOGICALXOREQ
|
||||
LOGICALXOREQ,
|
||||
#undef LOGICALANDEQ
|
||||
LOGICALANDEQ,
|
||||
#undef SEMICOLON
|
||||
SEMICOLON,
|
||||
#undef ARROW
|
||||
ARROW,
|
||||
#undef COLONCOLON
|
||||
COLONCOLON,
|
||||
#undef WHITESPACE
|
||||
WHITESPACE,
|
||||
#undef LINE_COMMENT
|
||||
LINE_COMMENT,
|
||||
#undef BLOCK_COMMENT
|
||||
BLOCK_COMMENT,
|
||||
#undef INVALID
|
||||
INVALID,
|
||||
};
|
||||
|
||||
Token() : fKind(Kind::INVALID), fOffset(-1), fLength(-1) {}
|
||||
|
||||
Token(Kind kind, int offset, int length) : fKind(kind), fOffset(offset), fLength(length) {}
|
||||
|
||||
Kind fKind;
|
||||
int fOffset;
|
||||
int fLength;
|
||||
};
|
||||
|
||||
class Lexer {
|
||||
public:
|
||||
void start(const char* text, size_t length) {
|
||||
fText = text;
|
||||
fLength = length;
|
||||
fOffset = 0;
|
||||
}
|
||||
|
||||
Token next();
|
||||
|
||||
private:
|
||||
const char* fText;
|
||||
int fLength;
|
||||
int fOffset;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
#endif
|
@ -7,26 +7,6 @@
|
||||
|
||||
#include "stdio.h"
|
||||
#include "SkSLParser.h"
|
||||
#include "SkSLToken.h"
|
||||
|
||||
#define register
|
||||
#include "disable_flex_warnings.h"
|
||||
#include "lex.sksl.c"
|
||||
static_assert(YY_FLEX_MAJOR_VERSION * 10000 + YY_FLEX_MINOR_VERSION * 100 +
|
||||
YY_FLEX_SUBMINOR_VERSION >= 20601,
|
||||
"we require Flex 2.6.1 or better for security reasons");
|
||||
#undef register
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#include "lex.layout.h"
|
||||
#include "ast/SkSLASTBinaryExpression.h"
|
||||
#include "ast/SkSLASTBlock.h"
|
||||
#include "ast/SkSLASTBoolLiteral.h"
|
||||
@ -83,7 +63,7 @@ public:
|
||||
|
||||
bool checkValid() {
|
||||
if (fParser->fDepth > MAX_PARSE_DEPTH) {
|
||||
fParser->error(fParser->peek().fPosition, String("exceeded max parse depth"));
|
||||
fParser->error(fParser->peek(), String("exceeded max parse depth"));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -93,20 +73,12 @@ private:
|
||||
Parser* fParser;
|
||||
};
|
||||
|
||||
Parser::Parser(String text, SymbolTable& types, ErrorReporter& errors)
|
||||
: fPushback(Position(-1, -1), Token::INVALID_TOKEN, String())
|
||||
Parser::Parser(const char* text, size_t length, SymbolTable& types, ErrorReporter& errors)
|
||||
: fText(text)
|
||||
, fPushback(Token::INVALID, -1, -1)
|
||||
, fTypes(types)
|
||||
, fErrors(errors) {
|
||||
sksllex_init(&fScanner);
|
||||
layoutlex_init(&fLayoutScanner);
|
||||
fBuffer = sksl_scan_string(text.c_str(), fScanner);
|
||||
skslset_lineno(1, fScanner);
|
||||
}
|
||||
|
||||
Parser::~Parser() {
|
||||
sksl_delete_buffer(fBuffer, fScanner);
|
||||
sksllex_destroy(fScanner);
|
||||
layoutlex_destroy(fLayoutScanner);
|
||||
fLexer.start(text, length);
|
||||
}
|
||||
|
||||
/* (precision | directive | section | declaration)* END_OF_FILE */
|
||||
@ -148,53 +120,39 @@ std::vector<std::unique_ptr<ASTDeclaration>> Parser::file() {
|
||||
}
|
||||
}
|
||||
|
||||
Token Parser::nextRawToken(bool needText) {
|
||||
if (fPushback.fKind != Token::INVALID_TOKEN) {
|
||||
Token result(std::move(fPushback));
|
||||
fPushback.fKind = Token::INVALID_TOKEN;
|
||||
fPushback.fText.clear();
|
||||
Token Parser::nextRawToken() {
|
||||
if (fPushback.fKind != Token::INVALID) {
|
||||
Token result = fPushback;
|
||||
fPushback.fKind = Token::INVALID;
|
||||
return result;
|
||||
}
|
||||
Token::Kind kind = (Token::Kind) sksllex(fScanner);
|
||||
if (!needText) {
|
||||
switch (kind) {
|
||||
case Token::Kind::DIRECTIVE: // fall through
|
||||
case Token::Kind::IDENTIFIER: // fall through
|
||||
case Token::Kind::INT_LITERAL: // fall through
|
||||
case Token::Kind::FLOAT_LITERAL: // fall through
|
||||
case Token::Kind::SECTION:
|
||||
needText = true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
static String unavailable("<unavailable>");
|
||||
return Token(Position(skslget_lineno(fScanner), -1), kind,
|
||||
needText ? String(skslget_text(fScanner)) : unavailable);
|
||||
Token result = fLexer.next();
|
||||
return result;
|
||||
}
|
||||
|
||||
Token Parser::nextToken() {
|
||||
Token token;
|
||||
do {
|
||||
token = this->nextRawToken(false);
|
||||
} while (token.fKind == Token::WHITESPACE);
|
||||
Token token = this->nextRawToken();
|
||||
while (token.fKind == Token::WHITESPACE || token.fKind == Token::LINE_COMMENT ||
|
||||
token.fKind == Token::BLOCK_COMMENT) {
|
||||
token = this->nextRawToken();
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
void Parser::pushback(Token t) {
|
||||
ASSERT(fPushback.fKind == Token::INVALID_TOKEN);
|
||||
ASSERT(fPushback.fKind == Token::INVALID);
|
||||
fPushback = std::move(t);
|
||||
}
|
||||
|
||||
Token Parser::peek() {
|
||||
if (fPushback.fKind == Token::INVALID_TOKEN) {
|
||||
if (fPushback.fKind == Token::INVALID) {
|
||||
fPushback = this->nextToken();
|
||||
}
|
||||
return fPushback;
|
||||
}
|
||||
|
||||
bool Parser::checkNext(Token::Kind kind, Token* result) {
|
||||
if (fPushback.fKind != Token::INVALID_TOKEN && fPushback.fKind != kind) {
|
||||
if (fPushback.fKind != Token::INVALID && fPushback.fKind != kind) {
|
||||
return false;
|
||||
}
|
||||
Token next = this->nextToken();
|
||||
@ -216,25 +174,25 @@ bool Parser::expect(Token::Kind kind, const char* expected, Token* result) {
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
if (next.fText.size()) {
|
||||
this->error(next.fPosition, "expected " + String(expected) + ", but found '" +
|
||||
next.fText + "'");
|
||||
} else {
|
||||
this->error(next.fPosition, "parse error, recompile in debug mode for details");
|
||||
}
|
||||
this->error(next, "expected " + String(expected) + ", but found '" +
|
||||
this->text(next) + "'");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void Parser::error(Position p, const char* msg) {
|
||||
this->error(p, String(msg));
|
||||
StringFragment Parser::text(Token token) {
|
||||
return StringFragment(fText + token.fOffset, token.fLength);
|
||||
}
|
||||
|
||||
void Parser::error(Position p, String msg) {
|
||||
fErrors.error(p, msg);
|
||||
void Parser::error(Token token, String msg) {
|
||||
this->error(token.fOffset, msg);
|
||||
}
|
||||
|
||||
bool Parser::isType(const String& name) {
|
||||
void Parser::error(int offset, String msg) {
|
||||
fErrors.error(offset, msg);
|
||||
}
|
||||
|
||||
bool Parser::isType(StringFragment name) {
|
||||
return nullptr != fTypes[name];
|
||||
}
|
||||
|
||||
@ -256,8 +214,8 @@ std::unique_ptr<ASTDeclaration> Parser::precision() {
|
||||
result = Modifiers::kHighp_Flag;
|
||||
break;
|
||||
default:
|
||||
this->error(p.fPosition, "expected 'lowp', 'mediump', or 'highp', but found '" +
|
||||
p.fText + "'");
|
||||
this->error(p, "expected 'lowp', 'mediump', or 'highp', but found '" +
|
||||
this->text(p) + "'");
|
||||
return nullptr;
|
||||
}
|
||||
// FIXME handle the type
|
||||
@ -265,7 +223,7 @@ std::unique_ptr<ASTDeclaration> Parser::precision() {
|
||||
return nullptr;
|
||||
}
|
||||
this->expect(Token::SEMICOLON, "';'");
|
||||
return std::unique_ptr<ASTDeclaration>(new ASTPrecision(p.fPosition, result));
|
||||
return std::unique_ptr<ASTDeclaration>(new ASTPrecision(p.fOffset, result));
|
||||
}
|
||||
|
||||
/* DIRECTIVE(#version) INT_LITERAL ("es" | "compatibility")? |
|
||||
@ -275,16 +233,18 @@ std::unique_ptr<ASTDeclaration> Parser::directive() {
|
||||
if (!this->expect(Token::DIRECTIVE, "a directive", &start)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (start.fText == "#version") {
|
||||
StringFragment text = this->text(start);
|
||||
if (text == "#version") {
|
||||
this->expect(Token::INT_LITERAL, "a version number");
|
||||
Token next = this->peek();
|
||||
if (next.fText == "es" || next.fText == "compatibility") {
|
||||
StringFragment nextText = this->text(next);
|
||||
if (nextText == "es" || nextText == "compatibility") {
|
||||
this->nextToken();
|
||||
}
|
||||
// version is ignored for now; it will eventually become an error when we stop pretending
|
||||
// to be GLSL
|
||||
return nullptr;
|
||||
} else if (start.fText == "#extension") {
|
||||
} else if (text == "#extension") {
|
||||
Token name;
|
||||
if (!this->expect(Token::IDENTIFIER, "an identifier", &name)) {
|
||||
return nullptr;
|
||||
@ -296,10 +256,10 @@ std::unique_ptr<ASTDeclaration> Parser::directive() {
|
||||
if (!this->expect(Token::IDENTIFIER, "an identifier")) {
|
||||
return nullptr;
|
||||
}
|
||||
return std::unique_ptr<ASTDeclaration>(new ASTExtension(start.fPosition,
|
||||
std::move(name.fText)));
|
||||
return std::unique_ptr<ASTDeclaration>(new ASTExtension(start.fOffset,
|
||||
String(this->text(name))));
|
||||
} else {
|
||||
this->error(start.fPosition, "unsupported directive '" + start.fText + "'");
|
||||
this->error(start, "unsupported directive '" + this->text(start) + "'");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
@ -318,7 +278,7 @@ std::unique_ptr<ASTDeclaration> Parser::section() {
|
||||
if (!this->expect(Token::IDENTIFIER, "an identifier", &argToken)) {
|
||||
return nullptr;
|
||||
}
|
||||
argument = argToken.fText;
|
||||
argument = this->text(argToken);
|
||||
if (!this->expect(Token::RPAREN, "')'")) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -329,7 +289,7 @@ std::unique_ptr<ASTDeclaration> Parser::section() {
|
||||
String text;
|
||||
int level = 1;
|
||||
for (;;) {
|
||||
Token next = this->nextRawToken(true);
|
||||
Token next = this->nextRawToken();
|
||||
switch (next.fKind) {
|
||||
case Token::LBRACE:
|
||||
++level;
|
||||
@ -338,7 +298,7 @@ std::unique_ptr<ASTDeclaration> Parser::section() {
|
||||
--level;
|
||||
break;
|
||||
case Token::END_OF_FILE:
|
||||
this->error(start.fPosition, "reached end of file while parsing section");
|
||||
this->error(start, "reached end of file while parsing section");
|
||||
return nullptr;
|
||||
default:
|
||||
break;
|
||||
@ -346,10 +306,13 @@ std::unique_ptr<ASTDeclaration> Parser::section() {
|
||||
if (!level) {
|
||||
break;
|
||||
}
|
||||
text += next.fText;
|
||||
text += this->text(next);
|
||||
}
|
||||
return std::unique_ptr<ASTDeclaration>(new ASTSection(start.fPosition,
|
||||
String(start.fText.c_str() + 1),
|
||||
StringFragment name = this->text(start);
|
||||
++name.fChars;
|
||||
--name.fLength;
|
||||
return std::unique_ptr<ASTDeclaration>(new ASTSection(start.fOffset,
|
||||
String(name),
|
||||
argument,
|
||||
text));
|
||||
}
|
||||
@ -359,7 +322,7 @@ std::unique_ptr<ASTDeclaration> Parser::section() {
|
||||
std::unique_ptr<ASTDeclaration> Parser::declaration() {
|
||||
Modifiers modifiers = this->modifiers();
|
||||
Token lookahead = this->peek();
|
||||
if (lookahead.fKind == Token::IDENTIFIER && !this->isType(lookahead.fText)) {
|
||||
if (lookahead.fKind == Token::IDENTIFIER && !this->isType(this->text(lookahead))) {
|
||||
// we have an identifier that's not a type, could be the start of an interface block
|
||||
return this->interfaceBlock(modifiers);
|
||||
}
|
||||
@ -403,14 +366,14 @@ std::unique_ptr<ASTDeclaration> Parser::declaration() {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return std::unique_ptr<ASTDeclaration>(new ASTFunction(name.fPosition,
|
||||
return std::unique_ptr<ASTDeclaration>(new ASTFunction(name.fOffset,
|
||||
modifiers,
|
||||
std::move(type),
|
||||
std::move(name.fText),
|
||||
this->text(name),
|
||||
std::move(parameters),
|
||||
std::move(body)));
|
||||
} else {
|
||||
return this->varDeclarationEnd(modifiers, std::move(type), std::move(name.fText));
|
||||
return this->varDeclarationEnd(modifiers, std::move(type), this->text(name));
|
||||
}
|
||||
}
|
||||
|
||||
@ -425,7 +388,7 @@ std::unique_ptr<ASTVarDeclarations> Parser::varDeclarations() {
|
||||
if (!this->expect(Token::IDENTIFIER, "an identifier", &name)) {
|
||||
return nullptr;
|
||||
}
|
||||
return this->varDeclarationEnd(modifiers, std::move(type), std::move(name.fText));
|
||||
return this->varDeclarationEnd(modifiers, std::move(type), this->text(name));
|
||||
}
|
||||
|
||||
/* STRUCT IDENTIFIER LBRACE varDeclaration* RBRACE */
|
||||
@ -450,7 +413,7 @@ std::unique_ptr<ASTType> Parser::structDeclaration() {
|
||||
auto type = (const Type*) fTypes[decl->fType->fName];
|
||||
for (int i = (int) var.fSizes.size() - 1; i >= 0; i--) {
|
||||
if (!var.fSizes[i] || var.fSizes[i]->fKind != ASTExpression::kInt_Kind) {
|
||||
this->error(decl->fPosition, "array size in struct field must be a constant");
|
||||
this->error(decl->fOffset, "array size in struct field must be a constant");
|
||||
return nullptr;
|
||||
}
|
||||
uint64_t columns = ((ASTIntLiteral&) *var.fSizes[i]).fValue;
|
||||
@ -460,15 +423,16 @@ std::unique_ptr<ASTType> Parser::structDeclaration() {
|
||||
}
|
||||
fields.push_back(Type::Field(decl->fModifiers, var.fName, type));
|
||||
if (var.fValue) {
|
||||
this->error(decl->fPosition, "initializers are not permitted on struct fields");
|
||||
this->error(decl->fOffset, "initializers are not permitted on struct fields");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!this->expect(Token::RBRACE, "'}'")) {
|
||||
return nullptr;
|
||||
}
|
||||
fTypes.add(name.fText, std::unique_ptr<Type>(new Type(name.fPosition, name.fText, fields)));
|
||||
return std::unique_ptr<ASTType>(new ASTType(name.fPosition, name.fText,
|
||||
fTypes.add(this->text(name), std::unique_ptr<Type>(new Type(name.fOffset, this->text(name),
|
||||
fields)));
|
||||
return std::unique_ptr<ASTType>(new ASTType(name.fOffset, this->text(name),
|
||||
ASTType::kStruct_Kind, std::vector<int>()));
|
||||
}
|
||||
|
||||
@ -482,11 +446,11 @@ std::unique_ptr<ASTVarDeclarations> Parser::structVarDeclaration(Modifiers modif
|
||||
if (this->checkNext(Token::IDENTIFIER, &name)) {
|
||||
std::unique_ptr<ASTVarDeclarations> result = this->varDeclarationEnd(modifiers,
|
||||
std::move(type),
|
||||
std::move(name.fText));
|
||||
this->text(name));
|
||||
if (result) {
|
||||
for (const auto& var : result->fVars) {
|
||||
if (var.fValue) {
|
||||
this->error(var.fValue->fPosition,
|
||||
this->error(var.fValue->fOffset,
|
||||
"struct variables cannot be initialized");
|
||||
}
|
||||
}
|
||||
@ -501,7 +465,7 @@ std::unique_ptr<ASTVarDeclarations> Parser::structVarDeclaration(Modifiers modif
|
||||
(LBRACKET expression? RBRACKET)* (EQ assignmentExpression)?)* SEMICOLON */
|
||||
std::unique_ptr<ASTVarDeclarations> Parser::varDeclarationEnd(Modifiers mods,
|
||||
std::unique_ptr<ASTType> type,
|
||||
String name) {
|
||||
StringFragment name) {
|
||||
std::vector<ASTVarDeclaration> vars;
|
||||
std::vector<std::unique_ptr<ASTExpression>> currentVarSizes;
|
||||
while (this->checkNext(Token::LBRACKET)) {
|
||||
@ -525,7 +489,7 @@ std::unique_ptr<ASTVarDeclarations> Parser::varDeclarationEnd(Modifiers mods,
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
vars.emplace_back(std::move(name), std::move(currentVarSizes), std::move(value));
|
||||
vars.emplace_back(name, std::move(currentVarSizes), std::move(value));
|
||||
while (this->checkNext(Token::COMMA)) {
|
||||
Token name;
|
||||
if (!this->expect(Token::IDENTIFIER, "an identifier", &name)) {
|
||||
@ -553,7 +517,7 @@ std::unique_ptr<ASTVarDeclarations> Parser::varDeclarationEnd(Modifiers mods,
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
vars.emplace_back(std::move(name.fText), std::move(currentVarSizes), std::move(value));
|
||||
vars.emplace_back(this->text(name), std::move(currentVarSizes), std::move(value));
|
||||
}
|
||||
if (!this->expect(Token::SEMICOLON, "';'")) {
|
||||
return nullptr;
|
||||
@ -580,14 +544,13 @@ std::unique_ptr<ASTParameter> Parser::parameter() {
|
||||
if (!this->expect(Token::INT_LITERAL, "a positive integer", &sizeToken)) {
|
||||
return nullptr;
|
||||
}
|
||||
sizes.push_back(SkSL::stoi(sizeToken.fText));
|
||||
sizes.push_back(SkSL::stoi(this->text(sizeToken)));
|
||||
if (!this->expect(Token::RBRACKET, "']'")) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return std::unique_ptr<ASTParameter>(new ASTParameter(name.fPosition, modifiers,
|
||||
std::move(type), name.fText,
|
||||
std::move(sizes)));
|
||||
return std::unique_ptr<ASTParameter>(new ASTParameter(name.fOffset, modifiers, std::move(type),
|
||||
this->text(name), std::move(sizes)));
|
||||
}
|
||||
|
||||
/** (EQ INT_LITERAL)? */
|
||||
@ -597,7 +560,7 @@ int Parser::layoutInt() {
|
||||
}
|
||||
Token resultToken;
|
||||
if (this->expect(Token::INT_LITERAL, "a non-negative integer", &resultToken)) {
|
||||
return SkSL::stoi(resultToken.fText);
|
||||
return SkSL::stoi(this->text(resultToken));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@ -607,13 +570,13 @@ String Parser::layoutCode() {
|
||||
if (!this->expect(Token::EQ, "'='")) {
|
||||
return "";
|
||||
}
|
||||
Token start = this->nextRawToken(true);
|
||||
Token start = this->nextRawToken();
|
||||
this->pushback(start);
|
||||
String code;
|
||||
int level = 1;
|
||||
bool done = false;
|
||||
while (!done) {
|
||||
Token next = this->nextRawToken(true);
|
||||
Token next = this->nextRawToken();
|
||||
switch (next.fKind) {
|
||||
case Token::LPAREN:
|
||||
++level;
|
||||
@ -627,7 +590,7 @@ String Parser::layoutCode() {
|
||||
}
|
||||
break;
|
||||
case Token::END_OF_FILE:
|
||||
this->error(start.fPosition, "reached end of file while parsing layout");
|
||||
this->error(start, "reached end of file while parsing layout");
|
||||
return nullptr;
|
||||
default:
|
||||
break;
|
||||
@ -639,7 +602,7 @@ String Parser::layoutCode() {
|
||||
this->pushback(std::move(next));
|
||||
}
|
||||
else {
|
||||
code += next.fText;
|
||||
code += this->text(next);
|
||||
}
|
||||
}
|
||||
return code;
|
||||
@ -651,10 +614,10 @@ Layout::Key Parser::layoutKey() {
|
||||
this->expect(Token::EQ, "'='");
|
||||
Token key;
|
||||
if (this->expect(Token::IDENTIFIER, "an identifer", &key)) {
|
||||
if (key.fText == "identity") {
|
||||
if (this->text(key) == "identity") {
|
||||
return Layout::kIdentity_Key;
|
||||
} else {
|
||||
this->error(key.fPosition, "unsupported layout key");
|
||||
this->error(key, "unsupported layout key");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -688,84 +651,84 @@ Layout Parser::layout() {
|
||||
}
|
||||
for (;;) {
|
||||
Token t = this->nextToken();
|
||||
YY_BUFFER_STATE buffer;
|
||||
buffer = layout_scan_string(t.fText.c_str(), fLayoutScanner);
|
||||
int token = layoutlex(fLayoutScanner);
|
||||
layout_delete_buffer(buffer, fLayoutScanner);
|
||||
if (token != Token::INVALID_TOKEN) {
|
||||
String text = this->text(t);
|
||||
fLayoutLexer.start(text.c_str(), text.size());
|
||||
int token = fLayoutLexer.next().fKind;
|
||||
if (token != LayoutToken::INVALID) {
|
||||
switch (token) {
|
||||
case Token::LOCATION:
|
||||
case LayoutToken::LOCATION:
|
||||
location = this->layoutInt();
|
||||
break;
|
||||
case Token::OFFSET:
|
||||
case LayoutToken::OFFSET:
|
||||
offset = this->layoutInt();
|
||||
break;
|
||||
case Token::BINDING:
|
||||
case LayoutToken::BINDING:
|
||||
binding = this->layoutInt();
|
||||
break;
|
||||
case Token::INDEX:
|
||||
case LayoutToken::INDEX:
|
||||
index = this->layoutInt();
|
||||
break;
|
||||
case Token::SET:
|
||||
case LayoutToken::SET:
|
||||
set = this->layoutInt();
|
||||
break;
|
||||
case Token::BUILTIN:
|
||||
case LayoutToken::BUILTIN:
|
||||
builtin = this->layoutInt();
|
||||
break;
|
||||
case Token::INPUT_ATTACHMENT_INDEX:
|
||||
case LayoutToken::INPUT_ATTACHMENT_INDEX:
|
||||
inputAttachmentIndex = this->layoutInt();
|
||||
break;
|
||||
case Token::ORIGIN_UPPER_LEFT:
|
||||
case LayoutToken::ORIGIN_UPPER_LEFT:
|
||||
originUpperLeft = true;
|
||||
break;
|
||||
case Token::OVERRIDE_COVERAGE:
|
||||
case LayoutToken::OVERRIDE_COVERAGE:
|
||||
overrideCoverage = true;
|
||||
break;
|
||||
case Token::BLEND_SUPPORT_ALL_EQUATIONS:
|
||||
case LayoutToken::BLEND_SUPPORT_ALL_EQUATIONS:
|
||||
blendSupportAllEquations = true;
|
||||
break;
|
||||
case Token::PUSH_CONSTANT:
|
||||
case LayoutToken::PUSH_CONSTANT:
|
||||
pushConstant = true;
|
||||
break;
|
||||
case Token::POINTS:
|
||||
case LayoutToken::POINTS:
|
||||
primitive = Layout::kPoints_Primitive;
|
||||
break;
|
||||
case Token::LINES:
|
||||
case LayoutToken::LINES:
|
||||
primitive = Layout::kLines_Primitive;
|
||||
break;
|
||||
case Token::LINE_STRIP:
|
||||
case LayoutToken::LINE_STRIP:
|
||||
primitive = Layout::kLineStrip_Primitive;
|
||||
break;
|
||||
case Token::LINES_ADJACENCY:
|
||||
case LayoutToken::LINES_ADJACENCY:
|
||||
primitive = Layout::kLinesAdjacency_Primitive;
|
||||
break;
|
||||
case Token::TRIANGLES:
|
||||
case LayoutToken::TRIANGLES:
|
||||
primitive = Layout::kTriangles_Primitive;
|
||||
break;
|
||||
case Token::TRIANGLE_STRIP:
|
||||
case LayoutToken::TRIANGLE_STRIP:
|
||||
primitive = Layout::kTriangleStrip_Primitive;
|
||||
break;
|
||||
case Token::TRIANGLES_ADJACENCY:
|
||||
case LayoutToken::TRIANGLES_ADJACENCY:
|
||||
primitive = Layout::kTrianglesAdjacency_Primitive;
|
||||
break;
|
||||
case Token::MAX_VERTICES:
|
||||
case LayoutToken::MAX_VERTICES:
|
||||
maxVertices = this->layoutInt();
|
||||
break;
|
||||
case Token::INVOCATIONS:
|
||||
case LayoutToken::INVOCATIONS:
|
||||
invocations = this->layoutInt();
|
||||
break;
|
||||
case Token::WHEN:
|
||||
case LayoutToken::WHEN:
|
||||
when = this->layoutCode();
|
||||
break;
|
||||
case Token::KEY:
|
||||
case LayoutToken::KEY:
|
||||
key = this->layoutKey();
|
||||
break;
|
||||
default:
|
||||
ASSERT(false);
|
||||
}
|
||||
} else if (Layout::ReadFormat(t.fText, &format)) {
|
||||
} else if (Layout::ReadFormat(this->text(t), &format)) {
|
||||
// AST::ReadFormat stored the result in 'format'.
|
||||
} else {
|
||||
this->error(t.fPosition, ("'" + t.fText +
|
||||
"' is not a valid layout qualifier").c_str());
|
||||
this->error(t, ("'" + this->text(t) + "' is not a valid layout qualifier").c_str());
|
||||
}
|
||||
if (this->checkNext(Token::RPAREN)) {
|
||||
break;
|
||||
@ -899,7 +862,7 @@ std::unique_ptr<ASTStatement> Parser::statement() {
|
||||
return this->block();
|
||||
case Token::SEMICOLON:
|
||||
this->nextToken();
|
||||
return std::unique_ptr<ASTStatement>(new ASTBlock(start.fPosition,
|
||||
return std::unique_ptr<ASTStatement>(new ASTBlock(start.fOffset,
|
||||
std::vector<std::unique_ptr<ASTStatement>>()));
|
||||
case Token::CONST: // fall through
|
||||
case Token::HIGHP: // fall through
|
||||
@ -912,7 +875,7 @@ std::unique_ptr<ASTStatement> Parser::statement() {
|
||||
return std::unique_ptr<ASTStatement>(new ASTVarDeclarationStatement(std::move(decl)));
|
||||
}
|
||||
case Token::IDENTIFIER:
|
||||
if (this->isType(start.fText)) {
|
||||
if (this->isType(this->text(start))) {
|
||||
auto decl = this->varDeclarations();
|
||||
if (!decl) {
|
||||
return nullptr;
|
||||
@ -932,8 +895,8 @@ std::unique_ptr<ASTType> Parser::type() {
|
||||
if (!this->expect(Token::IDENTIFIER, "a type", &type)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!this->isType(type.fText)) {
|
||||
this->error(type.fPosition, ("no type named '" + type.fText + "'").c_str());
|
||||
if (!this->isType(this->text(type))) {
|
||||
this->error(type, ("no type named '" + this->text(type) + "'").c_str());
|
||||
return nullptr;
|
||||
}
|
||||
std::vector<int> sizes;
|
||||
@ -950,7 +913,7 @@ std::unique_ptr<ASTType> Parser::type() {
|
||||
}
|
||||
this->expect(Token::RBRACKET, "']'");
|
||||
}
|
||||
return std::unique_ptr<ASTType>(new ASTType(type.fPosition, std::move(type.fText),
|
||||
return std::unique_ptr<ASTType>(new ASTType(type.fOffset, this->text(type),
|
||||
ASTType::kIdentifier_Kind, sizes));
|
||||
}
|
||||
|
||||
@ -964,7 +927,7 @@ std::unique_ptr<ASTDeclaration> Parser::interfaceBlock(Modifiers mods) {
|
||||
// we only get into interfaceBlock if we found a top-level identifier which was not a type.
|
||||
// 99% of the time, the user was not actually intending to create an interface block, so
|
||||
// it's better to report it as an unknown type
|
||||
this->error(name.fPosition, "no type named '" + name.fText + "'");
|
||||
this->error(name, "no type named '" + this->text(name) + "'");
|
||||
return nullptr;
|
||||
}
|
||||
this->nextToken();
|
||||
@ -978,8 +941,9 @@ std::unique_ptr<ASTDeclaration> Parser::interfaceBlock(Modifiers mods) {
|
||||
}
|
||||
this->nextToken();
|
||||
std::vector<std::unique_ptr<ASTExpression>> sizes;
|
||||
Token instanceName;
|
||||
if (this->checkNext(Token::IDENTIFIER, &instanceName)) {
|
||||
StringFragment instanceName;
|
||||
Token instanceNameToken;
|
||||
if (this->checkNext(Token::IDENTIFIER, &instanceNameToken)) {
|
||||
while (this->checkNext(Token::LBRACKET)) {
|
||||
if (this->peek().fKind != Token::RBRACKET) {
|
||||
std::unique_ptr<ASTExpression> size = this->expression();
|
||||
@ -992,12 +956,13 @@ std::unique_ptr<ASTDeclaration> Parser::interfaceBlock(Modifiers mods) {
|
||||
}
|
||||
this->expect(Token::RBRACKET, "']'");
|
||||
}
|
||||
instanceName = this->text(instanceNameToken);
|
||||
}
|
||||
this->expect(Token::SEMICOLON, "';'");
|
||||
return std::unique_ptr<ASTDeclaration>(new ASTInterfaceBlock(name.fPosition, mods,
|
||||
std::move(name.fText),
|
||||
return std::unique_ptr<ASTDeclaration>(new ASTInterfaceBlock(name.fOffset, mods,
|
||||
this->text(name),
|
||||
std::move(decls),
|
||||
std::move(instanceName.fText),
|
||||
instanceName,
|
||||
std::move(sizes)));
|
||||
}
|
||||
|
||||
@ -1029,7 +994,7 @@ std::unique_ptr<ASTIfStatement> Parser::ifStatement() {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return std::unique_ptr<ASTIfStatement>(new ASTIfStatement(start.fPosition,
|
||||
return std::unique_ptr<ASTIfStatement>(new ASTIfStatement(start.fOffset,
|
||||
isStatic,
|
||||
std::move(test),
|
||||
std::move(ifTrue),
|
||||
@ -1062,7 +1027,7 @@ std::unique_ptr<ASTDoStatement> Parser::doStatement() {
|
||||
if (!this->expect(Token::SEMICOLON, "';'")) {
|
||||
return nullptr;
|
||||
}
|
||||
return std::unique_ptr<ASTDoStatement>(new ASTDoStatement(start.fPosition,
|
||||
return std::unique_ptr<ASTDoStatement>(new ASTDoStatement(start.fOffset,
|
||||
std::move(statement),
|
||||
std::move(test)));
|
||||
}
|
||||
@ -1087,7 +1052,7 @@ std::unique_ptr<ASTWhileStatement> Parser::whileStatement() {
|
||||
if (!statement) {
|
||||
return nullptr;
|
||||
}
|
||||
return std::unique_ptr<ASTWhileStatement>(new ASTWhileStatement(start.fPosition,
|
||||
return std::unique_ptr<ASTWhileStatement>(new ASTWhileStatement(start.fOffset,
|
||||
std::move(test),
|
||||
std::move(statement)));
|
||||
}
|
||||
@ -1114,7 +1079,7 @@ std::unique_ptr<ASTSwitchCase> Parser::switchCase() {
|
||||
}
|
||||
statements.push_back(std::move(s));
|
||||
}
|
||||
return std::unique_ptr<ASTSwitchCase>(new ASTSwitchCase(start.fPosition, std::move(value),
|
||||
return std::unique_ptr<ASTSwitchCase>(new ASTSwitchCase(start.fOffset, std::move(value),
|
||||
std::move(statements)));
|
||||
}
|
||||
|
||||
@ -1162,13 +1127,13 @@ std::unique_ptr<ASTStatement> Parser::switchStatement() {
|
||||
}
|
||||
statements.push_back(std::move(s));
|
||||
}
|
||||
cases.emplace_back(new ASTSwitchCase(defaultStart.fPosition, nullptr,
|
||||
cases.emplace_back(new ASTSwitchCase(defaultStart.fOffset, nullptr,
|
||||
std::move(statements)));
|
||||
}
|
||||
if (!this->expect(Token::RBRACE, "'}'")) {
|
||||
return nullptr;
|
||||
}
|
||||
return std::unique_ptr<ASTStatement>(new ASTSwitchStatement(start.fPosition,
|
||||
return std::unique_ptr<ASTStatement>(new ASTSwitchStatement(start.fOffset,
|
||||
isStatic,
|
||||
std::move(value),
|
||||
std::move(cases)));
|
||||
@ -1200,7 +1165,7 @@ std::unique_ptr<ASTForStatement> Parser::forStatement() {
|
||||
break;
|
||||
}
|
||||
case Token::IDENTIFIER: {
|
||||
if (this->isType(nextToken.fText)) {
|
||||
if (this->isType(this->text(nextToken))) {
|
||||
std::unique_ptr<ASTVarDeclarations> vd = this->varDeclarations();
|
||||
if (!vd) {
|
||||
return nullptr;
|
||||
@ -1237,7 +1202,7 @@ std::unique_ptr<ASTForStatement> Parser::forStatement() {
|
||||
if (!statement) {
|
||||
return nullptr;
|
||||
}
|
||||
return std::unique_ptr<ASTForStatement>(new ASTForStatement(start.fPosition,
|
||||
return std::unique_ptr<ASTForStatement>(new ASTForStatement(start.fOffset,
|
||||
std::move(initializer),
|
||||
std::move(test), std::move(next),
|
||||
std::move(statement)));
|
||||
@ -1259,7 +1224,7 @@ std::unique_ptr<ASTReturnStatement> Parser::returnStatement() {
|
||||
if (!this->expect(Token::SEMICOLON, "';'")) {
|
||||
return nullptr;
|
||||
}
|
||||
return std::unique_ptr<ASTReturnStatement>(new ASTReturnStatement(start.fPosition,
|
||||
return std::unique_ptr<ASTReturnStatement>(new ASTReturnStatement(start.fOffset,
|
||||
std::move(expression)));
|
||||
}
|
||||
|
||||
@ -1272,7 +1237,7 @@ std::unique_ptr<ASTBreakStatement> Parser::breakStatement() {
|
||||
if (!this->expect(Token::SEMICOLON, "';'")) {
|
||||
return nullptr;
|
||||
}
|
||||
return std::unique_ptr<ASTBreakStatement>(new ASTBreakStatement(start.fPosition));
|
||||
return std::unique_ptr<ASTBreakStatement>(new ASTBreakStatement(start.fOffset));
|
||||
}
|
||||
|
||||
/* CONTINUE SEMICOLON */
|
||||
@ -1284,7 +1249,7 @@ std::unique_ptr<ASTContinueStatement> Parser::continueStatement() {
|
||||
if (!this->expect(Token::SEMICOLON, "';'")) {
|
||||
return nullptr;
|
||||
}
|
||||
return std::unique_ptr<ASTContinueStatement>(new ASTContinueStatement(start.fPosition));
|
||||
return std::unique_ptr<ASTContinueStatement>(new ASTContinueStatement(start.fOffset));
|
||||
}
|
||||
|
||||
/* DISCARD SEMICOLON */
|
||||
@ -1296,7 +1261,7 @@ std::unique_ptr<ASTDiscardStatement> Parser::discardStatement() {
|
||||
if (!this->expect(Token::SEMICOLON, "';'")) {
|
||||
return nullptr;
|
||||
}
|
||||
return std::unique_ptr<ASTDiscardStatement>(new ASTDiscardStatement(start.fPosition));
|
||||
return std::unique_ptr<ASTDiscardStatement>(new ASTDiscardStatement(start.fOffset));
|
||||
}
|
||||
|
||||
/* LBRACE statement* RBRACE */
|
||||
@ -1314,10 +1279,10 @@ std::unique_ptr<ASTBlock> Parser::block() {
|
||||
switch (this->peek().fKind) {
|
||||
case Token::RBRACE:
|
||||
this->nextToken();
|
||||
return std::unique_ptr<ASTBlock>(new ASTBlock(start.fPosition,
|
||||
return std::unique_ptr<ASTBlock>(new ASTBlock(start.fOffset,
|
||||
std::move(statements)));
|
||||
case Token::END_OF_FILE:
|
||||
this->error(this->peek().fPosition, "expected '}', but found end of file");
|
||||
this->error(this->peek(), "expected '}', but found end of file");
|
||||
return nullptr;
|
||||
default: {
|
||||
std::unique_ptr<ASTStatement> statement = this->statement();
|
||||
@ -1714,7 +1679,7 @@ std::unique_ptr<ASTSuffix> Parser::suffix() {
|
||||
switch (next.fKind) {
|
||||
case Token::LBRACKET: {
|
||||
if (this->checkNext(Token::RBRACKET)) {
|
||||
return std::unique_ptr<ASTSuffix>(new ASTIndexSuffix(next.fPosition));
|
||||
return std::unique_ptr<ASTSuffix>(new ASTIndexSuffix(next.fOffset));
|
||||
}
|
||||
std::unique_ptr<ASTExpression> e = this->expression();
|
||||
if (!e) {
|
||||
@ -1724,10 +1689,10 @@ std::unique_ptr<ASTSuffix> Parser::suffix() {
|
||||
return std::unique_ptr<ASTSuffix>(new ASTIndexSuffix(std::move(e)));
|
||||
}
|
||||
case Token::DOT: {
|
||||
Position pos = this->peek().fPosition;
|
||||
String text;
|
||||
int offset = this->peek().fOffset;
|
||||
StringFragment text;
|
||||
if (this->identifier(&text)) {
|
||||
return std::unique_ptr<ASTSuffix>(new ASTFieldSuffix(pos, std::move(text)));
|
||||
return std::unique_ptr<ASTSuffix>(new ASTFieldSuffix(offset, std::move(text)));
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@ -1746,17 +1711,17 @@ std::unique_ptr<ASTSuffix> Parser::suffix() {
|
||||
}
|
||||
}
|
||||
this->expect(Token::RPAREN, "')' to complete function parameters");
|
||||
return std::unique_ptr<ASTSuffix>(new ASTCallSuffix(next.fPosition,
|
||||
return std::unique_ptr<ASTSuffix>(new ASTCallSuffix(next.fOffset,
|
||||
std::move(parameters)));
|
||||
}
|
||||
case Token::PLUSPLUS:
|
||||
return std::unique_ptr<ASTSuffix>(new ASTSuffix(next.fPosition,
|
||||
return std::unique_ptr<ASTSuffix>(new ASTSuffix(next.fOffset,
|
||||
ASTSuffix::kPostIncrement_Kind));
|
||||
case Token::MINUSMINUS:
|
||||
return std::unique_ptr<ASTSuffix>(new ASTSuffix(next.fPosition,
|
||||
return std::unique_ptr<ASTSuffix>(new ASTSuffix(next.fOffset,
|
||||
ASTSuffix::kPostDecrement_Kind));
|
||||
default: {
|
||||
this->error(next.fPosition, "expected expression suffix, but found '" + next.fText +
|
||||
this->error(next, "expected expression suffix, but found '" + this->text(next) +
|
||||
"'\n");
|
||||
return nullptr;
|
||||
}
|
||||
@ -1769,23 +1734,23 @@ std::unique_ptr<ASTExpression> Parser::term() {
|
||||
Token t = this->peek();
|
||||
switch (t.fKind) {
|
||||
case Token::IDENTIFIER: {
|
||||
String text;
|
||||
StringFragment text;
|
||||
if (this->identifier(&text)) {
|
||||
result.reset(new ASTIdentifier(t.fPosition, std::move(text)));
|
||||
result.reset(new ASTIdentifier(t.fOffset, std::move(text)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Token::INT_LITERAL: {
|
||||
int64_t i;
|
||||
if (this->intLiteral(&i)) {
|
||||
result.reset(new ASTIntLiteral(t.fPosition, i));
|
||||
result.reset(new ASTIntLiteral(t.fOffset, i));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Token::FLOAT_LITERAL: {
|
||||
double f;
|
||||
if (this->floatLiteral(&f)) {
|
||||
result.reset(new ASTFloatLiteral(t.fPosition, f));
|
||||
result.reset(new ASTFloatLiteral(t.fOffset, f));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1793,7 +1758,7 @@ std::unique_ptr<ASTExpression> Parser::term() {
|
||||
case Token::FALSE_LITERAL: {
|
||||
bool b;
|
||||
if (this->boolLiteral(&b)) {
|
||||
result.reset(new ASTBoolLiteral(t.fPosition, b));
|
||||
result.reset(new ASTBoolLiteral(t.fOffset, b));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1807,7 +1772,7 @@ std::unique_ptr<ASTExpression> Parser::term() {
|
||||
}
|
||||
default:
|
||||
this->nextToken();
|
||||
this->error(t.fPosition, "expected expression, but found '" + t.fText + "'\n");
|
||||
this->error(t.fOffset, "expected expression, but found '" + this->text(t) + "'\n");
|
||||
result = nullptr;
|
||||
}
|
||||
return result;
|
||||
@ -1817,7 +1782,7 @@ std::unique_ptr<ASTExpression> Parser::term() {
|
||||
bool Parser::intLiteral(int64_t* dest) {
|
||||
Token t;
|
||||
if (this->expect(Token::INT_LITERAL, "integer literal", &t)) {
|
||||
*dest = SkSL::stol(t.fText);
|
||||
*dest = SkSL::stol(this->text(t));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -1827,7 +1792,7 @@ bool Parser::intLiteral(int64_t* dest) {
|
||||
bool Parser::floatLiteral(double* dest) {
|
||||
Token t;
|
||||
if (this->expect(Token::FLOAT_LITERAL, "float literal", &t)) {
|
||||
*dest = SkSL::stod(t.fText);
|
||||
*dest = SkSL::stod(this->text(t));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -1844,16 +1809,16 @@ bool Parser::boolLiteral(bool* dest) {
|
||||
*dest = false;
|
||||
return true;
|
||||
default:
|
||||
this->error(t.fPosition, "expected 'true' or 'false', but found '" + t.fText + "'\n");
|
||||
this->error(t, "expected 'true' or 'false', but found '" + this->text(t) + "'\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* IDENTIFIER */
|
||||
bool Parser::identifier(String* dest) {
|
||||
bool Parser::identifier(StringFragment* dest) {
|
||||
Token t;
|
||||
if (this->expect(Token::IDENTIFIER, "identifier", &t)) {
|
||||
*dest = std::move(t.fText);
|
||||
*dest = this->text(t);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -14,7 +14,8 @@
|
||||
#include <unordered_set>
|
||||
#include "SkSLErrorReporter.h"
|
||||
#include "ir/SkSLLayout.h"
|
||||
#include "SkSLToken.h"
|
||||
#include "SkSLLexer.h"
|
||||
#include "SkSLLayoutLexer.h"
|
||||
|
||||
struct yy_buffer_state;
|
||||
#define YY_TYPEDEF_YY_BUFFER_STATE
|
||||
@ -51,9 +52,7 @@ class SymbolTable;
|
||||
*/
|
||||
class Parser {
|
||||
public:
|
||||
Parser(String text, SymbolTable& types, ErrorReporter& errors);
|
||||
|
||||
~Parser();
|
||||
Parser(const char* text, size_t length, SymbolTable& types, ErrorReporter& errors);
|
||||
|
||||
/**
|
||||
* Consumes a complete .sksl file and produces a list of declarations. Errors are reported via
|
||||
@ -62,13 +61,15 @@ public:
|
||||
*/
|
||||
std::vector<std::unique_ptr<ASTDeclaration>> file();
|
||||
|
||||
StringFragment text(Token token);
|
||||
|
||||
Position position(Token token);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Return the next token, including whitespace tokens, from the parse stream. If needText is
|
||||
* false, the token's text is only filled in if it is a token with variable text (identifiers,
|
||||
* numbers, etc.).
|
||||
* Return the next token, including whitespace tokens, from the parse stream.
|
||||
*/
|
||||
Token nextRawToken(bool needText);
|
||||
Token nextRawToken();
|
||||
|
||||
/**
|
||||
* Return the next non-whitespace token from the parse stream.
|
||||
@ -103,15 +104,15 @@ private:
|
||||
* Returns true if the read token was as expected, false otherwise.
|
||||
*/
|
||||
bool expect(Token::Kind kind, const char* expected, Token* result = nullptr);
|
||||
bool expect(Token::Kind kind, String expected, Token* result = nullptr);
|
||||
|
||||
void error(Position p, const char* msg);
|
||||
void error(Position p, String msg);
|
||||
|
||||
void error(Token token, String msg);
|
||||
void error(int offset, String msg);
|
||||
/**
|
||||
* Returns true if the 'name' identifier refers to a type name. For instance, isType("int") will
|
||||
* always return true.
|
||||
*/
|
||||
bool isType(const String& name);
|
||||
bool isType(StringFragment 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
|
||||
@ -133,7 +134,7 @@ private:
|
||||
|
||||
std::unique_ptr<ASTVarDeclarations> varDeclarationEnd(Modifiers modifiers,
|
||||
std::unique_ptr<ASTType> type,
|
||||
String name);
|
||||
StringFragment name);
|
||||
|
||||
std::unique_ptr<ASTParameter> parameter();
|
||||
|
||||
@ -223,10 +224,11 @@ private:
|
||||
|
||||
bool boolLiteral(bool* dest);
|
||||
|
||||
bool identifier(String* dest);
|
||||
bool identifier(StringFragment* dest);
|
||||
|
||||
void* fScanner;
|
||||
void* fLayoutScanner;
|
||||
const char* fText;
|
||||
Lexer fLexer;
|
||||
LayoutLexer fLayoutLexer;
|
||||
YY_BUFFER_STATE fBuffer;
|
||||
// current parse depth, used to enforce a recursion limit to try to keep us from overflowing the
|
||||
// stack on pathological inputs
|
||||
|
@ -850,8 +850,7 @@ void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, OutputSt
|
||||
this->writeWord(word1, out);
|
||||
}
|
||||
|
||||
void SPIRVCodeGenerator::writeString(const char* string, OutputStream& out) {
|
||||
size_t length = strlen(string);
|
||||
void SPIRVCodeGenerator::writeString(const char* string, size_t length, OutputStream& out) {
|
||||
out.write(string, length);
|
||||
switch (length % 4) {
|
||||
case 1:
|
||||
@ -868,28 +867,25 @@ void SPIRVCodeGenerator::writeString(const char* string, OutputStream& out) {
|
||||
}
|
||||
}
|
||||
|
||||
void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, const char* string, OutputStream& out) {
|
||||
int32_t length = (int32_t) strlen(string);
|
||||
this->writeOpCode(opCode, 1 + (length + 4) / 4, out);
|
||||
this->writeString(string, out);
|
||||
void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, StringFragment string, OutputStream& out) {
|
||||
this->writeOpCode(opCode, 1 + (string.fLength + 4) / 4, out);
|
||||
this->writeString(string.fChars, string.fLength, out);
|
||||
}
|
||||
|
||||
|
||||
void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, const char* string,
|
||||
void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, StringFragment string,
|
||||
OutputStream& out) {
|
||||
int32_t length = (int32_t) strlen(string);
|
||||
this->writeOpCode(opCode, 2 + (length + 4) / 4, out);
|
||||
this->writeOpCode(opCode, 2 + (string.fLength + 4) / 4, out);
|
||||
this->writeWord(word1, out);
|
||||
this->writeString(string, out);
|
||||
this->writeString(string.fChars, string.fLength, out);
|
||||
}
|
||||
|
||||
void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2,
|
||||
const char* string, OutputStream& out) {
|
||||
int32_t length = (int32_t) strlen(string);
|
||||
this->writeOpCode(opCode, 3 + (length + 4) / 4, out);
|
||||
StringFragment string, OutputStream& out) {
|
||||
this->writeOpCode(opCode, 3 + (string.fLength + 4) / 4, out);
|
||||
this->writeWord(word1, out);
|
||||
this->writeWord(word2, out);
|
||||
this->writeString(string, out);
|
||||
this->writeString(string.fChars, string.fLength, out);
|
||||
}
|
||||
|
||||
void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2,
|
||||
@ -1003,12 +999,12 @@ void SPIRVCodeGenerator::writeStruct(const Type& type, const MemoryLayout& memor
|
||||
const Layout& fieldLayout = type.fields()[i].fModifiers.fLayout;
|
||||
if (fieldLayout.fOffset >= 0) {
|
||||
if (fieldLayout.fOffset < (int) offset) {
|
||||
fErrors.error(type.fPosition,
|
||||
fErrors.error(type.fOffset,
|
||||
"offset of field '" + type.fields()[i].fName + "' must be at "
|
||||
"least " + to_string((int) offset));
|
||||
}
|
||||
if (fieldLayout.fOffset % alignment) {
|
||||
fErrors.error(type.fPosition,
|
||||
fErrors.error(type.fOffset,
|
||||
"offset of field '" + type.fields()[i].fName + "' must be a multiple"
|
||||
" of " + to_string((int) alignment));
|
||||
}
|
||||
@ -1019,8 +1015,7 @@ void SPIRVCodeGenerator::writeStruct(const Type& type, const MemoryLayout& memor
|
||||
offset += alignment - mod;
|
||||
}
|
||||
}
|
||||
this->writeInstruction(SpvOpMemberName, resultId, i, type.fields()[i].fName.c_str(),
|
||||
fNameBuffer);
|
||||
this->writeInstruction(SpvOpMemberName, resultId, i, type.fields()[i].fName, fNameBuffer);
|
||||
this->writeLayout(fieldLayout, resultId, i);
|
||||
if (type.fields()[i].fModifiers.fLayout.fBuiltin < 0) {
|
||||
this->writeInstruction(SpvOpMemberDecorate, resultId, (SpvId) i, SpvDecorationOffset,
|
||||
@ -1081,7 +1076,7 @@ SpvId SPIRVCodeGenerator::getType(const Type& type, const MemoryLayout& layout)
|
||||
break;
|
||||
case Type::kArray_Kind: {
|
||||
if (type.columns() > 0) {
|
||||
IntLiteral count(fContext, Position(), type.columns());
|
||||
IntLiteral count(fContext, -1, type.columns());
|
||||
this->writeInstruction(SpvOpTypeArray, result,
|
||||
this->getType(type.componentType(), layout),
|
||||
this->writeIntLiteral(count), fConstantBuffer);
|
||||
@ -1331,9 +1326,9 @@ SpvId SPIRVCodeGenerator::writeSpecialIntrinsic(const FunctionCall& c, SpecialIn
|
||||
case kSubpassLoad_SpecialIntrinsic: {
|
||||
SpvId img = this->writeExpression(*c.fArguments[0], out);
|
||||
std::vector<std::unique_ptr<Expression>> args;
|
||||
args.emplace_back(new FloatLiteral(fContext, Position(), 0.0));
|
||||
args.emplace_back(new FloatLiteral(fContext, Position(), 0.0));
|
||||
Constructor ctor(Position(), *fContext.fFloat2_Type, std::move(args));
|
||||
args.emplace_back(new FloatLiteral(fContext, -1, 0.0));
|
||||
args.emplace_back(new FloatLiteral(fContext, -1, 0.0));
|
||||
Constructor ctor(-1, *fContext.fFloat2_Type, std::move(args));
|
||||
SpvId coords = this->writeConstantVector(ctor);
|
||||
if (1 == c.fArguments.size()) {
|
||||
this->writeInstruction(SpvOpImageRead,
|
||||
@ -1566,7 +1561,7 @@ SpvId SPIRVCodeGenerator::writeUIntConstructor(const Constructor& c, OutputStrea
|
||||
|
||||
void SPIRVCodeGenerator::writeUniformScaleMatrix(SpvId id, SpvId diagonal, const Type& type,
|
||||
OutputStream& out) {
|
||||
FloatLiteral zero(fContext, Position(), 0);
|
||||
FloatLiteral zero(fContext, -1, 0);
|
||||
SpvId zeroId = this->writeFloatLiteral(zero);
|
||||
std::vector<SpvId> columnIds;
|
||||
for (int column = 0; column < type.columns(); column++) {
|
||||
@ -1603,10 +1598,10 @@ void SPIRVCodeGenerator::writeMatrixCopy(SpvId id, SpvId src, const Type& srcTyp
|
||||
1));
|
||||
SpvId zeroId;
|
||||
if (dstType.componentType() == *fContext.fFloat_Type) {
|
||||
FloatLiteral zero(fContext, Position(), 0.0);
|
||||
FloatLiteral zero(fContext, -1, 0.0);
|
||||
zeroId = this->writeFloatLiteral(zero);
|
||||
} else if (dstType.componentType() == *fContext.fInt_Type) {
|
||||
IntLiteral zero(fContext, Position(), 0);
|
||||
IntLiteral zero(fContext, -1, 0);
|
||||
zeroId = this->writeIntLiteral(zero);
|
||||
} else {
|
||||
ABORT("unsupported matrix component type");
|
||||
@ -1864,7 +1859,7 @@ std::vector<SpvId> SPIRVCodeGenerator::getAccessChain(const Expression& expr, Ou
|
||||
case Expression::kFieldAccess_Kind: {
|
||||
FieldAccess& fieldExpr = (FieldAccess&) expr;
|
||||
chain = this->getAccessChain(*fieldExpr.fBase, out);
|
||||
IntLiteral index(fContext, Position(), fieldExpr.fFieldIndex);
|
||||
IntLiteral index(fContext, -1, fieldExpr.fFieldIndex);
|
||||
chain.push_back(this->writeIntLiteral(index));
|
||||
break;
|
||||
}
|
||||
@ -2010,7 +2005,7 @@ std::unique_ptr<SPIRVCodeGenerator::LValue> SPIRVCodeGenerator::getLValue(const
|
||||
SpvId base = this->getLValue(*swizzle.fBase, out)->getPointer();
|
||||
ASSERT(base);
|
||||
if (count == 1) {
|
||||
IntLiteral index(fContext, Position(), swizzle.fComponents[0]);
|
||||
IntLiteral index(fContext, -1, swizzle.fComponents[0]);
|
||||
SpvId member = this->nextId();
|
||||
this->writeInstruction(SpvOpAccessChain,
|
||||
this->getPointerType(swizzle.fType,
|
||||
@ -2064,20 +2059,19 @@ SpvId SPIRVCodeGenerator::writeVariableReference(const VariableReference& ref, O
|
||||
std::shared_ptr<SymbolTable> st(new SymbolTable(&fErrors));
|
||||
ASSERT(fRTHeightFieldIndex == (SpvId) -1);
|
||||
std::vector<Type::Field> fields;
|
||||
fields.emplace_back(Modifiers(), String(SKSL_RTHEIGHT_NAME),
|
||||
fContext.fFloat_Type.get());
|
||||
String name("sksl_synthetic_uniforms");
|
||||
Type intfStruct(Position(), name, fields);
|
||||
fields.emplace_back(Modifiers(), SKSL_RTHEIGHT_NAME, fContext.fFloat_Type.get());
|
||||
StringFragment name("sksl_synthetic_uniforms");
|
||||
Type intfStruct(-1, name, fields);
|
||||
Layout layout(-1, -1, 1, -1, -1, -1, -1, false, false, false,
|
||||
Layout::Format::kUnspecified, false, Layout::kUnspecified_Primitive, -1,
|
||||
-1, "", Layout::kNo_Key);
|
||||
Variable* intfVar = new Variable(Position(),
|
||||
Variable* intfVar = new Variable(-1,
|
||||
Modifiers(layout, Modifiers::kUniform_Flag),
|
||||
name,
|
||||
intfStruct,
|
||||
Variable::kGlobal_Storage);
|
||||
fSynthetics.takeOwnership(intfVar);
|
||||
InterfaceBlock intf(Position(), intfVar, name, String(""),
|
||||
InterfaceBlock intf(-1, intfVar, name, String(""),
|
||||
std::vector<std::unique_ptr<Expression>>(), st);
|
||||
fRTHeightStructId = this->writeInterfaceBlock(intf);
|
||||
fRTHeightFieldIndex = 0;
|
||||
@ -2087,7 +2081,7 @@ SpvId SPIRVCodeGenerator::writeVariableReference(const VariableReference& ref, O
|
||||
SpvId xId = this->nextId();
|
||||
this->writeInstruction(SpvOpCompositeExtract, this->getType(*fContext.fFloat_Type), xId,
|
||||
result, 0, out);
|
||||
IntLiteral fieldIndex(fContext, Position(), fRTHeightFieldIndex);
|
||||
IntLiteral fieldIndex(fContext, -1, fRTHeightFieldIndex);
|
||||
SpvId fieldIndexId = this->writeIntLiteral(fieldIndex);
|
||||
SpvId heightPtr = this->nextId();
|
||||
this->writeOpCode(SpvOpAccessChain, 5, out);
|
||||
@ -2104,9 +2098,9 @@ SpvId SPIRVCodeGenerator::writeVariableReference(const VariableReference& ref, O
|
||||
SpvId flippedYId = this->nextId();
|
||||
this->writeInstruction(SpvOpFSub, this->getType(*fContext.fFloat_Type), flippedYId,
|
||||
heightRead, rawYId, out);
|
||||
FloatLiteral zero(fContext, Position(), 0.0);
|
||||
FloatLiteral zero(fContext, -1, 0.0);
|
||||
SpvId zeroId = writeFloatLiteral(zero);
|
||||
FloatLiteral one(fContext, Position(), 1.0);
|
||||
FloatLiteral one(fContext, -1, 1.0);
|
||||
SpvId oneId = writeFloatLiteral(one);
|
||||
SpvId flipped = this->nextId();
|
||||
this->writeOpCode(SpvOpCompositeConstruct, 7, out);
|
||||
@ -2509,7 +2503,7 @@ SpvId SPIRVCodeGenerator::writeBinaryExpression(const BinaryExpression& b, Outpu
|
||||
|
||||
SpvId SPIRVCodeGenerator::writeLogicalAnd(const BinaryExpression& a, OutputStream& out) {
|
||||
ASSERT(a.fOperator == Token::LOGICALAND);
|
||||
BoolLiteral falseLiteral(fContext, Position(), false);
|
||||
BoolLiteral falseLiteral(fContext, -1, false);
|
||||
SpvId falseConstant = this->writeBoolLiteral(falseLiteral);
|
||||
SpvId lhs = this->writeExpression(*a.fLeft, out);
|
||||
SpvId rhsLabel = this->nextId();
|
||||
@ -2530,7 +2524,7 @@ SpvId SPIRVCodeGenerator::writeLogicalAnd(const BinaryExpression& a, OutputStrea
|
||||
|
||||
SpvId SPIRVCodeGenerator::writeLogicalOr(const BinaryExpression& o, OutputStream& out) {
|
||||
ASSERT(o.fOperator == Token::LOGICALOR);
|
||||
BoolLiteral trueLiteral(fContext, Position(), true);
|
||||
BoolLiteral trueLiteral(fContext, -1, true);
|
||||
SpvId trueConstant = this->writeBoolLiteral(trueLiteral);
|
||||
SpvId lhs = this->writeExpression(*o.fLeft, out);
|
||||
SpvId rhsLabel = this->nextId();
|
||||
@ -2584,10 +2578,10 @@ SpvId SPIRVCodeGenerator::writeTernaryExpression(const TernaryExpression& t, Out
|
||||
|
||||
std::unique_ptr<Expression> create_literal_1(const Context& context, const Type& type) {
|
||||
if (type == *context.fInt_Type) {
|
||||
return std::unique_ptr<Expression>(new IntLiteral(context, Position(), 1));
|
||||
return std::unique_ptr<Expression>(new IntLiteral(context, -1, 1));
|
||||
}
|
||||
else if (type == *context.fFloat_Type) {
|
||||
return std::unique_ptr<Expression>(new FloatLiteral(context, Position(), 1.0));
|
||||
return std::unique_ptr<Expression>(new FloatLiteral(context, -1, 1.0));
|
||||
} else {
|
||||
ABORT("math is unsupported on type '%s'", type.name().c_str());
|
||||
}
|
||||
@ -2747,7 +2741,7 @@ SpvId SPIRVCodeGenerator::writeFunctionStart(const FunctionDeclaration& f, Outpu
|
||||
SpvId result = fFunctionMap[&f];
|
||||
this->writeInstruction(SpvOpFunction, this->getType(f.fReturnType), result,
|
||||
SpvFunctionControlMaskNone, this->getFunctionType(f), out);
|
||||
this->writeInstruction(SpvOpName, result, f.fName.c_str(), fNameBuffer);
|
||||
this->writeInstruction(SpvOpName, result, f.fName, fNameBuffer);
|
||||
for (size_t i = 0; i < f.fParameters.size(); i++) {
|
||||
SpvId id = this->nextId();
|
||||
fVariableMap[f.fParameters[i]] = id;
|
||||
@ -2844,8 +2838,8 @@ SpvId SPIRVCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) {
|
||||
std::vector<Type::Field> fields = type->fields();
|
||||
fRTHeightStructId = result;
|
||||
fRTHeightFieldIndex = fields.size();
|
||||
fields.emplace_back(Modifiers(), String(SKSL_RTHEIGHT_NAME), fContext.fFloat_Type.get());
|
||||
type = new Type(type->fPosition, type->name(), fields);
|
||||
fields.emplace_back(Modifiers(), StringFragment(SKSL_RTHEIGHT_NAME), fContext.fFloat_Type.get());
|
||||
type = new Type(type->fOffset, type->name(), fields);
|
||||
}
|
||||
SpvId typeId = this->getType(*type, layout);
|
||||
if (intf.fVariable.fModifiers.fFlags & Modifiers::kBuffer_Flag) {
|
||||
@ -2922,7 +2916,7 @@ void SPIRVCodeGenerator::writeGlobalVars(Program::Kind kind, const VarDeclaratio
|
||||
fVariableMap[var] = id;
|
||||
SpvId type = this->getPointerType(var->fType, storageClass);
|
||||
this->writeInstruction(SpvOpVariable, type, id, storageClass, fConstantBuffer);
|
||||
this->writeInstruction(SpvOpName, id, var->fName.c_str(), fNameBuffer);
|
||||
this->writeInstruction(SpvOpName, id, var->fName, fNameBuffer);
|
||||
this->writePrecisionModifier(var->fModifiers, id);
|
||||
if (varDecl.fValue) {
|
||||
ASSERT(!fCurrentBlock);
|
||||
@ -2958,7 +2952,7 @@ void SPIRVCodeGenerator::writeVarDeclarations(const VarDeclarations& decl, Outpu
|
||||
fVariableMap[var] = id;
|
||||
SpvId type = this->getPointerType(var->fType, SpvStorageClassFunction);
|
||||
this->writeInstruction(SpvOpVariable, type, id, SpvStorageClassFunction, fVariableBuffer);
|
||||
this->writeInstruction(SpvOpName, id, var->fName.c_str(), fNameBuffer);
|
||||
this->writeInstruction(SpvOpName, id, var->fName, fNameBuffer);
|
||||
if (varDecl.fValue) {
|
||||
SpvId value = this->writeExpression(*varDecl.fValue, out);
|
||||
this->writeInstruction(SpvOpStore, id, value, out);
|
||||
@ -3086,7 +3080,7 @@ void SPIRVCodeGenerator::writeWhileStatement(const WhileStatement& w, OutputStre
|
||||
// the time being, we just fail with an error due to the lack of testing. If you encounter this
|
||||
// message, simply remove the error call below to see whether our while loop support actually
|
||||
// works.
|
||||
fErrors.error(w.fPosition, "internal error: while loop support has been disabled in SPIR-V, "
|
||||
fErrors.error(w.fOffset, "internal error: while loop support has been disabled in SPIR-V, "
|
||||
"see SkSLSPIRVCodeGenerator.cpp for details");
|
||||
|
||||
SpvId header = this->nextId();
|
||||
@ -3118,7 +3112,7 @@ void SPIRVCodeGenerator::writeDoStatement(const DoStatement& d, OutputStream& ou
|
||||
// the time being, we just fail with an error due to the lack of testing. If you encounter this
|
||||
// message, simply remove the error call below to see whether our do loop support actually
|
||||
// works.
|
||||
fErrors.error(d.fPosition, "internal error: do loop support has been disabled in SPIR-V, see "
|
||||
fErrors.error(d.fOffset, "internal error: do loop support has been disabled in SPIR-V, see "
|
||||
"SkSLSPIRVCodeGenerator.cpp for details");
|
||||
|
||||
SpvId header = this->nextId();
|
||||
@ -3268,7 +3262,7 @@ void SPIRVCodeGenerator::writeInstructions(const Program& program, OutputStream&
|
||||
this->writeCapabilities(out);
|
||||
this->writeInstruction(SpvOpExtInstImport, fGLSLExtendedInstructions, "GLSL.std.450", out);
|
||||
this->writeInstruction(SpvOpMemoryModel, SpvAddressingModelLogical, SpvMemoryModelGLSL450, out);
|
||||
this->writeOpCode(SpvOpEntryPoint, (SpvId) (3 + (strlen(main->fName.c_str()) + 4) / 4) +
|
||||
this->writeOpCode(SpvOpEntryPoint, (SpvId) (3 + (main->fName.fLength + 4) / 4) +
|
||||
(int32_t) interfaceVars.size(), out);
|
||||
switch (program.fKind) {
|
||||
case Program::kVertex_Kind:
|
||||
@ -3285,7 +3279,7 @@ void SPIRVCodeGenerator::writeInstructions(const Program& program, OutputStream&
|
||||
}
|
||||
SpvId entryPoint = fFunctionMap[main];
|
||||
this->writeWord(entryPoint, out);
|
||||
this->writeString(main->fName.c_str(), out);
|
||||
this->writeString(main->fName.fChars, main->fName.fLength, out);
|
||||
for (int var : interfaceVars) {
|
||||
this->writeWord(var, out);
|
||||
}
|
||||
|
@ -241,19 +241,19 @@ private:
|
||||
|
||||
void writeWord(int32_t word, OutputStream& out);
|
||||
|
||||
void writeString(const char* string, OutputStream& out);
|
||||
void writeString(const char* string, size_t length, OutputStream& out);
|
||||
|
||||
void writeLabel(SpvId id, OutputStream& out);
|
||||
|
||||
void writeInstruction(SpvOp_ opCode, OutputStream& out);
|
||||
|
||||
void writeInstruction(SpvOp_ opCode, const char* string, OutputStream& out);
|
||||
void writeInstruction(SpvOp_ opCode, StringFragment string, OutputStream& out);
|
||||
|
||||
void writeInstruction(SpvOp_ opCode, int32_t word1, OutputStream& out);
|
||||
|
||||
void writeInstruction(SpvOp_ opCode, int32_t word1, const char* string, OutputStream& out);
|
||||
void writeInstruction(SpvOp_ opCode, int32_t word1, StringFragment string, OutputStream& out);
|
||||
|
||||
void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, const char* string,
|
||||
void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, StringFragment string,
|
||||
OutputStream& out);
|
||||
|
||||
void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, OutputStream& out);
|
||||
|
@ -56,21 +56,21 @@ public:
|
||||
if (IsSupportedSection(s->fName.c_str())) {
|
||||
if (SectionAcceptsArgument(s->fName.c_str())) {
|
||||
if (!s->fArgument.size()) {
|
||||
errors.error(s->fPosition,
|
||||
errors.error(s->fOffset,
|
||||
("section '@" + s->fName +
|
||||
"' requires one parameter").c_str());
|
||||
}
|
||||
} else if (s->fArgument.size()) {
|
||||
errors.error(s->fPosition,
|
||||
errors.error(s->fOffset,
|
||||
("section '@" + s->fName + "' has no parameters").c_str());
|
||||
}
|
||||
} else {
|
||||
errors.error(s->fPosition,
|
||||
errors.error(s->fOffset,
|
||||
("unsupported section '@" + s->fName + "'").c_str());
|
||||
}
|
||||
if (!SectionPermitsDuplicates(s->fName.c_str()) &&
|
||||
fSections.find(s->fName) != fSections.end()) {
|
||||
errors.error(s->fPosition,
|
||||
errors.error(s->fOffset,
|
||||
("duplicate section '@" + s->fName + "'").c_str());
|
||||
}
|
||||
fSections[s->fName].push_back(s);
|
||||
|
@ -77,6 +77,32 @@ String String::operator+(const String& s) const {
|
||||
return result;
|
||||
}
|
||||
|
||||
String String::operator+(StringFragment s) const {
|
||||
String result(*this);
|
||||
result.append(s.fChars, s.fLength);
|
||||
return result;
|
||||
}
|
||||
|
||||
String& String::operator+=(char c) {
|
||||
INHERITED::operator+=(c);
|
||||
return *this;
|
||||
}
|
||||
|
||||
String& String::operator+=(const char* s) {
|
||||
INHERITED::operator+=(s);
|
||||
return *this;
|
||||
}
|
||||
|
||||
String& String::operator+=(const String& s) {
|
||||
INHERITED::operator+=(s);
|
||||
return *this;
|
||||
}
|
||||
|
||||
String& String::operator+=(StringFragment s) {
|
||||
this->append(s.fChars, s.fLength);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool String::operator==(const String& s) const {
|
||||
return this->size() == s.size() && !memcmp(c_str(), s.c_str(), this->size());
|
||||
}
|
||||
@ -107,6 +133,28 @@ bool operator!=(const char* s1, const String& s2) {
|
||||
return s2 != s1;
|
||||
}
|
||||
|
||||
bool StringFragment::operator==(StringFragment s) const {
|
||||
if (fLength != s.fLength) {
|
||||
return false;
|
||||
}
|
||||
return !memcmp(fChars, s.fChars, fLength);
|
||||
}
|
||||
|
||||
bool StringFragment::operator!=(StringFragment s) const {
|
||||
if (fLength != s.fLength) {
|
||||
return true;
|
||||
}
|
||||
return memcmp(fChars, s.fChars, fLength);
|
||||
}
|
||||
|
||||
bool StringFragment::operator==(const char* s) const {
|
||||
return !strncmp(fChars, s, fLength);
|
||||
}
|
||||
|
||||
bool StringFragment::operator!=(const char* s) const {
|
||||
return strncmp(fChars, s, fLength);
|
||||
}
|
||||
|
||||
String to_string(int32_t value) {
|
||||
return SkSL::String::printf("%d", value);
|
||||
}
|
||||
|
@ -8,6 +8,8 @@
|
||||
#ifndef SKSL_STRING
|
||||
#define SKSL_STRING
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#define SKSL_USE_STD_STRING
|
||||
|
||||
#include <stdarg.h>
|
||||
@ -22,6 +24,33 @@
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
// Represents a (not necessarily null-terminated) slice of a string.
|
||||
struct StringFragment {
|
||||
StringFragment()
|
||||
: fChars(nullptr)
|
||||
, fLength(0) {}
|
||||
|
||||
StringFragment(const char* chars)
|
||||
: fChars(chars)
|
||||
, fLength(strlen(chars)) {}
|
||||
|
||||
StringFragment(const char* chars, size_t length)
|
||||
: fChars(chars)
|
||||
, fLength(length) {}
|
||||
|
||||
char operator[](size_t idx) const {
|
||||
return fChars[idx];
|
||||
}
|
||||
|
||||
bool operator==(const char* s) const;
|
||||
bool operator!=(const char* s) const;
|
||||
bool operator==(StringFragment s) const;
|
||||
bool operator!=(StringFragment s) const;
|
||||
|
||||
const char* fChars;
|
||||
size_t fLength;
|
||||
};
|
||||
|
||||
class String : public SKSL_STRING_BASE {
|
||||
public:
|
||||
String() = default;
|
||||
@ -41,6 +70,9 @@ public:
|
||||
String(const char* s, size_t size)
|
||||
: INHERITED(s, size) {}
|
||||
|
||||
String(StringFragment s)
|
||||
: INHERITED(s.fChars, s.fLength) {}
|
||||
|
||||
static String printf(const char* fmt, ...);
|
||||
|
||||
#ifdef SKSL_USE_STD_STRING
|
||||
@ -53,6 +85,11 @@ public:
|
||||
|
||||
String operator+(const char* s) const;
|
||||
String operator+(const String& s) const;
|
||||
String operator+(StringFragment s) const;
|
||||
String& operator+=(char c);
|
||||
String& operator+=(const char* s);
|
||||
String& operator+=(const String& s);
|
||||
String& operator+=(StringFragment s);
|
||||
bool operator==(const char* s) const;
|
||||
bool operator!=(const char* s) const;
|
||||
bool operator==(const String& s) const;
|
||||
@ -86,6 +123,18 @@ long stol(const String& s);
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace std {
|
||||
template<> struct hash<SkSL::StringFragment> {
|
||||
size_t operator()(const SkSL::StringFragment& s) const {
|
||||
size_t result = 0;
|
||||
for (size_t i = 0; i < s.fLength; ++i) {
|
||||
result = result * 101 + s.fChars[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
} // namespace
|
||||
|
||||
#ifdef SKSL_USE_STD_STRING
|
||||
namespace std {
|
||||
template<> struct hash<SkSL::String> {
|
||||
|
@ -1,227 +0,0 @@
|
||||
/*
|
||||
* 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 {
|
||||
|
||||
#undef IN
|
||||
#undef OUT
|
||||
#undef CONST
|
||||
|
||||
/**
|
||||
* 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,
|
||||
WHITESPACE,
|
||||
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,
|
||||
BITWISENOT,
|
||||
LOGICALOR,
|
||||
LOGICALXOR,
|
||||
LOGICALAND,
|
||||
LOGICALNOT,
|
||||
QUESTION,
|
||||
COLON,
|
||||
EQ,
|
||||
EQEQ,
|
||||
NEQ,
|
||||
GT,
|
||||
LT,
|
||||
GTEQ,
|
||||
LTEQ,
|
||||
PLUSEQ,
|
||||
MINUSEQ,
|
||||
STAREQ,
|
||||
SLASHEQ,
|
||||
PERCENTEQ,
|
||||
SHLEQ,
|
||||
SHREQ,
|
||||
BITWISEOREQ,
|
||||
BITWISEXOREQ,
|
||||
BITWISEANDEQ,
|
||||
LOGICALOREQ,
|
||||
LOGICALXOREQ,
|
||||
LOGICALANDEQ,
|
||||
SEMICOLON,
|
||||
ARROW,
|
||||
COLONCOLON,
|
||||
IF,
|
||||
STATIC_IF,
|
||||
ELSE,
|
||||
FOR,
|
||||
WHILE,
|
||||
DO,
|
||||
SWITCH,
|
||||
STATIC_SWITCH,
|
||||
CASE,
|
||||
DEFAULT,
|
||||
RETURN,
|
||||
BREAK,
|
||||
CONTINUE,
|
||||
DISCARD,
|
||||
IN,
|
||||
OUT,
|
||||
INOUT,
|
||||
CONST,
|
||||
LOWP,
|
||||
MEDIUMP,
|
||||
HIGHP,
|
||||
UNIFORM,
|
||||
FLAT,
|
||||
NOPERSPECTIVE,
|
||||
READONLY,
|
||||
WRITEONLY,
|
||||
COHERENT,
|
||||
VOLATILE,
|
||||
RESTRICT,
|
||||
BUFFER,
|
||||
HASSIDEEFFECTS,
|
||||
STRUCT,
|
||||
LAYOUT,
|
||||
DIRECTIVE,
|
||||
SECTION,
|
||||
PRECISION,
|
||||
LOCATION,
|
||||
OFFSET,
|
||||
BINDING,
|
||||
INDEX,
|
||||
SET,
|
||||
BUILTIN,
|
||||
INPUT_ATTACHMENT_INDEX,
|
||||
ORIGIN_UPPER_LEFT,
|
||||
OVERRIDE_COVERAGE,
|
||||
BLEND_SUPPORT_ALL_EQUATIONS,
|
||||
PUSH_CONSTANT,
|
||||
POINTS,
|
||||
LINES,
|
||||
LINE_STRIP,
|
||||
LINES_ADJACENCY,
|
||||
TRIANGLES,
|
||||
TRIANGLE_STRIP,
|
||||
TRIANGLES_ADJACENCY,
|
||||
MAX_VERTICES,
|
||||
INVOCATIONS,
|
||||
WHEN,
|
||||
KEY,
|
||||
INVALID_TOKEN
|
||||
};
|
||||
|
||||
static String OperatorName(Kind kind) {
|
||||
switch (kind) {
|
||||
case Token::PLUS: return String("+");
|
||||
case Token::MINUS: return String("-");
|
||||
case Token::STAR: return String("*");
|
||||
case Token::SLASH: return String("/");
|
||||
case Token::PERCENT: return String("%");
|
||||
case Token::SHL: return String("<<");
|
||||
case Token::SHR: return String(">>");
|
||||
case Token::LOGICALNOT: return String("!");
|
||||
case Token::LOGICALAND: return String("&&");
|
||||
case Token::LOGICALOR: return String("||");
|
||||
case Token::LOGICALXOR: return String("^^");
|
||||
case Token::BITWISENOT: return String("~");
|
||||
case Token::BITWISEAND: return String("&");
|
||||
case Token::BITWISEOR: return String("|");
|
||||
case Token::BITWISEXOR: return String("^");
|
||||
case Token::EQ: return String("=");
|
||||
case Token::EQEQ: return String("==");
|
||||
case Token::NEQ: return String("!=");
|
||||
case Token::LT: return String("<");
|
||||
case Token::GT: return String(">");
|
||||
case Token::LTEQ: return String("<=");
|
||||
case Token::GTEQ: return String(">=");
|
||||
case Token::PLUSEQ: return String("+=");
|
||||
case Token::MINUSEQ: return String("-=");
|
||||
case Token::STAREQ: return String("*=");
|
||||
case Token::SLASHEQ: return String("/=");
|
||||
case Token::PERCENTEQ: return String("%=");
|
||||
case Token::SHLEQ: return String("<<=");
|
||||
case Token::SHREQ: return String(">>=");
|
||||
case Token::LOGICALANDEQ: return String("&&=");
|
||||
case Token::LOGICALOREQ: return String("||=");
|
||||
case Token::LOGICALXOREQ: return String("^^=");
|
||||
case Token::BITWISEANDEQ: return String("&=");
|
||||
case Token::BITWISEOREQ: return String("|=");
|
||||
case Token::BITWISEXOREQ: return String("^=");
|
||||
case Token::PLUSPLUS: return String("++");
|
||||
case Token::MINUSMINUS: return String("--");
|
||||
case Token::COMMA: return String(",");
|
||||
default:
|
||||
ABORT("unsupported operator: %d\n", kind);
|
||||
}
|
||||
}
|
||||
|
||||
Token() {
|
||||
}
|
||||
|
||||
Token(Position position, Kind kind, String text)
|
||||
: fPosition(position)
|
||||
, fKind(kind)
|
||||
, fText(std::move(text)) {}
|
||||
|
||||
static bool IsAssignment(Token::Kind op) {
|
||||
switch (op) {
|
||||
case Token::EQ: // fall through
|
||||
case Token::PLUSEQ: // fall through
|
||||
case Token::MINUSEQ: // fall through
|
||||
case Token::STAREQ: // fall through
|
||||
case Token::SLASHEQ: // fall through
|
||||
case Token::PERCENTEQ: // fall through
|
||||
case Token::SHLEQ: // fall through
|
||||
case Token::SHREQ: // fall through
|
||||
case Token::BITWISEOREQ: // fall through
|
||||
case Token::BITWISEXOREQ: // fall through
|
||||
case Token::BITWISEANDEQ: // fall through
|
||||
case Token::LOGICALOREQ: // fall through
|
||||
case Token::LOGICALXOREQ: // fall through
|
||||
case Token::LOGICALANDEQ:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Position fPosition;
|
||||
Kind fKind;
|
||||
// will be the empty string unless the token has variable text content (identifiers, numeric
|
||||
// literals, and directives)
|
||||
String fText;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
#endif
|
@ -9,7 +9,8 @@
|
||||
#define SKSL_ASTBINARYEXPRESSION
|
||||
|
||||
#include "SkSLASTExpression.h"
|
||||
#include "../SkSLToken.h"
|
||||
#include "../SkSLCompiler.h"
|
||||
#include "../SkSLLexer.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
@ -19,13 +20,13 @@ namespace SkSL {
|
||||
struct ASTBinaryExpression : public ASTExpression {
|
||||
ASTBinaryExpression(std::unique_ptr<ASTExpression> left, Token op,
|
||||
std::unique_ptr<ASTExpression> right)
|
||||
: INHERITED(op.fPosition, kBinary_Kind)
|
||||
: INHERITED(op.fOffset, kBinary_Kind)
|
||||
, fLeft(std::move(left))
|
||||
, fOperator(op.fKind)
|
||||
, fRight(std::move(right)) {}
|
||||
|
||||
String description() const override {
|
||||
return "(" + fLeft->description() + " " + Token::OperatorName(fOperator) + " " +
|
||||
return "(" + fLeft->description() + " " + Compiler::OperatorName(fOperator) + " " +
|
||||
fRight->description() + ")";
|
||||
}
|
||||
|
||||
|
@ -16,8 +16,8 @@ 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)
|
||||
ASTBlock(int offset, std::vector<std::unique_ptr<ASTStatement>> statements)
|
||||
: INHERITED(offset, kBlock_Kind)
|
||||
, fStatements(std::move(statements)) {}
|
||||
|
||||
String description() const override {
|
||||
|
@ -16,8 +16,8 @@ namespace SkSL {
|
||||
* Represents "true" or "false".
|
||||
*/
|
||||
struct ASTBoolLiteral : public ASTExpression {
|
||||
ASTBoolLiteral(Position position, bool value)
|
||||
: INHERITED(position, kBool_Kind)
|
||||
ASTBoolLiteral(int offset, bool value)
|
||||
: INHERITED(offset, kBool_Kind)
|
||||
, fValue(value) {}
|
||||
|
||||
String description() const override {
|
||||
|
@ -16,8 +16,8 @@ namespace SkSL {
|
||||
* A 'break' statement.
|
||||
*/
|
||||
struct ASTBreakStatement : public ASTStatement {
|
||||
ASTBreakStatement(Position position)
|
||||
: INHERITED(position, kBreak_Kind) {}
|
||||
ASTBreakStatement(int offset)
|
||||
: INHERITED(offset, kBreak_Kind) {}
|
||||
|
||||
String description() const override {
|
||||
return String("break;");
|
||||
|
@ -17,8 +17,8 @@ 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)
|
||||
ASTCallSuffix(int offset, std::vector<std::unique_ptr<ASTExpression>> arguments)
|
||||
: INHERITED(offset, ASTSuffix::kCall_Kind)
|
||||
, fArguments(std::move(arguments)) {}
|
||||
|
||||
String description() const override {
|
||||
|
@ -16,8 +16,8 @@ namespace SkSL {
|
||||
* A 'continue' statement.
|
||||
*/
|
||||
struct ASTContinueStatement : public ASTStatement {
|
||||
ASTContinueStatement(Position position)
|
||||
: INHERITED(position, kContinue_Kind) {}
|
||||
ASTContinueStatement(int offset)
|
||||
: INHERITED(offset, kContinue_Kind) {}
|
||||
|
||||
String description() const override {
|
||||
return String("continue;");
|
||||
|
@ -26,8 +26,8 @@ struct ASTDeclaration : public ASTPositionNode {
|
||||
kSection_Kind
|
||||
};
|
||||
|
||||
ASTDeclaration(Position position, Kind kind)
|
||||
: INHERITED(position)
|
||||
ASTDeclaration(int offset, Kind kind)
|
||||
: INHERITED(offset)
|
||||
, fKind(kind) {}
|
||||
|
||||
Kind fKind;
|
||||
|
@ -16,8 +16,8 @@ namespace SkSL {
|
||||
* A 'discard' statement.
|
||||
*/
|
||||
struct ASTDiscardStatement : public ASTStatement {
|
||||
ASTDiscardStatement(Position position)
|
||||
: INHERITED(position, kDiscard_Kind) {}
|
||||
ASTDiscardStatement(int offset)
|
||||
: INHERITED(offset, kDiscard_Kind) {}
|
||||
|
||||
String description() const override {
|
||||
return String("discard;");
|
||||
|
@ -16,9 +16,9 @@ namespace SkSL {
|
||||
* A 'do' loop.
|
||||
*/
|
||||
struct ASTDoStatement : public ASTStatement {
|
||||
ASTDoStatement(Position position, std::unique_ptr<ASTStatement> statement,
|
||||
ASTDoStatement(int offset, std::unique_ptr<ASTStatement> statement,
|
||||
std::unique_ptr<ASTExpression> test)
|
||||
: INHERITED(position, kDo_Kind)
|
||||
: INHERITED(offset, kDo_Kind)
|
||||
, fStatement(std::move(statement))
|
||||
, fTest(std::move(test)) {}
|
||||
|
||||
|
@ -27,8 +27,8 @@ struct ASTExpression : public ASTPositionNode {
|
||||
kTernary_Kind
|
||||
};
|
||||
|
||||
ASTExpression(Position position, Kind kind)
|
||||
: INHERITED(position)
|
||||
ASTExpression(int offset, Kind kind)
|
||||
: INHERITED(offset)
|
||||
, fKind(kind) {}
|
||||
|
||||
const Kind fKind;
|
||||
|
@ -17,7 +17,7 @@ namespace SkSL {
|
||||
*/
|
||||
struct ASTExpressionStatement : public ASTStatement {
|
||||
ASTExpressionStatement(std::unique_ptr<ASTExpression> expression)
|
||||
: INHERITED(expression->fPosition, kExpression_Kind)
|
||||
: INHERITED(expression->fOffset, kExpression_Kind)
|
||||
, fExpression(std::move(expression)) {}
|
||||
|
||||
String description() const override {
|
||||
|
@ -16,8 +16,8 @@ namespace SkSL {
|
||||
* An extension declaration.
|
||||
*/
|
||||
struct ASTExtension : public ASTDeclaration {
|
||||
ASTExtension(Position position, String name)
|
||||
: INHERITED(position, kExtension_Kind)
|
||||
ASTExtension(int offset, String name)
|
||||
: INHERITED(offset, kExtension_Kind)
|
||||
, fName(std::move(name)) {}
|
||||
|
||||
String description() const override {
|
||||
|
@ -17,15 +17,15 @@ namespace SkSL {
|
||||
* actually vector swizzle (which looks the same to the parser).
|
||||
*/
|
||||
struct ASTFieldSuffix : public ASTSuffix {
|
||||
ASTFieldSuffix(Position position, String field)
|
||||
: INHERITED(position, ASTSuffix::kField_Kind)
|
||||
, fField(std::move(field)) {}
|
||||
ASTFieldSuffix(int offset, StringFragment field)
|
||||
: INHERITED(offset, ASTSuffix::kField_Kind)
|
||||
, fField(field) {}
|
||||
|
||||
String description() const override {
|
||||
return "." + fField;
|
||||
}
|
||||
|
||||
String fField;
|
||||
StringFragment fField;
|
||||
|
||||
typedef ASTSuffix INHERITED;
|
||||
};
|
||||
|
@ -16,8 +16,8 @@ namespace SkSL {
|
||||
* A literal floating point number.
|
||||
*/
|
||||
struct ASTFloatLiteral : public ASTExpression {
|
||||
ASTFloatLiteral(Position position, double value)
|
||||
: INHERITED(position, kFloat_Kind)
|
||||
ASTFloatLiteral(int offset, double value)
|
||||
: INHERITED(offset, kFloat_Kind)
|
||||
, fValue(value) {}
|
||||
|
||||
String description() const override {
|
||||
|
@ -16,10 +16,10 @@ namespace SkSL {
|
||||
* A 'for' loop.
|
||||
*/
|
||||
struct ASTForStatement : public ASTStatement {
|
||||
ASTForStatement(Position position, std::unique_ptr<ASTStatement> initializer,
|
||||
ASTForStatement(int offset, std::unique_ptr<ASTStatement> initializer,
|
||||
std::unique_ptr<ASTExpression> test, std::unique_ptr<ASTExpression> next,
|
||||
std::unique_ptr<ASTStatement> statement)
|
||||
: INHERITED(position, kFor_Kind)
|
||||
: INHERITED(offset, kFor_Kind)
|
||||
, fInitializer(std::move(initializer))
|
||||
, fTest(std::move(test))
|
||||
, fNext(std::move(next))
|
||||
|
@ -19,13 +19,13 @@ namespace SkSL {
|
||||
* A function declaration or definition. The fBody field will be null for declarations.
|
||||
*/
|
||||
struct ASTFunction : public ASTDeclaration {
|
||||
ASTFunction(Position position, Modifiers modifiers, std::unique_ptr<ASTType> returnType,
|
||||
String name, std::vector<std::unique_ptr<ASTParameter>> parameters,
|
||||
ASTFunction(int offset, Modifiers modifiers, std::unique_ptr<ASTType> returnType,
|
||||
StringFragment name, std::vector<std::unique_ptr<ASTParameter>> parameters,
|
||||
std::unique_ptr<ASTBlock> body)
|
||||
: INHERITED(position, kFunction_Kind)
|
||||
: INHERITED(offset, kFunction_Kind)
|
||||
, fModifiers(modifiers)
|
||||
, fReturnType(std::move(returnType))
|
||||
, fName(std::move(name))
|
||||
, fName(name)
|
||||
, fParameters(std::move(parameters))
|
||||
, fBody(std::move(body)) {}
|
||||
|
||||
@ -47,7 +47,7 @@ struct ASTFunction : public ASTDeclaration {
|
||||
|
||||
const Modifiers fModifiers;
|
||||
const std::unique_ptr<ASTType> fReturnType;
|
||||
const String fName;
|
||||
const StringFragment fName;
|
||||
const std::vector<std::unique_ptr<ASTParameter>> fParameters;
|
||||
const std::unique_ptr<ASTBlock> fBody;
|
||||
|
||||
|
@ -16,15 +16,15 @@ namespace SkSL {
|
||||
* An identifier in an expression context.
|
||||
*/
|
||||
struct ASTIdentifier : public ASTExpression {
|
||||
ASTIdentifier(Position position, String text)
|
||||
: INHERITED(position, kIdentifier_Kind)
|
||||
, fText(std::move(text)) {}
|
||||
ASTIdentifier(int offset, StringFragment text)
|
||||
: INHERITED(offset, kIdentifier_Kind)
|
||||
, fText(text) {}
|
||||
|
||||
String description() const override {
|
||||
return fText;
|
||||
return String(fText);
|
||||
}
|
||||
|
||||
const String fText;
|
||||
const StringFragment fText;
|
||||
|
||||
typedef ASTExpression INHERITED;
|
||||
};
|
||||
|
@ -16,9 +16,9 @@ namespace SkSL {
|
||||
* An 'if' statement.
|
||||
*/
|
||||
struct ASTIfStatement : public ASTStatement {
|
||||
ASTIfStatement(Position position, bool isStatic, std::unique_ptr<ASTExpression> test,
|
||||
ASTIfStatement(int offset, bool isStatic, std::unique_ptr<ASTExpression> test,
|
||||
std::unique_ptr<ASTStatement> ifTrue, std::unique_ptr<ASTStatement> ifFalse)
|
||||
: INHERITED(position, kIf_Kind)
|
||||
: INHERITED(offset, kIf_Kind)
|
||||
, fIsStatic(isStatic)
|
||||
, fTest(std::move(test))
|
||||
, fIfTrue(std::move(ifTrue))
|
||||
|
@ -18,12 +18,12 @@ namespace SkSL {
|
||||
* 'float[](5, 6)' are represented with a null fExpression.
|
||||
*/
|
||||
struct ASTIndexSuffix : public ASTSuffix {
|
||||
ASTIndexSuffix(Position position)
|
||||
: INHERITED(position, ASTSuffix::kIndex_Kind)
|
||||
ASTIndexSuffix(int offset)
|
||||
: INHERITED(offset, ASTSuffix::kIndex_Kind)
|
||||
, fExpression(nullptr) {}
|
||||
|
||||
ASTIndexSuffix(std::unique_ptr<ASTExpression> expression)
|
||||
: INHERITED(expression ? expression->fPosition : Position(), ASTSuffix::kIndex_Kind)
|
||||
: INHERITED(expression ? expression->fOffset : -1, ASTSuffix::kIndex_Kind)
|
||||
, fExpression(std::move(expression)) {}
|
||||
|
||||
String description() const override {
|
||||
|
@ -17,8 +17,8 @@ namespace SkSL {
|
||||
* 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)
|
||||
ASTIntLiteral(int offset, uint64_t value)
|
||||
: INHERITED(offset, kInt_Kind)
|
||||
, fValue(value) {}
|
||||
|
||||
String description() const override {
|
||||
|
@ -23,17 +23,17 @@ namespace SkSL {
|
||||
*/
|
||||
struct ASTInterfaceBlock : public ASTDeclaration {
|
||||
// valueName is empty when it was not present in the source
|
||||
ASTInterfaceBlock(Position position,
|
||||
ASTInterfaceBlock(int offset,
|
||||
Modifiers modifiers,
|
||||
String typeName,
|
||||
StringFragment typeName,
|
||||
std::vector<std::unique_ptr<ASTVarDeclarations>> declarations,
|
||||
String instanceName,
|
||||
StringFragment instanceName,
|
||||
std::vector<std::unique_ptr<ASTExpression>> sizes)
|
||||
: INHERITED(position, kInterfaceBlock_Kind)
|
||||
: INHERITED(offset, kInterfaceBlock_Kind)
|
||||
, fModifiers(modifiers)
|
||||
, fTypeName(std::move(typeName))
|
||||
, fTypeName(typeName)
|
||||
, fDeclarations(std::move(declarations))
|
||||
, fInstanceName(std::move(instanceName))
|
||||
, fInstanceName(instanceName)
|
||||
, fSizes(std::move(sizes)) {}
|
||||
|
||||
String description() const override {
|
||||
@ -42,7 +42,7 @@ struct ASTInterfaceBlock : public ASTDeclaration {
|
||||
result += fDeclarations[i]->description() + "\n";
|
||||
}
|
||||
result += "}";
|
||||
if (fInstanceName.size()) {
|
||||
if (fInstanceName.fLength) {
|
||||
result += " " + fInstanceName;
|
||||
for (const auto& size : fSizes) {
|
||||
result += "[";
|
||||
@ -56,9 +56,9 @@ struct ASTInterfaceBlock : public ASTDeclaration {
|
||||
}
|
||||
|
||||
const Modifiers fModifiers;
|
||||
const String fTypeName;
|
||||
const StringFragment fTypeName;
|
||||
const std::vector<std::unique_ptr<ASTVarDeclarations>> fDeclarations;
|
||||
const String fInstanceName;
|
||||
const StringFragment fInstanceName;
|
||||
const std::vector<std::unique_ptr<ASTExpression>> fSizes;
|
||||
|
||||
typedef ASTDeclaration INHERITED;
|
||||
|
@ -20,7 +20,7 @@ namespace SkSL {
|
||||
*/
|
||||
struct ASTModifiersDeclaration : public ASTDeclaration {
|
||||
ASTModifiersDeclaration(Modifiers modifiers)
|
||||
: INHERITED(Position(), kModifiers_Kind)
|
||||
: INHERITED(-1, kModifiers_Kind)
|
||||
, fModifiers(modifiers) {}
|
||||
|
||||
String description() const {
|
||||
|
@ -20,12 +20,12 @@ namespace SkSL {
|
||||
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, Modifiers modifiers, std::unique_ptr<ASTType> type,
|
||||
String name, std::vector<int> sizes)
|
||||
: INHERITED(position)
|
||||
ASTParameter(int offset, Modifiers modifiers, std::unique_ptr<ASTType> type,
|
||||
StringFragment name, std::vector<int> sizes)
|
||||
: INHERITED(offset)
|
||||
, fModifiers(modifiers)
|
||||
, fType(std::move(type))
|
||||
, fName(std::move(name))
|
||||
, fName(name)
|
||||
, fSizes(std::move(sizes)) {}
|
||||
|
||||
String description() const override {
|
||||
@ -38,7 +38,7 @@ struct ASTParameter : public ASTPositionNode {
|
||||
|
||||
const Modifiers fModifiers;
|
||||
const std::unique_ptr<ASTType> fType;
|
||||
const String fName;
|
||||
const StringFragment fName;
|
||||
const std::vector<int> fSizes;
|
||||
|
||||
typedef ASTPositionNode INHERITED;
|
||||
|
@ -17,10 +17,12 @@ namespace SkSL {
|
||||
* An AST node with an associated position in the source.
|
||||
*/
|
||||
struct ASTPositionNode : public ASTNode {
|
||||
ASTPositionNode(Position position)
|
||||
: fPosition(position) {}
|
||||
ASTPositionNode(int offset)
|
||||
: fOffset(offset) {}
|
||||
|
||||
const Position fPosition;
|
||||
// character offset of this element within the program being compiled, for error reporting
|
||||
// purposes
|
||||
const int fOffset;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
@ -18,8 +18,8 @@ namespace SkSL {
|
||||
*/
|
||||
struct ASTPrecision : public ASTDeclaration {
|
||||
// FIXME handle the type
|
||||
ASTPrecision(Position position, Modifiers::Flag precision)
|
||||
: INHERITED(position, kPrecision_Kind)
|
||||
ASTPrecision(int offset, Modifiers::Flag precision)
|
||||
: INHERITED(offset, kPrecision_Kind)
|
||||
, fPrecision(precision) {}
|
||||
|
||||
String description() const {
|
||||
|
@ -9,7 +9,8 @@
|
||||
#define SKSL_ASTPREFIXEXPRESSION
|
||||
|
||||
#include "SkSLASTExpression.h"
|
||||
#include "../SkSLToken.h"
|
||||
#include "../SkSLCompiler.h"
|
||||
#include "../SkSLLexer.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
@ -18,12 +19,12 @@ namespace SkSL {
|
||||
*/
|
||||
struct ASTPrefixExpression : public ASTExpression {
|
||||
ASTPrefixExpression(Token op, std::unique_ptr<ASTExpression> operand)
|
||||
: INHERITED(op.fPosition, kPrefix_Kind)
|
||||
: INHERITED(op.fOffset, kPrefix_Kind)
|
||||
, fOperator(op.fKind)
|
||||
, fOperand(std::move(operand)) {}
|
||||
|
||||
String description() const override {
|
||||
return Token::OperatorName(fOperator) + fOperand->description();
|
||||
return Compiler::OperatorName(fOperator) + fOperand->description();
|
||||
}
|
||||
|
||||
const Token::Kind fOperator;
|
||||
|
@ -17,8 +17,8 @@ namespace SkSL {
|
||||
*/
|
||||
struct ASTReturnStatement : public ASTStatement {
|
||||
// expression may be null
|
||||
ASTReturnStatement(Position position, std::unique_ptr<ASTExpression> expression)
|
||||
: INHERITED(position, kReturn_Kind)
|
||||
ASTReturnStatement(int offset, std::unique_ptr<ASTExpression> expression)
|
||||
: INHERITED(offset, kReturn_Kind)
|
||||
, fExpression(std::move(expression)) {}
|
||||
|
||||
String description() const override {
|
||||
|
@ -16,8 +16,8 @@ namespace SkSL {
|
||||
* A section declaration (e.g. @body { body code here })..
|
||||
*/
|
||||
struct ASTSection : public ASTDeclaration {
|
||||
ASTSection(Position position, String name, String arg, String text)
|
||||
: INHERITED(position, kSection_Kind)
|
||||
ASTSection(int offset, String name, String arg, String text)
|
||||
: INHERITED(offset, kSection_Kind)
|
||||
, fName(std::move(name))
|
||||
, fArgument(std::move(arg))
|
||||
, fText(std::move(text)) {}
|
||||
|
@ -33,8 +33,8 @@ struct ASTStatement : public ASTPositionNode {
|
||||
kDiscard_Kind
|
||||
};
|
||||
|
||||
ASTStatement(Position position, Kind kind)
|
||||
: INHERITED(position)
|
||||
ASTStatement(int offset, Kind kind)
|
||||
: INHERITED(offset)
|
||||
, fKind(kind) {}
|
||||
|
||||
Kind fKind;
|
||||
|
@ -26,8 +26,8 @@ struct ASTSuffix : public ASTPositionNode {
|
||||
kPostDecrement_Kind
|
||||
};
|
||||
|
||||
ASTSuffix(Position position, Kind kind)
|
||||
: INHERITED(position)
|
||||
ASTSuffix(int offset, Kind kind)
|
||||
: INHERITED(offset)
|
||||
, fKind(kind) {}
|
||||
|
||||
String description() const override {
|
||||
|
@ -18,7 +18,7 @@ namespace SkSL {
|
||||
*/
|
||||
struct ASTSuffixExpression : public ASTExpression {
|
||||
ASTSuffixExpression(std::unique_ptr<ASTExpression> base, std::unique_ptr<ASTSuffix> suffix)
|
||||
: INHERITED(base->fPosition, kSuffix_Kind)
|
||||
: INHERITED(base->fOffset, kSuffix_Kind)
|
||||
, fBase(std::move(base))
|
||||
, fSuffix(std::move(suffix)) {}
|
||||
|
||||
|
@ -17,9 +17,9 @@ namespace SkSL {
|
||||
*/
|
||||
struct ASTSwitchCase : public ASTStatement {
|
||||
// a null value means "default:"
|
||||
ASTSwitchCase(Position position, std::unique_ptr<ASTExpression> value,
|
||||
ASTSwitchCase(int offset, std::unique_ptr<ASTExpression> value,
|
||||
std::vector<std::unique_ptr<ASTStatement>> statements)
|
||||
: INHERITED(position, kSwitch_Kind)
|
||||
: INHERITED(offset, kSwitch_Kind)
|
||||
, fValue(std::move(value))
|
||||
, fStatements(std::move(statements)) {}
|
||||
|
||||
|
@ -17,9 +17,9 @@ namespace SkSL {
|
||||
* A 'switch' statement.
|
||||
*/
|
||||
struct ASTSwitchStatement : public ASTStatement {
|
||||
ASTSwitchStatement(Position position, bool isStatic, std::unique_ptr<ASTExpression> value,
|
||||
ASTSwitchStatement(int offset, bool isStatic, std::unique_ptr<ASTExpression> value,
|
||||
std::vector<std::unique_ptr<ASTSwitchCase>> cases)
|
||||
: INHERITED(position, kSwitch_Kind)
|
||||
: INHERITED(offset, kSwitch_Kind)
|
||||
, fIsStatic(isStatic)
|
||||
, fValue(std::move(value))
|
||||
, fCases(std::move(cases)) {}
|
||||
|
@ -19,7 +19,7 @@ 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)
|
||||
: INHERITED(test->fOffset, kTernary_Kind)
|
||||
, fTest(std::move(test))
|
||||
, fIfTrue(std::move(ifTrue))
|
||||
, fIfFalse(std::move(ifFalse)) {}
|
||||
|
@ -21,9 +21,9 @@ struct ASTType : public ASTPositionNode {
|
||||
kStruct_Kind
|
||||
};
|
||||
|
||||
ASTType(Position position, String name, Kind kind, std::vector<int> sizes)
|
||||
: INHERITED(position)
|
||||
, fName(std::move(name))
|
||||
ASTType(int offset, StringFragment name, Kind kind, std::vector<int> sizes)
|
||||
: INHERITED(offset)
|
||||
, fName(name)
|
||||
, fKind(kind)
|
||||
, fSizes(std::move(sizes)) {}
|
||||
|
||||
@ -31,7 +31,7 @@ struct ASTType : public ASTPositionNode {
|
||||
return fName;
|
||||
}
|
||||
|
||||
const String fName;
|
||||
const StringFragment fName;
|
||||
|
||||
const Kind fKind;
|
||||
|
||||
|
@ -22,7 +22,7 @@ namespace SkSL {
|
||||
* instances.
|
||||
*/
|
||||
struct ASTVarDeclaration {
|
||||
ASTVarDeclaration(const String name,
|
||||
ASTVarDeclaration(StringFragment name,
|
||||
std::vector<std::unique_ptr<ASTExpression>> sizes,
|
||||
std::unique_ptr<ASTExpression> value)
|
||||
: fName(name)
|
||||
@ -30,7 +30,7 @@ struct ASTVarDeclaration {
|
||||
, fValue(std::move(value)) {}
|
||||
|
||||
String description() const {
|
||||
String result = fName;
|
||||
String result(fName);
|
||||
for (const auto& size : fSizes) {
|
||||
if (size) {
|
||||
result += "[" + size->description() + "]";
|
||||
@ -44,7 +44,7 @@ struct ASTVarDeclaration {
|
||||
return result;
|
||||
}
|
||||
|
||||
String fName;
|
||||
StringFragment fName;
|
||||
|
||||
// array sizes, if any. e.g. 'foo[3][]' has sizes [3, null]
|
||||
std::vector<std::unique_ptr<ASTExpression>> fSizes;
|
||||
@ -60,7 +60,7 @@ struct ASTVarDeclarations : public ASTDeclaration {
|
||||
ASTVarDeclarations(Modifiers modifiers,
|
||||
std::unique_ptr<ASTType> type,
|
||||
std::vector<ASTVarDeclaration> vars)
|
||||
: INHERITED(type->fPosition, kVar_Kind)
|
||||
: INHERITED(type->fOffset, kVar_Kind)
|
||||
, fModifiers(modifiers)
|
||||
, fType(std::move(type))
|
||||
, fVars(std::move(vars)) {}
|
||||
|
@ -18,7 +18,7 @@ namespace SkSL {
|
||||
*/
|
||||
struct ASTVarDeclarationStatement : public ASTStatement {
|
||||
ASTVarDeclarationStatement(std::unique_ptr<ASTVarDeclarations> decl)
|
||||
: INHERITED(decl->fPosition, kVarDeclaration_Kind)
|
||||
: INHERITED(decl->fOffset, kVarDeclaration_Kind)
|
||||
, fDeclarations(std::move(decl)) {}
|
||||
|
||||
String description() const override {
|
||||
|
@ -16,9 +16,9 @@ namespace SkSL {
|
||||
* A 'while' statement.
|
||||
*/
|
||||
struct ASTWhileStatement : public ASTStatement {
|
||||
ASTWhileStatement(Position position, std::unique_ptr<ASTExpression> test,
|
||||
ASTWhileStatement(int offset, std::unique_ptr<ASTExpression> test,
|
||||
std::unique_ptr<ASTStatement> statement)
|
||||
: INHERITED(position, kWhile_Kind)
|
||||
: INHERITED(offset, kWhile_Kind)
|
||||
, fTest(std::move(test))
|
||||
, fStatement(std::move(statement)) {}
|
||||
|
||||
|
@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright 2017 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
// useless include to avoid "#if before #include" complaint from Skia presubmit
|
||||
#include "SkSLUtil.h"
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunneeded-internal-declaration"
|
||||
#pragma clang diagnostic ignored "-Wnull-conversion"
|
||||
#pragma clang diagnostic ignored "-Wsign-compare"
|
||||
#pragma clang diagnostic ignored "-Wunused-function"
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-register"
|
||||
#endif
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wsign-compare"
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4018)
|
||||
#endif
|
||||
|
||||
#define YY_NO_UNPUT
|
@ -11,7 +11,7 @@
|
||||
#include "SkSLExpression.h"
|
||||
#include "SkSLExpression.h"
|
||||
#include "../SkSLIRGenerator.h"
|
||||
#include "../SkSLToken.h"
|
||||
#include "../SkSLLexer.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
@ -19,9 +19,9 @@ namespace SkSL {
|
||||
* A binary operation.
|
||||
*/
|
||||
struct BinaryExpression : public Expression {
|
||||
BinaryExpression(Position position, std::unique_ptr<Expression> left, Token::Kind op,
|
||||
BinaryExpression(int offset, std::unique_ptr<Expression> left, Token::Kind op,
|
||||
std::unique_ptr<Expression> right, const Type& type)
|
||||
: INHERITED(position, kBinary_Kind, type)
|
||||
: INHERITED(offset, kBinary_Kind, type)
|
||||
, fLeft(std::move(left))
|
||||
, fOperator(op)
|
||||
, fRight(std::move(right)) {}
|
||||
@ -34,12 +34,12 @@ struct BinaryExpression : public Expression {
|
||||
}
|
||||
|
||||
bool hasSideEffects() const override {
|
||||
return Token::IsAssignment(fOperator) || fLeft->hasSideEffects() ||
|
||||
return Compiler::IsAssignment(fOperator) || fLeft->hasSideEffects() ||
|
||||
fRight->hasSideEffects();
|
||||
}
|
||||
|
||||
String description() const override {
|
||||
return "(" + fLeft->description() + " " + Token::OperatorName(fOperator) + " " +
|
||||
return "(" + fLeft->description() + " " + Compiler::OperatorName(fOperator) + " " +
|
||||
fRight->description() + ")";
|
||||
}
|
||||
|
||||
|
@ -17,9 +17,9 @@ 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,
|
||||
Block(int offset, std::vector<std::unique_ptr<Statement>> statements,
|
||||
const std::shared_ptr<SymbolTable> symbols = nullptr)
|
||||
: INHERITED(position, kBlock_Kind)
|
||||
: INHERITED(offset, kBlock_Kind)
|
||||
, fSymbols(std::move(symbols))
|
||||
, fStatements(std::move(statements)) {}
|
||||
|
||||
|
@ -17,8 +17,8 @@ namespace SkSL {
|
||||
* Represents 'true' or 'false'.
|
||||
*/
|
||||
struct BoolLiteral : public Expression {
|
||||
BoolLiteral(const Context& context, Position position, bool value)
|
||||
: INHERITED(position, kBoolLiteral_Kind, *context.fBool_Type)
|
||||
BoolLiteral(const Context& context, int offset, bool value)
|
||||
: INHERITED(offset, kBoolLiteral_Kind, *context.fBool_Type)
|
||||
, fValue(value) {}
|
||||
|
||||
String description() const override {
|
||||
|
@ -17,8 +17,8 @@ namespace SkSL {
|
||||
* A 'break' statement.
|
||||
*/
|
||||
struct BreakStatement : public Statement {
|
||||
BreakStatement(Position position)
|
||||
: INHERITED(position, kBreak_Kind) {}
|
||||
BreakStatement(int offset)
|
||||
: INHERITED(offset, kBreak_Kind) {}
|
||||
|
||||
String description() const override {
|
||||
return String("break;");
|
||||
|
@ -16,7 +16,7 @@
|
||||
namespace SkSL {
|
||||
|
||||
/**
|
||||
* Represents the construction of a compound type, such as "float2x, y)".
|
||||
* Represents the construction of a compound type, such as "float2(x, y)".
|
||||
*
|
||||
* Vector constructors will always consist of either exactly 1 scalar, or a collection of vectors
|
||||
* and scalars totalling exactly the right number of scalar components.
|
||||
@ -25,9 +25,8 @@ namespace SkSL {
|
||||
* collection of vectors and scalars totalling exactly the right number of scalar components.
|
||||
*/
|
||||
struct Constructor : public Expression {
|
||||
Constructor(Position position, const Type& type,
|
||||
std::vector<std::unique_ptr<Expression>> arguments)
|
||||
: INHERITED(position, kConstructor_Kind, type)
|
||||
Constructor(int offset, const Type& type, std::vector<std::unique_ptr<Expression>> arguments)
|
||||
: INHERITED(offset, kConstructor_Kind, type)
|
||||
, fArguments(std::move(arguments)) {}
|
||||
|
||||
std::unique_ptr<Expression> constantPropagate(const IRGenerator& irGenerator,
|
||||
@ -37,13 +36,13 @@ struct Constructor : public Expression {
|
||||
// promote float(1) to 1.0
|
||||
int64_t intValue = ((IntLiteral&) *fArguments[0]).fValue;
|
||||
return std::unique_ptr<Expression>(new FloatLiteral(irGenerator.fContext,
|
||||
fPosition,
|
||||
fOffset,
|
||||
intValue));
|
||||
} else if (fType == *irGenerator.fContext.fUInt_Type) {
|
||||
// promote uint(1) to 1u
|
||||
int64_t intValue = ((IntLiteral&) *fArguments[0]).fValue;
|
||||
return std::unique_ptr<Expression>(new IntLiteral(irGenerator.fContext,
|
||||
fPosition,
|
||||
fOffset,
|
||||
intValue,
|
||||
&fType));
|
||||
}
|
||||
@ -96,8 +95,8 @@ struct Constructor : public Expression {
|
||||
// a constant scalar constructor should have been collapsed down to the appropriate
|
||||
// literal
|
||||
ASSERT(fType.kind() == Type::kMatrix_Kind);
|
||||
const FloatLiteral fzero(context, Position(), 0);
|
||||
const IntLiteral izero(context, Position(), 0);
|
||||
const FloatLiteral fzero(context, -1, 0);
|
||||
const IntLiteral izero(context, -1, 0);
|
||||
const Expression* zero;
|
||||
if (fType.componentType() == *context.fFloat_Type) {
|
||||
zero = &fzero;
|
||||
|
@ -17,8 +17,8 @@ namespace SkSL {
|
||||
* A 'continue' statement.
|
||||
*/
|
||||
struct ContinueStatement : public Statement {
|
||||
ContinueStatement(Position position)
|
||||
: INHERITED(position, kContinue_Kind) {}
|
||||
ContinueStatement(int offset)
|
||||
: INHERITED(offset, kContinue_Kind) {}
|
||||
|
||||
String description() const override {
|
||||
return String("continue;");
|
||||
|
@ -17,8 +17,8 @@ namespace SkSL {
|
||||
* A 'discard' statement.
|
||||
*/
|
||||
struct DiscardStatement : public Statement {
|
||||
DiscardStatement(Position position)
|
||||
: INHERITED(position, kDiscard_Kind) {}
|
||||
DiscardStatement(int offset)
|
||||
: INHERITED(offset, kDiscard_Kind) {}
|
||||
|
||||
String description() const override {
|
||||
return String("discard;");
|
||||
|
@ -17,9 +17,9 @@ namespace SkSL {
|
||||
* A 'do' statement.
|
||||
*/
|
||||
struct DoStatement : public Statement {
|
||||
DoStatement(Position position, std::unique_ptr<Statement> statement,
|
||||
DoStatement(int offset, std::unique_ptr<Statement> statement,
|
||||
std::unique_ptr<Expression> test)
|
||||
: INHERITED(position, kDo_Kind)
|
||||
: INHERITED(offset, kDo_Kind)
|
||||
, fStatement(std::move(statement))
|
||||
, fTest(std::move(test)) {}
|
||||
|
||||
|
@ -44,8 +44,8 @@ struct Expression : public IRNode {
|
||||
kDefined_Kind
|
||||
};
|
||||
|
||||
Expression(Position position, Kind kind, const Type& type)
|
||||
: INHERITED(position)
|
||||
Expression(int offset, Kind kind, const Type& type)
|
||||
: INHERITED(offset)
|
||||
, fKind(kind)
|
||||
, fType(std::move(type)) {}
|
||||
|
||||
|
@ -18,7 +18,7 @@ namespace SkSL {
|
||||
*/
|
||||
struct ExpressionStatement : public Statement {
|
||||
ExpressionStatement(std::unique_ptr<Expression> expression)
|
||||
: INHERITED(expression->fPosition, kExpression_Kind)
|
||||
: INHERITED(expression->fOffset, kExpression_Kind)
|
||||
, fExpression(std::move(expression)) {}
|
||||
|
||||
String description() const override {
|
||||
|
@ -16,8 +16,8 @@ namespace SkSL {
|
||||
* An extension declaration.
|
||||
*/
|
||||
struct Extension : public ProgramElement {
|
||||
Extension(Position position, String name)
|
||||
: INHERITED(position, kExtension_Kind)
|
||||
Extension(int offset, String name)
|
||||
: INHERITED(offset, kExtension_Kind)
|
||||
, fName(std::move(name)) {}
|
||||
|
||||
String description() const override {
|
||||
|
@ -22,8 +22,8 @@ namespace SkSL {
|
||||
* result of declaring anonymous interface blocks.
|
||||
*/
|
||||
struct Field : public Symbol {
|
||||
Field(Position position, const Variable& owner, int fieldIndex)
|
||||
: INHERITED(position, kField_Kind, owner.fType.fields()[fieldIndex].fName)
|
||||
Field(int offset, const Variable& owner, int fieldIndex)
|
||||
: INHERITED(offset, kField_Kind, owner.fType.fields()[fieldIndex].fName)
|
||||
, fOwner(owner)
|
||||
, fFieldIndex(fieldIndex) {}
|
||||
|
||||
|
@ -26,7 +26,7 @@ struct FieldAccess : public Expression {
|
||||
|
||||
FieldAccess(std::unique_ptr<Expression> base, int fieldIndex,
|
||||
OwnerKind ownerKind = kDefault_OwnerKind)
|
||||
: INHERITED(base->fPosition, kFieldAccess_Kind, *base->fType.fields()[fieldIndex].fType)
|
||||
: INHERITED(base->fOffset, kFieldAccess_Kind, *base->fType.fields()[fieldIndex].fType)
|
||||
, fBase(std::move(base))
|
||||
, fFieldIndex(fieldIndex)
|
||||
, fOwnerKind(ownerKind) {}
|
||||
|
@ -17,9 +17,9 @@ namespace SkSL {
|
||||
* A literal floating point number.
|
||||
*/
|
||||
struct FloatLiteral : public Expression {
|
||||
FloatLiteral(const Context& context, Position position, double value,
|
||||
FloatLiteral(const Context& context, int offset, double value,
|
||||
const Type* type = nullptr)
|
||||
: INHERITED(position, kFloatLiteral_Kind, type ? *type : *context.fFloat_Type)
|
||||
: INHERITED(offset, kFloatLiteral_Kind, type ? *type : *context.fFloat_Type)
|
||||
, fValue(value) {}
|
||||
|
||||
String description() const override {
|
||||
|
@ -18,10 +18,10 @@ namespace SkSL {
|
||||
* A 'for' statement.
|
||||
*/
|
||||
struct ForStatement : public Statement {
|
||||
ForStatement(Position position, std::unique_ptr<Statement> initializer,
|
||||
ForStatement(int offset, std::unique_ptr<Statement> initializer,
|
||||
std::unique_ptr<Expression> test, std::unique_ptr<Expression> next,
|
||||
std::unique_ptr<Statement> statement, std::shared_ptr<SymbolTable> symbols)
|
||||
: INHERITED(position, kFor_Kind)
|
||||
: INHERITED(offset, kFor_Kind)
|
||||
, fSymbols(symbols)
|
||||
, fInitializer(std::move(initializer))
|
||||
, fTest(std::move(test))
|
||||
|
@ -17,9 +17,9 @@ namespace SkSL {
|
||||
* A function invocation.
|
||||
*/
|
||||
struct FunctionCall : public Expression {
|
||||
FunctionCall(Position position, const Type& type, const FunctionDeclaration& function,
|
||||
FunctionCall(int offset, const Type& type, const FunctionDeclaration& function,
|
||||
std::vector<std::unique_ptr<Expression>> arguments)
|
||||
: INHERITED(position, kFunctionCall_Kind, type)
|
||||
: INHERITED(offset, kFunctionCall_Kind, type)
|
||||
, fFunction(std::move(function))
|
||||
, fArguments(std::move(arguments)) {}
|
||||
|
||||
@ -33,7 +33,7 @@ struct FunctionCall : public Expression {
|
||||
}
|
||||
|
||||
String description() const override {
|
||||
String result = fFunction.fName + "(";
|
||||
String result = String(fFunction.fName) + "(";
|
||||
String separator;
|
||||
for (size_t i = 0; i < fArguments.size(); i++) {
|
||||
result += separator;
|
||||
|
@ -21,9 +21,9 @@ namespace SkSL {
|
||||
* A function declaration (not a definition -- does not contain a body).
|
||||
*/
|
||||
struct FunctionDeclaration : public Symbol {
|
||||
FunctionDeclaration(Position position, Modifiers modifiers, String name,
|
||||
FunctionDeclaration(int offset, Modifiers modifiers, StringFragment name,
|
||||
std::vector<const Variable*> parameters, const Type& returnType)
|
||||
: INHERITED(position, kFunctionDeclaration_Kind, std::move(name))
|
||||
: INHERITED(offset, kFunctionDeclaration_Kind, std::move(name))
|
||||
, fDefined(false)
|
||||
, fBuiltin(false)
|
||||
, fModifiers(modifiers)
|
||||
|
@ -18,9 +18,9 @@ namespace SkSL {
|
||||
* A function definition (a declaration plus an associated block of code).
|
||||
*/
|
||||
struct FunctionDefinition : public ProgramElement {
|
||||
FunctionDefinition(Position position, const FunctionDeclaration& declaration,
|
||||
FunctionDefinition(int offset, const FunctionDeclaration& declaration,
|
||||
std::unique_ptr<Statement> body)
|
||||
: INHERITED(position, kFunction_Kind)
|
||||
: INHERITED(offset, kFunction_Kind)
|
||||
, fDeclaration(declaration)
|
||||
, fBody(std::move(body)) {}
|
||||
|
||||
|
@ -19,9 +19,9 @@ namespace SkSL {
|
||||
* always eventually replaced by FunctionCalls in valid programs.
|
||||
*/
|
||||
struct FunctionReference : public Expression {
|
||||
FunctionReference(const Context& context, Position position,
|
||||
FunctionReference(const Context& context, int offset,
|
||||
std::vector<const FunctionDeclaration*> function)
|
||||
: INHERITED(position, kFunctionReference_Kind, *context.fInvalid_Type)
|
||||
: INHERITED(offset, kFunctionReference_Kind, *context.fInvalid_Type)
|
||||
, fFunctions(function) {}
|
||||
|
||||
bool hasSideEffects() const override {
|
||||
|
@ -8,7 +8,7 @@
|
||||
#ifndef SKSL_IRNODE
|
||||
#define SKSL_IRNODE
|
||||
|
||||
#include "../SkSLPosition.h"
|
||||
#include "../SkSLLexer.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
@ -17,14 +17,16 @@ namespace SkSL {
|
||||
* version of the program (all types determined, everything validated), ready for code generation.
|
||||
*/
|
||||
struct IRNode {
|
||||
IRNode(Position position)
|
||||
: fPosition(position) {}
|
||||
IRNode(int offset)
|
||||
: fOffset(offset) {}
|
||||
|
||||
virtual ~IRNode() {}
|
||||
|
||||
virtual String description() const = 0;
|
||||
|
||||
const Position fPosition;
|
||||
// character offset of this element within the program being compiled, for error reporting
|
||||
// purposes
|
||||
const int fOffset;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
@ -17,9 +17,9 @@ namespace SkSL {
|
||||
* An 'if' statement.
|
||||
*/
|
||||
struct IfStatement : public Statement {
|
||||
IfStatement(Position position, bool isStatic, std::unique_ptr<Expression> test,
|
||||
IfStatement(int offset, bool isStatic, std::unique_ptr<Expression> test,
|
||||
std::unique_ptr<Statement> ifTrue, std::unique_ptr<Statement> ifFalse)
|
||||
: INHERITED(position, kIf_Kind)
|
||||
: INHERITED(offset, kIf_Kind)
|
||||
, fIsStatic(isStatic)
|
||||
, fTest(std::move(test))
|
||||
, fIfTrue(std::move(ifTrue))
|
||||
|
@ -45,7 +45,7 @@ static const Type& index_type(const Context& context, const Type& type) {
|
||||
struct IndexExpression : public Expression {
|
||||
IndexExpression(const Context& context, std::unique_ptr<Expression> base,
|
||||
std::unique_ptr<Expression> index)
|
||||
: INHERITED(base->fPosition, kIndex_Kind, index_type(context, base->fType))
|
||||
: INHERITED(base->fOffset, kIndex_Kind, index_type(context, base->fType))
|
||||
, fBase(std::move(base))
|
||||
, fIndex(std::move(index)) {
|
||||
ASSERT(fIndex->fType == *context.fInt_Type || fIndex->fType == *context.fUInt_Type);
|
||||
|
@ -19,8 +19,8 @@ namespace SkSL {
|
||||
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(const Context& context, Position position, int64_t value, const Type* type = nullptr)
|
||||
: INHERITED(position, kIntLiteral_Kind, type ? *type : *context.fInt_Type)
|
||||
IntLiteral(const Context& context, int offset, int64_t value, const Type* type = nullptr)
|
||||
: INHERITED(offset, kIntLiteral_Kind, type ? *type : *context.fInt_Type)
|
||||
, fValue(value) {}
|
||||
|
||||
String description() const override {
|
||||
|
@ -25,10 +25,10 @@ namespace SkSL {
|
||||
* At the IR level, this is represented by a single variable of struct type.
|
||||
*/
|
||||
struct InterfaceBlock : public ProgramElement {
|
||||
InterfaceBlock(Position position, const Variable* var, String typeName, String instanceName,
|
||||
InterfaceBlock(int offset, const Variable* var, String typeName, String instanceName,
|
||||
std::vector<std::unique_ptr<Expression>> sizes,
|
||||
std::shared_ptr<SymbolTable> typeOwner)
|
||||
: INHERITED(position, kInterfaceBlock_Kind)
|
||||
: INHERITED(offset, kInterfaceBlock_Kind)
|
||||
, fVariable(*var)
|
||||
, fTypeName(std::move(typeName))
|
||||
, fInstanceName(std::move(instanceName))
|
||||
|
@ -20,7 +20,7 @@ namespace SkSL {
|
||||
*/
|
||||
struct ModifiersDeclaration : public ProgramElement {
|
||||
ModifiersDeclaration(Modifiers modifiers)
|
||||
: INHERITED(Position(), kModifiers_Kind)
|
||||
: INHERITED(-1, kModifiers_Kind)
|
||||
, fModifiers(modifiers) {}
|
||||
|
||||
String description() const {
|
||||
|
@ -18,7 +18,7 @@ namespace SkSL {
|
||||
*/
|
||||
struct Nop : public Statement {
|
||||
Nop()
|
||||
: INHERITED(Position(), kNop_Kind) {}
|
||||
: INHERITED(-1, kNop_Kind) {}
|
||||
|
||||
virtual bool isEmpty() const override {
|
||||
return true;
|
||||
|
@ -9,7 +9,7 @@
|
||||
#define SKSL_POSTFIXEXPRESSION
|
||||
|
||||
#include "SkSLExpression.h"
|
||||
#include "SkSLToken.h"
|
||||
#include "SkSLLexer.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
@ -18,7 +18,7 @@ namespace SkSL {
|
||||
*/
|
||||
struct PostfixExpression : public Expression {
|
||||
PostfixExpression(std::unique_ptr<Expression> operand, Token::Kind op)
|
||||
: INHERITED(operand->fPosition, kPostfix_Kind, operand->fType)
|
||||
: INHERITED(operand->fOffset, kPostfix_Kind, operand->fType)
|
||||
, fOperand(std::move(operand))
|
||||
, fOperator(op) {}
|
||||
|
||||
@ -27,7 +27,7 @@ struct PostfixExpression : public Expression {
|
||||
}
|
||||
|
||||
String description() const override {
|
||||
return fOperand->description() + Token::OperatorName(fOperator);
|
||||
return fOperand->description() + Compiler::OperatorName(fOperator);
|
||||
}
|
||||
|
||||
std::unique_ptr<Expression> fOperand;
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include "SkSLExpression.h"
|
||||
#include "SkSLFloatLiteral.h"
|
||||
#include "SkSLIRGenerator.h"
|
||||
#include "SkSLToken.h"
|
||||
#include "SkSLLexer.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
@ -20,7 +20,7 @@ namespace SkSL {
|
||||
*/
|
||||
struct PrefixExpression : public Expression {
|
||||
PrefixExpression(Token::Kind op, std::unique_ptr<Expression> operand)
|
||||
: INHERITED(operand->fPosition, kPrefix_Kind, operand->fType)
|
||||
: INHERITED(operand->fOffset, kPrefix_Kind, operand->fType)
|
||||
, fOperand(std::move(operand))
|
||||
, fOperator(op) {}
|
||||
|
||||
@ -38,7 +38,7 @@ struct PrefixExpression : public Expression {
|
||||
if (fOperand->fKind == Expression::kFloatLiteral_Kind) {
|
||||
return std::unique_ptr<Expression>(new FloatLiteral(
|
||||
irGenerator.fContext,
|
||||
Position(),
|
||||
fOffset,
|
||||
-((FloatLiteral&) *fOperand).fValue));
|
||||
|
||||
}
|
||||
@ -46,7 +46,7 @@ struct PrefixExpression : public Expression {
|
||||
}
|
||||
|
||||
String description() const override {
|
||||
return Token::OperatorName(fOperator) + fOperand->description();
|
||||
return Compiler::OperatorName(fOperator) + fOperand->description();
|
||||
}
|
||||
|
||||
std::unique_ptr<Expression> fOperand;
|
||||
|
@ -39,15 +39,15 @@ struct Program {
|
||||
: fKind(kInt_Kind)
|
||||
, fValue(i) {}
|
||||
|
||||
std::unique_ptr<Expression> literal(const Context& context, Position position) const {
|
||||
std::unique_ptr<Expression> literal(const Context& context, int offset) const {
|
||||
switch (fKind) {
|
||||
case Program::Settings::Value::kBool_Kind:
|
||||
return std::unique_ptr<Expression>(new BoolLiteral(context,
|
||||
position,
|
||||
offset,
|
||||
fValue));
|
||||
case Program::Settings::Value::kInt_Kind:
|
||||
return std::unique_ptr<Expression>(new IntLiteral(context,
|
||||
position,
|
||||
offset,
|
||||
fValue));
|
||||
default:
|
||||
ASSERT(false);
|
||||
@ -103,6 +103,7 @@ struct Program {
|
||||
};
|
||||
|
||||
Program(Kind kind,
|
||||
std::unique_ptr<String> source,
|
||||
Settings settings,
|
||||
Modifiers::Flag defaultPrecision,
|
||||
Context* context,
|
||||
@ -110,6 +111,7 @@ struct Program {
|
||||
std::shared_ptr<SymbolTable> symbols,
|
||||
Inputs inputs)
|
||||
: fKind(kind)
|
||||
, fSource(std::move(source))
|
||||
, fSettings(settings)
|
||||
, fDefaultPrecision(defaultPrecision)
|
||||
, fContext(context)
|
||||
@ -118,6 +120,7 @@ struct Program {
|
||||
, fInputs(inputs) {}
|
||||
|
||||
Kind fKind;
|
||||
std::unique_ptr<String> fSource;
|
||||
Settings fSettings;
|
||||
// FIXME handle different types; currently it assumes this is for floats
|
||||
Modifiers::Flag fDefaultPrecision;
|
||||
|
@ -25,8 +25,8 @@ struct ProgramElement : public IRNode {
|
||||
kSection_Kind
|
||||
};
|
||||
|
||||
ProgramElement(Position position, Kind kind)
|
||||
: INHERITED(position)
|
||||
ProgramElement(int offset, Kind kind)
|
||||
: INHERITED(offset)
|
||||
, fKind(kind) {}
|
||||
|
||||
Kind fKind;
|
||||
|
@ -17,11 +17,11 @@ namespace SkSL {
|
||||
* A 'return' statement.
|
||||
*/
|
||||
struct ReturnStatement : public Statement {
|
||||
ReturnStatement(Position position)
|
||||
: INHERITED(position, kReturn_Kind) {}
|
||||
ReturnStatement(int offset)
|
||||
: INHERITED(offset, kReturn_Kind) {}
|
||||
|
||||
ReturnStatement(std::unique_ptr<Expression> expression)
|
||||
: INHERITED(expression->fPosition, kReturn_Kind)
|
||||
: INHERITED(expression->fOffset, kReturn_Kind)
|
||||
, fExpression(std::move(expression)) {}
|
||||
|
||||
String description() const override {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user