refactored SkSL VarDeclaration handling
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2312233002 Review-Url: https://codereview.chromium.org/2312233002
This commit is contained in:
parent
ef6a9b7f93
commit
14fe8cc16d
@ -148,8 +148,8 @@ void Compiler::internalConvertProgram(std::string text,
|
|||||||
ASTDeclaration& decl = *parsed[i];
|
ASTDeclaration& decl = *parsed[i];
|
||||||
switch (decl.fKind) {
|
switch (decl.fKind) {
|
||||||
case ASTDeclaration::kVar_Kind: {
|
case ASTDeclaration::kVar_Kind: {
|
||||||
std::unique_ptr<VarDeclaration> s = fIRGenerator->convertVarDeclaration(
|
std::unique_ptr<VarDeclarations> s = fIRGenerator->convertVarDeclarations(
|
||||||
(ASTVarDeclaration&) decl,
|
(ASTVarDeclarations&) decl,
|
||||||
Variable::kGlobal_Storage);
|
Variable::kGlobal_Storage);
|
||||||
if (s) {
|
if (s) {
|
||||||
result->push_back(std::move(s));
|
result->push_back(std::move(s));
|
||||||
|
@ -313,24 +313,24 @@ void GLSLCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) {
|
|||||||
this->writeLine("};");
|
this->writeLine("};");
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLSLCodeGenerator::writeVarDeclaration(const VarDeclaration& decl) {
|
void GLSLCodeGenerator::writeVarDeclarations(const VarDeclarations& decl) {
|
||||||
ASSERT(decl.fVars.size() > 0);
|
ASSERT(decl.fVars.size() > 0);
|
||||||
this->writeModifiers(decl.fVars[0]->fModifiers);
|
this->writeModifiers(decl.fVars[0].fVar->fModifiers);
|
||||||
this->writeType(decl.fBaseType);
|
this->writeType(decl.fBaseType);
|
||||||
std::string separator = " ";
|
std::string separator = " ";
|
||||||
for (size_t i = 0; i < decl.fVars.size(); i++) {
|
for (const auto& var : decl.fVars) {
|
||||||
ASSERT(decl.fVars[i]->fModifiers == decl.fVars[0]->fModifiers);
|
ASSERT(var.fVar->fModifiers == decl.fVars[0].fVar->fModifiers);
|
||||||
this->write(separator);
|
this->write(separator);
|
||||||
separator = ", ";
|
separator = ", ";
|
||||||
this->write(decl.fVars[i]->fName);
|
this->write(var.fVar->fName);
|
||||||
for (const auto& size : decl.fSizes[i]) {
|
for (const auto& size : var.fSizes) {
|
||||||
this->write("[");
|
this->write("[");
|
||||||
this->writeExpression(*size, kTopLevel_Precedence);
|
this->writeExpression(*size, kTopLevel_Precedence);
|
||||||
this->write("]");
|
this->write("]");
|
||||||
}
|
}
|
||||||
if (decl.fValues[i]) {
|
if (var.fValue) {
|
||||||
this->write(" = ");
|
this->write(" = ");
|
||||||
this->writeExpression(*decl.fValues[i], kTopLevel_Precedence);
|
this->writeExpression(*var.fValue, kTopLevel_Precedence);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this->write(";");
|
this->write(";");
|
||||||
@ -348,8 +348,8 @@ void GLSLCodeGenerator::writeStatement(const Statement& s) {
|
|||||||
case Statement::kReturn_Kind:
|
case Statement::kReturn_Kind:
|
||||||
this->writeReturnStatement((ReturnStatement&) s);
|
this->writeReturnStatement((ReturnStatement&) s);
|
||||||
break;
|
break;
|
||||||
case Statement::kVarDeclaration_Kind:
|
case Statement::kVarDeclarations_Kind:
|
||||||
this->writeVarDeclaration(*((VarDeclarationStatement&) s).fDeclaration);
|
this->writeVarDeclarations(*((VarDeclarationsStatement&) s).fDeclaration);
|
||||||
break;
|
break;
|
||||||
case Statement::kIf_Kind:
|
case Statement::kIf_Kind:
|
||||||
this->writeIfStatement((IfStatement&) s);
|
this->writeIfStatement((IfStatement&) s);
|
||||||
@ -455,9 +455,10 @@ void GLSLCodeGenerator::generateCode(const Program& program, std::ostream& out)
|
|||||||
this->writeExtension((Extension&) *e);
|
this->writeExtension((Extension&) *e);
|
||||||
break;
|
break;
|
||||||
case ProgramElement::kVar_Kind: {
|
case ProgramElement::kVar_Kind: {
|
||||||
VarDeclaration& decl = (VarDeclaration&) *e;
|
VarDeclarations& decl = (VarDeclarations&) *e;
|
||||||
if (decl.fVars.size() > 0 && decl.fVars[0]->fModifiers.fLayout.fBuiltin == -1) {
|
if (decl.fVars.size() > 0 &&
|
||||||
this->writeVarDeclaration(decl);
|
decl.fVars[0].fVar->fModifiers.fLayout.fBuiltin == -1) {
|
||||||
|
this->writeVarDeclarations(decl);
|
||||||
this->writeLine();
|
this->writeLine();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -115,7 +115,7 @@ private:
|
|||||||
|
|
||||||
void writeGlobalVars(const VarDeclaration& vs);
|
void writeGlobalVars(const VarDeclaration& vs);
|
||||||
|
|
||||||
void writeVarDeclaration(const VarDeclaration& decl);
|
void writeVarDeclarations(const VarDeclarations& decl);
|
||||||
|
|
||||||
void writeVariableReference(const VariableReference& ref);
|
void writeVariableReference(const VariableReference& ref);
|
||||||
|
|
||||||
|
@ -129,35 +129,32 @@ std::unique_ptr<Block> IRGenerator::convertBlock(const ASTBlock& block) {
|
|||||||
|
|
||||||
std::unique_ptr<Statement> IRGenerator::convertVarDeclarationStatement(
|
std::unique_ptr<Statement> IRGenerator::convertVarDeclarationStatement(
|
||||||
const ASTVarDeclarationStatement& s) {
|
const ASTVarDeclarationStatement& s) {
|
||||||
auto decl = this->convertVarDeclaration(*s.fDeclaration, Variable::kLocal_Storage);
|
auto decl = this->convertVarDeclarations(*s.fDeclarations, Variable::kLocal_Storage);
|
||||||
if (!decl) {
|
if (!decl) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return std::unique_ptr<Statement>(new VarDeclarationStatement(std::move(decl)));
|
return std::unique_ptr<Statement>(new VarDeclarationsStatement(std::move(decl)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Modifiers IRGenerator::convertModifiers(const ASTModifiers& modifiers) {
|
Modifiers IRGenerator::convertModifiers(const ASTModifiers& modifiers) {
|
||||||
return Modifiers(modifiers);
|
return Modifiers(modifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<VarDeclaration> IRGenerator::convertVarDeclaration(const ASTVarDeclaration& decl,
|
std::unique_ptr<VarDeclarations> IRGenerator::convertVarDeclarations(const ASTVarDeclarations& decl,
|
||||||
Variable::Storage storage) {
|
Variable::Storage storage) {
|
||||||
std::vector<const Variable*> variables;
|
std::vector<VarDeclaration> variables;
|
||||||
std::vector<std::vector<std::unique_ptr<Expression>>> sizes;
|
|
||||||
std::vector<std::unique_ptr<Expression>> values;
|
|
||||||
const Type* baseType = this->convertType(*decl.fType);
|
const Type* baseType = this->convertType(*decl.fType);
|
||||||
if (!baseType) {
|
if (!baseType) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < decl.fNames.size(); i++) {
|
for (const auto& varDecl : decl.fVars) {
|
||||||
Modifiers modifiers = this->convertModifiers(decl.fModifiers);
|
Modifiers modifiers = this->convertModifiers(decl.fModifiers);
|
||||||
const Type* type = baseType;
|
const Type* type = baseType;
|
||||||
ASSERT(type->kind() != Type::kArray_Kind);
|
ASSERT(type->kind() != Type::kArray_Kind);
|
||||||
std::vector<std::unique_ptr<Expression>> currentVarSizes;
|
std::vector<std::unique_ptr<Expression>> sizes;
|
||||||
for (size_t j = 0; j < decl.fSizes[i].size(); j++) {
|
for (const auto& rawSize : varDecl.fSizes) {
|
||||||
if (decl.fSizes[i][j]) {
|
if (rawSize) {
|
||||||
ASTExpression& rawSize = *decl.fSizes[i][j];
|
auto size = this->coerce(this->convertExpression(*rawSize), *fContext.fInt_Type);
|
||||||
auto size = this->coerce(this->convertExpression(rawSize), *fContext.fInt_Type);
|
|
||||||
if (!size) {
|
if (!size) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -175,39 +172,35 @@ std::unique_ptr<VarDeclaration> IRGenerator::convertVarDeclaration(const ASTVarD
|
|||||||
}
|
}
|
||||||
type = new Type(name, Type::kArray_Kind, *type, (int) count);
|
type = new Type(name, Type::kArray_Kind, *type, (int) count);
|
||||||
fSymbolTable->takeOwnership((Type*) type);
|
fSymbolTable->takeOwnership((Type*) type);
|
||||||
currentVarSizes.push_back(std::move(size));
|
sizes.push_back(std::move(size));
|
||||||
} else {
|
} else {
|
||||||
type = new Type(type->fName + "[]", Type::kArray_Kind, *type, -1);
|
type = new Type(type->fName + "[]", Type::kArray_Kind, *type, -1);
|
||||||
fSymbolTable->takeOwnership((Type*) type);
|
fSymbolTable->takeOwnership((Type*) type);
|
||||||
currentVarSizes.push_back(nullptr);
|
sizes.push_back(nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto var = std::unique_ptr<Variable>(new Variable(decl.fPosition, modifiers, decl.fNames[i],
|
auto var = std::unique_ptr<Variable>(new Variable(decl.fPosition, modifiers, varDecl.fName,
|
||||||
*type, storage));
|
*type, storage));
|
||||||
std::unique_ptr<Expression> value;
|
std::unique_ptr<Expression> value;
|
||||||
if (decl.fValues[i]) {
|
if (varDecl.fValue) {
|
||||||
value = this->convertExpression(*decl.fValues[i]);
|
value = this->convertExpression(*varDecl.fValue);
|
||||||
if (!value) {
|
if (!value) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
value = this->coerce(std::move(value), *type);
|
value = this->coerce(std::move(value), *type);
|
||||||
}
|
}
|
||||||
if ("gl_FragCoord" == decl.fNames[i] && (*fSymbolTable)[decl.fNames[i]]) {
|
if ("gl_FragCoord" == varDecl.fName && (*fSymbolTable)[varDecl.fName]) {
|
||||||
// already defined, just update the modifiers
|
// already defined, just update the modifiers
|
||||||
Variable* old = (Variable*) (*fSymbolTable)[decl.fNames[i]];
|
Variable* old = (Variable*) (*fSymbolTable)[varDecl.fName];
|
||||||
old->fModifiers = var->fModifiers;
|
old->fModifiers = var->fModifiers;
|
||||||
} else {
|
} else {
|
||||||
variables.push_back(var.get());
|
variables.emplace_back(var.get(), std::move(sizes), std::move(value));
|
||||||
fSymbolTable->add(decl.fNames[i], std::move(var));
|
fSymbolTable->add(varDecl.fName, std::move(var));
|
||||||
values.push_back(std::move(value));
|
|
||||||
sizes.push_back(std::move(currentVarSizes));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return std::unique_ptr<VarDeclaration>(new VarDeclaration(decl.fPosition,
|
return std::unique_ptr<VarDeclarations>(new VarDeclarations(decl.fPosition,
|
||||||
baseType,
|
baseType,
|
||||||
std::move(variables),
|
std::move(variables)));
|
||||||
std::move(sizes),
|
|
||||||
std::move(values)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Statement> IRGenerator::convertIf(const ASTIfStatement& s) {
|
std::unique_ptr<Statement> IRGenerator::convertIf(const ASTIfStatement& s) {
|
||||||
@ -482,21 +475,21 @@ std::unique_ptr<InterfaceBlock> IRGenerator::convertInterfaceBlock(const ASTInte
|
|||||||
Modifiers mods = this->convertModifiers(intf.fModifiers);
|
Modifiers mods = this->convertModifiers(intf.fModifiers);
|
||||||
std::vector<Type::Field> fields;
|
std::vector<Type::Field> fields;
|
||||||
for (size_t i = 0; i < intf.fDeclarations.size(); i++) {
|
for (size_t i = 0; i < intf.fDeclarations.size(); i++) {
|
||||||
std::unique_ptr<VarDeclaration> decl = this->convertVarDeclaration(
|
std::unique_ptr<VarDeclarations> decl = this->convertVarDeclarations(
|
||||||
*intf.fDeclarations[i],
|
*intf.fDeclarations[i],
|
||||||
Variable::kGlobal_Storage);
|
Variable::kGlobal_Storage);
|
||||||
for (size_t j = 0; j < decl->fVars.size(); j++) {
|
for (const auto& var : decl->fVars) {
|
||||||
fields.push_back(Type::Field(decl->fVars[j]->fModifiers, decl->fVars[j]->fName,
|
fields.push_back(Type::Field(var.fVar->fModifiers, var.fVar->fName,
|
||||||
&decl->fVars[j]->fType));
|
&var.fVar->fType));
|
||||||
if (decl->fValues[j]) {
|
if (var.fValue) {
|
||||||
fErrors.error(decl->fPosition,
|
fErrors.error(decl->fPosition,
|
||||||
"initializers are not permitted on interface block fields");
|
"initializers are not permitted on interface block fields");
|
||||||
}
|
}
|
||||||
if (decl->fVars[j]->fModifiers.fFlags & (Modifiers::kIn_Flag |
|
if (var.fVar->fModifiers.fFlags & (Modifiers::kIn_Flag |
|
||||||
Modifiers::kOut_Flag |
|
Modifiers::kOut_Flag |
|
||||||
Modifiers::kUniform_Flag |
|
Modifiers::kUniform_Flag |
|
||||||
Modifiers::kConst_Flag)) {
|
Modifiers::kConst_Flag)) {
|
||||||
fErrors.error(decl->fPosition,
|
fErrors.error(decl->fPosition,
|
||||||
"interface block fields may not have storage qualifiers");
|
"interface block fields may not have storage qualifiers");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,8 +56,8 @@ public:
|
|||||||
IRGenerator(const Context* context, std::shared_ptr<SymbolTable> root,
|
IRGenerator(const Context* context, std::shared_ptr<SymbolTable> root,
|
||||||
ErrorReporter& errorReporter);
|
ErrorReporter& errorReporter);
|
||||||
|
|
||||||
std::unique_ptr<VarDeclaration> convertVarDeclaration(const ASTVarDeclaration& decl,
|
std::unique_ptr<VarDeclarations> convertVarDeclarations(const ASTVarDeclarations& decl,
|
||||||
Variable::Storage storage);
|
Variable::Storage storage);
|
||||||
std::unique_ptr<FunctionDefinition> convertFunction(const ASTFunction& f);
|
std::unique_ptr<FunctionDefinition> convertFunction(const ASTFunction& f);
|
||||||
std::unique_ptr<Statement> convertStatement(const ASTStatement& statement);
|
std::unique_ptr<Statement> convertStatement(const ASTStatement& statement);
|
||||||
std::unique_ptr<Expression> convertExpression(const ASTExpression& expression);
|
std::unique_ptr<Expression> convertExpression(const ASTExpression& expression);
|
||||||
|
@ -274,7 +274,7 @@ std::unique_ptr<ASTDeclaration> Parser::declaration() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* modifiers type IDENTIFIER varDeclarationEnd */
|
/* modifiers type IDENTIFIER varDeclarationEnd */
|
||||||
std::unique_ptr<ASTVarDeclaration> Parser::varDeclaration() {
|
std::unique_ptr<ASTVarDeclarations> Parser::varDeclarations() {
|
||||||
ASTModifiers modifiers = this->modifiers();
|
ASTModifiers modifiers = this->modifiers();
|
||||||
std::unique_ptr<ASTType> type(this->type());
|
std::unique_ptr<ASTType> type(this->type());
|
||||||
if (!type) {
|
if (!type) {
|
||||||
@ -301,23 +301,23 @@ std::unique_ptr<ASTType> Parser::structDeclaration() {
|
|||||||
}
|
}
|
||||||
std::vector<Type::Field> fields;
|
std::vector<Type::Field> fields;
|
||||||
while (this->peek().fKind != Token::RBRACE) {
|
while (this->peek().fKind != Token::RBRACE) {
|
||||||
std::unique_ptr<ASTVarDeclaration> decl = this->varDeclaration();
|
std::unique_ptr<ASTVarDeclarations> decl = this->varDeclarations();
|
||||||
if (!decl) {
|
if (!decl) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < decl->fNames.size(); i++) {
|
for (const auto& var : decl->fVars) {
|
||||||
auto type = (const Type*) fTypes[decl->fType->fName];
|
auto type = (const Type*) fTypes[decl->fType->fName];
|
||||||
for (int j = (int) decl->fSizes[i].size() - 1; j >= 0; j--) {
|
for (int i = (int) var.fSizes.size() - 1; i >= 0; i--) {
|
||||||
if (decl->fSizes[i][j]->fKind != ASTExpression::kInt_Kind) {
|
if (var.fSizes[i]->fKind != ASTExpression::kInt_Kind) {
|
||||||
this->error(decl->fPosition, "array size in struct field must be a constant");
|
this->error(decl->fPosition, "array size in struct field must be a constant");
|
||||||
}
|
}
|
||||||
uint64_t columns = ((ASTIntLiteral&) *decl->fSizes[i][j]).fValue;
|
uint64_t columns = ((ASTIntLiteral&) *var.fSizes[i]).fValue;
|
||||||
std::string name = type->name() + "[" + to_string(columns) + "]";
|
std::string name = type->name() + "[" + to_string(columns) + "]";
|
||||||
type = new Type(name, Type::kArray_Kind, *type, (int) columns);
|
type = new Type(name, Type::kArray_Kind, *type, (int) columns);
|
||||||
fTypes.takeOwnership((Type*) type);
|
fTypes.takeOwnership((Type*) type);
|
||||||
}
|
}
|
||||||
fields.push_back(Type::Field(decl->fModifiers, decl->fNames[i], type));
|
fields.push_back(Type::Field(decl->fModifiers, var.fName, type));
|
||||||
if (decl->fValues[i]) {
|
if (var.fValue) {
|
||||||
this->error(decl->fPosition, "initializers are not permitted on struct fields");
|
this->error(decl->fPosition, "initializers are not permitted on struct fields");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -331,20 +331,20 @@ std::unique_ptr<ASTType> Parser::structDeclaration() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* structDeclaration ((IDENTIFIER varDeclarationEnd) | SEMICOLON) */
|
/* structDeclaration ((IDENTIFIER varDeclarationEnd) | SEMICOLON) */
|
||||||
std::unique_ptr<ASTVarDeclaration> Parser::structVarDeclaration(ASTModifiers modifiers) {
|
std::unique_ptr<ASTVarDeclarations> Parser::structVarDeclaration(ASTModifiers modifiers) {
|
||||||
std::unique_ptr<ASTType> type = this->structDeclaration();
|
std::unique_ptr<ASTType> type = this->structDeclaration();
|
||||||
if (!type) {
|
if (!type) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (peek().fKind == Token::IDENTIFIER) {
|
if (peek().fKind == Token::IDENTIFIER) {
|
||||||
Token name = this->nextToken();
|
Token name = this->nextToken();
|
||||||
std::unique_ptr<ASTVarDeclaration> result = this->varDeclarationEnd(modifiers,
|
std::unique_ptr<ASTVarDeclarations> result = this->varDeclarationEnd(modifiers,
|
||||||
std::move(type),
|
std::move(type),
|
||||||
std::move(name.fText));
|
std::move(name.fText));
|
||||||
if (result) {
|
if (result) {
|
||||||
for (size_t i = 0; i < result->fValues.size(); i++) {
|
for (const auto& var : result->fVars) {
|
||||||
if (result->fValues[i]) {
|
if (var.fValue) {
|
||||||
this->error(result->fValues[i]->fPosition,
|
this->error(var.fValue->fPosition,
|
||||||
"struct variables cannot be initialized");
|
"struct variables cannot be initialized");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -357,12 +357,10 @@ std::unique_ptr<ASTVarDeclaration> Parser::structVarDeclaration(ASTModifiers mod
|
|||||||
|
|
||||||
/* (LBRACKET expression? RBRACKET)* (EQ expression)? (COMMA IDENTIFER
|
/* (LBRACKET expression? RBRACKET)* (EQ expression)? (COMMA IDENTIFER
|
||||||
(LBRACKET expression? RBRACKET)* (EQ expression)?)* SEMICOLON */
|
(LBRACKET expression? RBRACKET)* (EQ expression)?)* SEMICOLON */
|
||||||
std::unique_ptr<ASTVarDeclaration> Parser::varDeclarationEnd(ASTModifiers mods,
|
std::unique_ptr<ASTVarDeclarations> Parser::varDeclarationEnd(ASTModifiers mods,
|
||||||
std::unique_ptr<ASTType> type,
|
std::unique_ptr<ASTType> type,
|
||||||
std::string name) {
|
std::string name) {
|
||||||
std::vector<std::string> names;
|
std::vector<ASTVarDeclaration> vars;
|
||||||
std::vector<std::vector<std::unique_ptr<ASTExpression>>> sizes;
|
|
||||||
names.push_back(name);
|
|
||||||
std::vector<std::unique_ptr<ASTExpression>> currentVarSizes;
|
std::vector<std::unique_ptr<ASTExpression>> currentVarSizes;
|
||||||
while (this->peek().fKind == Token::LBRACKET) {
|
while (this->peek().fKind == Token::LBRACKET) {
|
||||||
this->nextToken();
|
this->nextToken();
|
||||||
@ -380,26 +378,23 @@ std::unique_ptr<ASTVarDeclaration> Parser::varDeclarationEnd(ASTModifiers mods,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sizes.push_back(std::move(currentVarSizes));
|
std::unique_ptr<ASTExpression> value;
|
||||||
std::vector<std::unique_ptr<ASTExpression>> values;
|
|
||||||
if (this->peek().fKind == Token::EQ) {
|
if (this->peek().fKind == Token::EQ) {
|
||||||
this->nextToken();
|
this->nextToken();
|
||||||
std::unique_ptr<ASTExpression> value(this->expression());
|
value = this->expression();
|
||||||
if (!value) {
|
if (!value) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
values.push_back(std::move(value));
|
|
||||||
} else {
|
|
||||||
values.push_back(nullptr);
|
|
||||||
}
|
}
|
||||||
|
vars.emplace_back(std::move(name), std::move(currentVarSizes), std::move(value));
|
||||||
while (this->peek().fKind == Token::COMMA) {
|
while (this->peek().fKind == Token::COMMA) {
|
||||||
this->nextToken();
|
this->nextToken();
|
||||||
Token name;
|
Token name;
|
||||||
if (!this->expect(Token::IDENTIFIER, "an identifier", &name)) {
|
if (!this->expect(Token::IDENTIFIER, "an identifier", &name)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
names.push_back(name.fText);
|
|
||||||
currentVarSizes.clear();
|
currentVarSizes.clear();
|
||||||
|
value.reset();
|
||||||
while (this->peek().fKind == Token::LBRACKET) {
|
while (this->peek().fKind == Token::LBRACKET) {
|
||||||
this->nextToken();
|
this->nextToken();
|
||||||
if (this->peek().fKind == Token::RBRACKET) {
|
if (this->peek().fKind == Token::RBRACKET) {
|
||||||
@ -416,26 +411,21 @@ std::unique_ptr<ASTVarDeclaration> Parser::varDeclarationEnd(ASTModifiers mods,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sizes.push_back(std::move(currentVarSizes));
|
|
||||||
if (this->peek().fKind == Token::EQ) {
|
if (this->peek().fKind == Token::EQ) {
|
||||||
this->nextToken();
|
this->nextToken();
|
||||||
std::unique_ptr<ASTExpression> value(this->expression());
|
value = this->expression();
|
||||||
if (!value) {
|
if (!value) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
values.push_back(std::move(value));
|
|
||||||
} else {
|
|
||||||
values.push_back(nullptr);
|
|
||||||
}
|
}
|
||||||
|
vars.emplace_back(std::move(name.fText), std::move(currentVarSizes), std::move(value));
|
||||||
}
|
}
|
||||||
if (!this->expect(Token::SEMICOLON, "';'")) {
|
if (!this->expect(Token::SEMICOLON, "';'")) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return std::unique_ptr<ASTVarDeclaration>(new ASTVarDeclaration(std::move(mods),
|
return std::unique_ptr<ASTVarDeclarations>(new ASTVarDeclarations(std::move(mods),
|
||||||
std::move(type),
|
std::move(type),
|
||||||
std::move(names),
|
std::move(vars)));
|
||||||
std::move(sizes),
|
|
||||||
std::move(values)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* modifiers type IDENTIFIER (LBRACKET INT_LITERAL RBRACKET)? */
|
/* modifiers type IDENTIFIER (LBRACKET INT_LITERAL RBRACKET)? */
|
||||||
@ -614,7 +604,7 @@ std::unique_ptr<ASTStatement> Parser::statement() {
|
|||||||
case Token::HIGHP: // fall through
|
case Token::HIGHP: // fall through
|
||||||
case Token::MEDIUMP: // fall through
|
case Token::MEDIUMP: // fall through
|
||||||
case Token::LOWP: {
|
case Token::LOWP: {
|
||||||
auto decl = this->varDeclaration();
|
auto decl = this->varDeclarations();
|
||||||
if (!decl) {
|
if (!decl) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -622,7 +612,7 @@ std::unique_ptr<ASTStatement> Parser::statement() {
|
|||||||
}
|
}
|
||||||
case Token::IDENTIFIER:
|
case Token::IDENTIFIER:
|
||||||
if (this->isType(start.fText)) {
|
if (this->isType(start.fText)) {
|
||||||
auto decl = this->varDeclaration();
|
auto decl = this->varDeclarations();
|
||||||
if (!decl) {
|
if (!decl) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -663,9 +653,9 @@ std::unique_ptr<ASTDeclaration> Parser::interfaceBlock(ASTModifiers mods) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
this->nextToken();
|
this->nextToken();
|
||||||
std::vector<std::unique_ptr<ASTVarDeclaration>> decls;
|
std::vector<std::unique_ptr<ASTVarDeclarations>> decls;
|
||||||
while (this->peek().fKind != Token::RBRACE) {
|
while (this->peek().fKind != Token::RBRACE) {
|
||||||
std::unique_ptr<ASTVarDeclaration> decl = this->varDeclaration();
|
std::unique_ptr<ASTVarDeclarations> decl = this->varDeclarations();
|
||||||
if (!decl) {
|
if (!decl) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -788,12 +778,12 @@ std::unique_ptr<ASTForStatement> Parser::forStatement() {
|
|||||||
break;
|
break;
|
||||||
case Token::CONST:
|
case Token::CONST:
|
||||||
initializer = std::unique_ptr<ASTStatement>(new ASTVarDeclarationStatement(
|
initializer = std::unique_ptr<ASTStatement>(new ASTVarDeclarationStatement(
|
||||||
this->varDeclaration()));
|
this->varDeclarations()));
|
||||||
break;
|
break;
|
||||||
case Token::IDENTIFIER:
|
case Token::IDENTIFIER:
|
||||||
if (this->isType(nextToken.fText)) {
|
if (this->isType(nextToken.fText)) {
|
||||||
initializer = std::unique_ptr<ASTStatement>(new ASTVarDeclarationStatement(
|
initializer = std::unique_ptr<ASTStatement>(new ASTVarDeclarationStatement(
|
||||||
this->varDeclaration()));
|
this->varDeclarations()));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
|
@ -40,7 +40,7 @@ struct ASTStatement;
|
|||||||
struct ASTSuffix;
|
struct ASTSuffix;
|
||||||
struct ASTType;
|
struct ASTType;
|
||||||
struct ASTWhileStatement;
|
struct ASTWhileStatement;
|
||||||
struct ASTVarDeclaration;
|
struct ASTVarDeclarations;
|
||||||
class SymbolTable;
|
class SymbolTable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -106,15 +106,15 @@ private:
|
|||||||
|
|
||||||
std::unique_ptr<ASTDeclaration> declaration();
|
std::unique_ptr<ASTDeclaration> declaration();
|
||||||
|
|
||||||
std::unique_ptr<ASTVarDeclaration> varDeclaration();
|
std::unique_ptr<ASTVarDeclarations> varDeclarations();
|
||||||
|
|
||||||
std::unique_ptr<ASTType> structDeclaration();
|
std::unique_ptr<ASTType> structDeclaration();
|
||||||
|
|
||||||
std::unique_ptr<ASTVarDeclaration> structVarDeclaration(ASTModifiers modifiers);
|
std::unique_ptr<ASTVarDeclarations> structVarDeclaration(ASTModifiers modifiers);
|
||||||
|
|
||||||
std::unique_ptr<ASTVarDeclaration> varDeclarationEnd(ASTModifiers modifiers,
|
std::unique_ptr<ASTVarDeclarations> varDeclarationEnd(ASTModifiers modifiers,
|
||||||
std::unique_ptr<ASTType> type,
|
std::unique_ptr<ASTType> type,
|
||||||
std::string name);
|
std::string name);
|
||||||
|
|
||||||
std::unique_ptr<ASTParameter> parameter();
|
std::unique_ptr<ASTParameter> parameter();
|
||||||
|
|
||||||
|
@ -2363,23 +2363,25 @@ SpvId SPIRVCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPIRVCodeGenerator::writeGlobalVars(const VarDeclaration& decl, std::ostream& out) {
|
void SPIRVCodeGenerator::writeGlobalVars(const VarDeclarations& decl, std::ostream& out) {
|
||||||
for (size_t i = 0; i < decl.fVars.size(); i++) {
|
for (size_t i = 0; i < decl.fVars.size(); i++) {
|
||||||
if (!decl.fVars[i]->fIsReadFrom && !decl.fVars[i]->fIsWrittenTo &&
|
const VarDeclaration& varDecl = decl.fVars[i];
|
||||||
!(decl.fVars[i]->fModifiers.fFlags & (Modifiers::kIn_Flag |
|
const Variable* var = varDecl.fVar;
|
||||||
Modifiers::kOut_Flag |
|
if (!var->fIsReadFrom && !var->fIsWrittenTo &&
|
||||||
Modifiers::kUniform_Flag))) {
|
!(var->fModifiers.fFlags & (Modifiers::kIn_Flag |
|
||||||
|
Modifiers::kOut_Flag |
|
||||||
|
Modifiers::kUniform_Flag))) {
|
||||||
// variable is dead and not an input / output var (the Vulkan debug layers complain if
|
// variable is dead and not an input / output var (the Vulkan debug layers complain if
|
||||||
// we elide an interface var, even if it's dead)
|
// we elide an interface var, even if it's dead)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
SpvStorageClass_ storageClass;
|
SpvStorageClass_ storageClass;
|
||||||
if (decl.fVars[i]->fModifiers.fFlags & Modifiers::kIn_Flag) {
|
if (var->fModifiers.fFlags & Modifiers::kIn_Flag) {
|
||||||
storageClass = SpvStorageClassInput;
|
storageClass = SpvStorageClassInput;
|
||||||
} else if (decl.fVars[i]->fModifiers.fFlags & Modifiers::kOut_Flag) {
|
} else if (var->fModifiers.fFlags & Modifiers::kOut_Flag) {
|
||||||
storageClass = SpvStorageClassOutput;
|
storageClass = SpvStorageClassOutput;
|
||||||
} else if (decl.fVars[i]->fModifiers.fFlags & Modifiers::kUniform_Flag) {
|
} else if (var->fModifiers.fFlags & Modifiers::kUniform_Flag) {
|
||||||
if (decl.fVars[i]->fType.kind() == Type::kSampler_Kind) {
|
if (var->fType.kind() == Type::kSampler_Kind) {
|
||||||
storageClass = SpvStorageClassUniformConstant;
|
storageClass = SpvStorageClassUniformConstant;
|
||||||
} else {
|
} else {
|
||||||
storageClass = SpvStorageClassUniform;
|
storageClass = SpvStorageClassUniform;
|
||||||
@ -2388,36 +2390,37 @@ void SPIRVCodeGenerator::writeGlobalVars(const VarDeclaration& decl, std::ostrea
|
|||||||
storageClass = SpvStorageClassPrivate;
|
storageClass = SpvStorageClassPrivate;
|
||||||
}
|
}
|
||||||
SpvId id = this->nextId();
|
SpvId id = this->nextId();
|
||||||
fVariableMap[decl.fVars[i]] = id;
|
fVariableMap[var] = id;
|
||||||
SpvId type = this->getPointerType(decl.fVars[i]->fType, storageClass);
|
SpvId type = this->getPointerType(var->fType, storageClass);
|
||||||
this->writeInstruction(SpvOpVariable, type, id, storageClass, fConstantBuffer);
|
this->writeInstruction(SpvOpVariable, type, id, storageClass, fConstantBuffer);
|
||||||
this->writeInstruction(SpvOpName, id, decl.fVars[i]->fName.c_str(), fNameBuffer);
|
this->writeInstruction(SpvOpName, id, var->fName.c_str(), fNameBuffer);
|
||||||
if (decl.fVars[i]->fType.kind() == Type::kMatrix_Kind) {
|
if (var->fType.kind() == Type::kMatrix_Kind) {
|
||||||
this->writeInstruction(SpvOpMemberDecorate, id, (SpvId) i, SpvDecorationColMajor,
|
this->writeInstruction(SpvOpMemberDecorate, id, (SpvId) i, SpvDecorationColMajor,
|
||||||
fDecorationBuffer);
|
fDecorationBuffer);
|
||||||
this->writeInstruction(SpvOpMemberDecorate, id, (SpvId) i, SpvDecorationMatrixStride,
|
this->writeInstruction(SpvOpMemberDecorate, id, (SpvId) i, SpvDecorationMatrixStride,
|
||||||
(SpvId) decl.fVars[i]->fType.stride(), fDecorationBuffer);
|
(SpvId) var->fType.stride(), fDecorationBuffer);
|
||||||
}
|
}
|
||||||
if (decl.fValues[i]) {
|
if (varDecl.fValue) {
|
||||||
ASSERT(!fCurrentBlock);
|
ASSERT(!fCurrentBlock);
|
||||||
fCurrentBlock = -1;
|
fCurrentBlock = -1;
|
||||||
SpvId value = this->writeExpression(*decl.fValues[i], fGlobalInitializersBuffer);
|
SpvId value = this->writeExpression(*varDecl.fValue, fGlobalInitializersBuffer);
|
||||||
this->writeInstruction(SpvOpStore, id, value, fGlobalInitializersBuffer);
|
this->writeInstruction(SpvOpStore, id, value, fGlobalInitializersBuffer);
|
||||||
fCurrentBlock = 0;
|
fCurrentBlock = 0;
|
||||||
}
|
}
|
||||||
this->writeLayout(decl.fVars[i]->fModifiers.fLayout, id);
|
this->writeLayout(var->fModifiers.fLayout, id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPIRVCodeGenerator::writeVarDeclaration(const VarDeclaration& decl, std::ostream& out) {
|
void SPIRVCodeGenerator::writeVarDeclarations(const VarDeclarations& decl, std::ostream& out) {
|
||||||
for (size_t i = 0; i < decl.fVars.size(); i++) {
|
for (const auto& varDecl : decl.fVars) {
|
||||||
|
const Variable* var = varDecl.fVar;
|
||||||
SpvId id = this->nextId();
|
SpvId id = this->nextId();
|
||||||
fVariableMap[decl.fVars[i]] = id;
|
fVariableMap[var] = id;
|
||||||
SpvId type = this->getPointerType(decl.fVars[i]->fType, SpvStorageClassFunction);
|
SpvId type = this->getPointerType(var->fType, SpvStorageClassFunction);
|
||||||
this->writeInstruction(SpvOpVariable, type, id, SpvStorageClassFunction, fVariableBuffer);
|
this->writeInstruction(SpvOpVariable, type, id, SpvStorageClassFunction, fVariableBuffer);
|
||||||
this->writeInstruction(SpvOpName, id, decl.fVars[i]->fName.c_str(), fNameBuffer);
|
this->writeInstruction(SpvOpName, id, var->fName.c_str(), fNameBuffer);
|
||||||
if (decl.fValues[i]) {
|
if (varDecl.fValue) {
|
||||||
SpvId value = this->writeExpression(*decl.fValues[i], out);
|
SpvId value = this->writeExpression(*varDecl.fValue, out);
|
||||||
this->writeInstruction(SpvOpStore, id, value, out);
|
this->writeInstruction(SpvOpStore, id, value, out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2434,8 +2437,8 @@ void SPIRVCodeGenerator::writeStatement(const Statement& s, std::ostream& out) {
|
|||||||
case Statement::kReturn_Kind:
|
case Statement::kReturn_Kind:
|
||||||
this->writeReturnStatement((ReturnStatement&) s, out);
|
this->writeReturnStatement((ReturnStatement&) s, out);
|
||||||
break;
|
break;
|
||||||
case Statement::kVarDeclaration_Kind:
|
case Statement::kVarDeclarations_Kind:
|
||||||
this->writeVarDeclaration(*((VarDeclarationStatement&) s).fDeclaration, out);
|
this->writeVarDeclarations(*((VarDeclarationsStatement&) s).fDeclaration, out);
|
||||||
break;
|
break;
|
||||||
case Statement::kIf_Kind:
|
case Statement::kIf_Kind:
|
||||||
this->writeIfStatement((IfStatement&) s, out);
|
this->writeIfStatement((IfStatement&) s, out);
|
||||||
@ -2559,7 +2562,7 @@ void SPIRVCodeGenerator::writeInstructions(const Program& program, std::ostream&
|
|||||||
}
|
}
|
||||||
for (size_t i = 0; i < program.fElements.size(); i++) {
|
for (size_t i = 0; i < program.fElements.size(); i++) {
|
||||||
if (program.fElements[i]->fKind == ProgramElement::kVar_Kind) {
|
if (program.fElements[i]->fKind == ProgramElement::kVar_Kind) {
|
||||||
this->writeGlobalVars(((VarDeclaration&) *program.fElements[i]), body);
|
this->writeGlobalVars(((VarDeclarations&) *program.fElements[i]), body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < program.fElements.size(); i++) {
|
for (size_t i = 0; i < program.fElements.size(); i++) {
|
||||||
|
@ -115,9 +115,9 @@ private:
|
|||||||
|
|
||||||
SpvId writeFunction(const FunctionDefinition& f, std::ostream& out);
|
SpvId writeFunction(const FunctionDefinition& f, std::ostream& out);
|
||||||
|
|
||||||
void writeGlobalVars(const VarDeclaration& v, std::ostream& out);
|
void writeGlobalVars(const VarDeclarations& v, std::ostream& out);
|
||||||
|
|
||||||
void writeVarDeclaration(const VarDeclaration& decl, std::ostream& out);
|
void writeVarDeclarations(const VarDeclarations& decl, std::ostream& out);
|
||||||
|
|
||||||
SpvId writeVariableReference(const VariableReference& ref, std::ostream& out);
|
SpvId writeVariableReference(const VariableReference& ref, std::ostream& out);
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ struct ASTInterfaceBlock : public ASTDeclaration {
|
|||||||
ASTModifiers modifiers,
|
ASTModifiers modifiers,
|
||||||
std::string interfaceName,
|
std::string interfaceName,
|
||||||
std::string valueName,
|
std::string valueName,
|
||||||
std::vector<std::unique_ptr<ASTVarDeclaration>> declarations)
|
std::vector<std::unique_ptr<ASTVarDeclarations>> declarations)
|
||||||
: INHERITED(position, kInterfaceBlock_Kind)
|
: INHERITED(position, kInterfaceBlock_Kind)
|
||||||
, fModifiers(modifiers)
|
, fModifiers(modifiers)
|
||||||
, fInterfaceName(std::move(interfaceName))
|
, fInterfaceName(std::move(interfaceName))
|
||||||
@ -48,7 +48,7 @@ struct ASTInterfaceBlock : public ASTDeclaration {
|
|||||||
const ASTModifiers fModifiers;
|
const ASTModifiers fModifiers;
|
||||||
const std::string fInterfaceName;
|
const std::string fInterfaceName;
|
||||||
const std::string fValueName;
|
const std::string fValueName;
|
||||||
const std::vector<std::unique_ptr<ASTVarDeclaration>> fDeclarations;
|
const std::vector<std::unique_ptr<ASTVarDeclarations>> fDeclarations;
|
||||||
|
|
||||||
typedef ASTDeclaration INHERITED;
|
typedef ASTDeclaration INHERITED;
|
||||||
};
|
};
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
* found in the LICENSE file.
|
* found in the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SKSL_ASTVARDECLARATION
|
#ifndef SKSL_ASTVARDECLARATIONS
|
||||||
#define SKSL_ASTVARDECLARATION
|
#define SKSL_ASTVARDECLARATIONS
|
||||||
|
|
||||||
#include "SkSLASTDeclaration.h"
|
#include "SkSLASTDeclaration.h"
|
||||||
#include "SkSLASTModifiers.h"
|
#include "SkSLASTModifiers.h"
|
||||||
@ -17,51 +17,68 @@
|
|||||||
namespace SkSL {
|
namespace SkSL {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A variable declaration, which may consist of multiple individual variables. For instance
|
* A single variable declaration within a var declaration statement. For instance, the statement
|
||||||
* 'int x, y = 1, z[4][2]' is a single ASTVarDeclaration. This declaration would have a type of
|
* 'int x = 2, y[3];' is an ASTVarDeclarations statement containing two individual ASTVarDeclaration
|
||||||
* 'int', names ['x', 'y', 'z'], sizes of [[], [], [4, 2]], and values of [null, 1, null].
|
* instances.
|
||||||
*/
|
*/
|
||||||
struct ASTVarDeclaration : public ASTDeclaration {
|
struct ASTVarDeclaration {
|
||||||
ASTVarDeclaration(ASTModifiers modifiers,
|
ASTVarDeclaration(const std::string name,
|
||||||
std::unique_ptr<ASTType> type,
|
std::vector<std::unique_ptr<ASTExpression>> sizes,
|
||||||
std::vector<std::string> names,
|
std::unique_ptr<ASTExpression> value)
|
||||||
std::vector<std::vector<std::unique_ptr<ASTExpression>>> sizes,
|
: fName(name)
|
||||||
std::vector<std::unique_ptr<ASTExpression>> values)
|
|
||||||
: INHERITED(type->fPosition, kVar_Kind)
|
|
||||||
, fModifiers(modifiers)
|
|
||||||
, fType(std::move(type))
|
|
||||||
, fNames(std::move(names))
|
|
||||||
, fSizes(std::move(sizes))
|
, fSizes(std::move(sizes))
|
||||||
, fValues(std::move(values)) {
|
, fValue(std::move(value)) {}
|
||||||
ASSERT(fNames.size() == fValues.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string description() const override {
|
std::string description() const {
|
||||||
std::string result = fModifiers.description() + fType->description() + " ";
|
std::string result = fName;
|
||||||
std::string separator = "";
|
for (const auto& size : fSizes) {
|
||||||
for (size_t i = 0; i < fNames.size(); i++) {
|
if (size) {
|
||||||
result += separator;
|
result += "[" + size->description() + "]";
|
||||||
separator = ", ";
|
} else {
|
||||||
result += fNames[i];
|
result += "[]";
|
||||||
for (size_t j = 0; j < fSizes[i].size(); j++) {
|
|
||||||
if (fSizes[i][j]) {
|
|
||||||
result += "[" + fSizes[i][j]->description() + "]";
|
|
||||||
} else {
|
|
||||||
result += "[]";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (fValues[i]) {
|
|
||||||
result += " = " + fValues[i]->description();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (fValue) {
|
||||||
|
result += " = " + fValue->description();
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string fName;
|
||||||
|
|
||||||
|
// array sizes, if any. e.g. 'foo[3][]' has sizes [3, null]
|
||||||
|
std::vector<std::unique_ptr<ASTExpression>> fSizes;
|
||||||
|
|
||||||
|
// initial value, may be null
|
||||||
|
std::unique_ptr<ASTExpression> fValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A variable declaration statement, which may consist of one or more individual variables.
|
||||||
|
*/
|
||||||
|
struct ASTVarDeclarations : public ASTDeclaration {
|
||||||
|
ASTVarDeclarations(ASTModifiers modifiers,
|
||||||
|
std::unique_ptr<ASTType> type,
|
||||||
|
std::vector<ASTVarDeclaration> vars)
|
||||||
|
: INHERITED(type->fPosition, kVar_Kind)
|
||||||
|
, fModifiers(modifiers)
|
||||||
|
, fType(std::move(type))
|
||||||
|
, fVars(std::move(vars)) {}
|
||||||
|
|
||||||
|
std::string description() const override {
|
||||||
|
std::string result = fModifiers.description() + fType->description() + " ";
|
||||||
|
std::string separator = "";
|
||||||
|
for (const auto& var : fVars) {
|
||||||
|
result += separator;
|
||||||
|
separator = ", ";
|
||||||
|
result += var.description();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
const ASTModifiers fModifiers;
|
const ASTModifiers fModifiers;
|
||||||
const std::unique_ptr<ASTType> fType;
|
const std::unique_ptr<ASTType> fType;
|
||||||
const std::vector<std::string> fNames;
|
const std::vector<ASTVarDeclaration> fVars;
|
||||||
const std::vector<std::vector<std::unique_ptr<ASTExpression>>> fSizes;
|
|
||||||
const std::vector<std::unique_ptr<ASTExpression>> fValues;
|
|
||||||
|
|
||||||
typedef ASTDeclaration INHERITED;
|
typedef ASTDeclaration INHERITED;
|
||||||
};
|
};
|
||||||
|
@ -17,15 +17,15 @@ namespace SkSL {
|
|||||||
* A variable declaration appearing as a statement within a function.
|
* A variable declaration appearing as a statement within a function.
|
||||||
*/
|
*/
|
||||||
struct ASTVarDeclarationStatement : public ASTStatement {
|
struct ASTVarDeclarationStatement : public ASTStatement {
|
||||||
ASTVarDeclarationStatement(std::unique_ptr<ASTVarDeclaration> decl)
|
ASTVarDeclarationStatement(std::unique_ptr<ASTVarDeclarations> decl)
|
||||||
: INHERITED(decl->fPosition, kVarDeclaration_Kind)
|
: INHERITED(decl->fPosition, kVarDeclaration_Kind)
|
||||||
, fDeclaration(std::move(decl)) {}
|
, fDeclarations(std::move(decl)) {}
|
||||||
|
|
||||||
std::string description() const override {
|
std::string description() const override {
|
||||||
return fDeclaration->description() + ";";
|
return fDeclarations->description() + ";";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<ASTVarDeclaration> fDeclaration;
|
std::unique_ptr<ASTVarDeclarations> fDeclarations;
|
||||||
|
|
||||||
typedef ASTStatement INHERITED;
|
typedef ASTStatement INHERITED;
|
||||||
};
|
};
|
||||||
|
@ -27,7 +27,7 @@ struct Statement : public IRNode {
|
|||||||
kFor_Kind,
|
kFor_Kind,
|
||||||
kIf_Kind,
|
kIf_Kind,
|
||||||
kReturn_Kind,
|
kReturn_Kind,
|
||||||
kVarDeclaration_Kind,
|
kVarDeclarations_Kind,
|
||||||
kWhile_Kind
|
kWhile_Kind
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
* found in the LICENSE file.
|
* found in the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SKSL_VARDECLARATION
|
#ifndef SKSL_VARDECLARATIONS
|
||||||
#define SKSL_VARDECLARATION
|
#define SKSL_VARDECLARATIONS
|
||||||
|
|
||||||
#include "SkSLExpression.h"
|
#include "SkSLExpression.h"
|
||||||
#include "SkSLStatement.h"
|
#include "SkSLStatement.h"
|
||||||
@ -15,51 +15,65 @@
|
|||||||
namespace SkSL {
|
namespace SkSL {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A variable declaration, which may consist of multiple individual variables. For instance
|
* A single variable declaration within a var declaration statement. For instance, the statement
|
||||||
* 'int x, y = 1, z[4][2];' is a single VarDeclaration. This declaration would have a base type of
|
* 'int x = 2, y[3];' is a VarDeclarations statement containing two individual VarDeclaration
|
||||||
* 'int', names ['x', 'y', 'z'], sizes of [[], [], [4, 2]], and values of [null, 1, null].
|
* instances.
|
||||||
*/
|
*/
|
||||||
struct VarDeclaration : public ProgramElement {
|
struct VarDeclaration {
|
||||||
VarDeclaration(Position position, const Type* baseType, std::vector<const Variable*> vars,
|
VarDeclaration(const Variable* var,
|
||||||
std::vector<std::vector<std::unique_ptr<Expression>>> sizes,
|
std::vector<std::unique_ptr<Expression>> sizes,
|
||||||
std::vector<std::unique_ptr<Expression>> values)
|
std::unique_ptr<Expression> value)
|
||||||
|
: fVar(var)
|
||||||
|
, fSizes(std::move(sizes))
|
||||||
|
, fValue(std::move(value)) {}
|
||||||
|
|
||||||
|
std::string description() const {
|
||||||
|
std::string result = fVar->fName;
|
||||||
|
for (const auto& size : fSizes) {
|
||||||
|
if (size) {
|
||||||
|
result += "[" + size->description() + "]";
|
||||||
|
} else {
|
||||||
|
result += "[]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fValue) {
|
||||||
|
result += " = " + fValue->description();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Variable* fVar;
|
||||||
|
std::vector<std::unique_ptr<Expression>> fSizes;
|
||||||
|
std::unique_ptr<Expression> fValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A variable declaration statement, which may consist of one or more individual variables.
|
||||||
|
*/
|
||||||
|
struct VarDeclarations : public ProgramElement {
|
||||||
|
VarDeclarations(Position position, const Type* baseType,
|
||||||
|
std::vector<VarDeclaration> vars)
|
||||||
: INHERITED(position, kVar_Kind)
|
: INHERITED(position, kVar_Kind)
|
||||||
, fBaseType(*baseType)
|
, fBaseType(*baseType)
|
||||||
, fVars(std::move(vars))
|
, fVars(std::move(vars)) {}
|
||||||
, fSizes(std::move(sizes))
|
|
||||||
, fValues(std::move(values)) {}
|
|
||||||
|
|
||||||
std::string description() const override {
|
std::string description() const override {
|
||||||
std::string result = fVars[0]->fModifiers.description();
|
if (!fVars.size()) {
|
||||||
const Type* baseType = &fVars[0]->fType;
|
return "";
|
||||||
while (baseType->kind() == Type::kArray_Kind) {
|
|
||||||
baseType = &baseType->componentType();
|
|
||||||
}
|
}
|
||||||
result += baseType->description();
|
std::string result = fVars[0].fVar->fModifiers.description() + fBaseType.description() +
|
||||||
std::string separator = " ";
|
" ";
|
||||||
for (size_t i = 0; i < fVars.size(); i++) {
|
std::string separator = "";
|
||||||
|
for (const auto& var : fVars) {
|
||||||
result += separator;
|
result += separator;
|
||||||
separator = ", ";
|
separator = ", ";
|
||||||
result += fVars[i]->fName;
|
result += var.description();
|
||||||
for (size_t j = 0; j < fSizes[i].size(); j++) {
|
|
||||||
if (fSizes[i][j]) {
|
|
||||||
result += "[" + fSizes[i][j]->description() + "]";
|
|
||||||
} else {
|
|
||||||
result += "[]";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (fValues[i]) {
|
|
||||||
result += " = " + fValues[i]->description();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
result += ";";
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Type& fBaseType;
|
const Type& fBaseType;
|
||||||
const std::vector<const Variable*> fVars;
|
const std::vector<VarDeclaration> fVars;
|
||||||
const std::vector<std::vector<std::unique_ptr<Expression>>> fSizes;
|
|
||||||
const std::vector<std::unique_ptr<Expression>> fValues;
|
|
||||||
|
|
||||||
typedef ProgramElement INHERITED;
|
typedef ProgramElement INHERITED;
|
||||||
};
|
};
|
||||||
|
@ -14,18 +14,18 @@
|
|||||||
namespace SkSL {
|
namespace SkSL {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A variable declaration appearing as a statement within a function.
|
* One or more variable declarations appearing as a statement within a function.
|
||||||
*/
|
*/
|
||||||
struct VarDeclarationStatement : public Statement {
|
struct VarDeclarationsStatement : public Statement {
|
||||||
VarDeclarationStatement(std::unique_ptr<VarDeclaration> decl)
|
VarDeclarationsStatement(std::unique_ptr<VarDeclarations> decl)
|
||||||
: INHERITED(decl->fPosition, kVarDeclaration_Kind)
|
: INHERITED(decl->fPosition, kVarDeclarations_Kind)
|
||||||
, fDeclaration(std::move(decl)) {}
|
, fDeclaration(std::move(decl)) {}
|
||||||
|
|
||||||
std::string description() const override {
|
std::string description() const override {
|
||||||
return fDeclaration->description();
|
return fDeclaration->description();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::shared_ptr<VarDeclaration> fDeclaration;
|
const std::shared_ptr<VarDeclarations> fDeclaration;
|
||||||
|
|
||||||
typedef Statement INHERITED;
|
typedef Statement INHERITED;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user