Revert "Use SkSL "offset" to actually mean "line""
This reverts commit 47f76853c6
.
Reason for revert: Test failures
Original change's description:
> Use SkSL "offset" to actually mean "line"
>
> SkSL internally tracks token offsets, but only ever reports errors using
> line numbers. With the introduction of the DSL, which (being embedded in
> C++ source) only has access to line numbers in the first place, tracking
> offsets went from merely providing little benefit to actively making
> life more difficult.
>
> We are changing SkSL's position tracking from handling offsets to
> handling line numbers, but to simplify the review process the change is
> split up into two main steps. The first step (this CL) starts using
> line numbers everywhere, but avoids the thousand-line churn of actually
> renaming "offset", so most "offset" fields, variables, and parameters
> will be briefly misnamed and will actually contain a line number.
>
> The followup CL will complete the process by renaming all of the
> now-misnamed fields, variables, and parameters, but will not make any
> behavioral changes.
>
> Bug: skia:12459
> Change-Id: I30dc87cf4b816c5ddd7b8ae1be32586388962085
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/451419
> Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
> Reviewed-by: John Stiles <johnstiles@google.com>
Bug: skia:12459
Change-Id: I562d9980cd43a2fc5108e562155fe731a1761dca
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/452720
Auto-Submit: Brian Osman <brianosman@google.com>
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
This commit is contained in:
parent
cc91452f0a
commit
a909dd6b8d
@ -60,57 +60,57 @@ public:
|
||||
virtual VariableStorage storage() const = 0;
|
||||
|
||||
DSLExpression x() {
|
||||
return DSLExpression(*this, PositionInfo()).x();
|
||||
return DSLExpression(*this).x();
|
||||
}
|
||||
|
||||
DSLExpression y() {
|
||||
return DSLExpression(*this, PositionInfo()).y();
|
||||
return DSLExpression(*this).y();
|
||||
}
|
||||
|
||||
DSLExpression z() {
|
||||
return DSLExpression(*this, PositionInfo()).z();
|
||||
return DSLExpression(*this).z();
|
||||
}
|
||||
|
||||
DSLExpression w() {
|
||||
return DSLExpression(*this, PositionInfo()).w();
|
||||
return DSLExpression(*this).w();
|
||||
}
|
||||
|
||||
DSLExpression r() {
|
||||
return DSLExpression(*this, PositionInfo()).r();
|
||||
return DSLExpression(*this).r();
|
||||
}
|
||||
|
||||
DSLExpression g() {
|
||||
return DSLExpression(*this, PositionInfo()).g();
|
||||
return DSLExpression(*this).g();
|
||||
}
|
||||
|
||||
DSLExpression b() {
|
||||
return DSLExpression(*this, PositionInfo()).b();
|
||||
return DSLExpression(*this).b();
|
||||
}
|
||||
|
||||
DSLExpression a() {
|
||||
return DSLExpression(*this, PositionInfo()).a();
|
||||
return DSLExpression(*this).a();
|
||||
}
|
||||
|
||||
DSLExpression field(skstd::string_view name) {
|
||||
return DSLExpression(*this, PositionInfo()).field(name);
|
||||
return DSLExpression(*this).field(name);
|
||||
}
|
||||
|
||||
DSLPossibleExpression operator[](DSLExpression&& index);
|
||||
|
||||
DSLPossibleExpression operator++() {
|
||||
return ++DSLExpression(*this, PositionInfo());
|
||||
return ++DSLExpression(*this);
|
||||
}
|
||||
|
||||
DSLPossibleExpression operator++(int) {
|
||||
return DSLExpression(*this, PositionInfo())++;
|
||||
return DSLExpression(*this)++;
|
||||
}
|
||||
|
||||
DSLPossibleExpression operator--() {
|
||||
return --DSLExpression(*this, PositionInfo());
|
||||
return --DSLExpression(*this);
|
||||
}
|
||||
|
||||
DSLPossibleExpression operator--(int) {
|
||||
return DSLExpression(*this, PositionInfo())--;
|
||||
return DSLExpression(*this)--;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -35,21 +35,40 @@ public:
|
||||
static PositionInfo Capture() { return PositionInfo(); }
|
||||
#endif // __has_builtin(__builtin_FILE) && __has_builtin(__builtin_LINE)
|
||||
|
||||
static PositionInfo Offset(const char* file, const char* text, int offset) {
|
||||
PositionInfo result(file, -1);
|
||||
result.fText = text;
|
||||
result.fOffset = offset;
|
||||
return result;
|
||||
}
|
||||
|
||||
const char* file_name() const {
|
||||
return fFile;
|
||||
}
|
||||
|
||||
int line() {
|
||||
if (fLine == -1) {
|
||||
if (fOffset == -1 || !fText) {
|
||||
return -1;
|
||||
}
|
||||
fLine = 1;
|
||||
for (int i = 0; i < fOffset; i++) {
|
||||
if (fText[i] == '\n') {
|
||||
++fLine;
|
||||
}
|
||||
}
|
||||
}
|
||||
return fLine;
|
||||
}
|
||||
|
||||
// Temporary method until we finish replacing offset with line
|
||||
int offset() {
|
||||
return fLine;
|
||||
return fOffset;
|
||||
}
|
||||
|
||||
private:
|
||||
const char* fFile = nullptr;
|
||||
const char* fText = nullptr;
|
||||
int32_t fOffset = -1;
|
||||
int32_t fLine = -1;
|
||||
};
|
||||
|
||||
|
@ -102,7 +102,7 @@ DSLParser::DSLParser(Compiler* compiler, const ProgramSettings& settings, Progra
|
||||
, fSettings(settings)
|
||||
, fKind(kind)
|
||||
, fText(std::make_unique<String>(std::move(text)))
|
||||
, fPushback(Token::Kind::TK_NONE, /*offset=*/-1, /*length=*/-1, /*line=*/-1) {
|
||||
, fPushback(Token::Kind::TK_NONE, -1, -1) {
|
||||
// We don't want to have to worry about manually releasing all of the objects in the event that
|
||||
// an error occurs
|
||||
fSettings.fAssertDSLObjectsReleased = false;
|
||||
@ -192,15 +192,15 @@ skstd::string_view DSLParser::text(Token token) {
|
||||
}
|
||||
|
||||
PositionInfo DSLParser::position(Token t) {
|
||||
return this->position(t.fLine);
|
||||
return this->position(t.fOffset);
|
||||
}
|
||||
|
||||
PositionInfo DSLParser::position(int offset) {
|
||||
return PositionInfo("<unknown>", offset);
|
||||
return PositionInfo::Offset("<unknown>", fText->c_str(), offset);
|
||||
}
|
||||
|
||||
void DSLParser::error(Token token, String msg) {
|
||||
this->error(token.fLine, msg);
|
||||
this->error(token.fOffset, msg);
|
||||
}
|
||||
|
||||
void DSLParser::error(int offset, String msg) {
|
||||
@ -284,7 +284,7 @@ bool DSLParser::declaration() {
|
||||
switch (lookahead.fKind) {
|
||||
case Token::Kind::TK_SEMICOLON:
|
||||
this->nextToken();
|
||||
this->error(lookahead, "expected a declaration, but found ';'");
|
||||
this->error(lookahead.fOffset, "expected a declaration, but found ';'");
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
@ -424,13 +424,13 @@ bool DSLParser::parseInitializer(int offset, DSLExpression* initializer) {
|
||||
void DSLParser::globalVarDeclarationEnd(PositionInfo pos, const dsl::DSLModifiers& mods,
|
||||
dsl::DSLType baseType, skstd::string_view name) {
|
||||
using namespace dsl;
|
||||
int line = this->peek().fLine;
|
||||
int offset = this->peek().fOffset;
|
||||
DSLType type = baseType;
|
||||
DSLExpression initializer;
|
||||
if (!this->parseArrayDimensions(line, &type)) {
|
||||
if (!this->parseArrayDimensions(offset, &type)) {
|
||||
return;
|
||||
}
|
||||
this->parseInitializer(line, &initializer);
|
||||
this->parseInitializer(offset, &initializer);
|
||||
DSLGlobalVar first(mods, type, name, std::move(initializer), pos);
|
||||
Declare(first);
|
||||
AddToSymbolTable(first);
|
||||
@ -441,15 +441,14 @@ void DSLParser::globalVarDeclarationEnd(PositionInfo pos, const dsl::DSLModifier
|
||||
if (!this->expectIdentifier(&identifierName)) {
|
||||
return;
|
||||
}
|
||||
if (!this->parseArrayDimensions(line, &type)) {
|
||||
if (!this->parseArrayDimensions(offset, &type)) {
|
||||
return;
|
||||
}
|
||||
DSLExpression anotherInitializer;
|
||||
if (!this->parseInitializer(line, &anotherInitializer)) {
|
||||
if (!this->parseInitializer(offset, &anotherInitializer)) {
|
||||
return;
|
||||
}
|
||||
DSLGlobalVar next(mods, type, this->text(identifierName), std::move(anotherInitializer),
|
||||
this->position(line));
|
||||
DSLGlobalVar next(mods, type, this->text(identifierName), std::move(anotherInitializer));
|
||||
Declare(next);
|
||||
AddToSymbolTable(next, this->position(identifierName));
|
||||
}
|
||||
@ -461,13 +460,13 @@ void DSLParser::globalVarDeclarationEnd(PositionInfo pos, const dsl::DSLModifier
|
||||
DSLStatement DSLParser::localVarDeclarationEnd(PositionInfo pos, const dsl::DSLModifiers& mods,
|
||||
dsl::DSLType baseType, skstd::string_view name) {
|
||||
using namespace dsl;
|
||||
int line = this->peek().fLine;
|
||||
int offset = this->peek().fOffset;
|
||||
DSLType type = baseType;
|
||||
DSLExpression initializer;
|
||||
if (!this->parseArrayDimensions(line, &type)) {
|
||||
if (!this->parseArrayDimensions(offset, &type)) {
|
||||
return {};
|
||||
}
|
||||
this->parseInitializer(line, &initializer);
|
||||
this->parseInitializer(offset, &initializer);
|
||||
DSLVar first(mods, type, name, std::move(initializer), pos);
|
||||
DSLStatement result = Declare(first);
|
||||
AddToSymbolTable(first);
|
||||
@ -478,15 +477,14 @@ DSLStatement DSLParser::localVarDeclarationEnd(PositionInfo pos, const dsl::DSLM
|
||||
if (!this->expectIdentifier(&identifierName)) {
|
||||
return result;
|
||||
}
|
||||
if (!this->parseArrayDimensions(line, &type)) {
|
||||
if (!this->parseArrayDimensions(offset, &type)) {
|
||||
return result;
|
||||
}
|
||||
DSLExpression anotherInitializer;
|
||||
if (!this->parseInitializer(line, &anotherInitializer)) {
|
||||
if (!this->parseInitializer(offset, &anotherInitializer)) {
|
||||
return result;
|
||||
}
|
||||
DSLVar next(mods, type, this->text(identifierName), std::move(anotherInitializer),
|
||||
this->position(line));
|
||||
DSLVar next(mods, type, this->text(identifierName), std::move(anotherInitializer));
|
||||
DSLWriter::AddVarDeclaration(result, next);
|
||||
AddToSymbolTable(next, this->position(identifierName));
|
||||
}
|
||||
@ -594,7 +592,8 @@ skstd::optional<DSLType> DSLParser::structDeclaration() {
|
||||
}
|
||||
}
|
||||
if (fields.empty()) {
|
||||
this->error(name, "struct '" + this->text(name) + "' must contain at least one field");
|
||||
this->error(name.fOffset,
|
||||
"struct '" + this->text(name) + "' must contain at least one field");
|
||||
}
|
||||
return dsl::Struct(this->text(name), SkMakeSpan(fields), this->position(name));
|
||||
}
|
||||
@ -1638,10 +1637,10 @@ DSLExpression DSLParser::suffix(DSLExpression base) {
|
||||
return std::move(result);
|
||||
}
|
||||
case Token::Kind::TK_DOT: {
|
||||
int line = this->peek().fLine;
|
||||
int offset = this->peek().fOffset;
|
||||
skstd::string_view text;
|
||||
if (this->identifier(&text)) {
|
||||
return this->swizzle(line, std::move(base), text);
|
||||
return this->swizzle(offset, std::move(base), text);
|
||||
}
|
||||
[[fallthrough]];
|
||||
}
|
||||
@ -1655,13 +1654,13 @@ DSLExpression DSLParser::suffix(DSLExpression base) {
|
||||
// identifiers that directly follow the float
|
||||
Token id = this->nextRawToken();
|
||||
if (id.fKind == Token::Kind::TK_IDENTIFIER) {
|
||||
return this->swizzle(next.fLine, std::move(base), field + this->text(id));
|
||||
return this->swizzle(next.fOffset, std::move(base), field + this->text(id));
|
||||
} else if (field.empty()) {
|
||||
this->error(next, "expected field name or swizzle mask after '.'");
|
||||
return {{DSLExpression::Poison()}};
|
||||
}
|
||||
this->pushback(id);
|
||||
return this->swizzle(next.fLine, std::move(base), field);
|
||||
return this->swizzle(next.fOffset, std::move(base), field);
|
||||
}
|
||||
case Token::Kind::TK_LPAREN: {
|
||||
ExpressionArray args;
|
||||
@ -1678,7 +1677,7 @@ DSLExpression DSLParser::suffix(DSLExpression base) {
|
||||
}
|
||||
}
|
||||
this->expect(Token::Kind::TK_RPAREN, "')' to complete function arguments");
|
||||
return this->call(next.fLine, std::move(base), std::move(args));
|
||||
return this->call(next.fOffset, std::move(base), std::move(args));
|
||||
}
|
||||
case Token::Kind::TK_PLUSPLUS:
|
||||
return std::move(base)++;
|
||||
@ -1737,9 +1736,8 @@ DSLExpression DSLParser::term() {
|
||||
}
|
||||
default:
|
||||
this->nextToken();
|
||||
this->error(t, "expected expression, but found '" + this->text(t) + "'");
|
||||
this->error(t.fOffset, "expected expression, but found '" + this->text(t) + "'");
|
||||
fEncounteredFatalError = true;
|
||||
break;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
@ -325,7 +325,7 @@ private:
|
||||
|
||||
DSLParser* fParser;
|
||||
Token fPushbackCheckpoint;
|
||||
SkSL::Lexer::Checkpoint fLexerCheckpoint;
|
||||
int32_t fLexerCheckpoint;
|
||||
ForwardingErrorReporter fErrorReporter;
|
||||
ErrorReporter* fOldErrorReporter;
|
||||
bool fOldEncounteredFatalError;
|
||||
|
@ -21,16 +21,30 @@ void ErrorReporter::error(skstd::string_view msg, PositionInfo position) {
|
||||
this->handleError(msg, position);
|
||||
}
|
||||
|
||||
void ErrorReporter::error(int line, skstd::string_view msg) {
|
||||
void ErrorReporter::error(int offset, skstd::string_view msg) {
|
||||
if (msg.contains(Compiler::POISON_TAG)) {
|
||||
// don't report errors on poison values
|
||||
return;
|
||||
}
|
||||
if (line == -1) {
|
||||
if (offset == -1) {
|
||||
++fErrorCount;
|
||||
fPendingErrors.push_back(String(msg));
|
||||
} else {
|
||||
this->error(msg, PositionInfo(/*file=*/nullptr, line));
|
||||
this->error(msg, this->position(offset));
|
||||
}
|
||||
}
|
||||
|
||||
PositionInfo ErrorReporter::position(int offset) const {
|
||||
if (fSource && offset >= 0) {
|
||||
int line = 1;
|
||||
for (int i = 0; i < offset; i++) {
|
||||
if (fSource[i] == '\n') {
|
||||
++line;
|
||||
}
|
||||
}
|
||||
return PositionInfo(/*file=*/nullptr, line);
|
||||
} else {
|
||||
return PositionInfo();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -844,13 +844,13 @@ Token Lexer::next() {
|
||||
// a bit.
|
||||
int32_t startOffset = fOffset;
|
||||
if (startOffset == (int32_t)fText.length()) {
|
||||
return Token(Token::Kind::TK_END_OF_FILE, startOffset, 0, fLine);
|
||||
return Token(Token::Kind::TK_END_OF_FILE, startOffset, 0);
|
||||
}
|
||||
State state = 1;
|
||||
for (;;) {
|
||||
if (fOffset >= (int32_t)fText.length()) {
|
||||
if (kAccepts[state] == -1) {
|
||||
return Token(Token::Kind::TK_END_OF_FILE, startOffset, 0, fLine);
|
||||
return Token(Token::Kind::TK_END_OF_FILE, startOffset, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -864,12 +864,9 @@ Token Lexer::next() {
|
||||
}
|
||||
state = newState;
|
||||
++fOffset;
|
||||
if (c == '\n') {
|
||||
++fLine;
|
||||
}
|
||||
}
|
||||
Token::Kind kind = (Token::Kind)kAccepts[state];
|
||||
return Token(kind, startOffset, fOffset - startOffset, fLine);
|
||||
return Token(kind, startOffset, fOffset - startOffset);
|
||||
}
|
||||
|
||||
} // namespace SkSL
|
||||
|
@ -106,14 +106,14 @@ struct Token {
|
||||
TK_NONE,
|
||||
};
|
||||
|
||||
Token() {}
|
||||
Token(Kind kind, int32_t offset, int32_t length, int32_t line)
|
||||
: fKind(kind), fOffset(offset), fLength(length), fLine(line) {}
|
||||
Token() : fKind(Kind::TK_NONE), fOffset(-1), fLength(-1) {}
|
||||
|
||||
Kind fKind = Kind::TK_NONE;
|
||||
int32_t fOffset = -1;
|
||||
int32_t fLength = -1;
|
||||
int32_t fLine = -1;
|
||||
Token(Kind kind, int32_t offset, int32_t length)
|
||||
: fKind(kind), fOffset(offset), fLength(length) {}
|
||||
|
||||
Kind fKind;
|
||||
int fOffset;
|
||||
int fLength;
|
||||
};
|
||||
|
||||
class Lexer {
|
||||
@ -121,27 +121,17 @@ public:
|
||||
void start(skstd::string_view text) {
|
||||
fText = text;
|
||||
fOffset = 0;
|
||||
fLine = 1;
|
||||
}
|
||||
|
||||
Token next();
|
||||
|
||||
struct Checkpoint {
|
||||
int32_t fOffset;
|
||||
int32_t fLine;
|
||||
};
|
||||
int32_t getCheckpoint() const { return fOffset; }
|
||||
|
||||
Checkpoint getCheckpoint() const { return {fOffset, fLine}; }
|
||||
|
||||
void rewindToCheckpoint(Checkpoint checkpoint) {
|
||||
fOffset = checkpoint.fOffset;
|
||||
fLine = checkpoint.fLine;
|
||||
}
|
||||
void rewindToCheckpoint(int32_t checkpoint) { fOffset = checkpoint; }
|
||||
|
||||
private:
|
||||
skstd::string_view fText;
|
||||
int32_t fOffset;
|
||||
int32_t fLine;
|
||||
};
|
||||
|
||||
} // namespace SkSL
|
||||
|
@ -89,7 +89,7 @@ void Parser::InitLayoutMap() {
|
||||
|
||||
Parser::Parser(skstd::string_view text, SymbolTable& symbols, ErrorReporter& errors)
|
||||
: fText(text)
|
||||
, fPushback(Token::Kind::TK_NONE, /*offset=*/-1, /*length=*/-1, /*line=*/-1)
|
||||
, fPushback(Token::Kind::TK_NONE, -1, -1)
|
||||
, fSymbols(symbols)
|
||||
, fErrors(&errors) {
|
||||
fLexer.start(text);
|
||||
@ -119,7 +119,7 @@ void Parser::createEmptyChild(ASTNode::ID target) {
|
||||
std::unique_ptr<ASTFile> Parser::compilationUnit() {
|
||||
fFile = std::make_unique<ASTFile>();
|
||||
fFile->fNodes.reserve(fText.size() / 10); // a typical program is approx 10:1 for chars:nodes
|
||||
ASTNode::ID result = this->createNode(/*offset=*/1, ASTNode::Kind::kFile);
|
||||
ASTNode::ID result = this->createNode(/*offset=*/0, ASTNode::Kind::kFile);
|
||||
fFile->fRoot = result;
|
||||
for (;;) {
|
||||
switch (this->peek().fKind) {
|
||||
|
@ -301,7 +301,7 @@ private:
|
||||
|
||||
Parser* fParser;
|
||||
Token fPushbackCheckpoint;
|
||||
Lexer::Checkpoint fLexerCheckpoint;
|
||||
int32_t fLexerCheckpoint;
|
||||
ForwardingErrorReporter fErrorReporter;
|
||||
ErrorReporter* fOldErrorReporter;
|
||||
bool fDone = false;
|
||||
|
@ -3554,7 +3554,7 @@ void SPIRVCodeGenerator::writeInstructions(const Program& program, OutputStream&
|
||||
}
|
||||
// Make sure we have a main() function.
|
||||
if (!main) {
|
||||
fContext.fErrors->error(/*offset=*/-1, "program does not contain a main() function");
|
||||
fContext.fErrors->error(/*offset=*/0, "program does not contain a main() function");
|
||||
return;
|
||||
}
|
||||
// Emit interface blocks.
|
||||
|
@ -149,7 +149,7 @@ public:
|
||||
for (DSLVar& v : vars) {
|
||||
statements.push_back(Declare(v, pos).release());
|
||||
}
|
||||
return SkSL::Block::MakeUnscoped(pos.line(), std::move(statements));
|
||||
return SkSL::Block::MakeUnscoped(/*offset=*/-1, std::move(statements));
|
||||
}
|
||||
|
||||
static void Declare(DSLGlobalVar& var, PositionInfo pos) {
|
||||
@ -191,7 +191,7 @@ public:
|
||||
|
||||
static DSLPossibleStatement For(DSLStatement initializer, DSLExpression test,
|
||||
DSLExpression next, DSLStatement stmt, PositionInfo pos) {
|
||||
return ForStatement::Convert(DSLWriter::Context(), pos.line(),
|
||||
return ForStatement::Convert(DSLWriter::Context(), /*offset=*/-1,
|
||||
initializer.releaseIfPossible(), test.releaseIfPossible(),
|
||||
next.releaseIfPossible(), stmt.release(),
|
||||
DSLWriter::SymbolTable());
|
||||
@ -216,13 +216,14 @@ public:
|
||||
if (baseType->isArray()) {
|
||||
baseType = &baseType->componentType();
|
||||
}
|
||||
DSLWriter::IRGenerator().checkVarDeclaration(pos.line(), field.fModifiers.fModifiers,
|
||||
DSLWriter::IRGenerator().checkVarDeclaration(/*offset=*/-1, field.fModifiers.fModifiers,
|
||||
baseType, Variable::Storage::kInterfaceBlock);
|
||||
GetErrorReporter().reportPendingErrors(field.fPosition);
|
||||
skslFields.push_back(SkSL::Type::Field(field.fModifiers.fModifiers, field.fName,
|
||||
&field.fType.skslType()));
|
||||
}
|
||||
const SkSL::Type* structType = DSLWriter::SymbolTable()->takeOwnershipOfSymbol(
|
||||
SkSL::Type::MakeStructType(pos.line(), typeName, std::move(skslFields)));
|
||||
SkSL::Type::MakeStructType(/*offset=*/-1, typeName, std::move(skslFields)));
|
||||
DSLType varType = arraySize > 0 ? Array(structType, arraySize) : DSLType(structType);
|
||||
DSLGlobalVar var(modifiers, varType, !varName.empty() ? varName : typeName);
|
||||
// Interface blocks can't be declared, so we always need to mark the var declared ourselves.
|
||||
@ -232,14 +233,14 @@ public:
|
||||
}
|
||||
const SkSL::Variable* skslVar = DSLWriter::Var(var);
|
||||
if (skslVar) {
|
||||
auto intf = std::make_unique<SkSL::InterfaceBlock>(pos.line(),
|
||||
auto intf = std::make_unique<SkSL::InterfaceBlock>(/*offset=*/-1,
|
||||
*skslVar, typeName, varName, arraySize, DSLWriter::SymbolTable());
|
||||
DSLWriter::IRGenerator().scanInterfaceBlock(*intf);
|
||||
DSLWriter::ProgramElements().push_back(std::move(intf));
|
||||
if (varName.empty()) {
|
||||
const std::vector<SkSL::Type::Field>& structFields = structType->fields();
|
||||
for (size_t i = 0; i < structFields.size(); ++i) {
|
||||
DSLWriter::SymbolTable()->add(std::make_unique<SkSL::Field>(pos.line(),
|
||||
DSLWriter::SymbolTable()->add(std::make_unique<SkSL::Field>(/*offset=*/-1,
|
||||
skslVar,
|
||||
i));
|
||||
}
|
||||
@ -247,10 +248,11 @@ public:
|
||||
AddToSymbolTable(var);
|
||||
}
|
||||
}
|
||||
GetErrorReporter().reportPendingErrors(pos);
|
||||
return var;
|
||||
}
|
||||
|
||||
static DSLStatement Return(DSLExpression value, PositionInfo pos) {
|
||||
static DSLPossibleStatement Return(DSLExpression value, PositionInfo pos) {
|
||||
// Note that because Return is called before the function in which it resides exists, at
|
||||
// this point we do not know the function's return type. We therefore do not check for
|
||||
// errors, or coerce the value to the correct type, until the return statement is actually
|
||||
|
@ -83,12 +83,11 @@ DSLPossibleStatement::~DSLPossibleStatement() {
|
||||
}
|
||||
|
||||
DSLStatement operator,(DSLStatement left, DSLStatement right) {
|
||||
int line = left.fStatement->fOffset;
|
||||
StatementArray stmts;
|
||||
stmts.reserve_back(2);
|
||||
stmts.push_back(left.release());
|
||||
stmts.push_back(right.release());
|
||||
return DSLStatement(SkSL::Block::MakeUnscoped(line, std::move(stmts)));
|
||||
return DSLStatement(SkSL::Block::MakeUnscoped(/*offset=*/-1, std::move(stmts)));
|
||||
}
|
||||
|
||||
} // namespace dsl
|
||||
|
@ -221,8 +221,8 @@ DSLExpression DSLType::Construct(DSLType type, SkSpan<DSLExpression> argArray) {
|
||||
}
|
||||
|
||||
DSLType Array(const DSLType& base, int count, PositionInfo pos) {
|
||||
count = base.skslType().convertArraySize(DSLWriter::Context(),
|
||||
DSLExpression(count, pos).release());
|
||||
count = base.skslType().convertArraySize(DSLWriter::Context(), DSLExpression(count).release());
|
||||
DSLWriter::ReportErrors(pos);
|
||||
if (!count) {
|
||||
return DSLType(kPoison_Type);
|
||||
}
|
||||
|
@ -158,12 +158,12 @@ VariableStorage DSLParameter::storage() const {
|
||||
|
||||
|
||||
DSLPossibleExpression DSLVarBase::operator[](DSLExpression&& index) {
|
||||
return DSLExpression(*this, PositionInfo())[std::move(index)];
|
||||
return DSLExpression(*this)[std::move(index)];
|
||||
}
|
||||
|
||||
DSLPossibleExpression DSLVarBase::assign(DSLExpression expr) {
|
||||
return DSLWriter::ConvertBinary(DSLExpression(*this, PositionInfo()).release(),
|
||||
SkSL::Token::Kind::TK_EQ, expr.release());
|
||||
return DSLWriter::ConvertBinary(DSLExpression(*this).release(), SkSL::Token::Kind::TK_EQ,
|
||||
expr.release());
|
||||
}
|
||||
|
||||
DSLPossibleExpression DSLVar::operator=(DSLExpression expr) {
|
||||
@ -184,7 +184,7 @@ std::unique_ptr<SkSL::Expression> DSLGlobalVar::methodCall(skstd::string_view me
|
||||
DSLWriter::ReportError("type does not support method calls", pos);
|
||||
return nullptr;
|
||||
}
|
||||
return DSLWriter::ConvertField(DSLExpression(*this, PositionInfo()).release(), methodName);
|
||||
return DSLWriter::ConvertField(DSLExpression(*this).release(), methodName);
|
||||
}
|
||||
|
||||
DSLPossibleExpression DSLGlobalVar::eval(DSLExpression x, PositionInfo pos) {
|
||||
|
@ -65,7 +65,7 @@ std::unique_ptr<Expression> ConstructorScalarCast::Make(const Context& context,
|
||||
}
|
||||
// We can cast scalar literals at compile-time.
|
||||
if (arg->is<Literal>()) {
|
||||
return Literal::Make(offset, arg->as<Literal>().value(), &type);
|
||||
return Literal::Make(arg->fOffset, arg->as<Literal>().value(), &type);
|
||||
}
|
||||
return std::make_unique<ConstructorScalarCast>(offset, type, std::move(arg));
|
||||
}
|
||||
|
@ -51,18 +51,19 @@ void writeH(const DFA& dfa, const char* lexer, const char* token,
|
||||
out << R"(
|
||||
};
|
||||
|
||||
)" << token << "() {}";
|
||||
)" << token << R"(()
|
||||
: fKind(Kind::TK_NONE)
|
||||
, fOffset(-1)
|
||||
, fLength(-1) {}
|
||||
|
||||
out << token << R"((Kind kind, int32_t offset, int32_t length, int32_t line)
|
||||
)" << token << R"((Kind kind, int32_t offset, int32_t length)
|
||||
: fKind(kind)
|
||||
, fOffset(offset)
|
||||
, fLength(length)
|
||||
, fLine(line) {}
|
||||
, fLength(length) {}
|
||||
|
||||
Kind fKind = Kind::TK_NONE;
|
||||
int32_t fOffset = -1;
|
||||
int32_t fLength = -1;
|
||||
int32_t fLine = -1;
|
||||
Kind fKind;
|
||||
int fOffset;
|
||||
int fLength;
|
||||
};
|
||||
|
||||
class )" << lexer << R"( {
|
||||
@ -70,29 +71,21 @@ public:
|
||||
void start(skstd::string_view text) {
|
||||
fText = text;
|
||||
fOffset = 0;
|
||||
fLine = 1;
|
||||
}
|
||||
|
||||
)" << token << R"( next();
|
||||
|
||||
struct Checkpoint {
|
||||
int32_t fOffset;
|
||||
int32_t fLine;
|
||||
};
|
||||
|
||||
Checkpoint getCheckpoint() const {
|
||||
return {fOffset, fLine};
|
||||
int32_t getCheckpoint() const {
|
||||
return fOffset;
|
||||
}
|
||||
|
||||
void rewindToCheckpoint(Checkpoint checkpoint) {
|
||||
fOffset = checkpoint.fOffset;
|
||||
fLine = checkpoint.fLine;
|
||||
void rewindToCheckpoint(int32_t checkpoint) {
|
||||
fOffset = checkpoint;
|
||||
}
|
||||
|
||||
private:
|
||||
skstd::string_view fText;
|
||||
int32_t fOffset;
|
||||
int32_t fLine;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
@ -161,13 +154,13 @@ void writeCPP(const DFA& dfa, const char* lexer, const char* token, const char*
|
||||
// a bit.
|
||||
int32_t startOffset = fOffset;
|
||||
if (startOffset == (int32_t)fText.length()) {
|
||||
return )" << token << "(" << token << R"(::Kind::TK_END_OF_FILE, startOffset, 0, fLine);
|
||||
return )" << token << "(" << token << R"(::Kind::TK_END_OF_FILE, startOffset, 0);
|
||||
}
|
||||
State state = 1;
|
||||
for (;;) {
|
||||
if (fOffset >= (int32_t)fText.length()) {
|
||||
if (kAccepts[state] == -1) {
|
||||
return Token(Token::Kind::TK_END_OF_FILE, startOffset, 0, fLine);
|
||||
return Token(Token::Kind::TK_END_OF_FILE, startOffset, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -181,12 +174,9 @@ void writeCPP(const DFA& dfa, const char* lexer, const char* token, const char*
|
||||
}
|
||||
state = newState;
|
||||
++fOffset;
|
||||
if (c == '\n') {
|
||||
++fLine;
|
||||
}
|
||||
}
|
||||
Token::Kind kind = ()" << token << R"(::Kind) kAccepts[state];
|
||||
return )" << token << R"((kind, startOffset, fOffset - startOffset, fLine);
|
||||
return )" << token << R"((kind, startOffset, fOffset - startOffset);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
@ -1,4 +1,4 @@
|
||||
### Compilation failed:
|
||||
|
||||
error: program does not contain a main() function
|
||||
error: 1: program does not contain a main() function
|
||||
1 error
|
||||
|
Loading…
Reference in New Issue
Block a user