Skip to content

Commit

Permalink
[bugfix] OKL for loop init statement (#618)
Browse files Browse the repository at this point in the history
  • Loading branch information
kris-rowe committed Aug 16, 2022
1 parent 6b0d5f2 commit 2e576e6
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 9 deletions.
41 changes: 33 additions & 8 deletions src/occa/internal/lang/modes/oklForStatement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ namespace occa {
if (!(0 < loop_range)) {
valid = false;
if(printErrors_)
forSmnt_.printError("OKL for loop is empty or infinite!");
forSmnt_.printError("OKL for loop range is empty or infinite!");
}
}
delete loop_range_node;
Expand All @@ -75,35 +75,60 @@ namespace occa {

bool oklForStatement::hasValidInit() {
statement_t &initSmnt = *(forSmnt.init);
// Check for declaration
if (initSmnt.type() != statementType::declaration) {
if (printErrors) {
initSmnt.printError(sourceStr() + "Expected a declaration statement");
}
const auto init_statement_type = initSmnt.type();

if(statementType::empty == init_statement_type) {
if(printErrors)
initSmnt.printError(sourceStr()
+ "OKL for loop init-statement cannot be be a null statement");
return false;
}

if(statementType::declaration != init_statement_type) {
if(printErrors)
initSmnt.printError(sourceStr()
+ "OKL for loop init-statement must be a simple declaration with initializer");
return false;
}

// Can only have one declaration
declarationStatement &declSmnt = (declarationStatement&) initSmnt;

if (declSmnt.declarations.size() > 1) {
if (printErrors) {
declSmnt.declarations[1].printError(
sourceStr() + "Can only have 1 iterator variable"
sourceStr() + "OKL for loops can only have 1 iterator variable"
);
}
return false;
}

// Get iterator and value
variableDeclaration &decl = declSmnt.declarations[0];
iterator = &decl.variable();
if(!(iterator->isNamed())) {
if(printErrors)
declSmnt.printError(sourceStr()
+ "OKL for loop variable does not have a name.");
return false;
}

if(!decl.hasValue()) {
if(printErrors)
decl.printError(sourceStr()
+ "OKL for loop variable is not initialized.");
return false;
}
initValue = decl.value;

// Valid types: {char, short, int, long}
const type_t *type = iterator->vartype.flatten().type;
if (!type ||
((*type != char_) &&
(*type != short_) &&
(*type != int_))) {
if (printErrors) {
iterator->printError(sourceStr() + "Iterator variable needs to be of type"
iterator->printError(sourceStr() + "OKL for loop iterator variable needs to be of type"
" [char, short, int, long]");
}
return false;
Expand Down
2 changes: 1 addition & 1 deletion src/occa/internal/lang/variable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ namespace occa {
}

bool variable_t::isNamed() const {
return source->value.size();
return !(this->name().empty());
}

std::string& variable_t::name() {
Expand Down
6 changes: 6 additions & 0 deletions tests/src/internal/lang/modes/okl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ void testProperOKLLoops() {
parseBadOKLSource(oStart + "for (int o = 0; o < 2;; @outer) {" + oMid + "}" + oEnd);
parseBadOKLSource(oStart + "for (int o = 0; o < 2; o *= 2; @outer) {" + oMid + "}" + oEnd);
parseBadOKLSource(oStart + "for (int o = 0; o < 2; ++j; @outer) {" + oMid + "}" + oEnd);
parseBadOKLSource(oStart + "for (int o; o < 2; ++o; @outer) {" + oMid + "}" + oEnd);
parseBadOKLSource(oStart + "for (int; o < 2; ++o; @outer) {" + oMid + "}" + oEnd);
parseBadOKLSource(oStart + "for ( ; o < 2; ++o; @outer) {" + oMid + "}" + oEnd);

parseBadOKLSource(iStart + "for (i = 0;;; @inner) {}" + iEnd);
parseBadOKLSource(iStart + "for (float i = 0;;; @inner) {}" + iEnd);
Expand All @@ -107,6 +110,9 @@ void testProperOKLLoops() {
parseBadOKLSource(iStart + "for (int i = 0; i < 2;; @inner) {}" + iEnd);
parseBadOKLSource(iStart + "for (int i = 0; i < 2; i *= 2; @inner) {}" + iEnd);
parseBadOKLSource(iStart + "for (int i = 0; i < 2; ++j; @inner) {}" + iEnd);
parseBadOKLSource(iStart + "for (int i; i < 2; ++i; @inner) {}" + iEnd);
parseBadOKLSource(iStart + "for (int; i < 2; ++i; @inner) {}" + iEnd);
parseBadOKLSource(iStart + "for ( ; i < 2; ++i; @inner) {}" + iEnd);

// No double @outer + @inner
parseBadOKLSource(
Expand Down

0 comments on commit 2e576e6

Please sign in to comment.