summaryrefslogtreecommitdiffstats
path: root/source/slang/check.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/check.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/check.cpp')
-rw-r--r--source/slang/check.cpp42
1 files changed, 42 insertions, 0 deletions
diff --git a/source/slang/check.cpp b/source/slang/check.cpp
index 1c1c6d5d3..26d28d495 100644
--- a/source/slang/check.cpp
+++ b/source/slang/check.cpp
@@ -1735,6 +1735,48 @@ namespace Slang
PopOuterStmt(stmt);
}
+
+ RefPtr<ExpressionSyntaxNode> checkExpressionAndExpectIntegerConstant(RefPtr<ExpressionSyntaxNode> expr, RefPtr<IntVal>* outIntVal)
+ {
+ expr = CheckExpr(expr);
+ auto intVal = CheckIntegerConstantExpression(expr);
+ if (outIntVal)
+ *outIntVal = intVal;
+ return expr;
+ }
+
+ void visitCompileTimeForStmt(CompileTimeForStmt* stmt)
+ {
+ PushOuterStmt(stmt);
+
+ stmt->varDecl->Type.type = ExpressionType::GetInt();
+ addModifier(stmt->varDecl, new ConstModifier());
+
+ RefPtr<IntVal> rangeBeginVal;
+ RefPtr<IntVal> rangeEndVal;
+
+ if (stmt->rangeBeginExpr)
+ {
+ stmt->rangeBeginExpr = checkExpressionAndExpectIntegerConstant(stmt->rangeBeginExpr, &rangeBeginVal);
+ }
+ else
+ {
+ RefPtr<ConstantIntVal> rangeBeginConst = new ConstantIntVal();
+ rangeBeginConst->value = 0;
+ rangeBeginVal = rangeBeginConst;
+ }
+
+ stmt->rangeEndExpr = checkExpressionAndExpectIntegerConstant(stmt->rangeEndExpr, &rangeEndVal);
+
+ stmt->rangeBeginVal = rangeBeginVal;
+ stmt->rangeEndVal = rangeEndVal;
+
+ checkStmt(stmt->body);
+
+
+ PopOuterStmt(stmt);
+ }
+
void visitSwitchStmt(SwitchStmt* stmt)
{
PushOuterStmt(stmt);