summaryrefslogtreecommitdiffstats
path: root/source/slang/lower.cpp
diff options
context:
space:
mode:
authorTim Foley <tfoley@nvidia.com>2017-07-18 14:51:12 -0700
committerTim Foley <tfoley@nvidia.com>2017-07-18 14:51:12 -0700
commit2476c035ec15d3ee22239ebd1fe10e6e8c1e01e3 (patch)
tree30e1bf209e232d7f8d6723959db68b2c0cb015dd /source/slang/lower.cpp
parent3d313d963f29f6ca6a8d12bd5c403a70c49aca2a (diff)
Add a compile-time loop construct to Slang
The basic syntax is: $for(i in Range(0,99)) { /* stuff goes here */ } Note that the exact form is very restrictive. All that you are allowed to change is `i`, `0`, `99` or `/* stuff goes here */`. As a tiny bit of syntax sugar, the following should work: $for(i in Range(99)) { /* stuff goes here */ } Note that the range given is half-open (C++ iterator `[begin,end)` style). Both the beginning and end of the range must be compile-time constant expressions that Slang knows how to constant-fold. The implementation will basically generate code for `/* stuff goes here */` N times, once for each value in the half-open range. Each time, the variable `i` will be replaced with a different compile-time-constant expression. While I was working on a test case for this, I also found that our build of glslang had an issue with resource limits, so I fixed that. Clients will need to build a new glslang to use the fix.
Diffstat (limited to 'source/slang/lower.cpp')
-rw-r--r--source/slang/lower.cpp35
1 files changed, 35 insertions, 0 deletions
diff --git a/source/slang/lower.cpp b/source/slang/lower.cpp
index bbbfe724b..127ef75ca 100644
--- a/source/slang/lower.cpp
+++ b/source/slang/lower.cpp
@@ -1628,6 +1628,41 @@ struct LoweringVisitor
lowerForStmtCommon(new UnscopedForStmt(), stmt);
}
+ void visitCompileTimeForStmt(CompileTimeForStmt* stmt)
+ {
+ // We can either lower this here, so that emit logic doesn't have to deal with it,
+ // or else just translate it and then let emit deal with it.
+ //
+ // The right answer is really to lower it here, I guess.
+
+ auto rangeBeginVal = GetIntVal(stmt->rangeBeginVal);
+ auto rangeEndVal = GetIntVal(stmt->rangeEndVal);
+
+ if (rangeBeginVal >= rangeEndVal)
+ return;
+
+ auto varDecl = stmt->varDecl;
+
+ auto varType = lowerType(varDecl->Type);
+
+ for (IntegerLiteralValue ii = rangeBeginVal; ii < rangeEndVal; ++ii)
+ {
+ RefPtr<ConstantExpressionSyntaxNode> constExpr = new ConstantExpressionSyntaxNode();
+ constExpr->Type.type = varType.type;
+ constExpr->ConstType = ConstantExpressionSyntaxNode::ConstantType::Int;
+ constExpr->integerValue = ii;
+
+ RefPtr<VaryingTupleVarDecl> loweredVarDecl = new VaryingTupleVarDecl();
+ loweredVarDecl->Position = varDecl->Position;
+ loweredVarDecl->Type = varType;
+ loweredVarDecl->Expr = constExpr;
+
+ shared->loweredDecls[varDecl] = loweredVarDecl;
+
+ lowerStmtImpl(stmt->body);
+ }
+ }
+
void visitWhileStatementSyntaxNode(WhileStatementSyntaxNode* stmt)
{
RefPtr<WhileStatementSyntaxNode> loweredStmt = new WhileStatementSyntaxNode();